MiniprogramController.php 12 KB

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