MCashier.Class.php 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  1. <?php
  2. namespace JinDouYun\Model\Cashier;
  3. use JinDouYun\Controller\Common\Logger;
  4. use JinDouYun\Dao\Cashier\DCashierConnectLog;
  5. use JinDouYun\Dao\Cashier\DCashierCustomerPrice;
  6. use JinDouYun\Dao\Cashier\DCashierEntryData;
  7. use JinDouYun\Dao\Cashier\DCashierPushMoneyDetail;
  8. use JinDouYun\Dao\Cashier\DCashierSettings;
  9. use JinDouYun\Dao\Customer\DCustomer;
  10. use JinDouYun\Dao\Department\DStaff;
  11. use JinDouYun\Dao\Order\DOrder;
  12. use JinDouYun\Dao\Order\DOrderIndex;
  13. use JinDouYun\Dao\UserCenter\DUserCenter;
  14. use JinDouYun\Model\Customer\MShippingAddress;
  15. use Mall\Framework\Core\ErrorCode;
  16. use Mall\Framework\Core\ResultWrapper;
  17. use Mall\Framework\Core\StatusCode;
  18. /**
  19. * Description:
  20. * Class MCashier
  21. * @package JinDouYun\Model\Cashier
  22. */
  23. class MCashier
  24. {
  25. /**
  26. * @var int
  27. */
  28. private $onlineUserId;
  29. /**
  30. * @var int
  31. */
  32. private $onlineEnterpriseId;
  33. /**
  34. * @var DOrderIndex
  35. */
  36. private $objDOrderIndex;
  37. /**
  38. * @var DCashierSettings
  39. */
  40. private $objDCashierSettings;
  41. /**
  42. * @var array 收银台配置信息
  43. */
  44. private $setting = [];
  45. /**
  46. * @var DStaff
  47. */
  48. private $objDStaff;
  49. /**
  50. * @var int 单表数据量
  51. */
  52. private $cutTable = 200000;
  53. /**
  54. * @var DOrder
  55. */
  56. private $objDOrder;
  57. /**
  58. * @var DCashierPushMoneyDetail
  59. */
  60. private $objDCashierPushMoneyDetail;
  61. /**
  62. * @var DCashierConnectLog
  63. */
  64. private $objDCashierConnectLog;
  65. /**
  66. * @var DCashierEntryData
  67. */
  68. private $objDCashierEntryData;
  69. /**
  70. * @var DCashierCustomerPrice
  71. */
  72. private $objDCashierCustomerPrice;
  73. /**
  74. * MCashier constructor.
  75. * @param $onlineUserId
  76. * @param $onlineEnterpriseId
  77. * @throws \Exception
  78. */
  79. public function __construct($onlineUserId, $onlineEnterpriseId)
  80. {
  81. $this->onlineUserId = $onlineUserId;
  82. $this->onlineEnterpriseId = $onlineEnterpriseId;
  83. $this->objDOrderIndex = new DOrderIndex();
  84. $this->objDOrderIndex->setTable('qianniao_order_index_'.$this->onlineEnterpriseId);
  85. $this->objDCashierSettings = new DCashierSettings();
  86. $this->objDStaff = new DStaff();
  87. $this->objDStaff->setTable('qianniao_staff_'.$this->onlineEnterpriseId);
  88. $this->objDOrder = new DOrder();
  89. $this->objDCashierPushMoneyDetail = new DCashierPushMoneyDetail();
  90. $this->objDCashierPushMoneyDetail->setTable('qianniao_cashier_push_money_detail_'.$this->onlineEnterpriseId);
  91. $this->objDCashierConnectLog = new DCashierConnectLog();
  92. $this->objDCashierConnectLog->setTable('qianniao_cashier_connect_log_'.$this->onlineEnterpriseId);
  93. $this->objDCashierEntryData = new DCashierEntryData();
  94. $this->objDCashierEntryData->setTable('qianniao_cashier_entry_data_'.$this->onlineEnterpriseId);
  95. $this->objDCashierCustomerPrice = new DCashierCustomerPrice();
  96. $this->objDCashierCustomerPrice->setTable('qianniao_cashier_customer_price_'.$this->onlineEnterpriseId);
  97. }
  98. /**
  99. * Doc: (des="计算订单的提成")
  100. * User: XMing
  101. * Date: 2020/9/2
  102. * Time: 12:18 下午
  103. * @param int $orderId
  104. * @return ResultWrapper
  105. * @throws \Exception
  106. */
  107. public function calculatePushMoney(int $orderId)
  108. {
  109. $settingResult = self::getCashierSetting();
  110. if (!$settingResult->isSuccess()){
  111. return ResultWrapper::fail($settingResult->getData(),$settingResult->getErrorCode());
  112. }
  113. $this->setting = $settingResult->getData()['add_form'];
  114. if (!isset($this->setting['guide_push_money'])){
  115. return ResultWrapper::fail('未获取到导购员配置',ErrorCode::$paramError);
  116. }
  117. $guide_push_money = $this->setting['guide_push_money'];
  118. if (!isset($this->setting['cashier_push_money'])){
  119. return ResultWrapper::fail('未获取到收银员配置',ErrorCode::$paramError);
  120. }
  121. $cashier_push_money = $this->setting['cashier_push_money'];
  122. $orderIndexInfo = $this->objDOrderIndex->get(['id' => $orderId]);
  123. if ($orderIndexInfo === false){
  124. return ResultWrapper::fail($this->objDOrderIndex->error(),ErrorCode::$dberror);
  125. }
  126. if (empty($orderIndexInfo)){
  127. return ResultWrapper::fail('未获取到指定订单',ErrorCode::$paramError);
  128. }
  129. $fix = (int)ceil($orderIndexInfo['userCenterId'] / $this->cutTable);
  130. //切换分表
  131. $this->objDOrder->setTable('qianniao_order_'.$this->onlineEnterpriseId.'_'.$fix);
  132. $order = $this->objDOrder->get(['id' => $orderId]);
  133. if ($order === false){
  134. return ResultWrapper::fail($this->objDOrder->error(),ErrorCode::$dberror);
  135. }
  136. if (empty($order)){
  137. return ResultWrapper::fail('未获取到指定的订单',ErrorCode::$paramError);
  138. }
  139. $orderMap = [
  140. 'cashierUid' => $order['cashierUid'],
  141. 'guideUids' => $order['guideUids'],
  142. 'orderId' => $orderId,
  143. 'payMoney' => $order['payAmount'],
  144. 'orderNo' => $order['no'],
  145. 'shopId' => $order['shopId'],
  146. 'payType' => $order['payType']
  147. ];
  148. //是否开启导购提成
  149. $insertLogMap = [];
  150. $staffMap = [];
  151. if ($guide_push_money['status'] == StatusCode::$standard){
  152. $buildGuideDataResult = self::buildGuidePushMoney($guide_push_money['type'],$guide_push_money['push_money_rate'],$orderMap);
  153. if (!$buildGuideDataResult->isSuccess()){
  154. return ResultWrapper::fail($buildGuideDataResult->getData(),$buildGuideDataResult->getErrorCode());
  155. }
  156. $buildGuideData = $buildGuideDataResult->getData();
  157. if (!empty($buildGuideData)){
  158. $buildGuideLogMap = $buildGuideData['buildLogMap'];
  159. $buildGuideStaffMap = $buildGuideData['buildStaffMap'];
  160. $insertLogMap = array_merge($insertLogMap,$buildGuideLogMap);
  161. $staffMap = array_merge($staffMap,$buildGuideStaffMap);
  162. }
  163. }else{
  164. Logger::logs(E_USER_ERROR,'未开启导购提成',__CLASS__,__LINE__,$this->setting);
  165. }
  166. //是否开启收银提成
  167. if ($cashier_push_money['status'] == StatusCode::$standard){
  168. $buildCashierDataResult = self::buildCashierPushMoney($cashier_push_money['type'],$cashier_push_money['push_money_rate'],$orderMap);
  169. if (!$buildCashierDataResult->isSuccess()){
  170. return ResultWrapper::fail($buildCashierDataResult->getData(),$buildCashierDataResult->getErrorCode());
  171. }
  172. $buildLogData = $buildCashierDataResult->getData();
  173. if (!empty($buildLogData)){
  174. $buildCashierLogMap = $buildLogData['buildLogMap'];
  175. $buildCashierStaffMap = $buildLogData['buildStaffMap'];
  176. $insertLogMap = array_merge($insertLogMap,$buildCashierLogMap);
  177. $staffMap = array_merge($staffMap,$buildCashierStaffMap);
  178. }
  179. }else{
  180. Logger::logs(E_USER_ERROR,'未开启收银提成',__CLASS__,__LINE__,$this->setting);
  181. }
  182. $this->objDStaff->beginTransaction();
  183. //处理收银员/导购员的提成,
  184. if (!empty($staffMap)){
  185. $staffUpdateResult = self::buildStaffMoney($staffMap);
  186. if (!$staffUpdateResult->isSuccess()){
  187. return ResultWrapper::fail($staffUpdateResult->getData(),$staffUpdateResult->getErrorCode());
  188. }
  189. $staffUpdate = $staffUpdateResult->getData();
  190. Logger::logs(E_USER_ERROR,'员工余额变动数据',__CLASS__,__LINE__,$staffUpdate);
  191. foreach ($staffUpdate as $value){
  192. $updateResult = $this->objDStaff->update(['balance' => $value['balance'],'updateTime' => time()],['userCenterId' => $value['userCenterId']]);
  193. if ($updateResult === false){
  194. $this->objDStaff->rollBack();
  195. return ResultWrapper::fail($this->objDStaff->error(),ErrorCode::$dberror);
  196. }
  197. }
  198. }
  199. if (!empty($insertLogMap)){
  200. Logger::logs(E_USER_ERROR,'提成记录插入数据',__CLASS__,__LINE__,$insertLogMap);
  201. $insertResult = $this->objDCashierPushMoneyDetail->insert($insertLogMap,true);
  202. if ($insertResult === false){
  203. $this->objDStaff->rollBack();
  204. return ResultWrapper::fail($this->objDCashierPushMoneyDetail->error(),ErrorCode::$dberror);
  205. }
  206. }
  207. //回写收银金额
  208. if (!empty($orderMap['payMoney'])){
  209. $writeCashierMoneyResult = self::writeCashierMoney($orderMap['cashierUid'],$orderMap['payMoney'],$orderMap['payType'],$orderMap['shopId']);
  210. if (!$writeCashierMoneyResult->isSuccess()){
  211. $this->objDStaff->rollBack();
  212. return ResultWrapper::fail($writeCashierMoneyResult->getData(),$writeCashierMoneyResult->getErrorCode());
  213. }
  214. $writeCashierMoneyData = $writeCashierMoneyResult->getData();
  215. $logId = $writeCashierMoneyData['id'];
  216. unset($writeCashierMoneyData['id']);
  217. $logUpdate = $this->objDCashierConnectLog->update($writeCashierMoneyData,['id' => $logId]);
  218. if ($logUpdate === false){
  219. $this->objDStaff->rollBack();
  220. return ResultWrapper::fail($this->objDCashierConnectLog->error(),ErrorCode::$dberror);
  221. }
  222. }
  223. $this->objDStaff->commit();
  224. return ResultWrapper::success(true);
  225. }
  226. /**
  227. * Doc: (des="")
  228. * User: XMing
  229. * Date: 2020/9/2
  230. * Time: 6:36 下午
  231. * @param int $cashierUid
  232. * @param float $money
  233. * @param $payType
  234. * @param $shopId
  235. * @return ResultWrapper
  236. */
  237. private function writeCashierMoney(int $cashierUid,float $money,$payType,$shopId)
  238. {
  239. //获取当前的收银员的交接记录
  240. $cashierLog = $this->objDCashierConnectLog->get(['userCenterId' => $cashierUid,'shopId' => $shopId,'workStatus' => StatusCode::$auditStatus['auditIng']]);
  241. if ($cashierLog === false){
  242. return ResultWrapper::fail($this->objDCashierConnectLog->error(),ErrorCode::$dberror);
  243. }
  244. if (empty($cashierLog)){
  245. return ResultWrapper::fail('获取当前收银员工作记录失败',ErrorCode::$paramError);
  246. }
  247. $oldCollectionMoney = $cashierLog['collectionMoney'];
  248. $collectionData = empty($cashierLog['collectionData']) ? [] : json_decode($cashierLog['collectionData'],true);
  249. if (empty($collectionData)){
  250. $collectionData = [
  251. 'other' => '0.00',
  252. 'alipay' => '0.00',
  253. 'balance' => '0.00',
  254. 'cash' => '0.00',
  255. 'wechat' => '0.00'
  256. ];
  257. switch ($payType){
  258. case StatusCode::$payType['cash']:
  259. $collectionData['cash'] = $money;
  260. break;
  261. case StatusCode::$payType['other']:
  262. //其他
  263. $collectionData['other'] = $money;
  264. break;
  265. default:
  266. $collectionData['other'] = $money;
  267. break;
  268. }
  269. }else{
  270. switch($payType){
  271. case StatusCode::$payType['cash']:
  272. $old = isset($collectionData['cash']) ? $collectionData['cash'] : 0;
  273. $collectionData['cash'] = bcadd($old,$money,2);
  274. break;
  275. case StatusCode::$payType['other']:
  276. //其他
  277. $old = isset($collectionData['other']) ? $collectionData['other'] : 0;
  278. $collectionData['other'] = bcadd($old,$money,2);
  279. break;
  280. default:
  281. $old = isset($collectionData['other']) ? $collectionData['other'] : 0;
  282. $collectionData['other'] = bcadd($old,$money,2);
  283. break;
  284. }
  285. }
  286. $update = [
  287. 'collectionMoney' => bcadd($oldCollectionMoney,$money,2),
  288. 'collectionData' => \json_encode($collectionData),
  289. 'id' => $cashierLog['id'],
  290. 'updateTime' => time()
  291. ];
  292. Logger::logs(E_USER_ERROR,'收银统计信息',__CLASS__,__LINE__,$update);
  293. return ResultWrapper::success($update);
  294. }
  295. /**
  296. * Doc: (des="")
  297. * User: XMing
  298. * Date: 2020/9/2
  299. * Time: 5:04 下午
  300. * @param array $staffMap
  301. * @return ResultWrapper
  302. */
  303. private function buildStaffMoney(array $staffMap)
  304. {
  305. $allUids = [];
  306. foreach ($staffMap as $value){
  307. $allUids[] = $value['userCenterId'];
  308. }
  309. $staffLists = $this->objDStaff->select(['userCenterId' => $allUids]);
  310. if ($staffLists === false){
  311. return ResultWrapper::fail($this->objDStaff->error(),ErrorCode::$dberror);
  312. }
  313. if (empty($staffLists)){
  314. return ResultWrapper::fail('未查询到员工数据',ErrorCode::$paramError);
  315. }
  316. $map = [];
  317. foreach ($staffLists as $value){
  318. $map[$value['userCenterId']] = $value;
  319. }
  320. foreach ($staffMap as $key => $item){
  321. if (!isset($map[$item['userCenterId']])){
  322. unset($staffMap[$key]);
  323. continue;
  324. }
  325. $oldBalance = $map[$item['userCenterId']]['balance'];
  326. $changeBalance = $item['retMoney'];
  327. $balance = bcadd($oldBalance,$changeBalance,2);
  328. $staffMap[$key]['balance'] = $balance;
  329. $staffMap[$key]['oldBalance'] = $oldBalance;
  330. }
  331. return ResultWrapper::success($staffMap);
  332. }
  333. /**
  334. * Doc: (des="获取首映台配置")
  335. * User: XMing
  336. * Date: 2020/9/2
  337. * Time: 2:19 下午
  338. * @return ResultWrapper
  339. */
  340. private function getCashierSetting()
  341. {
  342. $setting = $this->objDCashierSettings->get_field('content',['enterpriseId'=>$this->onlineEnterpriseId]);
  343. if ($setting === false){
  344. return ResultWrapper::fail($this->objDCashierSettings->error(),ErrorCode::$dberror);
  345. }
  346. if (empty($setting)){
  347. return ResultWrapper::fail('收银台设置为空',ErrorCode::$paramError);
  348. }
  349. $setting = json_decode($setting,true);
  350. return ResultWrapper::success($setting);
  351. }
  352. /**
  353. * Doc: (des="计算导购提成")
  354. * User: XMing
  355. * Date: 2020/9/2
  356. * Time: 2:38 下午
  357. * @param int $type
  358. * @param float $rate
  359. * @param array $orderData
  360. * @return ResultWrapper
  361. */
  362. private function buildGuidePushMoney(int $type,float $rate,array $orderData)
  363. {
  364. //查询导购是否开启自定义提成
  365. $guideUidsStr = $orderData['guideUids'];
  366. if (empty($guideUidsStr)){
  367. return ResultWrapper::success([]);
  368. }
  369. $guideUidIds = explode(',',$guideUidsStr);
  370. $staffLists = $this->objDStaff->select(['userCenterId' => $guideUidIds]);
  371. if ($staffLists === false){
  372. return ResultWrapper::fail($this->objDStaff->error(),ErrorCode::$dberror);
  373. }
  374. if (empty($staffLists)){
  375. return ResultWrapper::fail('未获取到导购的信息',ErrorCode::$paramError);
  376. }
  377. $staffMap = [];
  378. foreach ($staffLists as $value){
  379. $staffMap[$value['userCenterId']] = $value;
  380. }
  381. $map = [];
  382. foreach ($guideUidIds as $uid){
  383. if (!isset($staffMap[$uid])){
  384. //没有获取到,一般情况下是不存在的,除非有脏数据
  385. continue;
  386. }
  387. if ($staffMap[$uid]['isSetRule'] == StatusCode::$standard){
  388. //设置了自定义的规则
  389. $rule = json_decode($staffMap[$uid]['rule'],true);
  390. $map[$uid] = [
  391. 'type' => $rule['push_money_type'],
  392. 'rate' => $rule['push_money_rate'],
  393. 'staffName' => $staffMap[$uid]['staffName'],
  394. 'userCenterId' => $staffMap[$uid]['userCenterId'],
  395. ];
  396. continue;
  397. }
  398. //默认的规则
  399. $map[$uid] = [
  400. 'type' => $type,
  401. 'rate' => $rate,
  402. 'staffName' => $staffMap[$uid]['staffName'],
  403. 'userCenterId' => $staffMap[$uid]['userCenterId'],
  404. ];
  405. }
  406. $buildStaffMap = [];
  407. $buildLogMap = [];
  408. //计算导购员的提成
  409. foreach ($map as $uid => $item){
  410. $retMoney = 0;
  411. switch ($item['type']){
  412. case StatusCode::$delete:
  413. //按订单
  414. $retMoney = $item['rate'];
  415. break;
  416. case StatusCode::$standard:
  417. //按订单金额
  418. if (empty($item['rate'])){
  419. continue 2;
  420. }
  421. $rate = bcdiv($item['rate'],100,2);
  422. $retMoney = bcmul($rate,$orderData['payMoney'],2);
  423. break;
  424. }
  425. $buildStaffMap[] = [
  426. 'userCenterId' => $uid,
  427. 'retMoney' => $retMoney
  428. ];
  429. $buildLogMap[] = [
  430. 'pushType' => 2,
  431. 'staffName' => $item['staffName'],
  432. 'orderId' => $orderData['orderId'],
  433. 'orderNo' => $orderData['orderNo'],
  434. 'orderMoney' => $orderData['payMoney'],
  435. 'pushMoneyRate' => $item['rate'],
  436. 'pushMoney' => $retMoney,
  437. 'auditStatus' => StatusCode::$auditStatus['auditPass'],
  438. 'auditTime' => time(),
  439. 'createTime' => time(),
  440. 'shopId' => $orderData['shopId'],
  441. 'userCenterId' => $item['userCenterId']
  442. ];
  443. }
  444. return ResultWrapper::success([
  445. 'buildStaffMap' => $buildStaffMap,
  446. 'buildLogMap' => $buildLogMap
  447. ]);
  448. }
  449. /**
  450. * Doc: (des="计算收银提成")
  451. * User: XMing
  452. * Date: 2020/9/2
  453. * Time: 2:39 下午
  454. * @param int $type
  455. * @param float $rate
  456. * @param array $orderData
  457. * @return ResultWrapper
  458. */
  459. private function buildCashierPushMoney(int $type,float $rate,array $orderData)
  460. {
  461. $cashierUid = $orderData['cashierUid'];
  462. if (empty($cashierUid)){
  463. return ResultWrapper::success([]);
  464. }
  465. $staffInfo = $this->objDStaff->get(['userCenterId' => $cashierUid]);
  466. if ($staffInfo === false){
  467. return ResultWrapper::fail($this->objDStaff->error(),ErrorCode::$dberror);
  468. }
  469. if (empty($staffInfo)){
  470. return ResultWrapper::success([
  471. 'buildStaffMap' => [],
  472. 'buildLogMap' => []
  473. ]);
  474. }
  475. if ($staffInfo['isSetRule'] == StatusCode::$standard){
  476. $rule = json_decode($staffInfo['rule'],true);
  477. $type = $rule['push_money_type'];
  478. $rate = $rule['push_money_rate'];
  479. }
  480. //计算收银员工的提成
  481. $retMoney = 0;
  482. switch ($type) {
  483. case StatusCode::$delete:
  484. //按订单
  485. $retMoney = $rate;
  486. break;
  487. case StatusCode::$standard:
  488. //按订单金额
  489. if (empty($rate)) {
  490. return ResultWrapper::fail('提成百分比设置为空', ErrorCode::$paramError);
  491. }
  492. $retMoney = bcmul(bcdiv($rate, 100, 2), $orderData['payMoney'], 2);
  493. break;
  494. }
  495. $buildStaffMap[] = [
  496. 'retMoney' => $retMoney,
  497. 'userCenterId' => $cashierUid,
  498. ];
  499. $buildLogMap[] = [
  500. 'pushType' => 1,
  501. 'staffName' => $staffInfo['staffName'],
  502. 'orderId' => $orderData['orderId'],
  503. 'orderNo' => $orderData['orderNo'],
  504. 'orderMoney' => $orderData['payMoney'],
  505. 'pushMoneyRate' => $rate,
  506. 'pushMoney' => $retMoney,
  507. 'auditStatus' => StatusCode::$auditStatus['auditPass'],
  508. 'auditTime' => time(),
  509. 'createTime' => time(),
  510. 'shopId' => $orderData['shopId'],
  511. 'userCenterId' => $staffInfo['userCenterId']
  512. ];
  513. return ResultWrapper::success([
  514. 'buildStaffMap' => $buildStaffMap,
  515. 'buildLogMap' => $buildLogMap
  516. ]);
  517. }
  518. /**
  519. * Doc: (des="统计项")
  520. * User: XMing
  521. * Date: 2020/9/3
  522. * Time: 3:22 下午
  523. * @param array $params
  524. * @return ResultWrapper
  525. */
  526. public function overView(array $params)
  527. {
  528. $cashier_push_money_result = self::getPushMoneyBySql(StatusCode::$roleId['cashier'],$params);
  529. if (!$cashier_push_money_result->isSuccess()){
  530. return ResultWrapper::fail($cashier_push_money_result->getData(),$cashier_push_money_result->getErrorCode());
  531. }
  532. $guide_push_money_result = self::getPushMoneyBySql(StatusCode::$roleId['guide'],$params);
  533. if (!$guide_push_money_result->isSuccess()){
  534. return ResultWrapper::fail($guide_push_money_result->getData(),$guide_push_money_result->getErrorCode());
  535. }
  536. $orderResult = self::getPushOrderNumBySql($params);
  537. if (!$orderResult->isSuccess()){
  538. return ResultWrapper::fail($orderResult->getData(),$orderResult->getErrorCode());
  539. }
  540. $orderMap = $orderResult->getData();
  541. //提成统计
  542. $listResult = self::getListBySql($params,(isset($params['type']) && !empty($params['type'])) ? $params['type'] : StatusCode::$roleId['cashier']);
  543. if (!$listResult->isSuccess()){
  544. return ResultWrapper::fail($listResult->getData(),$listResult->getErrorCode());
  545. }
  546. $list = $listResult->getData();
  547. $data = [
  548. 'statistics'=>[
  549. 'cashier_push_money' => $cashier_push_money_result->getData(),
  550. 'guide_push_money' => $guide_push_money_result->getData(),
  551. 'order_num' => $orderMap['num'],
  552. 'order_pay_price' => $orderMap['payAmount']
  553. ],
  554. 'list' => $list['data'],
  555. 'screen_time' => [
  556. 'startTime' => $params['startTime'],
  557. 'endTime' => $params['endTime'],
  558. ],
  559. ];
  560. $ret = [
  561. 'total' => $list['total'],
  562. 'data' => $data
  563. ];
  564. return ResultWrapper::success($ret);
  565. }
  566. /**
  567. * Doc: (des="统计列表数据")
  568. * User: XMing
  569. * Date: 2020/9/15
  570. * Time: 11:33 上午
  571. * @param array $params
  572. * @param int $pushType
  573. * @return ResultWrapper
  574. */
  575. private function getListBySql(array $params,int $pushType = 1)
  576. {
  577. $fields = '*,SUM(pushMoney) AS totalPushMoney,SUM(orderMoney) AS totalOrderMoney,COUNT(id) AS num';
  578. $sql = 'SELECT '.$fields.' FROM qianniao_cashier_push_money_detail_'.$this->onlineEnterpriseId.' WHERE pushType = '.$pushType;
  579. if (isset($params['startTime']) && !empty($params['startTime']) &&
  580. isset($params['endTime']) && !empty($params['endTime'])){
  581. $sql .= ' AND createTime BETWEEN '.$params['startTime'].' AND '.$params['endTime'];
  582. }
  583. if (isset($params['userCenterId']) && !empty($params['userCenterId'])){
  584. $sql .= ' AND userCenterId = '.$params['userCenterId'];
  585. }
  586. $sql .= ' GROUP BY userCenterId ORDER BY totalPushMoney DESC ';
  587. $count = count((array)$this->objDCashierPushMoneyDetail->query($sql));
  588. if (isset($params['limit']) && !empty($params['limit']) && isset($params['offset']) && !empty($params['offset'])){
  589. $sql .= ' LIMIT '.$params['offset'].','.$params['limit'];
  590. }
  591. $query = $this->objDCashierPushMoneyDetail->query($sql);
  592. if ($query === false){
  593. return ResultWrapper::fail($this->objDCashierPushMoneyDetail->error(),ErrorCode::$dberror);
  594. }
  595. $userMap = [];
  596. $allUserCenterIds = array_column($query,'userCenterId');
  597. if (!empty($allUserCenterIds)){
  598. $objDUserCenter = new DUserCenter();
  599. $userList = $objDUserCenter->select(['id' =>$allUserCenterIds],'id,mobile');
  600. if ($userList === false){
  601. return ResultWrapper::fail($objDUserCenter->error(),ErrorCode::$dberror);
  602. }
  603. foreach ($userList as $value){
  604. $userMap[$value['id']] = $value['mobile'];
  605. }
  606. }
  607. $map = [];
  608. foreach ($query as $value){
  609. $map[] = [
  610. 'mobile' => isset($userMap[$value['userCenterId']]) ? $userMap[$value['userCenterId']] : '',
  611. 'staffName' => $value['staffName'],
  612. 'order_num' => $value['num'],
  613. 'order_price' => $value['totalOrderMoney'],
  614. 'shop_id' => $value['shopId'],
  615. 'push_money' => $value['totalPushMoney'],
  616. ];
  617. }
  618. return ResultWrapper::success(['data'=>$map,'total'=>$count]);
  619. }
  620. /**
  621. * Doc: (des="统计收银,导购提成")
  622. * User: XMing
  623. * Date: 2020/9/15
  624. * Time: 9:59 上午
  625. * @param int $pushType
  626. * @param array $params
  627. * @return ResultWrapper
  628. */
  629. private function getPushMoneyBySql(int $pushType,array $params)
  630. {
  631. $fields = 'SUM(pushMoney) AS totalSum';
  632. $sql = 'SELECT '.$fields.' FROM qianniao_cashier_push_money_detail_'.$this->onlineEnterpriseId.' WHERE pushType = '.$pushType;
  633. if (isset($params['startTime']) && !empty($params['startTime']) &&
  634. isset($params['endTime']) && !empty($params['endTime'])){
  635. $sql .= ' AND createTime BETWEEN '.$params['startTime'].' AND '.$params['endTime'];
  636. }
  637. $queryResult = $this->objDCashierPushMoneyDetail->query($sql);
  638. if ($queryResult === false){
  639. return ResultWrapper::fail($this->objDCashierPushMoneyDetail->error(),ErrorCode::$dberror);
  640. }
  641. $result = array_shift($queryResult);
  642. return ResultWrapper::success($result['totalSum']);
  643. }
  644. /**
  645. * Doc: (des="通过sql,统计订单数据量")
  646. * User: XMing
  647. * Date: 2020/9/15
  648. * Time: 10:11 上午
  649. * @param array $params
  650. * @return ResultWrapper
  651. */
  652. private function getPushOrderNumBySql(array $params)
  653. {
  654. $fields = 'id,userCenterId,id as orderId';
  655. $sql = 'SELECT '.$fields.' FROM qianniao_order_index_'.$this->onlineEnterpriseId.' WHERE orderType = '.StatusCode::$orderType['cashierOrder'];
  656. if (isset($params['startTime']) && !empty($params['startTime']) &&
  657. isset($params['endTime']) && !empty($params['endTime'])){
  658. $sql .= ' AND createTime BETWEEN '.$params['startTime'].' AND '.$params['endTime'];
  659. }
  660. $queryIndex = $this->objDOrderIndex->query($sql);
  661. if ($queryIndex === false){
  662. return ResultWrapper::fail($this->objDOrderIndex->error(),ErrorCode::$dberror);
  663. }
  664. unset($fields);
  665. unset($sql);
  666. //计算分表
  667. $allGroupData = [];
  668. foreach ($queryIndex as $key => $val) {
  669. $tableNum = ceil($val['userCenterId'] / $this->cutTable);
  670. $allGroupData[$tableNum][] = $val['orderId'];
  671. }
  672. $payAmount = 0;
  673. $fields = 'SUM(payAmount) as payAmount';
  674. foreach ($allGroupData as $k => $orderIds){
  675. if (!empty($orderIds)){
  676. $idStr = implode(',',$orderIds);
  677. $sql = 'SELECT '.$fields.' FROM qianniao_order_'.$this->onlineEnterpriseId.'_'.$k.' WHERE id IN('.$idStr.')';
  678. $queryOrder = $this->objDOrder->query($sql);
  679. if ($queryOrder === false){
  680. return ResultWrapper::fail($this->objDOrder->error(),ErrorCode::$dberror);
  681. }
  682. $result = array_shift($queryOrder);
  683. $payAmount = bcadd($payAmount,$result['payAmount'],2);
  684. }
  685. }
  686. return ResultWrapper::success([
  687. 'payAmount' => $payAmount,
  688. 'num' => count((array)$queryIndex),
  689. ]);
  690. }
  691. /**
  692. * Doc: (des="根据手机号检索会员信息")
  693. * User: XMing
  694. * Date: 2020/9/11
  695. * Time: 2:57 下午
  696. * @param string $mobile
  697. * @return ResultWrapper
  698. * @throws \Exception
  699. */
  700. public function searchCustomerDetails(string $mobile)
  701. {
  702. $objDCustomer = new DCustomer();
  703. $objDCustomer->setTable('qianniao_customer_'.$this->onlineEnterpriseId);
  704. $fields = 'u.mobile,u.id as userCenterId,c.id as customerId,c.salesManId,c.avatar,c.name,c.birthday,c.provinceCode,c.cityCode,
  705. c.districtCode,c.status,c.auditFailReason,c.enableStatus,c.type,c.shopId,c.remark,c.money,c.totalPayMoney,c.createTime';
  706. $sql = 'SELECT '.$fields.' FROM qianniao_user_center AS u
  707. LEFT JOIN qianniao_customer_' .$this->onlineEnterpriseId .' AS c
  708. ON u.id = c.userCenterId
  709. WHERE u.mobile = ' . $mobile . ' LIMIT 1';
  710. $customerInfo = $objDCustomer->query($sql);
  711. if ($customerInfo === false) {
  712. return ResultWrapper::fail($objDCustomer->error(), ErrorCode::$dberror);
  713. }
  714. if (empty($customerInfo)) {
  715. return ResultWrapper::success([]);
  716. }
  717. $customerInfo = array_shift($customerInfo);
  718. if (empty($customerInfo['customerId'])){
  719. return ResultWrapper::success([]);
  720. }
  721. $objMShippingAddress = new MShippingAddress($this->onlineEnterpriseId);
  722. $addressListsResult = $objMShippingAddress->getAllShippingAddress(['customerId'=>$customerInfo['customerId'],'limit'=>10,'offset'=>0]);
  723. if (!$addressListsResult->isSuccess()){
  724. return ResultWrapper::fail($addressListsResult->getData(),$addressListsResult->getErrorCode());
  725. }
  726. $addressLists = $addressListsResult->getData()['data'];
  727. $defaultAddress = (object)[];
  728. if (!empty($addressLists)){
  729. foreach ($addressLists as $val){
  730. if ($val['defaultStatus'] == StatusCode::$standard){
  731. $defaultAddress = $val;
  732. break;
  733. }
  734. }
  735. }
  736. //统计客户订单数
  737. $objDOrderIndex = new DOrderIndex();
  738. $objDOrderIndex->setTable('qianniao_order_index_'.$this->onlineEnterpriseId);
  739. $orderNum = $objDOrderIndex->count(['customerId' => $customerInfo['customerId']]);
  740. if ($orderNum === false){
  741. return ResultWrapper::fail($objDOrderIndex->error(),ErrorCode::$dberror);
  742. }
  743. //根据用户id获取staffId
  744. $map = [
  745. 'mobile' => $customerInfo['mobile'],
  746. 'customerId' => $customerInfo['customerId'],
  747. 'salesManId' => $customerInfo['salesManId'],
  748. 'avatar' => $customerInfo['avatar'],
  749. 'name' => $customerInfo['name'],
  750. 'remark' => is_null($customerInfo['remark']) ? '' : $customerInfo['remark'],
  751. 'createTime' => $customerInfo['createTime'],
  752. 'birthday' => is_null($customerInfo['birthday']) ? 0 : $customerInfo['birthday'],
  753. 'orderNum' => $orderNum,
  754. 'vipCard' => (object)[],
  755. 'address' => $addressLists,
  756. 'defaultAddress' => $defaultAddress,
  757. 'money' => bcadd($customerInfo['money'],0,2),
  758. 'totalPayMoney' => bcadd($customerInfo['totalPayMoney'],0,2),
  759. 'userCenterId' => $customerInfo['userCenterId']
  760. ];
  761. return ResultWrapper::success($map);
  762. }
  763. /**
  764. * Doc: (des="收银台挂单")
  765. * User: XMing
  766. * Date: 2020/9/12
  767. * Time: 6:05 下午
  768. * @param $data
  769. * @return ResultWrapper
  770. */
  771. public function saveEntryData($data)
  772. {
  773. $insert = $this->objDCashierEntryData->insert(
  774. [
  775. 'shopId' => $data['shopId'],
  776. 'entryData' => $data['entryData'],
  777. 'userCenterId'=>$this->onlineUserId,
  778. 'createTime' => time()
  779. ]
  780. );
  781. if ($insert === false){
  782. return ResultWrapper::fail($this->objDCashierEntryData->error(),ErrorCode::$dberror);
  783. }
  784. return ResultWrapper::success(true);
  785. }
  786. /**
  787. * Doc: (des="获取挂单记录")
  788. * User: XMing
  789. * Date: 2020/9/12
  790. * Time: 6:22 下午
  791. * @param array $selectParams
  792. * @return ResultWrapper
  793. */
  794. public function getAllEntryData(array $selectParams)
  795. {
  796. $limit = $selectParams['limit'];
  797. unset($selectParams['limit']);
  798. $offset = $selectParams['offset'];
  799. unset($selectParams['offset']);
  800. $dbResult = $this->objDCashierEntryData->select(['userCenterId'=>$this->onlineUserId,'shopId' => $selectParams['shopId']], '*', 'createTime DESC', $limit, $offset);
  801. if ($dbResult === false) {
  802. return ResultWrapper::fail($this->objDCashierEntryData->error(), ErrorCode::$dberror);
  803. }
  804. foreach ($dbResult as &$value){
  805. $value['entryData'] = json_decode($value['entryData'],true);
  806. }
  807. $total = $this->objDCashierEntryData->count(['userCenterId'=>$this->onlineUserId,'shopId' => $selectParams['shopId']]);
  808. $return = [
  809. 'data' => $dbResult,
  810. 'total' => ($total) ? intval($total) : 0,
  811. ];
  812. return ResultWrapper::success($return);
  813. }
  814. /**
  815. * Doc: (des="获取挂单")
  816. * User: XMing
  817. * Date: 2020/9/12
  818. * Time: 6:30 下午
  819. * @param int $id
  820. * @return ResultWrapper
  821. */
  822. public function getEntryData(int $id)
  823. {
  824. $result = $this->objDCashierEntryData->get(['id'=>$id]);
  825. if ($result === false) {
  826. return ResultWrapper::fail($this->objDCashierEntryData->error(), ErrorCode::$dberror);
  827. }
  828. if (!empty($result)){
  829. $this->objDCashierEntryData->delete(['id'=>$id]);
  830. $result['entryData'] = json_decode($result['entryData'],true);
  831. return ResultWrapper::success($result);
  832. }
  833. return ResultWrapper::success([]);
  834. }
  835. /**
  836. * Doc: (des="删除挂单")
  837. * User: XMing
  838. * Date: 2020/9/12
  839. * Time: 6:39 下午
  840. * @param $id
  841. * @return ResultWrapper
  842. */
  843. public function delEntryData(int $id)
  844. {
  845. $result = $this->objDCashierEntryData->delete(['id' => $id]);
  846. if ($result === false) {
  847. return ResultWrapper::fail($this->objDCashierEntryData->error(), ErrorCode::$dberror);
  848. }
  849. return ResultWrapper::success(true);
  850. }
  851. /**
  852. * Doc: (des="收银台商品改价")
  853. * User: XMing
  854. * Date: 2020/9/14
  855. * Time: 9:33 上午
  856. * @param array $params
  857. * @return ResultWrapper
  858. */
  859. public function changePrice(array $params)
  860. {
  861. $insert = [
  862. 'skuId' => $params['skuId'],
  863. 'price' => $params['changePrice'],
  864. 'cashierUid' => $this->onlineUserId,
  865. 'customerUid' => $params['customerUid']
  866. ];
  867. $insert = $this->objDCashierCustomerPrice->replace($insert);
  868. if ($insert === false) {
  869. return ResultWrapper::fail($this->objDCashierEntryData->error(), ErrorCode::$dberror);
  870. }
  871. return ResultWrapper::success(true);
  872. }
  873. }