OtherOrderServices.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\services\order;
  12. use app\dao\order\OtherOrderDao;
  13. use app\services\BaseServices;
  14. use app\services\pay\OrderPayServices;
  15. use app\services\pay\PayServices;
  16. use app\services\statistic\TradeStatisticServices;
  17. use app\services\store\finance\StoreFinanceFlowServices;
  18. use app\services\user\member\MemberShipServices;
  19. use app\services\user\UserServices;
  20. use app\services\user\member\MemberCardServices;
  21. use crmeb\services\AliPayService;
  22. use crmeb\services\wechat\Payment;
  23. use crmeb\traits\ServicesTrait;
  24. use think\exception\ValidateException;
  25. use app\jobs\user\MicroPayOrderJob;
  26. /**
  27. * Class OtherOrderServices
  28. * @package app\services\order
  29. * @mixin OtherOrderDao
  30. */
  31. class OtherOrderServices extends BaseServices
  32. {
  33. use ServicesTrait;
  34. /**
  35. * 订单类型
  36. * @var string[]
  37. */
  38. protected $type = [
  39. 0 => '免费领取',
  40. 1 => '购买会员卡',
  41. 2 => '卡密激活',
  42. 3 => '收银订单',
  43. 4 => '赠送'
  44. ];
  45. /**
  46. * 初始化,获得dao层句柄
  47. * OtherOrderServices constructor.
  48. * @param OtherOrderDao $dao
  49. */
  50. public function __construct(OtherOrderDao $dao)
  51. {
  52. $this->dao = $dao;
  53. }
  54. /**
  55. * @param int $storeId
  56. * @return int
  57. */
  58. public function getvipOrderCount(int $storeId)
  59. {
  60. return $this->dao->count(['store_id' => $storeId, 'paid' => 1, 'type' => [0, 1, 2, 4]]);
  61. }
  62. /**
  63. * 生成会员购买订单数据
  64. * @param array $data
  65. * @param int $type
  66. * @param string $changeType
  67. * @return \crmeb\basic\BaseModel|\think\Model
  68. */
  69. public function addOtherOrderData(array $data, int $type = 1, string $changeType = 'create_member_order')
  70. {
  71. if (!$data) throw new ValidateException('数据不能为空');
  72. $add = [
  73. 'uid' => $data['uid'],
  74. 'store_id' => $data['store_id'] ?? 0,
  75. 'staff_id' => $data['staff_id'] ?? 0,
  76. 'type' => $data['type'] ?? 1,
  77. 'order_id' => $data['order_id'],
  78. 'channel_type' => $data['channel_type'],
  79. 'pay_type' => $data['pay_type'] ?? 0,
  80. 'member_type' => $data['member_type'] ?? 0,
  81. 'member_price' => $data['member_price'] ?? 0.00,
  82. 'pay_price' => $data['pay_price'] ?? 0.00,
  83. 'code' => $data['member_code'] ?? '',
  84. 'vip_day' => $data['vip_day'] ?? 0,
  85. 'is_permanent' => $data['is_permanent'] ?? 0,
  86. 'is_free' => $data['is_free'] ?? 0,
  87. 'overdue_time' => $data['overdue_time'] ?? 0,
  88. 'status' => 0,
  89. 'paid' => $data['paid'] ?? 0,
  90. 'pay_time' => $data['pay_time'] ?? 0,
  91. 'money' => $data['money'] ?? 0,
  92. 'add_time' => time(),
  93. ];
  94. $res = $this->dao->save($add);
  95. if (!$res) {
  96. throw new ValidateException('订单创建失败');
  97. }
  98. /** @var OtherOrderStatusServices $statusService */
  99. $statusService = app()->make(OtherOrderStatusServices::class);
  100. $statusService->save([
  101. 'oid' => $res['id'],
  102. 'change_type' => $changeType,
  103. 'change_message' => '订单生成',
  104. 'change_time' => time(),
  105. 'shop_type' => $type,
  106. ]);
  107. return $res;
  108. }
  109. /**
  110. * 能否领取免费
  111. * @param int $uid
  112. * @return array
  113. * @throws \think\db\exception\DataNotFoundException
  114. * @throws \think\db\exception\DbException
  115. * @throws \think\db\exception\ModelNotFoundException
  116. */
  117. public function isCanGetFree(int $uid)
  118. {
  119. /** @var UserServices $userService */
  120. $userService = app()->make(UserServices::class);
  121. /** @var MemberShipServices $memberShipService */
  122. $memberShipService = app()->make(MemberShipServices::class);
  123. /** @var TradeStatisticServices $tradeService */
  124. $tradeService = app()->make(TradeStatisticServices::class);
  125. /** @var StoreOrderEconomizeServices $economizeService */
  126. $economizeService = app()->make(StoreOrderEconomizeServices::class);
  127. $freeDay = $memberShipService->getVipDay(['type' => "free"]);
  128. $freeConfig = array();
  129. $freeConfig['price'] = 0;
  130. $freeConfig['pre_price'] = 0;
  131. $freeConfig['title'] = "免费会员";
  132. $freeConfig['type'] = "free";
  133. $freeConfig['vip_day'] = $freeDay ? $freeDay : 0;
  134. $userInfo = $userService->get($uid);
  135. if ($freeConfig) {
  136. $freeConfig['is_record'] = 0;
  137. $record = $this->dao->getOneByWhere(['uid' => $uid, 'is_free' => 1]);
  138. if ($record) {
  139. $freeConfig['is_record'] = 1;
  140. }
  141. }
  142. $registerTime = $tradeService->TimeConvert(['start_time' => date('Y-m-d H:i:s', $userInfo['add_time']), 'end_time' => date('Y-m-d H:i:s', time())]);
  143. $userInfo['register_days'] = $registerTime['days'];
  144. $userInfo['economize_money'] = $economizeService->sumEconomizeMoney($uid);
  145. $userInfo['shop_name'] = sys_config('site_name');
  146. $freeConfig['user_info'] = $userInfo;
  147. return $freeConfig;
  148. }
  149. /**
  150. * 查询会员卡订单数据
  151. * @param array $where
  152. * @param string $field
  153. * @return array|\think\Model|null
  154. * @throws \think\db\exception\DataNotFoundException
  155. * @throws \think\db\exception\DbException
  156. * @throws \think\db\exception\ModelNotFoundException
  157. */
  158. public function getOne(array $where, string $field = '*')
  159. {
  160. return $this->dao->getOne($where, $field);
  161. }
  162. /**
  163. * 创建订单
  164. * @param int $uid
  165. * @param int $memberId
  166. * @param string $payPrice
  167. * @param string $channelType
  168. * @param string $payType
  169. * @param $type
  170. * @param int $store_id
  171. * @param int $staff_id
  172. * @return \crmeb\basic\BaseModel|\think\Model
  173. * @throws \think\db\exception\DataNotFoundException
  174. * @throws \think\db\exception\DbException
  175. * @throws \think\db\exception\ModelNotFoundException
  176. */
  177. public function createOrder(int $uid, int $memberId, string $payPrice = '0', string $channelType, string $payType = 'weixin', $type = 1, int $store_id = 0, int $staff_id = 0)
  178. {
  179. /** @var StoreOrderCreateServices $storeOrderCreateService */
  180. $storeOrderCreateService = app()->make(StoreOrderCreateServices::class);
  181. $orderInfo = [
  182. 'uid' => $uid,
  183. 'order_id' => $storeOrderCreateService->getNewOrderId('hy'),
  184. 'pay_type' => $payType,
  185. 'channel_type' => $channelType,
  186. 'member_code' => "",
  187. 'store_id' => $store_id,
  188. 'staff_id' => $staff_id
  189. ];
  190. if ($type != 3) { //区别 0:免费领取会员 1:购买会员 2:卡密领取会员 3:线下付款
  191. [$memberPrice, $isFree, $isPermanent, $overdueTime, $memberInfo] = $this->checkPayMemberType($uid, $memberId);
  192. $orderInfo['member_price'] = $memberPrice;
  193. $orderInfo['pay_price'] = $memberInfo['pre_price'];
  194. $orderInfo['money'] = $memberPrice;
  195. $orderInfo['vip_day'] = $memberInfo['vip_day'];
  196. $orderInfo['member_type'] = $memberInfo['id'];
  197. $orderInfo['overdue_time'] = $overdueTime;
  198. $orderInfo['is_permanent'] = $isPermanent;
  199. $orderInfo['is_free'] = $isFree;
  200. $orderInfo['type'] = $type;
  201. $changeType = "create_member_order";
  202. } else {
  203. $orderInfo['type'] = $type;
  204. $orderInfo['member_code'] = "";
  205. $changeType = "create_offline_scan_order";
  206. $orderInfo['money'] = $payPrice;
  207. }
  208. return $this->addOtherOrderData($orderInfo, $type, $changeType);
  209. }
  210. /**
  211. *
  212. * @param int $uid
  213. * @param $price
  214. * @param $merberId
  215. * @param $type
  216. * @param $from
  217. * @param array $staffinfo
  218. * @param string $authCode 扫码code
  219. * @return array
  220. * @throws \think\db\exception\DataNotFoundException
  221. * @throws \think\db\exception\ModelNotFoundException
  222. */
  223. public function payMember(int $uid, int $memberId, float $price, int $payType, string $from, array $staffinfo = [], string $authCode = '')
  224. {
  225. /** @var UserServices $userServices */
  226. $userServices = app()->make(UserServices::class);
  227. $user = $userServices->getUserInfo($uid);
  228. if (!$user) {
  229. throw new ValidateException('用户数据不存在');
  230. }
  231. if (!$staffinfo) {
  232. throw new ValidateException('请稍后重试');
  233. }
  234. /** @var StoreOrderCreateServices $storeOrderCreateService */
  235. $storeOrderCreateService = app()->make(StoreOrderCreateServices::class);
  236. $orderInfo = [
  237. 'uid' => $uid,
  238. 'order_id' => $storeOrderCreateService->getNewOrderId('hy'),
  239. 'channel_type' => $user['user_type'],
  240. 'member_code' => "",
  241. 'store_id' => $staffinfo['store_id'],
  242. 'staff_id' => $staffinfo['id']
  243. ];
  244. [$memberPrice, $isFree, $isPermanent, $overdueTime, $memberInfo] = $this->checkPayMemberType($uid, $memberId);
  245. $type = $memberInfo['type'] == 'free' ? 0 : 1;
  246. $orderInfo['member_price'] = $memberPrice;
  247. $orderInfo['pay_price'] = $memberInfo['pre_price'];
  248. $orderInfo['money'] = $memberPrice;
  249. $orderInfo['vip_day'] = $memberInfo['vip_day'];
  250. $orderInfo['member_type'] = $memberInfo['id'];
  251. $orderInfo['overdue_time'] = $overdueTime;
  252. $orderInfo['is_permanent'] = $isPermanent;
  253. $orderInfo['is_free'] = $isFree;
  254. $orderInfo['type'] = $type;
  255. $changeType = "create_member_order";
  256. switch ((int)$payType) {
  257. case 2://门店充值-用户扫码付款
  258. case 3://门店充值-付款码付款
  259. //自动判定支付方式
  260. if ($authCode) {
  261. $orderInfo['auth_code'] = $authCode;
  262. if (Payment::isWechatAuthCode($authCode)) {
  263. $orderInfo['pay_type'] = PayServices::WEIXIN_PAY;
  264. } else if (AliPayService::isAliPayAuthCode($authCode)) {
  265. $orderInfo['pay_type'] = PayServices::ALIAPY_PAY;
  266. } else {
  267. throw new ValidateException('付款二维码错误');
  268. }
  269. } else {
  270. $orderInfo['pay_type'] = $from;
  271. }
  272. $memberOrder = $this->addOtherOrderData($orderInfo, $type, $changeType);
  273. $memberOrder = $memberOrder->toArray();
  274. try {
  275. /** @var OrderPayServices $payServices */
  276. $payServices = app()->make(OrderPayServices::class);
  277. $order_info = $payServices->otherRecharge($memberOrder,$memberOrder['pay_type'], $authCode);
  278. if ($payType == 3) {
  279. if ($order_info['paid'] === 1) {
  280. //修改支付状态
  281. $this->paySuccess($memberOrder,$memberOrder['pay_type']);
  282. return [
  283. 'msg' => $order_info['message'],
  284. 'status' => 'SUCCESS',
  285. 'type' => $from,
  286. 'payInfo' => [],
  287. 'data' => [
  288. 'jsConfig' => [],
  289. 'order_id' => $memberOrder['order_id']
  290. ]
  291. ];
  292. } else {
  293. //发起支付但是还没有支付,需要在5秒后查询支付状态
  294. if ($memberOrder['pay_type'] === PayServices::WEIXIN_PAY) {
  295. if (isset($order_info['payInfo']['err_code']) && in_array($order_info['payInfo']['err_code'], ['AUTH_CODE_INVALID', 'NOTENOUGH'])) {
  296. return ['status' => 'ERROR', 'msg' => '支付失败', 'payInfo' => $order_info];
  297. }
  298. $secs = 5;
  299. if (isset($order_info['payInfo']['err_code']) && $order_info['payInfo']['err_code'] === 'USERPAYING') {
  300. $secs = 10;
  301. }
  302. MicroPayOrderJob::dispatchSece($secs, [$memberOrder['order_id'],2]);
  303. }
  304. return [
  305. 'msg' => $order_info['message'] ?? '等待支付中',
  306. 'status' => 'PAY_ING',
  307. 'type' => $from,
  308. 'payInfo' => $order_info,
  309. 'data' => [
  310. 'jsConfig' => [],
  311. 'order_id' => $memberOrder['order_id']
  312. ]
  313. ];
  314. }
  315. }
  316. } catch (\Exception $e) {
  317. \think\facade\Log::error('充值失败,原因:' . $e->getMessage());
  318. throw new ValidateException('充值失败:' . $e->getMessage());
  319. }
  320. return ['msg' => '', 'status' => 'PAY', 'type' => $from, 'data' => ['jsConfig' => $order_info, 'order_id' => $memberOrder['order_id']]];
  321. break;
  322. case 4: //现金支付
  323. $orderInfo['pay_type'] = PayServices::CASH_PAY;
  324. $memberOrder = $this->addOtherOrderData($orderInfo, $type, $changeType);
  325. if (!$memberOrder) {
  326. throw new ValidateException('订单生成失败!');
  327. }
  328. $memberOrder = $memberOrder->toArray();
  329. try {
  330. //修改支付状态
  331. $this->paySuccess($memberOrder,$memberOrder['pay_type']);
  332. } catch (\Exception $e) {
  333. throw new ValidateException($e->getMessage());
  334. }
  335. return [
  336. 'msg' => '',
  337. 'status' => 'SUCCESS',
  338. 'type' => $from,
  339. 'payInfo' => [],
  340. 'data' => [
  341. 'jsConfig' => [],
  342. 'order_id' => $memberOrder['order_id']
  343. ]
  344. ];
  345. break;
  346. default:
  347. throw new ValidateException('缺少参数');
  348. break;
  349. }
  350. }
  351. /**
  352. * 免费卡领取支付
  353. * @param $orderInfo
  354. * @return bool
  355. */
  356. public function zeroYuanPayment($orderInfo)
  357. {
  358. if ($orderInfo['paid']) {
  359. throw new ValidateException('该订单已支付!');
  360. }
  361. /** @var MemberShipServices $memberShipServices */
  362. $memberShipServices = app()->make(MemberShipServices::class);
  363. $member_type = $memberShipServices->value(['id' => $orderInfo['member_type']], 'type');
  364. if ($member_type != 'free') {
  365. throw new ValidateException('支付失败!');
  366. }
  367. $res = $this->paySuccess($orderInfo, 'yue');//余额支付成功
  368. return $res;
  369. }
  370. /**
  371. * 会员卡支付成功
  372. * @param array $orderInfo
  373. * @param string $paytype
  374. * @return bool
  375. */
  376. public function paySuccess(array $orderInfo, string $paytype = PayServices::WEIXIN_PAY, array $other = [])
  377. {
  378. /** @var OtherOrderStatusServices $statusService */
  379. $statusService = app()->make(OtherOrderStatusServices::class);
  380. /** @var UserServices $userServices */
  381. $userServices = app()->make(UserServices::class);
  382. /** @var MemberShipServices $memberShipServices */
  383. $memberShipServices = app()->make(MemberShipServices::class);
  384. $orderInfo['member_type'] = $memberShipServices->value(['id' => $orderInfo['member_type']], 'type');
  385. switch ($orderInfo['type']) {
  386. case 0 :
  387. case 1:
  388. case 2 :
  389. $res1 = $userServices->setMemberOverdueTime($orderInfo['vip_day'], $orderInfo['uid'], 1, $orderInfo['member_type']);
  390. break;
  391. case 3:
  392. $res1 = true;
  393. break;
  394. }
  395. $update = [];
  396. if (isset($other['trade_no'])) {
  397. $update['trade_no'] = $other['trade_no'];
  398. }
  399. $update['paid'] = 1;
  400. $update['pay_type'] = $paytype;
  401. $update['pay_time'] = time();
  402. $res2 = $this->dao->update($orderInfo['id'], $update);
  403. $res3 = $statusService->save([
  404. 'oid' => $orderInfo['id'],
  405. 'change_type' => 'pay_success',
  406. 'change_message' => '用户付款成功',
  407. 'shop_type' => $orderInfo['type'],
  408. 'change_time' => time()
  409. ]);
  410. //记录流水账单
  411. if ($orderInfo['store_id'] > 0) {
  412. /** @var StoreFinanceFlowServices $storeFinanceFlowServices */
  413. $storeFinanceFlowServices = app()->make(StoreFinanceFlowServices::class);
  414. $orderInfo['pay_type'] = $paytype;
  415. $orderInfo['pay_time'] = time();
  416. $storeFinanceFlowServices->setFinance($orderInfo, 3);
  417. }
  418. //支付成功后发送消息
  419. event('user.vipPay', [$orderInfo]);
  420. $res = $res1 && $res2 && $res3;
  421. return false !== $res;
  422. }
  423. /**
  424. * 修改
  425. * @param array $where
  426. * @param array $data
  427. * @return mixed
  428. */
  429. public function update(array $where, array $data)
  430. {
  431. return $this->dao->update($where, $data);
  432. }
  433. /**
  434. * 购买会员卡数据校验
  435. * @param int $uid
  436. * @param int $memberId
  437. * @param string $payPrice
  438. * @return array
  439. * @throws \think\db\exception\DataNotFoundException
  440. * @throws \think\db\exception\DbException
  441. * @throws \think\db\exception\ModelNotFoundException
  442. */
  443. public function checkPayMemberType(int $uid, int $memberId)
  444. {
  445. /** @var MemberShipServices $memberShipService */
  446. $memberShipService = app()->make(MemberShipServices::class);
  447. $memberInfo = $memberShipService->getMemberInfo($memberId);
  448. /** @var UserServices $userService */
  449. $userService = app()->make(UserServices::class);
  450. $userInfo = $userService->get($uid);
  451. if ($userInfo['is_money_level'] > 0 && $userInfo['is_ever_level'] > 0) throw new ValidateException('您已是永久会员无需再购买!');
  452. $memberTypes = $memberInfo['type'] ?? '';
  453. $price = $memberInfo['pre_price'];
  454. if ($memberTypes == 'free' && $memberInfo['vip_day'] <= 0) throw new ValidateException('网络错误!');
  455. if ($userInfo['overdue_time'] > time()) {
  456. $time = $userInfo['overdue_time'];
  457. } else {
  458. $time = time();
  459. }
  460. switch ($memberTypes) {
  461. case "free"://免费会员
  462. $isCanGetFree = $this->isCanGetFree($uid);
  463. if ($isCanGetFree['is_record'] == 1) throw new ValidateException('您已经领取过免费会员!');
  464. $memberPrice = 0.00; //会员卡价格
  465. $isFree = 1;//代表免费
  466. $isPermanent = 0;//代表非永久
  467. $overdueTime = bcadd(bcmul(abs($memberInfo['vip_day']), "86400", 0), $time, 0);
  468. break;
  469. case "ever":
  470. $memberPrice = $price;
  471. $isFree = 0;
  472. $isPermanent = 1;
  473. $overdueTime = -1;
  474. break;
  475. default:
  476. $memberPrice = $price;
  477. $isFree = 0;
  478. $isPermanent = 0;
  479. $overdueTime =$memberShipService->getOverdueTime($uid, $memberId, $userInfo, $memberInfo);
  480. break;
  481. }
  482. return [$memberPrice, $isFree, $isPermanent, $overdueTime, $memberInfo];
  483. }
  484. /**
  485. * 根据查询用户购买会员金额
  486. * @param array $where
  487. * @return mixed
  488. */
  489. public function getMemberMoneyByWhere(array $where, string $sumField, string $selectType, string $group = "")
  490. {
  491. switch ($selectType) {
  492. case "sum" :
  493. return $this->dao->getWhereSumField($where, $sumField);
  494. case "group" :
  495. return $this->dao->getGroupField($where, $sumField, $group);
  496. }
  497. }
  498. /**
  499. * 线下收银列表
  500. * @param array $where
  501. * @return array
  502. * @throws \think\db\exception\DataNotFoundException
  503. * @throws \think\db\exception\DbException
  504. * @throws \think\db\exception\ModelNotFoundException
  505. */
  506. public function getScanOrderList(array $where)
  507. {
  508. $where['type'] = 3;
  509. $where['paid'] = 1;
  510. [$page, $limit] = $this->getPageValue();
  511. if ($where['add_time']) {
  512. [$startTime, $endTime] = explode('-', $where['add_time']);
  513. if ($startTime || $endTime) {
  514. $startTime = strtotime($startTime);
  515. $endTime = strtotime($endTime . ' 23:59:59');
  516. $where['add_time'] = [$startTime, $endTime];
  517. }
  518. }
  519. if ($where['name']) {
  520. /** @var UserServices $userService */
  521. $userService = app()->make(UserServices::class);
  522. $userInfo = $userService->getUserInfoList(['nickname' => $where['name']], "uid");
  523. if ($userInfo) $where['uid'] = array_column($userInfo, 'uid');
  524. }
  525. $list = $this->dao->getScanOrderList($where, $page, $limit);
  526. /** @var UserServices $userService */
  527. $userService = app()->make(UserServices::class);
  528. if ($list) {
  529. $userInfos = $userService->getColumn([['uid', 'IN', array_unique(array_column($list, 'uid'))]], 'uid,phone,nickname', 'uid');
  530. foreach ($list as &$v) {
  531. $v['add_time'] = date('Y-m-d H:i:s', $v['add_time']);
  532. $v['pay_time'] = $v['pay_time'] ? date('Y-m-d H:i:s', $v['pay_time']) : '';
  533. $v['phone'] = $userInfos[$v['uid']]['phone'] ?? '';
  534. $v['nickname'] = $userInfos[$v['uid']]['nickname'] ?? '';
  535. switch ($v['pay_type']) {
  536. case "yue" :
  537. $v['pay_type'] = "余额";
  538. break;
  539. case "weixin" :
  540. $v['pay_type'] = "微信";
  541. break;
  542. case "alipay" :
  543. $v['pay_type'] = "支付宝";
  544. break;
  545. case "offline" :
  546. $v['pay_type'] = "线下支付";
  547. break;
  548. case "cash" :
  549. $v['pay_type'] = "现金支付";
  550. break;
  551. }
  552. $v['true_price'] = bcsub($v['money'], $v['pay_price'], 2);
  553. }
  554. }
  555. $count = $this->dao->count($where);
  556. return compact('list', 'count');
  557. }
  558. /**
  559. * 获取会员记录
  560. * @param array $where
  561. * @return array
  562. * @throws \think\db\exception\DataNotFoundException
  563. * @throws \think\db\exception\DbException
  564. * @throws \think\db\exception\ModelNotFoundException
  565. */
  566. public function getMemberRecord(array $where, int $limit = 0)
  567. {
  568. $where['type'] = [0, 1, 2, 4];
  569. if (isset($where['add_time']) && $where['add_time']) {
  570. $where['time'] = $where['add_time'];
  571. unset($where['add_time']);
  572. }
  573. if ($limit) {
  574. [$page] = $this->getPageValue();
  575. } else {
  576. [$page, $limit] = $this->getPageValue();
  577. }
  578. $list = $this->dao->getMemberRecord($where, '*', ['user', 'staff'], $page, $limit);
  579. if ($list) {
  580. /** @var MemberShipServices $memberShipService */
  581. $memberShipService = app()->make(MemberShipServices::class);
  582. $shipInfo = $memberShipService->getColumn([], 'title,type', 'id');
  583. foreach ($list as &$v) {
  584. $v['overdue_time'] = $v['member_type'] == 'ever' || ($shipInfo[$v['member_type']]['type'] ?? '') == 'ever' ? '永久' : ($v['overdue_time'] ? date('Y-m-d H:i:s', $v['overdue_time']) : '');
  585. $v['vip_day'] = $v['member_type'] == 'ever' || ($shipInfo[$v['member_type']]['type'] ?? '') == 'ever' ? '永久' : $v['vip_day'];
  586. $v['member_type'] = $v['member_type'] ? ($shipInfo[$v['member_type']]['title'] ?? '') : ($this->type[$v['type']] ?? '其他');
  587. $v['pay_time'] = $v['pay_time'] ? date('Y-m-d H:i:s', $v['pay_time']) : '';
  588. $v['add_time'] = date('Y-m-d H:i:s', $v['add_time']);
  589. switch ($v['pay_type']) {
  590. case "yue" :
  591. $v['pay_type'] = "余额";
  592. break;
  593. case "weixin" :
  594. $v['pay_type'] = "微信";
  595. break;
  596. case "alipay" :
  597. $v['pay_type'] = "支付宝";
  598. break;
  599. case "admin" :
  600. $v['pay_type'] = "后台赠送";
  601. break;
  602. case "offline" :
  603. $v['pay_type'] = "线下支付";
  604. break;
  605. case "cash" :
  606. $v['pay_type'] = "现金支付";
  607. break;
  608. }
  609. if ($v['type'] == 0) $v['pay_type'] = "免费领取";
  610. if ($v['type'] == 2) {
  611. $v['pay_type'] = "卡密领取";
  612. $v['member_type'] = "卡密激活";
  613. }
  614. if ($v['type'] == 1 && $v['is_free'] == 1) $v['pay_type'] = "免费领取";
  615. $v['user']['overdue_time'] = isset($v['user']['overdue_time']) ? (date('Y-m-d', $v['user']['overdue_time']) == "1970-01-01" ? "" : date('Y-m-d H:i:s', $v['user']['overdue_time'])) : '';
  616. }
  617. }
  618. $count = $this->dao->count($where);
  619. return compact('list', 'count');
  620. }
  621. /**
  622. * 门店付费会员统计详情列表
  623. * @param int $store_id
  624. * @param int $staff_id
  625. * @param array $time
  626. * @return array|array[]
  627. */
  628. public function time(int $store_id, int $staff_id, array $time = [])
  629. {
  630. if (!$time) {
  631. return [[], []];
  632. }
  633. [$start, $stop, $front, $front_stop] = $time;
  634. $where = ['store_id' => $store_id, 'paid' => 1, 'type' => [0, 1, 2, 4]];
  635. if ($staff_id) {
  636. $where['staff_id'] = $staff_id;
  637. }
  638. $frontPrice = $this->dao->sum($where + ['time' => [$front, $front_stop]], 'pay_price', true);
  639. $nowPrice = $this->dao->sum($where + ['time' => [$start, $stop]], 'pay_price', true);
  640. [$page, $limit] = $this->getPageValue();
  641. $list = $this->dao->getMemberRecord($where + ['time' => [$start, $stop]], 'id,order_id,uid,pay_price,add_time', ['user' => function ($query) {
  642. $query->field(['uid', 'avatar', 'nickname', 'phone'])->bind([
  643. 'avatar' => 'avatar',
  644. 'nickname' => 'nickname',
  645. 'phone' => 'phone'
  646. ]);
  647. }], $page, $limit);
  648. foreach ($list as &$item) {
  649. $item['add_time'] = $item['add_time'] ? date('Y-m-d H:i:s', $item['add_time']) : '';
  650. }
  651. return [[$nowPrice, $frontPrice], $list];
  652. }
  653. }