QuotaController.php 20 KB

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