QuotaController.php 19 KB

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