StoreController.php 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  1. <?php
  2. namespace addons\Store\api\modules\v2\controllers;
  3. use addons\PlatformStoreClerk\common\models\PlatformStoreClerkOrderDetail;
  4. use addons\ReservationService\common\enums\ReservationServiceEnum;
  5. use addons\ReservationService\common\logic\NoticeLogic;
  6. use addons\ReservationService\common\models\ReservationServiceOrder;
  7. use addons\ReservationService\common\models\ReservationServiceUser;
  8. use addons\ReservationService\common\models\ReservationServiceUserBookTime;
  9. use addons\ReservationService\common\services\OrderService;
  10. use addons\SecondaryCard\common\models\SecondaryCard;
  11. use addons\SecondaryCard\common\models\SecondaryCardOrder;
  12. use addons\SecondaryCard\common\models\SecondaryCardUseLog;
  13. use addons\SecondaryCard\common\service\SecondaryCardOrderService;
  14. use addons\SecondaryCard\common\service\SecondaryCardService;
  15. use addons\Store\common\models\Store;
  16. use addons\Store\common\models\StoreClerk;
  17. use addons\Store\common\models\StoreClerkLog;
  18. use addons\Store\common\models\StoreOrder;
  19. use addons\Store\common\models\StoreOrderDetail;
  20. use addons\Store\common\models\StoreOrderReserve;
  21. use common\enums\AddonsEnum;
  22. use common\enums\MarketingTypeEnum;
  23. use common\enums\OrderStatusEnum;
  24. use common\enums\PayTypeEnum;
  25. use common\enums\ShippingTypeEnum;
  26. use common\enums\StatusEnum;
  27. use common\globals\GlobalInvoke;
  28. use common\models\common\ClerkLog;
  29. use common\models\mall\MallAddons;
  30. use common\models\order\Order;
  31. use common\models\order\OrderDetail;
  32. use common\models\order\OrderExpress;
  33. use common\models\order\OrderMarketing;
  34. use common\models\order\OrderReserve;
  35. use common\models\user\Town;
  36. use common\models\user\User;
  37. use Yii;
  38. use addons\Store\common\enums\StoreEnum;
  39. use addons\Store\common\models\StoreCate;
  40. use addons\Store\common\services\StoreService;
  41. use common\models\common\Region;
  42. /**
  43. * 默认控制器
  44. *
  45. * Class DefaultController
  46. * @package addons\Store\api\modules\v2\controllers
  47. */
  48. class StoreController extends BaseController
  49. {
  50. public $modelClass = '';
  51. /**
  52. * 不用进行登录验证的方法
  53. *
  54. * 例如: ['index', 'update', 'create', 'view', 'delete']
  55. * 默认全部需要验证
  56. *
  57. * @var array
  58. */
  59. protected $authOptional = ['index', 'clerk', 'is-clerk', 'clerk-log', 'detail', 'setting', 'store-cate-tree', 'get-address-list', 'address-info', 'get-town-list',
  60. 'reservation-service-list', 'reservation-service-detail', 'reservation-service-talking', 'clerk-common', 'clerk-common-log', 'reservation-service-reject',
  61. 'clerk-common-log-detail',];
  62. public function actionIndex()
  63. {
  64. $store = $this->store;
  65. $data = [
  66. 'id' => $this->store_id,
  67. 'store_name' => $store['store_name'],
  68. 'shop_owner' => $store['shop_owner'],
  69. 'balance' => $store['balance'],
  70. 'unsettled_amount' => $store['unsettled_amount'],
  71. 'logo_img' => $store['logo_img'],
  72. 'shop_mobile' => $store['shop_mobile'],
  73. 'is_show_platform_store_clerk' => 0
  74. ];
  75. //是否显示核销统计【插件:门店核销】
  76. if (MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_PLATFORM_STORE_CLERK)) {
  77. $data['is_show_platform_store_clerk'] = 1;
  78. }
  79. return $this->success('success', $data);
  80. }
  81. //判断是否是核销员
  82. public function actionIsClerk()
  83. {
  84. $mall_id = $this->mall_id;
  85. $store = Store::getOne([['id' => $this->store_id]], true, [], false, 'id,user_id,balance');
  86. $user_id = $store['user_id'];
  87. $rse = StoreClerk::getOne([['mall_id' => $mall_id], ['user_id' => $user_id], ['status' => StatusEnum::ENABLED]]);
  88. if (empty($rse)) return $this->error('你不是核销员');
  89. return $this->success('操作成功', ['store_id' => $rse['store_id']]);
  90. }
  91. //核销
  92. public function actionClerk()
  93. {
  94. $params = Yii::$app->request->post();
  95. $store = Store::getOne([['id' => $this->store_id]], true, [], false, 'id,user_id,balance');
  96. $user_id = $store['user_id'];
  97. $storeService = new StoreService();
  98. $storeService->mall_id = $this->mall_id;
  99. $storeService->store_id = $this->store_id;
  100. $params['clerk_id'] = $storeService->getClerkIdByUserId($user_id, true);
  101. $mall_id = $this->mall_id;
  102. $params['mall_id'] = $mall_id;
  103. $rse = StoreClerk::getOne([['mall_id' => $mall_id], ['user_id' => $user_id], ['status' => StatusEnum::ENABLED]]);
  104. if (empty($rse)) return $this->error('你不是核销员');
  105. $params['store_id'] = $rse['store_id'];
  106. $rse = StoreClerkLog::setData($params);
  107. if ($rse == false) return $this->error(StoreClerkLog::getStaticError());
  108. return $this->success('操作成功');
  109. }
  110. // 已核销和未核销的订单
  111. public function actionClerkLog()
  112. {
  113. $params = \Yii::$app->request->get();
  114. $params['take_status'] = $params['take_status'] ?? 0;
  115. $order_params['order'] = 'id desc';
  116. $order_params['with'] = ['detail', 'base_user'];
  117. $order_params['select'] = 'id,mall_id,pay_money,store_id,shipping_type,order_no,order_status,user_id';
  118. $order_params['where'] = [
  119. ['mall_id' => $this->mall_id],
  120. ['store_id' => $this->store_id],
  121. ['shipping_type' => ShippingTypeEnum::PICKUP]
  122. ];
  123. if ($params['take_status'] == 1) { // 已核销
  124. $order_params['where'][] = ['order_status' => [OrderStatusEnum::TAKE_FINISH, OrderStatusEnum::ACCOMPLISH]];
  125. } else if ($params['take_status'] == 2) { // 待核销
  126. $order_params['where'][] = ['order_status' => OrderStatusEnum::TAKE];
  127. } else { // 全部
  128. $order_params['where'][] = ['order_status' => [OrderStatusEnum::TAKE, OrderStatusEnum::TAKE_FINISH, OrderStatusEnum::ACCOMPLISH]];
  129. }
  130. $order_params['limit'] = $params['limit'] ?? 10;
  131. $order_list = Order::listPage($order_params, false);
  132. $order_nos = array_column($order_list['list'], 'order_no');
  133. $clerk_log = StoreClerkLog::lists([
  134. 'where' => [['order_no' => $order_nos]],
  135. 'select' => '*',
  136. 'index' => 'order_no'
  137. ]);
  138. foreach ($order_list['list'] as $key => $item) {
  139. $item['nickname'] = $item['base_user']['nickname'] ?? '';
  140. $item['avatar_url'] = $item['base_user']['avatar_url'] ?? '';
  141. if (in_array($item['order_status'], [OrderStatusEnum::TAKE_FINISH, OrderStatusEnum::ACCOMPLISH])) {
  142. $item['clerk_status'] = '已核销';
  143. } else {
  144. $item['clerk_status'] = '待核销';
  145. }
  146. $item['details'] = $item['detail'];
  147. $item['total_num'] = count($item['detail']);
  148. $item['order_id'] = $item['id'];
  149. $item['clerk_id'] = '';
  150. if (isset($clerk_log[$item['order_no']])) {
  151. $clerk = $clerk_log[$item['order_no']];
  152. $item['clerk_id'] = $clerk['clerk_id'] ?? 0;
  153. $item['mobile'] = $clerk['mobile'] ?? '';
  154. }
  155. $item['mobile'] = $item['mobile'] ?? '';
  156. unset($item['detail'], $item['base_user']);
  157. $order_list['list'][$key] = $item;
  158. }
  159. return $this->success('操作成功', $order_list);
  160. }
  161. /**
  162. * 订单详情
  163. * @return mixed|void
  164. */
  165. public function actionDetail()
  166. {
  167. $params = \Yii::$app->request->get();
  168. $res = \Yii::$app->services->validate->validate($params, [
  169. [['order_id'], 'required'],
  170. ]);
  171. if ($res === false) return $this->error(\Yii::$app->services->validate->getErrorMessage());
  172. $store = Store::getOne([['id' => $this->store_id]], true, [], false, 'id,user_id,balance');
  173. // $user_id = $store['user_id'];
  174. $select = 'id,mall_id,store_id,order_no,receiver_name,mobile,pay_money,shipping_money,original_goods_price,coupon_money,goods_price,order_status,pay_status,
  175. shipping_status,review_status,is_feedback,address,created_at,pay_time,region_name,remark,consign_time,finish_time,sign_time,shipping_type,payment_type,score,score_money,marketing_id,marketing_type,extra_info,order_source';
  176. $where = [];
  177. $where[] = ['mall_id' => $this->mall_id];
  178. $where[] = ['or',
  179. ['id' => $params['order_id']],
  180. ['clerk_code' => $params['order_id']],
  181. ];
  182. $order = Order::getOne($where, true, ['detail' => function ($query) {
  183. $query->select('id,order_id,goods_id,goods_name,pic_url,num,price,is_feedback,sign_id,goods_attr_name,order_status,adjust_money,extra_info');
  184. }], false, $select);
  185. // $rse = StoreClerk::getOne([['mall_id' => $this->mall_id], ['user_id' => $user_id, 'store_id' => $order['store_id']], ['status' => StatusEnum::ENABLED]]);
  186. // if (empty($rse)) return $this->error('你不是核销员');
  187. if (empty($order)) return $this->error('该订单不存在', []);
  188. $marketing = OrderMarketing::getMarketingInfo($order);
  189. $order['order_status_text'] = OrderStatusEnum::getMap();
  190. $order['is_feedback_text'] = OrderStatusEnum::getFeedbackMap();
  191. $order['shipping_type_text'] = ShippingTypeEnum::getMap();
  192. $order['payment_type_text'] = PayTypeEnum::getMap();
  193. $order['pay_type_list'] = \Yii::$app->services->pay->getEnablePayment($this->mall_id, $this->platform);
  194. $adjust_money = array_sum(array_column($order['detail'], 'adjust_money'));//预留字段
  195. if ($adjust_money) {
  196. $order['change_price'] = $adjust_money;
  197. }
  198. $order['marketing'] = $marketing;
  199. $order['marketing_type_map'] = MarketingTypeEnum::getMap();
  200. $order_setting = Yii::$app->services->setting->mall->get($this->mall_id, 'order');
  201. $order['payment_expire_time'] = $order_setting['payment_expire_time'] ?? 30;
  202. $order['auto_receiving_time'] = $order_setting['auto_receiving_time'] ?? 14;
  203. // 获取订单详情的状态文字描述
  204. $order['status_text'] = OrderStatusEnum::getApiStatus($order['status'], $order['shipping_type']);
  205. $order['status'] == OrderStatusEnum::NOT_PAY && $order['status_text']['desc'] = $order['payment_expire_time'] . $order['status_text']['desc'];
  206. $order['status'] == OrderStatusEnum::SHIPMENTS && $order['status_text']['desc'] = $order['auto_receiving_time'] . $order['status_text']['desc'];
  207. $order['show_clerk_button'] = $order['order_status'] == OrderStatusEnum::TAKE ? 1:0;
  208. // 公共调用
  209. $order = GlobalInvoke::exec(GlobalInvoke::ORDER_DETAIL, $this->mall_id, [
  210. 'order' => $order,
  211. 'mall_id' => $this->mall_id,
  212. ]) ?: $order;
  213. return $this->success('操作成功', $order);
  214. }
  215. public function actionSetting()
  216. {
  217. if (Yii::$app->request->isGet) {
  218. $detail = Store::getOne([['id' => $this->store_id], ['mall_id' => $this->mall_id]], true);
  219. $detail['cIds'] = [];
  220. $detail['province'] = '';
  221. $detail['city'] = '';
  222. $detail['district'] = '';
  223. $detail['c_name'] = '';
  224. $c_name = '';
  225. if ($detail) {
  226. if (!empty($detail['c_id'])) {
  227. $cate = StoreCate::findOne(['mall_id' => $this->mall_id, 'id' => $detail['c_id']]);
  228. if (!empty($cate['parent_id'])) {
  229. $parent = StoreCate::findOne(['mall_id' => $this->mall_id, 'id' => $cate['parent_id']]);
  230. if (!empty($parent['parent_id'])) {
  231. $detail['cIds'][] = $parent['parent_id'];
  232. }
  233. if (!empty($parent['name'])) {
  234. $c_name .= $parent['name'] . '/';
  235. }
  236. $detail['cIds'][] = $cate['parent_id'];
  237. }
  238. $detail['cIds'][] = $detail['c_id'];
  239. $c_name .= $cate['name'];
  240. }
  241. $detail['c_name'] = $c_name;
  242. $region_id_arr = [$detail['province_id'], $detail['city_id'], $detail['district_id']];
  243. $region_list = Region::lists(['where' => [['id' => $region_id_arr]], 'index' => 'id', 'select' => 'id,name']);
  244. if (!empty($detail['province_id'])) {
  245. $detail['province'] = $region_list[$detail['province_id']]['name'];
  246. $detail['city'] = $region_list[$detail['city_id']]['name'];
  247. $detail['district'] = $region_list[$detail['district_id']]['name'];
  248. }
  249. }
  250. $detail['address_detail'] = $detail['address'] ?? '';
  251. $detail['ll'] = $detail['latitude'] . ',' . $detail['longitude'];
  252. if (!empty($detail['freight_type'])) {
  253. $detail['freight_type'] = json_decode($detail['freight_type'], true);
  254. } else {
  255. $detail['freight_type'] = [
  256. 'express_delivery' => 0,
  257. 'merchant_distribution' => 0,
  258. 'self_mention' => 0,
  259. ];
  260. }
  261. if (!empty($detail['intra_city_distribution'])) {
  262. $detail['intra_city_distribution'] = json_decode($detail['intra_city_distribution'], true);
  263. } else {
  264. $detail['intra_city_distribution'] = ['distribution_scope' => 0, 'initial_delivery_amount' => 0, 'full_money' => 0, 'reduce_money' => 0, 'distribution_fee' => 0];
  265. }
  266. if (!empty($detail['introduce'])) {
  267. $detail['introduce'] = json_decode($detail['introduce'], true);
  268. } else {
  269. $detail['introduce'] = [];
  270. }
  271. if (!empty($detail['bannar_pic'])) {
  272. $detail['bannar_pic'] = json_decode($detail['bannar_pic'], true);
  273. } else {
  274. $detail['bannar_pic'] = [];
  275. }
  276. if (!isset($detail['show_style'])) {
  277. $detail['show_style'] = "1";
  278. }
  279. $platform_address = \Yii::$app->services->setting->addons->get($this->mall_id, StoreEnum::ADDONS_NAME, 'basic.platform_address');
  280. $detail['platform_address'] = $platform_address ?? '';
  281. return $this->success('操作成功', ['detail' => $detail]);
  282. }
  283. if (Yii::$app->request->isPost) {
  284. $params = Yii::$app->request->post();
  285. $params['id'] = $this->store_id;
  286. $params['mall_id'] = $this->mall_id;
  287. // $params['freight_type'] = [
  288. // "express_delivery" => 0,
  289. // "merchant_distribution" => 0,
  290. // "self_mention" => 1
  291. // ];
  292. if (isset($params['longitude'])) $params['longitude'] = (string)$params['longitude'];
  293. if (isset($params['latitude'])) $params['latitude'] = (string)$params['latitude'];
  294. if (isset($params['shop_mobile'])) $params['shop_mobile'] = (string)$params['shop_mobile'];
  295. if (isset($params['shop_owner'])) $params['shop_owner'] = (string)$params['shop_owner'];
  296. if (isset($params['device_id'])) $params['device_id'] = (string)$params['device_id'];
  297. if (isset($params['store_desc'])) $params['store_desc'] = (string)$params['store_desc'];
  298. if (empty($params['introduce'])) unset($params['introduce']);
  299. if (empty($params['bannar_pic'])) unset($params['bannar_pic']);
  300. $res = Store::setData($params);
  301. if ($res == false) return $this->success(Store::getStaticError());
  302. return $this->success('操作成功');
  303. }
  304. }
  305. public function actionGetAddressList()
  306. {
  307. $get = Yii::$app->request->get();
  308. if (!empty($get['id'])) $where[] = ['parent_id' => $get['id']];
  309. if (empty($get['level'])) {
  310. $level = 1;
  311. } else {
  312. $level = $get['level'];
  313. }
  314. $where[] = ['level' => $level];
  315. $params['where'] = $where;
  316. $params['select'] = 'id,name,parent_id,level,lng,lat';
  317. $list = Region::lists($params);
  318. return $this->success('操作成功', $list);
  319. }
  320. public function actionStoreCateTree()
  321. {
  322. if (Yii::$app->request->isGet) {
  323. $cond = [['mall_id' => $this->mall_id]];
  324. $list = StoreCate::getCates($cond, [], true, 'id,name,parent_id');
  325. $list = StoreCate::getTreeCate($list);
  326. return $this->success('操作成功', compact('list'));
  327. }
  328. }
  329. /**
  330. * 获取省市区数据
  331. * @return \yii\web\Response
  332. */
  333. public function actionAddressInfo()
  334. {
  335. $list = Region::getRegionList([['<>', 'parent_id', -1]], 'id,name,parent_id,level', [], 1);
  336. return $this->success('ok', $list);
  337. }
  338. /**
  339. * 获取乡镇列表
  340. * @return mixed|void
  341. */
  342. public function actionGetTownList()
  343. {
  344. $params = Yii::$app->request->get();
  345. $res = Yii::$app->services->validate->validate($params, [
  346. [['district_id'], 'required', 'message' => 'district_id必传'],
  347. ]);
  348. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  349. $where[] = ['district_id' => !empty($params['district_id']) ? $params['district_id'] : ''];
  350. $params['order'] = 'id desc';
  351. $params['select'] = 'id,adcode,name';
  352. $params['where'] = $where;
  353. $page_data = Town::listPage($params, false);
  354. return $this->success('操作成功', $page_data);
  355. }
  356. /**
  357. * 获取验证码
  358. *
  359. * @return void
  360. */
  361. public function actionGetCaptcha()
  362. {
  363. $service = new StoreService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]);
  364. return $service->sendCaptcha()
  365. ? $this->success('发送成功')
  366. : $this->error($service->getError());
  367. }
  368. /**
  369. * 修改密码
  370. *
  371. * @return void
  372. */
  373. public function actionChangePwd()
  374. {
  375. $params = Yii::$app->request->post();
  376. $res = Yii::$app->services->validate->validate($params, [
  377. [['captcha'], 'required', 'message' => '验证码不能为空'],
  378. [['password'], 'required', 'message' => '修改密码不能为空'],
  379. ]);
  380. if ($res === false) {
  381. return $this->error(Yii::$app->services->validate->getErrorMessage());
  382. }
  383. $service = new StoreService(['mall_id' => $this->mall_id, 'store_id' => $this->store_id]);
  384. return $service->changePwd($params['captcha'], $params['password'])
  385. ? $this->success('修改成功')
  386. : $this->error($service->getError());
  387. }
  388. /**
  389. * 兑换管理 :是否显示
  390. */
  391. public function actionCheckExchange()
  392. {
  393. $is_show = 0;
  394. if (MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_GOLD_BADGE) !== 0) {
  395. $config = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_GOLD_BADGE, 'basic');
  396. $is_show = $config['is_enable'] ?? 0;
  397. }
  398. return $this->success('操作成功', ['is_show' => $is_show]);
  399. }
  400. public function actionPlatformClerkList()
  401. {
  402. if (Yii::$app->request->isGet) {
  403. $get = Yii::$app->request->get();
  404. if (!MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_PLATFORM_STORE_CLERK)) {
  405. return $this->success('获取成功', []);
  406. }
  407. // 检查提交的参数
  408. $res = Yii::$app->services->validate->validate($get, [
  409. [['page', 'limit'], 'integer'],
  410. ]);
  411. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  412. $where[] = ['=', 'mall_id', $this->mall_id];
  413. $where[] = ['=', 'clerk_store_id', $this->store_id];
  414. $where[] = ['=', 'status', StatusEnum::ENABLED];
  415. $order = 'id desc,created_at desc';
  416. $select = 'id,order_id,order_detail_id,reward_num,clerk_time,clerk_user_id,user_id';
  417. $with = ['orderDetail', 'order', 'clerkUser', 'user'];
  418. $params = array('where' => $where, 'order' => $order, 'select' => $select, 'with' => $with, 'limit' => $get['limit'] ?? 10, 'page' => $get['page'] ?? 1);
  419. $list = PlatformStoreClerkOrderDetail::listPage($params);
  420. foreach ($list['list'] as &$item) {
  421. $item['reward_num'] = $item['reward_num'] ?: 0;
  422. $item['clerk_time'] = date('Y-m-d H:i:s', $item['clerk_time']);
  423. $item['goods_name'] = $item['orderDetail']['goods_name'] ?? '';
  424. $item['order_no'] = $item['order']['order_no'] ?? '';
  425. //$item['user'] = $user;
  426. $item['clerk_user_info'] = '核销员' . $item['clerkUser']['nickname'] . '(id:' . $item['clerk_user_id'] . ')';
  427. unset($item['order'], $item['orderDetail'], $item['clerkUser']);
  428. }
  429. return $this->success('获取成功', $list);
  430. }
  431. }
  432. /**
  433. * 预约管理
  434. * @Author:hua
  435. * @Date:2024-03-06 18:05
  436. * @Copyright:copyright(c)2024 广东七件事集团
  437. * @return mixed|void
  438. */
  439. public function actionReservationServiceList()
  440. {
  441. $data = Yii::$app->request->get();
  442. $valid = Yii::$app->services->validate->validate($data, [
  443. [['limit', 'page', 'order_status'], 'integer'],
  444. ]);
  445. if ($valid === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  446. $data['store_id'] = $this->store_id;
  447. $ret = $this->page($this->mall_id, $data);
  448. return is_string($ret) ? $this->error($ret) : $this->success('获取成功', $ret);
  449. }
  450. protected function page(int $mall_id, array $params)
  451. {
  452. if (!MallAddons::isInstall($mall_id, 'SecondaryCard')) {
  453. return '请先安装次卡插件';
  454. }
  455. if (!MallAddons::isInstall($mall_id, 'ReservationService')) {
  456. return '请先安装预约服务插件';
  457. }
  458. $where = [
  459. ['mall_id' => $mall_id],
  460. ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]],
  461. ['!=','service_status', ReservationServiceEnum::RESERVE_ORDER_STATUS_CLOSED ],
  462. ['store_id' => $params['store_id']],
  463. ['reservation_model' => 1],
  464. ['!=', 'secondary_card_id', 0]
  465. ];
  466. if (isset($params['order_status']) && $params['order_status'] !== '' && $params['order_status'] != 999) {
  467. $where[] = ['service_status' => $params['order_status']];
  468. }
  469. $with = [
  470. ];
  471. $ret = ReservationServiceOrder::listPage([
  472. 'where' => $where,
  473. 'order' => 'id desc',
  474. 'limit' => $params['limit'] ?? 10,
  475. 'with' => $with
  476. ]);
  477. if (!empty(ReservationServiceOrder::getStaticError())) return ReservationServiceOrder::getStaticError();
  478. $ret['status_text_map'] = ReservationServiceEnum::RESERVE_ORDER_STATUS_MAP;
  479. if (!empty($ret['list'])) {
  480. $mall_name = Yii::$app->services->setting->mall->get($mall_id, 'basic.name');
  481. $mall_logo = Yii::$app->services->setting->mall->get($mall_id, 'basic.logo');
  482. $user_ids = array_column($ret['list'],'user_id');
  483. $user_list = User::lists(['where'=>[['id'=>$user_ids]],'index'=>'id']);
  484. $secondary_card_order_list = [];
  485. //次卡部分----start
  486. if (MallAddons::isInstall($mall_id, 'SecondaryCard')) {
  487. $secondary_card_no_arr = array_column($ret['list'], 'secondary_card_no');
  488. $secondary_card_order_list = SecondaryCardOrder::lists([
  489. 'where' => [
  490. ['order_no' => $secondary_card_no_arr],
  491. ],
  492. 'with' => ['secondaryCard'],
  493. 'index' => 'order_no'
  494. ]);
  495. }
  496. $reservation_service_order_ids = array_column($ret['list'], 'id');
  497. // $use_log_list = SecondaryCardUseLog::lists(['where' => [['reservation_service_order_id' => $reservation_service_order_ids]], 'index' => 'reservation_service_order_id']);
  498. foreach ($ret['list'] as &$item) {
  499. $item['status_text'] = ReservationServiceEnum::RESERVE_ORDER_STATUS_MAP[$item['service_status']];
  500. // $item['service_status'] = ReservationServiceEnum::RESERVE_ORDER_STATUS_MAP[$item['service_status']];
  501. $item['service_start_at_text'] = "";
  502. if (!empty($item['service_start_at'])) $item['service_start_at_text'] = date('Y-m-d H:i', $item['service_start_at']);
  503. $item['mall_name'] = $mall_name;
  504. $item['mall_logo'] = $mall_logo;
  505. $store = Store::findOne(['id' => $item['store_id']]);
  506. $item['mall_name'] = $store->store_name;
  507. $item['mall_logo'] = $store->logo_img;
  508. $reserveOrder = StoreOrderReserve::findOne(['main_order_id' => $item['order_id']]);
  509. $item['service_type'] = $reserveOrder->service_type;
  510. $item['service_type_text'] = ReservationServiceEnum::SERVICE_TYPE_MAP[$reserveOrder->service_type] ?? '未知服务';
  511. //次卡部分----start
  512. if (!empty($secondary_card_order_list) && isset($secondary_card_order_list[$item['secondary_card_no']])) {
  513. $secondary_card_order = $secondary_card_order_list[$item['secondary_card_no']];
  514. $secondary_card = [
  515. 'name' => $secondary_card_order['secondaryCard']['name'],
  516. 'font_color' => $secondary_card_order['secondaryCard']['font_color'],
  517. 'background' => $secondary_card_order['secondaryCard']['background'],
  518. 'appointment_interval_duration' => $secondary_card_order['secondaryCard']['appointment_interval_duration'],
  519. 'price' => $secondary_card_order['secondaryCard']['price'],
  520. 'times' => 1,
  521. 'order_no' => $secondary_card_order['order_no'],
  522. 'reservation_service_order_id' => $item['id'],
  523. ];
  524. // $secondary_card['service_times'] = $use_log_list[$item['id']]['clerk_nums'] ?? 1;
  525. // $secondary_card['service_money'] = $use_log_list[$item['id']]['service_income'] ?? 0;
  526. $secondary_card['service_type_text'] = '到店服务';
  527. $secondary_card['service_start_at_text'] = $item['service_start_at_text'];
  528. $secondary_card['status_text'] = $item['status_text'];
  529. $secondary_card['status'] = $item['service_status'];
  530. $secondary_card['mall_name'] = $item['mall_name'];
  531. $secondary_card['mall_logo'] = $item['mall_logo'];
  532. $secondary_card['order_id'] = $item['order_id'];
  533. $secondary_card['nickname'] = $user_list[$item['user_id']]['nickname'];
  534. $secondary_card['avatar_url'] = $user_list[$item['user_id']]['avatar_url'];
  535. $item = $secondary_card;
  536. }
  537. //次卡部分----end
  538. }
  539. }
  540. return $ret;
  541. }
  542. /**
  543. * 预约订单详情
  544. * @Author:hua
  545. * @Date:2024-03-06 18:21
  546. * @Copyright:copyright(c)2024 广东七件事集团
  547. * @return mixed|void
  548. */
  549. public function actionReservationServiceDetail()
  550. {
  551. $data = Yii::$app->request->get();
  552. $valid = Yii::$app->services->validate->validate($data, [
  553. [['id'], 'integer'],
  554. [['id'], 'required']
  555. ]);
  556. if ($valid === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  557. $ret = $this->getDetailById($this->mall_id, $this->store_id, $data['id']);
  558. return is_string($ret) ? $this->error($ret) : $this->success('获取成功', $ret);
  559. }
  560. protected function getDetailById(int $mall_id, int $store_id, int $id)
  561. {
  562. if (!MallAddons::isInstall($mall_id, 'SecondaryCard')) {
  563. return '请先安装次卡插件';
  564. }
  565. if (!MallAddons::isInstall($mall_id, 'ReservationService')) {
  566. return '请先安装预约服务插件';
  567. }
  568. $rWhere = [
  569. ['mall_id' => $mall_id],
  570. ['id' => $id],
  571. ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]],
  572. ['store_id' => $store_id]
  573. ];
  574. $model = ReservationServiceOrder::getOne($rWhere);
  575. if (empty($model)) return '预约记录不存在';
  576. $order_no = Order::find()->where(['mall_id' => $mall_id])
  577. ->andWhere(['id' => $model->order_id])
  578. ->select('order_no')->scalar();
  579. if (empty($order_no)) return '订单不存在.';
  580. $storeOrder = StoreOrder::findOne(['mall_id' => $mall_id, 'store_id' => $model->store_id, 'order_no' => $order_no]);
  581. if (empty($storeOrder)) return '订单不存在!';
  582. $orderReserve = StoreOrderReserve::getOne([
  583. ['mall_id' => $mall_id],
  584. ['reserve_type' => StatusEnum::ENABLED],
  585. ['order_id' => $storeOrder->id]
  586. ]);
  587. if (empty($orderReserve)) return '订单不存在';
  588. $order = (new OrderService())->orderDetail($mall_id, $model->order_id);
  589. if (is_array($order)) {
  590. $order['user'] = $model->getUser()->select('id, nickname, avatar_url, mobile')->one()->toArray();
  591. $order['reserve'] = $orderReserve->toArray();
  592. $order['service_status_map'] = ReservationServiceEnum::RESERVE_ORDER_STATUS_MAP;
  593. $order['service_status_text'] = $order['service_status_map'][$model->service_status] ?? '未知状态';
  594. $order['service_start_at_text'] = date('Y-m-d H:i', $model->service_start_at);
  595. $order['service_min'] = ($model->service_end_at - $model->service_start_at) / 60; // 分钟
  596. $order['service_status'] = $model->service_status;
  597. $order['service_type'] = $orderReserve->service_type; // 是否为上面服务
  598. $order['commission'] = bcmul($model->commission, 1, 2); // 是否为上门服务
  599. $order['service_type_text'] = ReservationServiceEnum::SERVICE_TYPE_MAP[$orderReserve->service_type] ?? '未知服务';
  600. if (!empty($order['finish_time'])) date('Y-m-d H:i:s', $order['finish_time']);
  601. if (!empty($order['sign_time'])) date('Y-m-d H:i:s', $order['sign_time']);
  602. }
  603. //次卡部分
  604. if (!empty($model->secondary_card_id)) {
  605. $secondary_card = SecondaryCard::findOne(['id' => $model->secondary_card_id]);
  606. $order['secondary_card'] = [
  607. 'name' => $secondary_card['name'],
  608. 'background' => $secondary_card['background'],
  609. 'font_color' => $secondary_card['font_color'],
  610. 'service' => json_decode($secondary_card['service'], true),
  611. 'secondary_card_no' => $model->secondary_card_no,
  612. ];
  613. $order['service_type_text'] = \addons\ReservationService\common\services\SecondaryCardService::getServiceTypeText($secondary_card);
  614. $secondary_card_order = SecondaryCardOrder::findOne(['order_no' => $model->secondary_card_no]);
  615. $order['secondary_card']['verifiable_times'] = $secondary_card_order['verifiable_times'];
  616. $order['secondary_card']['use_times'] = $secondary_card['verifiable_times'] - $secondary_card_order['verifiable_times'];
  617. $order['secondary_card']['clerk_code'] = $secondary_card_order['clerk_code'];
  618. $order['secondary_card']['order_source'] = SecondaryCardOrderService::getSourceName($secondary_card_order, $secondary_card['use_type']);
  619. $use_log = SecondaryCardUseLog::findOne(['reservation_service_order_id' => $model['id']]);
  620. $order['secondary_card']['service_times'] = $use_log['clerk_nums'] ?? 1;
  621. $order['secondary_card']['service_income'] = $use_log['service_income'] ?? 0;
  622. $order['secondary_card']['clerk_money'] = $use_log['clerk_money'] ?? bcdiv($secondary_card_order['pay_money'], $secondary_card['verifiable_times'], 2);
  623. $order['secondary_card']['pay_money'] = $secondary_card_order['pay_money'];
  624. $order['secondary_card']['reservation_service_order_id'] = $id;
  625. $order['secondary_card']['service_type_text'] = $order['service_type_text'];
  626. $order['secondary_card']['service_status_text'] = $order['service_status_text'];
  627. $order['secondary_card']['status'] = $order['service_status'];
  628. $order['secondary_card']['service_start_at_text'] = $order['service_start_at_text'];
  629. $order['secondary_card']['service_min'] = $order['service_min'];
  630. $order['secondary_card']['created_at'] = $order['created_at'];
  631. $order['secondary_card']['mall_name'] = $order['mall_name'];
  632. $order['secondary_card']['mall_logo'] = $order['mall_logo'];
  633. $order['secondary_card']['pay_time'] = date('Y-m-d H:i:s', $secondary_card_order['open_time']);
  634. }
  635. return $order['secondary_card'];
  636. }
  637. /**
  638. * 确认订单-接受
  639. * @Author:hua
  640. * @Date:2024-03-06 18:22
  641. * @Copyright:copyright(c)2024 广东七件事集团
  642. * @return mixed|void
  643. */
  644. public function actionReservationServiceTalking()
  645. {
  646. $data = Yii::$app->request->get();
  647. $valid = Yii::$app->services->validate->validate($data, [
  648. [['id'], 'integer'],
  649. [['id'], 'required'],
  650. ]);
  651. if ($valid === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  652. $ret = $this->talking($this->mall_id, $this->store_id, $data['id']);
  653. return is_string($ret) ? $this->error($ret) : $this->success('操作成功');
  654. }
  655. /**
  656. * 拒绝接单
  657. * @return mixed|null
  658. */
  659. public function actionReservationServiceReject()
  660. {
  661. $data = Yii::$app->request->post();
  662. $valid = Yii::$app->services->validate->validate($data, [
  663. [['id'], 'integer'],
  664. [['reason'], 'string'],
  665. [['id'], 'required']
  666. ]);
  667. if ($valid === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  668. $ret = $this->reject($this->mall_id, $this->store['user_id'], $data['id'], 0, !empty($data['reason']) ? $data['reason'] : '无');
  669. return is_string($ret) ? $this->error($ret) : $this->success('操作成功');
  670. }
  671. /**
  672. * 拒绝接单
  673. * @Author:hua
  674. * @Date:2024-03-14 15:41
  675. * @Copyright:copyright(c)2024 广东七件事集团
  676. * @param $mall_id
  677. * @param $user_id
  678. * @param $order_id
  679. * @param int $store_id
  680. * @param string $reason
  681. * @return ReservationServiceOrder|string
  682. */
  683. public function reject( $mall_id, $user_id, $order_id, $store_id = 0, $reason = '无')
  684. {
  685. $where = [
  686. ['mall_id' => $mall_id],
  687. ['id' => $order_id],
  688. ['status' => StatusEnum::ENABLED],
  689. ['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL]
  690. ];
  691. if (!empty($store_id)) $where[] = ['store_id' => $store_id];
  692. /**
  693. * @var $model ReservationServiceOrder
  694. */
  695. $model = ReservationServiceOrder::getOne($where);
  696. if (empty($model)) return '预约记录不存在';
  697. $store_name = $this->store['store_name'];
  698. $t = \Yii::$app->db->beginTransaction();
  699. try {
  700. $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_REJECT;
  701. $model->remark = "{$model->remark} 门店 [$store_name] 拒绝了当前次卡的预约, 拒绝理由[$reason] \n";
  702. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  703. $order = Order::findOne(['id'=>$model->order_id]);
  704. $order->status = StatusEnum::DISABLED;
  705. $order->save();
  706. StoreOrder::updateAll(['status'=>StatusEnum::DISABLED],['order_no'=>$order->order_no]);
  707. $t->commit();
  708. // 记录数据
  709. return $model;
  710. } catch (\Exception $e) {
  711. $t->rollBack();
  712. return $e->getMessage();
  713. }
  714. }
  715. public function talking(int $mall_id, int $store_id, int $order_id)
  716. {
  717. $where = [
  718. ['mall_id' => $mall_id],
  719. ['id' => $order_id],
  720. ['status' => StatusEnum::ENABLED],
  721. ['store_id' => $store_id],
  722. ['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL]
  723. ];
  724. $model = ReservationServiceOrder::getOne($where);
  725. if (empty($model)) return '预约记录不存在';
  726. try {
  727. $store_order_reserve = StoreOrderReserve::findOne(['main_order_id' => $model['order_id']]);
  728. if (empty($store_order_reserve)) throw new \Exception("预约订单不存在");
  729. $store_order_reserve->reserve_status = StatusEnum::ENABLED;
  730. $store_order_reserve->reserve_date_time = date('Y-m-d H:i', $model->service_start_at) . ',' . date('Y-m-d H:i', $model->service_end_at);
  731. if (!$store_order_reserve->save()) throw new \Exception($store_order_reserve->getErrorMessage());
  732. $order_reserve = OrderReserve::findOne(['order_id' => $model['order_id']]);
  733. if (empty($order_reserve)) throw new \Exception("预约订单不存在");
  734. $order_reserve->reserve_status = StatusEnum::ENABLED;
  735. $order_reserve->reserve_date_time = date('Y-m-d H:i', $model->service_start_at) . ',' . date('Y-m-d H:i', $model->service_end_at);
  736. if (!$order_reserve->save()) throw new \Exception($store_order_reserve->getErrorMessage());
  737. // 执行发货操作
  738. $user = User::findOne(['id' => $this->store['user_id']]);
  739. $form = [];
  740. $form['mall_id'] = $model->mall_id;
  741. $form['mch_id'] = 0;
  742. $form['shipping_type'] = 0;
  743. $form['id'] = $model->order_id;
  744. $form['operator_id'] = $this->store['user_id'];
  745. $form['order_detail_ids'] = OrderDetail::find()->where(['order_id' => $model->order_id])->select('id')->column();
  746. $form['operator_name'] = $user['nickname'];
  747. $res = OrderExpress::delivery($form); // 发货
  748. if($res==false) {
  749. throw new \Exception(OrderExpress::getStaticError());
  750. }
  751. $form = [];
  752. $form['mall_id'] = $mall_id;
  753. $form['shipping_type'] = 0;
  754. $form['mch_id'] = 0;
  755. $form['store_id'] = $model->store_id;
  756. $form['operator_id'] = $this->store['user_id'];
  757. $form['operator_name'] = $user['nickname'];
  758. $form['id'] = $store_order_reserve->order_id;
  759. $form['order_detail_ids'] = StoreOrderDetail::find()->where(['order_id' => $store_order_reserve->order_id])->select('id')->column();
  760. $res = StoreOrder::OrderExpressDelivery($form);
  761. if (!$res) throw new \Exception(StoreOrder::getStaticError());
  762. $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING;
  763. $model->server_status = ReservationServiceEnum::ARRIVED_AT_STORE;
  764. $model->remark = "{$model->remark} 门店 [$store_id] 接受了当前订单的预约 \n";
  765. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  766. return $model;
  767. } catch (\Exception $e) {
  768. return $e->getMessage() . $e->getFile() . $e->getLine();
  769. }
  770. }
  771. /**
  772. * 公共核销
  773. * @Author:hua
  774. * @Date:2024-03-09 09:32
  775. * @Copyright:copyright(c)2024 广东七件事集团
  776. * @return mixed|void
  777. */
  778. public function actionClerkCommon()
  779. {
  780. try {
  781. $request = \Yii::$app->request;
  782. if ($request->isGet) {
  783. $params = $request->get();
  784. $params['method'] = 'get';
  785. $params['platform'] = $this->platform;
  786. $params['mall_id'] = $this->mall_id;
  787. $params['user_id'] = $this->store['user_id'];
  788. $params['store_id'] = $this->store_id;
  789. $params['from'] = 'store_mobile_terminal';
  790. $result = GlobalInvoke::exec(GlobalInvoke::INVOKE_CLERK, $this->mall_id, $params);
  791. if (empty($result)) return $this->error('获取数据失败');
  792. return $this->success('操作成功', $result);
  793. }
  794. if ($request->isPost) {
  795. $params = $request->post();
  796. $params['method'] = 'post';
  797. $params['platform'] = $this->platform;
  798. $params['mall_id'] = $this->mall_id;
  799. $params['user_id'] = $this->store['user_id'];
  800. $params['store_id'] = $this->store_id;
  801. $params['from'] = 'store_mobile_terminal';
  802. $result = GlobalInvoke::exec(GlobalInvoke::INVOKE_CLERK, $this->mall_id, $params);
  803. if (empty($result)) return $this->error('核销失败');
  804. return $this->success('操作成功', $result);
  805. }
  806. } catch (\Exception $e) {
  807. return $this->error($e->getMessage());
  808. }
  809. }
  810. /**
  811. * 公共核销记录
  812. * @Author:hua
  813. * @Date:2024-03-09 11:58
  814. * @Copyright:copyright(c)2024 广东七件事集团
  815. * @return mixed|void
  816. */
  817. public function actionClerkCommonLog()
  818. {
  819. $params = \Yii::$app->request->get();
  820. $where[] = ['mall_id' => $this->mall_id];
  821. $where[] = ['user_id' => $this->store['user_id']];
  822. $where[] = ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]];
  823. $params['where'] = $where;
  824. $params['order'] = 'id DESC';
  825. $params['select'] = 'id,mall_id,user_id,name,pic,mall_logo,mall_name,clerk_code,type,extra,created_at';
  826. $pageData = ClerkLog::getPageLists($params);
  827. return $this->success('操作成功', $pageData);
  828. }
  829. public function actionClerkCommonLogDetail()
  830. {
  831. try {
  832. $params = \Yii::$app->request->get();
  833. $res = \Yii::$app->services->validate->validate($params, [
  834. [['clerk_log_id', 'type'], 'required'],
  835. ]);
  836. if ($res === false) return $this->error(\Yii::$app->services->validate->getErrorMessage());
  837. $params['platform'] = $this->platform;
  838. $params['mall_id'] = $this->mall_id;
  839. $params['user_id'] = $this->store['user_id'];
  840. $result = GlobalInvoke::exec(GlobalInvoke::INVOKE_CLERK_DETAIL, $this->mall_id, $params);
  841. if (empty($result)) return $this->error('获取数据失败');
  842. return $this->success('操作成功', $result);
  843. } catch (\Exception $e) {
  844. return $this->error($e->getMessage());
  845. }
  846. }
  847. }