MiniprogramController.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. <?php
  2. namespace Modules\Manage\Http\Controllers;
  3. use Catch\Exceptions\FailedException;
  4. use Illuminate\Foundation\Validation\ValidatesRequests;
  5. use Illuminate\Routing\Controller;
  6. use Catch\Base\CatchController;
  7. use Illuminate\Http\Request;
  8. use Illuminate\Support\Facades\DB;
  9. use Modules\Channel\Exceptions\ChannelBusinessException;
  10. use Modules\Channel\Models\UserHasMiniprograms;
  11. use Modules\Channel\Services\User\UserService;
  12. use Modules\Common\Errors\Errors;
  13. use Modules\Manage\Enmus\MiniprogramType;
  14. use Modules\Manage\Http\Requests\MiniprogramRequest;
  15. use Modules\Manage\Http\Requests\MiniprogramUpdateRequest;
  16. use Modules\Manage\Models\Miniprogram;
  17. use Modules\User\Http\Controllers\UserTrait;
  18. class MiniprogramController extends CatchController
  19. {
  20. use UserTrait;
  21. use ValidatesRequests;
  22. public function __construct(protected readonly Miniprogram $miniprogram, protected readonly UserHasMiniprograms $userHasMiniprograms)
  23. {
  24. }
  25. const COMPANY_ROLE = 'company';
  26. const ADMINISTRATOR_ROLE = 'administrator';
  27. const OPTIMIZER_ROLE = 'optimizer';
  28. /**
  29. * 小程序列表
  30. * @param Request $request
  31. * @return void
  32. */
  33. public function index(Request $request)
  34. {
  35. $uid = $this->getLoginUser()->id;
  36. $name = $request->get('name');
  37. $play_name = $request->get('play_name');
  38. $company = $request->get('company');
  39. $type = $request->get('type');
  40. $page_size = $request->input('limit', 15);
  41. $where = [];
  42. if ($name) {
  43. $where[] = ['name', 'like', '%' . $name . '%'];
  44. }
  45. if ($play_name) {
  46. $where[] = ['play_name', 'like', '%' . $play_name . '%'];
  47. }
  48. if ($company) {
  49. $where[] = ['company', 'like', '%' . $company . '%'];
  50. }
  51. if ($type) {
  52. $where[] = ['type', '=', $type];
  53. }
  54. if (UserService::userHasRole($uid, 'administrator')) {
  55. $result = $this->miniprogram->where($where)->orderBy('id', 'desc')->paginate($page_size);
  56. } else {
  57. $result = $this->userHasMiniprograms->join('miniprogram', 'miniprogram.id', '=', 'user_has_miniprograms.miniprogram_id')
  58. ->where('user_has_miniprograms.is_enabled', 1)
  59. ->where('uid', $uid)
  60. ->where($where)
  61. ->select('miniprogram.*')
  62. ->paginate($page_size);
  63. }
  64. foreach ($result as $item) {
  65. $item->type_name = MiniprogramType::from($item->type)->name();
  66. $item->status_name = $item->status == 1 ? '启用' : '禁用';
  67. $item->pay_merchant_name = getProp($item->pay_merchant_info, 'name', '-');
  68. unset($item->pay_merchant_info);
  69. }
  70. return $result;
  71. }
  72. /**
  73. * 添加小程序
  74. *
  75. * @param MiniprogramRequest $request
  76. * @return void
  77. */
  78. public function store(MiniprogramRequest $request)
  79. {
  80. $validate_result = $request->validated();
  81. $validate_result['remark'] = $request->post('remark', '') ?? '';
  82. $validate_result['pay_merchant_id'] = $request->post('pay_merchant_id', 0);
  83. if (getProp($validate_result, 'pay_merchant_id', 0)) {
  84. $info = DB::table('pay_merchants')->where('id', $validate_result['pay_merchant_id'])->first();
  85. if (empty($info)) {
  86. throw new FailedException("支付方式不存在");
  87. }
  88. if ($info->miniprogram_type != $validate_result['type']) {
  89. throw new FailedException("小程序类型和支付的小程序类型不匹配");
  90. }
  91. $validate_result['pay_merchant_info'] = [
  92. 'pay_merchant_id' => $info->id,
  93. 'name' => $info->name,
  94. 'pay_type' => $info->pay_type,
  95. 'payee_name' => $info->payee_name,
  96. 'miniprogram_type' => $info->miniprogram_type,
  97. 'pay_appid' => $info->pay_appid,
  98. ];
  99. } else {
  100. $validate_result['pay_merchant_id'] = 0;
  101. $validate_result['pay_merchant_info'] = [];
  102. }
  103. return $this->miniprogram->create($validate_result)->toArray();
  104. }
  105. /**
  106. * 小程序详情
  107. *
  108. * @param [type] $id
  109. * @return void
  110. */
  111. public function show($id)
  112. {
  113. return $this->miniprogram->find($id)->toArray();
  114. }
  115. /**
  116. * 更新小程序
  117. *
  118. * @param [type] $id
  119. * @param MiniprogramUpdateRequest $request
  120. * @return void
  121. */
  122. public function update($id, MiniprogramUpdateRequest $request)
  123. {
  124. $validate_result = $request->validated();
  125. if ($request->post('remark', '')) {
  126. $validate_result['remark'] = $request->post('remark', '');
  127. }
  128. if (getProp($validate_result, 'pay_merchant_id', 0)) {
  129. $info = DB::table('pay_merchants')->where('id', $validate_result['pay_merchant_id'])->first();
  130. if (empty($info)) {
  131. throw new FailedException("支付方式不存在");
  132. }
  133. if ($info->miniprogram_type != $validate_result['type']) {
  134. throw new FailedException("小程序类型和支付的小程序类型不匹配");
  135. }
  136. $validate_result['pay_merchant_info'] = [
  137. 'pay_merchant_id' => $info->id,
  138. 'name' => $info->name,
  139. 'pay_type' => $info->pay_type,
  140. 'payee_name' => $info->payee_name,
  141. 'miniprogram_type' => $info->miniprogram_type,
  142. 'pay_appid' => $info->pay_appid,
  143. ];
  144. } else {
  145. $validate_result['pay_merchant_id'] = 0;
  146. $validate_result['pay_merchant_info'] = [];
  147. }
  148. $this->miniprogram->where('id', $id)->update($validate_result);
  149. return [];
  150. }
  151. /**
  152. * 小程序类型列表
  153. *
  154. * @return array [ ['name'=>'微信小程序','id'=>1],[],[] ]
  155. */
  156. public function typeList()
  157. {
  158. $type_list = MiniprogramType::cases();
  159. $data = array_map(fn($item) => ['name' => $item->name(), 'value' => $item->value()], $type_list);
  160. return $data;
  161. }
  162. /**
  163. * 获取所有公司
  164. *
  165. * @return void
  166. */
  167. public function companyList()
  168. {
  169. return $this->miniprogram->select(DB::raw('distinct company'))->get()->pluck('company');
  170. }
  171. /**
  172. * 绑定小程序和投放公司的关系 或者投放公司把小程序分配给优化师
  173. * @param [type] $miniprogram_id
  174. * @param Request $request uid=2,3,4,5 actison=on|off on:分配,off取消分配
  175. * @return array
  176. *
  177. */
  178. public function allocationStore($miniprogram_id, Request $request)
  179. {
  180. $uid = $this->getLoginUser()->id;
  181. if (!UserService::userHasRoles($uid, [self::COMPANY_ROLE, self::ADMINISTRATOR_ROLE])) {
  182. ChannelBusinessException::throwError(Errors::PARAM_EMPTY);
  183. }
  184. $uids = $request->post('uids');
  185. $action = $request->post('action');
  186. if (empty($miniprogram_id) || empty($uids) || empty($action) || !in_array($action, ['on', 'off'])) {
  187. ChannelBusinessException::throwError(Errors::PARAM_EMPTY);
  188. }
  189. $miniprogram_info = $this->miniprogram->find($miniprogram_id);
  190. if (!$miniprogram_info || $miniprogram_info->status == 0) {
  191. ChannelBusinessException::throwError(Errors::MINIPROGRAM_STATUS_ERROR);
  192. }
  193. $userContext = $this->getUserContext(null);
  194. if ($userContext['loginUserRoles']->contains(self::COMPANY_ROLE)) {
  195. // 公司给投手分配小程序
  196. return $this->allocationStoreCompany($miniprogram_id, $uids, $action);
  197. } else {
  198. $companyId = explode(',', $uids)[0] ?: 0;
  199. if (empty($companyId)) {
  200. ChannelBusinessException::throwError(Errors::PARAM_EMPTY);
  201. }
  202. if (!UserService::userHasRoles($companyId, [self::COMPANY_ROLE])) {
  203. ChannelBusinessException::throwError(Errors::MINIPROGRAM_OWNER_ACCOUNT_ROLE_ERROR);
  204. }
  205. // 小程序原拥有公司账号id
  206. $ownerCompanyId = DB::table('user_has_miniprograms as up')
  207. ->leftJoin('user_has_roles as ur', 'ur.user_id', '=', 'up.uid')
  208. ->leftJoin('roles as r', 'r.id', '=', 'ur.role_id')
  209. ->where('up.is_enabled', 1)
  210. ->where('up.miniprogram_id', $miniprogram_id)
  211. ->where('r.identify', 'company')->orderBy('up.id', 'desc')
  212. ->value('up.uid');
  213. if ($companyId == $ownerCompanyId) {
  214. // 相同则不修改
  215. return true;
  216. }
  217. if ($ownerCompanyId > 0) {
  218. // 若小程序已经分配给其他公司
  219. $this->userHasMiniprograms::where('miniprogram_id', $miniprogram_id)->update(['is_enabled' => 0]);
  220. }
  221. $result = $this->userHasMiniprograms->where('uid', $companyId)->where('miniprogram_id', $miniprogram_id)->first();
  222. if ($result) {
  223. if ($result->is_enabled == 0) {
  224. $result->is_enabled = 1;
  225. $result->save();
  226. }
  227. return true;
  228. }
  229. $this->userHasMiniprograms->create([
  230. 'uid' => $companyId, 'miniprogram_id' => $miniprogram_id, 'is_enabled' => 1
  231. ]);
  232. return true;
  233. }
  234. }
  235. protected function allocationStoreCompany($miniprogram_id, $uids, $action)
  236. {
  237. return collect(explode(',', $uids))->filter(function (int $value, int $key) use ($miniprogram_id, $action) {
  238. $user_access = UserService::userHasRoles($value, [self::COMPANY_ROLE, self::OPTIMIZER_ROLE]);
  239. //只能分配给投手公司或者优化师
  240. if ($user_access) {
  241. $result = $this->userHasMiniprograms->where('uid', $value)->where('miniprogram_id', $miniprogram_id)->first();
  242. if ($action == 'off') {
  243. if ($result) {
  244. $result->is_enabled = 0;
  245. $result->save();
  246. }
  247. return true;
  248. }
  249. if ($result) {
  250. if ($result->is_enabled == 0) {
  251. $result->is_enabled = 1;
  252. $result->save();
  253. }
  254. return true;
  255. }
  256. $this->userHasMiniprograms->create([
  257. 'uid' => $value, 'miniprogram_id' => $miniprogram_id, 'is_enabled' => 1
  258. ]);
  259. return true;
  260. }
  261. return false;
  262. });
  263. }
  264. /**
  265. * 获取投手公司和小程序的绑定关系,用于前端数据回显
  266. * @param [type] $miniprogram_id
  267. * @return []
  268. * response = [
  269. * 'on'=>[ ['id'=>1,'username'=>'公司1','user_has_miniprogram'=>1],[] ],
  270. * 'off'=>[['id'=>1,'username'=>'公司1','user_has_miniprogram'=>0],[]],
  271. * 'all'=>[
  272. * ['id'=>1,'username'=>'公司1','user_has_miniprogram'=>1],
  273. * ['id'=>2,'username'=>'公司1','user_has_miniprogram'=>0]
  274. * ]
  275. * ]
  276. *
  277. */
  278. public function getAllocationInfo($miniprogram_id)
  279. {
  280. $uid = $this->getLoginUser()->id;
  281. if (UserService::userHasRole($uid, self::ADMINISTRATOR_ROLE)) {
  282. $all_company_account = UserService::listByRole(self::COMPANY_ROLE, ['users.username', 'users.id']);
  283. } else {
  284. $all_company_account = UserService::getOptimizers($uid, ['users.username', 'users.id']);
  285. }
  286. $result = $all_company_account->map(function ($item, $key) use ($miniprogram_id) {
  287. $info = $this->userHasMiniprograms->where('uid', $item->id)->where('miniprogram_id', $miniprogram_id)->where('is_enabled', 1)->count();
  288. if ($info) {
  289. $item->user_has_miniprogram = 1;
  290. $item->user_has_miniprogram_flag = 'on';
  291. } else {
  292. $item->user_has_miniprogram = 0;
  293. $item->user_has_miniprogram_flag = 'off';
  294. }
  295. return $item;
  296. });
  297. $group = $result->groupBy('user_has_miniprogram_flag')->toArray();
  298. if (!isset($group['on'])) {
  299. $group['on'] = [];
  300. }
  301. if (!isset($group['off'])) {
  302. $group['off'] = [];
  303. }
  304. $group['all'] = $result->toArray();
  305. return $group;
  306. }
  307. /**
  308. * 设置染色时间
  309. * @param Request $request
  310. */
  311. public function setRanseDuration(Request $request) {
  312. $this->validate($request, [
  313. 'no_charge_user_duration' => 'required|integer|min:0',
  314. 'charge_user_duration' => 'required|integer|gte:no_charge_user_duration',
  315. 'miniprogram_id' => 'required|min:1',
  316. ]);
  317. $uid = $this->getLoginUserId();
  318. $now = date('Y-m-d H:i:s');
  319. DB::table('ranse_config')
  320. ->where([
  321. ['user_id', '=', $uid],
  322. ['is_enabled', '=', 1],
  323. ['miniprogram_id', '=', $request->input('miniprogram_id')]
  324. ])
  325. ->update(['is_enabled' => 0, 'updated_at' => $now]);
  326. DB::table('ranse_config')
  327. ->insert([
  328. 'user_id' => $uid, 'is_enabled' => 1,
  329. 'no_charge_user_duration' => $request->input('no_charge_user_duration'),
  330. 'charge_user_duration' => $request->input('charge_user_duration'),
  331. 'miniprogram_id' => $request->input('miniprogram_id'),
  332. 'created_at' => $now, 'updated_at' => $now,
  333. ]);
  334. return 'ok';
  335. }
  336. /**
  337. * 获取染色时间
  338. * @param Request $request
  339. * @return array
  340. */
  341. public function getRanseDuration(Request $request) {
  342. $uid = $this->getLoginUserId();
  343. $config = DB::table('ranse_config')
  344. ->where([
  345. ['user_id', '=', $uid],
  346. ['is_enabled', '=', 1],
  347. ['miniprogram_id', '=', $request->input('miniprogram_id')]
  348. ])
  349. ->first();
  350. if(!$config) {
  351. $config = DB::table('ranse_config')
  352. ->where([
  353. 'user_id' => 0, 'miniprogram_id' => 0, 'is_enabled' =>1
  354. ])->first();
  355. }
  356. return [
  357. 'charge_user_duration' => $config->charge_user_duration,
  358. 'no_charge_user_duration' => $config->no_charge_user_duration,
  359. ];
  360. }
  361. }