QuotaController.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <?php
  2. namespace app\admin\controller\member;
  3. use app\admin\service\added\AddedService;
  4. use app\admin\validate\member\RuleAddedValidate;
  5. use app\admin\validate\member\RulePricingValidate;
  6. use app\controller\Curd;
  7. use app\model\Member;
  8. use app\model\MemberQuota;
  9. use app\model\RuleAdded;
  10. use app\model\RuleAddedComponent;
  11. use app\model\RulePricing;
  12. use app\model\SysSerial;
  13. use app\model\SysUser;
  14. use support\Db;
  15. use support\Redis;
  16. use support\exception\BusinessException;
  17. use support\Request;
  18. use support\Response;
  19. use support\view\Raw;
  20. use Tinywan\Jwt\JwtToken;
  21. class QuotaController extends Curd
  22. {
  23. public function __construct()
  24. {
  25. $this->model = new MemberQuota();
  26. // $this->validate = true;
  27. // $this->validateClass = new RuleAddedValidate();
  28. }
  29. public function select(Request $request): Response
  30. {
  31. $page = $request->get('page', 1);
  32. $pageSize = $request->get('pageSize', 20);
  33. $keywords = $request->get('keywords', '');
  34. $memberId = $request->get('member_id', '');
  35. $memberIds = [];
  36. if (!empty($keywords)) {
  37. $memberIds = Member::leftJoin('member_cert', 'member_cert.join_cert_member_id', '=', 'member.member_id')
  38. ->where('member.member_mobile', 'like', '%' . $keywords . '%')
  39. ->orWhere('member_cert.member_cert_name', 'like', '%' . $keywords . '%')
  40. ->pluck('member.member_id')
  41. ->toArray();
  42. if (empty($memberIds)) {
  43. return json_success('', []);
  44. }
  45. }
  46. if (!empty($memberId)) {
  47. $memberIds = $memberId;
  48. }
  49. foreach ($memberIds as &$id) {
  50. $id = "'" . $id . "'";
  51. }
  52. $rows = MemberQuota::select('join_quota_member_id', 'join_member_rule_added_component_id', Db::raw('MAX(`member_quota_addtimes`) as `new_addtimes`'))
  53. // ->when(!empty($memberIds), function ($query) use ($placeholders,$pars) {
  54. // $query->whereRaw("join_quota_member_id in ($placeholders))", $pars);
  55. // })
  56. ->when(!empty($memberIds), function ($query) use ($memberIds) {
  57. $query->whereIn('join_quota_member_id', $memberIds);
  58. })
  59. ->groupBy('join_member_rule_added_component_id', 'join_quota_member_id');
  60. $bindings = $rows->getBindings();
  61. $sql = str_replace('?', '%s', $rows->toSql());
  62. $sql = sprintf($sql, ...$bindings);
  63. $total = MemberQuota::from(Db::raw("({$sql}) t"))->count();
  64. $rows = MemberQuota::from(Db::raw("({$sql}) t"))
  65. ->orderBy('new_addtimes', 'desc')
  66. // ->orderByDesc('new_addtimes')
  67. ->forPage($page, $pageSize)
  68. ->get()
  69. ->toArray();
  70. foreach ($rows as &$row) {
  71. $quota = MemberQuota::with([
  72. 'member' => function ($query) {
  73. $query->select('member_id', 'member_mobile');
  74. },
  75. 'cert' => function ($query) {
  76. $query->select('join_cert_member_id', 'member_cert_name');
  77. },
  78. 'component' => function ($query) {
  79. $query->select('rule_added_component_id', 'rule_added_component_name');
  80. }
  81. ])->where('join_quota_member_id', $row['join_quota_member_id'])
  82. ->where('join_member_rule_added_component_id', $row['join_member_rule_added_component_id'])
  83. ->first()
  84. ->toArray();
  85. $quotaUsed = MemberQuota::where('join_quota_member_id', $row['join_quota_member_id'])
  86. ->where('join_member_rule_added_component_id', $row['join_member_rule_added_component_id'])
  87. ->where('member_quota_status', 'USED')
  88. ->count();
  89. $quota['used'] = $quotaUsed;
  90. if ($quota['member_quota_nbr'] == '-99.00') {
  91. $quota['total'] = '不限次';
  92. $quota['unused'] = '不限次';
  93. } else {
  94. $quotaTotal = MemberQuota::where('join_quota_member_id', $row['join_quota_member_id'])
  95. ->where('join_member_rule_added_component_id', $row['join_member_rule_added_component_id'])
  96. ->count();
  97. $quota['total'] = $quotaTotal;
  98. $quota['unused'] = $quotaTotal - $quotaUsed;
  99. }
  100. if (!empty($quota['member']) && !empty($quota['member']['member_mobile'])) {
  101. $quota['member']['member_mobile'] = substr_replace($quota['member']['member_mobile'], '****', 3, 4);
  102. }
  103. $addedId = RuleAddedComponent::where('rule_added_component_id', $row['join_member_rule_added_component_id'])->value('join_component_rule_added_id');
  104. $addedName = RuleAdded::where('rule_added_id', $addedId)->value('rule_added_name');
  105. $quota['added_name'] = $addedName;
  106. $row = $quota;
  107. }
  108. return json_success('', compact('rows', 'page', 'pageSize', 'total'));
  109. }
  110. protected function doSelect(array $where, string $field = null, string $order = 'desc')
  111. {
  112. $model = $this->model->with([
  113. 'member' => function ($query) {
  114. $query->select('member_id', 'member_mobile');
  115. },
  116. 'cert' => function ($query) {
  117. $query->select('join_cert_member_id', 'member_cert_name');
  118. },
  119. 'component' => function ($query) {
  120. $query->select('rule_added_component_id', 'rule_added_component_name');
  121. }
  122. ]);
  123. $model = $model->groupBy('join_member_rule_added_component_id');
  124. foreach ($where as $column => $value) {
  125. if (is_array($value)) {
  126. if ($value[0] === 'like' || $value[0] === 'not like') {
  127. $model = $model->where($column, $value[0], "%$value[1]%");
  128. } elseif (in_array($value[0], ['>', '=', '<', '<>'])) {
  129. $model = $model->where($column, $value[0], $value[1]);
  130. } elseif ($value[0] == 'in' && !empty($value[1])) {
  131. $valArr = $value[1];
  132. if (is_string($value[1])) {
  133. $valArr = explode(",", trim($value[1]));
  134. }
  135. $model = $model->whereIn($column, $valArr);
  136. } elseif ($value[0] == 'not in' && !empty($value[1])) {
  137. $valArr = $value[1];
  138. if (is_string($value[1])) {
  139. $valArr = explode(",", trim($value[1]));
  140. }
  141. $model = $model->whereNotIn($column, $valArr);
  142. } elseif ($value[0] == 'null') {
  143. $model = $model->whereNull($column);
  144. } elseif ($value[0] == 'not null') {
  145. $model = $model->whereNotNull($column);
  146. } elseif ($value[0] !== '' || $value[1] !== '') {
  147. $model = $model->whereBetween($column, $value);
  148. }
  149. } else {
  150. $model = $model->where($column, $value);
  151. }
  152. }
  153. if ($field) {
  154. $model = $model->orderBy($field, $order);
  155. }
  156. return $model;
  157. }
  158. // protected function insertInput(Request $request): array
  159. // {
  160. // $data = $this->inputFilter($request->post());
  161. // $data['rule_added_id'] = "RA" . str_pad(SysSerial::getSerial(), 16, '0', STR_PAD_LEFT) . random_string(6, 'up');
  162. //
  163. // return $data;
  164. // }
  165. protected function updateInput(Request $request): array
  166. {
  167. $primary_key = $this->model->getKeyName();
  168. $id = $request->post($primary_key);
  169. $data = $this->inputFilter($request->post());
  170. // if (!empty($data['rule_pricing_goods_json'])) {
  171. // $data['rule_pricing_goods_json'] = json_encode(explode(',', $data['rule_pricing_goods_json']));
  172. // } else {
  173. // $data['rule_pricing_goods_json'] = '[]';
  174. // }
  175. $model = $this->model->find($id);
  176. if (!$model) {
  177. throw new BusinessException('记录不存在', 2);
  178. }
  179. unset($data[$primary_key]);
  180. return [$id, $data];
  181. }
  182. public function writeOffList(Request $request)
  183. {
  184. $page = $request->get('page', 1);
  185. $pageSize = $request->get('pageSize', 20);
  186. $memberId = $request->get('member_id', '');
  187. $componentId = $request->get('component_id', '');
  188. $quotas = MemberQuota::with([
  189. 'member' => function ($query) {
  190. $query->select('member_id', 'member_mobile');
  191. },
  192. 'cert' => function ($query) {
  193. $query->select('join_cert_member_id', 'member_cert_name');
  194. },
  195. 'component' => function ($query) {
  196. $query->select('rule_added_component_id', 'rule_added_component_name');
  197. }
  198. ])->where('join_quota_member_id', $memberId)
  199. ->where('join_member_rule_added_component_id', $componentId)
  200. ->where('member_quota_status', 'USED');
  201. $total = $quotas->count('*');
  202. $rows = $quotas->orderBy('member_quota_used_json->charge->charge_write_off_time', 'desc')
  203. ->forPage($page, $pageSize)
  204. ->get()
  205. ->toArray();
  206. foreach ($rows as &$quota) {
  207. $quota['premises'] = '';
  208. $quota['username'] = '';
  209. if (!empty($quota['member_quota_used_json'])) {
  210. $usedJson = json_decode($quota['member_quota_used_json'], true);
  211. $quota['premises'] = $usedJson['charge']['charge_premises'] ?? '';
  212. $quota['remark'] = $usedJson['charge']['charge_content'] ?? '';
  213. if (isset($usedJson['charge']['charge_user_id'])) {
  214. $user = SysUser::where('user_id', $usedJson['charge']['charge_user_id'])
  215. ->select('user_id', 'user_name')
  216. ->first();
  217. if ($user) {
  218. $quota['username'] = $user->user_name;
  219. }
  220. }
  221. }
  222. if (!empty($quota['member']) && !empty($quota['member']['member_mobile'])) {
  223. $quota['member']['member_mobile'] = substr_replace($quota['member']['member_mobile'], '****', 3, 4);
  224. }
  225. }
  226. return json_success('', compact('rows', 'page', 'pageSize', 'total'));
  227. // return json_success('', $quotas);
  228. }
  229. /**
  230. * @Desc 额度核销
  231. * @Author Gorden
  232. * @Date 2024/6/4 8:32
  233. *
  234. * @param Request $request
  235. * @return Response
  236. */
  237. public function writeOff(Request $request)
  238. {
  239. $params = $request->post();
  240. $memberId = $params['member_id'] ?? [];
  241. $componentId = $params['component_id'] ?? [];
  242. $nbr = $params['nbr'];
  243. $times = $params['times'] ?? '';
  244. $code = $params['sms_code'] ?? '';
  245. if (!$memberId || !$componentId) {
  246. return json_fail("参数异常");
  247. }
  248. $quotas = MemberQuota::where('join_quota_member_id', $memberId[0])
  249. ->where('join_member_rule_added_component_id', $componentId[0])
  250. ->where('member_quota_status', 'PENDING')
  251. ->limit($nbr)
  252. ->get()
  253. ->toArray();
  254. if ($quotas[0]['member_quota_nbr'] != '-99.00' && count($quotas) < intval($nbr)) {
  255. return json_fail("可核销数量不足");
  256. }
  257. $member = Member::find(current($memberId));
  258. $mobile = $member->member_mobile;
  259. $key = "SMS:CODE:QUOTA:" . $mobile;
  260. $redisCode = Redis::get($key);
  261. if ($redisCode != $code) {
  262. return json_fail("验证码错误,请重新输入");
  263. }
  264. Redis::del($key);
  265. if (!$times) {
  266. $params['times'] = date('Y-m-d H:i:s');
  267. } else {
  268. $params['times'] = date('Y-m-d H:i:s', strtotime($times));
  269. }
  270. try {
  271. // 生成核销数据
  272. $writeOffData = AddedService::generateWriteOffData($params);
  273. if ($quotas[0]['member_quota_nbr'] != '-99.00') {
  274. foreach ($quotas as $quota) {
  275. $writeOffData['member_quota_id'] = $quota['member_quota_id'];
  276. MemberQuota::where('member_quota_id', $quota['member_quota_id'])->update([
  277. 'member_quota_status' => 'USED',
  278. 'member_quota_used_json' => json_encode($writeOffData)
  279. ]);
  280. }
  281. } else {
  282. $quota = $quotas[0];
  283. for ($i = 0; $i < $nbr; $i++) {
  284. $quota['member_quota_id'] = 'MQ' . date('ymdH') . random_string(6, 'up');
  285. $quota['member_quota_status'] = 'USED';
  286. $quota['member_quota_used_json'] = json_encode($writeOffData);
  287. $quota['member_quota_addtimes'] = strtotime($quota['member_quota_addtimes']);
  288. $quota['member_quota_nbr'] = 1;
  289. MemberQuota::insert($quota);
  290. }
  291. }
  292. _syslog("核销", "核销成功");
  293. return json_success("核销成功");
  294. } catch (\Exception $e) {
  295. dump($e->getMessage());
  296. _syslog("核销", "核销失败");
  297. return json_fail("核销失败");
  298. }
  299. }
  300. /**
  301. * @Desc 额度核销-批量
  302. * @Author Gorden
  303. * @Date 2024/6/4 8:32
  304. *
  305. * @param Request $request
  306. * @return Response
  307. */
  308. public function writeOffBatch(Request $request)
  309. {
  310. $params = $request->post();
  311. $memberId = $params['member_id'] ?? '';
  312. $times = $params['times'] ?? '';
  313. $code = $params['sms_code'] ?? '';
  314. if (!$memberId || !$code) {
  315. return json_fail("参数异常");
  316. }
  317. // 验证码核验
  318. $member = Member::find($memberId);
  319. $mobile = $member->member_mobile;
  320. $key = "SMS:CODE:WRITE_OFF:" . $mobile;
  321. $redisCode = Redis::get($key);
  322. if ($redisCode != $code) {
  323. return json_fail("验证码错误,请重新输入");
  324. }
  325. if (!$times) {
  326. $params['times'] = date('Y-m-d H:i:s');
  327. } else {
  328. $params['times'] = date('Y-m-d H:i:s', strtotime($times));
  329. }
  330. Db::beginTransaction();
  331. try {
  332. foreach ($params['quotaList'] as $quota) {
  333. if (!isset($quota['nbr']) || intval($quota['nbr']) == 0) {
  334. continue;
  335. }
  336. $nbr = intval($quota['nbr']);
  337. $quotas = MemberQuota::where('join_quota_member_id', $memberId)
  338. ->where('join_member_rule_added_component_id', $quota['rule_added_component_id'])
  339. ->where('member_quota_status', 'PENDING')
  340. ->limit($nbr)
  341. ->get()
  342. ->toArray();
  343. if ($quotas[0]['member_quota_nbr'] != '-99.00' && count($quotas) < intval($nbr)) {
  344. Db::rollBack();
  345. return json_fail("可核销数量不足");
  346. }
  347. // 生成核销数据
  348. $param = [
  349. 'component_id' => $quota['rule_added_component_id'],
  350. 'member_id' => $memberId,
  351. 'write_off_member_id' => $params['write_off_member_id'],
  352. 'dept_premises_id' => $params['dept_premises_id'] ?? '',
  353. 'times' => $params['times'],
  354. 'remark' => $params['remark'] ?? ''
  355. ];
  356. $writeOffData = AddedService::generateWriteOffData($param);
  357. if ($quotas[0]['member_quota_nbr'] != '-99.00') {
  358. foreach ($quotas as $quota) {
  359. $writeOffData['member_quota_id'] = $quota['member_quota_id'];
  360. MemberQuota::where('member_quota_id', $quota['member_quota_id'])->update([
  361. 'member_quota_status' => 'USED',
  362. 'member_quota_used_json' => json_encode($writeOffData)
  363. ]);
  364. }
  365. } else {
  366. $quota = $quotas[0];
  367. for ($i = 0; $i < $nbr; $i++) {
  368. $quota['member_quota_id'] = 'MQ' . date('ymdH') . random_string(6, 'up');
  369. $quota['member_quota_status'] = 'USED';
  370. $quota['member_quota_used_json'] = json_encode($writeOffData);
  371. $quota['member_quota_addtimes'] = strtotime($quota['member_quota_addtimes']);
  372. $quota['member_quota_nbr'] = 1;
  373. MemberQuota::insert($quota);
  374. }
  375. }
  376. }
  377. _syslog("核销", "核销成功");
  378. // 清除验证码
  379. // Redis::del($key);
  380. Db::commit();
  381. return json_success("核销成功");
  382. } catch (\Exception $e) {
  383. Db::rollBack();
  384. dump($e->getMessage());
  385. _syslog("核销", "核销失败");
  386. return json_fail("核销失败");
  387. }
  388. }
  389. public static function doWriteOff($params)
  390. {
  391. $quotas = MemberQuota::where('join_quota_member_id', $params['member_id'])
  392. ->where('join_member_rule_added_component_id', $params['component_id'])
  393. ->where('member_quota_status', 'PENDING')
  394. ->limit($params['nbr'])
  395. ->get()
  396. ->toArray();
  397. if (count($quotas) < intval($params['nbr'])) {
  398. throw new BusinessException('可核销数量不足');
  399. }
  400. if (!$params['times']) {
  401. $params['times'] = date('Y-m-d H:i:s');
  402. } else {
  403. $params['times'] = date('Y-m-d H:i:s', strtotime($params['times']));
  404. }
  405. try {
  406. // 生成核销数据
  407. $writeOffData = AddedService::generateWriteOffData($params);
  408. foreach ($quotas as $quota) {
  409. $writeOffData['member_quota_id'] = $quota['member_quota_id'];
  410. MemberQuota::where('member_quota_id', $quota['member_quota_id'])->update([
  411. 'member_quota_status' => 'USED',
  412. 'member_quota_used_json' => json_encode($writeOffData)
  413. ]);
  414. }
  415. _syslog("核销", "核销成功");
  416. return json_success("核销成功");
  417. } catch (\Exception $e) {
  418. _syslog("核销", "核销失败");
  419. throw new BusinessException('核销失败');
  420. // return json_fail("核销失败");
  421. }
  422. }
  423. /**
  424. * 会员账户,批量核销选择的权益
  425. */
  426. public function chooseList(Request $request)
  427. {
  428. $memberId = $request->get('member_id', '');
  429. $componentIds = $request->get('component_ids', []);
  430. if (empty($componentIds) || !$memberId) {
  431. return json_fail("参数异常");
  432. }
  433. $components = RuleAddedComponent::whereIn('rule_added_component_id', $componentIds)
  434. ->select('rule_added_component_name', 'rule_added_component_id')
  435. ->get();
  436. foreach ($components as &$component) {
  437. $component->unused = MemberQuota::where('join_quota_member_id', $memberId)
  438. ->where('join_member_rule_added_component_id', $component->rule_added_component_id)
  439. ->where('member_quota_status', 'PENDING')
  440. ->count();
  441. }
  442. $member = Member::where('member_id', $memberId)->select('member_id', 'member_mobile')->first();
  443. return json_success('', ['member' => $member, 'quotas' => $components]);
  444. }
  445. }