QuotaController.php 19 KB

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