SecondaryCardService.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. <?php
  2. namespace addons\SecondaryCard\common\service;
  3. use addons\SecondaryCard\common\enums\SecondaryCardEnum;
  4. use addons\SecondaryCard\common\models\SecondaryCard;
  5. use addons\SecondaryCard\common\models\SecondaryCardRelateStore;
  6. use addons\SecondaryCard\common\models\SecondaryCardReservationService;
  7. use addons\Store\common\models\Store;
  8. use addons\Store\common\models\StoreCate;
  9. use addons\Store\common\models\StoreMiniCode;
  10. use addons\Store\common\services\StoreReserveSettingService;
  11. use common\enums\AddonsEnum;
  12. use common\enums\StatusEnum;
  13. use common\helpers\MiniQrCode;
  14. use common\models\mall\Mall;
  15. use common\models\mall\MallAddons;
  16. use common\models\mall\MallHost;
  17. use common\traits\ErrorTrait;
  18. class SecondaryCardService
  19. {
  20. use ErrorTrait;
  21. public static function setData($params)
  22. {
  23. $t = \Yii::$app->db->beginTransaction();
  24. try {
  25. $params['service'] = json_encode($params['service']);
  26. $params['reservation_day'] = json_encode($params['reservation_day']);
  27. $params['reservation_time'] = json_encode($params['reservation_time']);
  28. $params['sell_time_start'] = strtotime($params['sell_time_start']);
  29. $params['sell_time_end'] = strtotime($params['sell_time_end']);
  30. $res = $secondary_card = SecondaryCard::setData($params);
  31. if (empty($res)) {
  32. throw new \Exception(SecondaryCard::getStaticError());
  33. }
  34. if (!empty($params['use_type'])) {
  35. $res = SecondaryCardRelateStore::setData($params['mall_id'], $secondary_card['id'], $params['store_ids'], $secondary_card['create_source_type'], $secondary_card['store_type']);
  36. if (empty($res)) {
  37. throw new \Exception(SecondaryCardRelateStore::getStaticError());
  38. }
  39. }
  40. $t->commit();
  41. return ['id' => $secondary_card['id']];
  42. } catch (\Exception $e) {
  43. $t->rollBack();
  44. throw new \Exception($e->getMessage());
  45. }
  46. }
  47. public static function getOne($id, $mall_id)
  48. {
  49. $secondary_card = SecondaryCard::getOne([['id' => $id, 'mall_id' => $mall_id]], true);
  50. $store_ids = [];
  51. $store_list = [];
  52. // switch ($secondary_card['store_type']) {
  53. // case 1:
  54. // if (!empty($secondary_card['use_type'])) {
  55. // $list = SecondaryCardRelateStore::lists(['where' => [['secondary_card_id' => $id], ['status' => StatusEnum::ENABLED]]]);
  56. // $o2o_store_ids = [];
  57. // foreach ($list as $item) {
  58. // $o2o_store_ids[] = $item['store_id'];
  59. // }
  60. // if (!empty($o2o_store_ids) && MallAddons::isInstall($mall_id, 'Store')) {
  61. // $o2o_store_list = Store::lists([
  62. // 'where' => [['id' => $o2o_store_ids]],
  63. // 'select' => 'id,store_name,shop_owner,shop_mobile']);
  64. // $store_list = array_merge($store_list, $o2o_store_list);
  65. // $store_ids = array_merge($store_ids, $o2o_store_ids);
  66. // }
  67. //
  68. // }
  69. // break;
  70. //
  71. // }
  72. $secondary_card['store_ids'] = $store_ids;
  73. $secondary_card['store_list'] = $store_list;
  74. $secondary_card['sell_time_start'] = $secondary_card['sell_time_start'] > 0 ? date('Y-m-d H:i:s', $secondary_card['sell_time_start']) : '';
  75. $secondary_card['sell_time_end'] = $secondary_card['sell_time_end'] > 0 ? date('Y-m-d H:i:s', $secondary_card['sell_time_end']) : '';
  76. $secondary_card['service'] = json_decode($secondary_card['service'], true);
  77. $secondary_card['reservation_day'] = json_decode($secondary_card['reservation_day'], true);
  78. $secondary_card['reservation_time'] = json_decode($secondary_card['reservation_time'], true);
  79. return $secondary_card;
  80. }
  81. public static function getList($params)
  82. {
  83. $params['where'][] = ['sc.mall_id' => $params['mall_id']];
  84. $params['where'][] = ['sc.status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]];
  85. if (isset($params['is_on_sales']) && $params['is_on_sales'] !== '') {
  86. $params['where'][] = ['sc.is_on_sales' => $params['is_on_sales']];
  87. }
  88. if (!empty($params['name'])) {
  89. $params['where'][] = ['like', 'sc.name', trim($params['name'])];
  90. }
  91. if (!empty($params['date_time'][0])) {
  92. $params['where'][] = ['>=', 'sc.created_at', strtotime($params['date_time'][0])];
  93. }
  94. if (!empty($params['date_time'][1])) {
  95. $params['where'][] = ['<=', 'sc.created_at', strtotime($params['date_time'][1])];
  96. }
  97. if (!empty($params['create_source_id'])) {
  98. $params['where'][] = [
  99. 'or',
  100. ['sc.use_type' => 0],
  101. ['scrs.store_id' => $params['create_source_id'], 'scrs.store_type' => $params['store_type']]
  102. ];
  103. $params['join'] = [['left join', SecondaryCardRelateStore::tableName() . ' as scrs', 'sc.id = scrs.secondary_card_id']];
  104. }
  105. $params['order'] = 'sc.id DESC';
  106. if (!empty($params['sort_column']) && !empty($params['sort_order'])) {
  107. $sort_order = $params['sort_order'] == 'ascending' ? 'asc' : 'desc';
  108. $params['order'] = 'sc.' . $params['sort_column'] . ' ' . $sort_order;
  109. }
  110. $params['alias'] = 'sc';
  111. $pageData = SecondaryCard::listPage($params, false);
  112. if (!empty($pageData['list'])) {
  113. $o2o_store_ids = [];
  114. $o2o_store_list = [];
  115. $ids = [];
  116. foreach ($pageData['list'] as $item) {
  117. $ids[] = $item['id'];
  118. switch ($item['create_source_type']) {
  119. case 1:
  120. $o2o_store_ids[] = $item['create_source_id'];
  121. break;
  122. }
  123. }
  124. if (!empty($o2o_store_ids) && MallAddons::isInstall($params['mall_id'], 'Store')) {
  125. $o2o_store_list = self::getO2OStoreList($o2o_store_ids);
  126. }
  127. $store_counts_arr = self::getStoreCounts($params['mall_id'], $ids);
  128. $mall_name = \Yii::$app->services->setting->mall->get($params['mall_id'], 'basic.name');
  129. $H5Url = MallHost::getHost($params['mall_id'], 'h5_url');
  130. $mall = Mall::findOne(['id' => $params['mall_id']]);
  131. $mall_sign = $mall['mall_sign'];
  132. foreach ($pageData['list'] as &$item) {
  133. if (empty($item['use_type'])) {
  134. $item['store_counts'] = '全部门店';
  135. } else {
  136. $item['store_counts'] = $store_counts_arr[$item['id']]['counts'] ?? 0;
  137. }
  138. $item['source'] = '';
  139. switch ($item['create_source_type']) {
  140. case 0:
  141. $item['source'] = $mall_name;
  142. break;
  143. case 1:
  144. $item['source'] = $o2o_store_list[$item['create_source_id']]['store_name'] ?? '';
  145. break;
  146. }
  147. $item['promotion_code'] = $H5Url . '/#/customAddons/SecondaryCard/cardDetail?id=' . $item['id'] . "&sign={$mall_sign}";
  148. }
  149. }
  150. return $pageData;
  151. }
  152. public static function changeIsOnSales($id, $mall_id, $is_on_sales, $create_source_id = 0,$create_source_type = 0)
  153. {
  154. set_time_limit(0);
  155. $t = \Yii::$app->db->beginTransaction();
  156. try {
  157. $secondary_card = SecondaryCard::findOne(['id' => $id, 'mall_id' => $mall_id, 'status' => [StatusEnum::ENABLED]]);
  158. if ($create_source_type == 0) {//平台执行上下架
  159. $secondary_card->is_on_sales = $is_on_sales;
  160. $res = $secondary_card->save();
  161. } else {//门店执行上下架
  162. if ($secondary_card->create_source_id == $create_source_id && $secondary_card->create_source_type == $create_source_type) {
  163. $secondary_card->is_on_sales = $is_on_sales;
  164. $res = $secondary_card->save();
  165. } else {
  166. if ($is_on_sales == 1) {
  167. throw new \Exception('无权限操作');
  168. }
  169. if ($secondary_card->use_type == SecondaryCardEnum::USE_TYPE_ALL) {
  170. self::allToBeStore($secondary_card, $create_source_id);
  171. } else {
  172. self::operate($secondary_card, $create_source_id, $is_on_sales);
  173. }
  174. }
  175. }
  176. $t->commit();
  177. return true;
  178. } catch (\Exception $e) {
  179. $t->rollBack();
  180. throw new \Exception($e->getMessage());
  181. }
  182. }
  183. public static function operate($secondary_card, $create_source_id, $is_on_sales)
  184. {
  185. $model = SecondaryCardRelateStore::findOne([
  186. 'create_source_type' => $secondary_card['create_source_type'],
  187. 'store_type' => $secondary_card->store_type,
  188. 'secondary_card_id' => $secondary_card['id'],
  189. 'store_id' => $create_source_id,
  190. ]);
  191. $res = $model->delete();
  192. if (empty($res)) {
  193. throw new \Exception($model->getError());
  194. }
  195. $model = SecondaryCardRelateStore::findOne([
  196. 'create_source_type' => $secondary_card['create_source_type'],
  197. 'store_type' => $secondary_card['store_type'],
  198. 'secondary_card_id' => $secondary_card['id'],
  199. 'store_id' => $create_source_id,
  200. ]);
  201. if (empty($model)) {
  202. $secondary_card->is_on_sales = $is_on_sales;
  203. $res = $secondary_card->save();
  204. }
  205. }
  206. public static function allToBeStore($secondary_card, $create_source_id)
  207. {
  208. $secondary_card->use_type = SecondaryCardEnum::USE_TYPE_STORE;
  209. $secondary_card->save();
  210. switch ($secondary_card->store_type) {
  211. case SecondaryCardEnum::STORE_TYPE_O2O:
  212. $i = 1;
  213. $page_size = 1000;
  214. while ($store_list = Store::find()
  215. ->where(['mall_id' => $secondary_card['mall_id'], 'status' => StatusEnum::ENABLED])
  216. ->andWhere(['!=', 'id', $create_source_id])
  217. ->orderBy('id asc')
  218. ->offset(($i - 1) * $page_size)->limit($page_size)->all()) {
  219. if ($store_list) {
  220. $store_ids = array_column($store_list, 'id');
  221. $res = SecondaryCardRelateStore::setData($secondary_card['mall_id'], $secondary_card['id'], $store_ids, $secondary_card['create_source_type'], $secondary_card['store_type']);
  222. if (empty($res)) {
  223. throw new \Exception(SecondaryCardRelateStore::getStaticError());
  224. }
  225. }
  226. $i++;
  227. }
  228. break;
  229. }
  230. }
  231. public static function uploadIsOnSales($id, $mall_id, $is_on_sales, $create_source_id = 0)
  232. {
  233. $t = \Yii::$app->db->beginTransaction();
  234. try {
  235. $secondary_card = SecondaryCard::findOne(['id' => $id, 'mall_id' => $mall_id, 'status' => [StatusEnum::ENABLED]]);
  236. if (empty($secondary_card)) throw new \Exception('次卡不存在');
  237. if ($secondary_card['use_type'] == SecondaryCardEnum::USE_TYPE_STORE) {
  238. $model = SecondaryCardRelateStore::findOne([
  239. 'store_type' => $secondary_card['store_type'],
  240. 'secondary_card_id' => $secondary_card['id'],
  241. ]);
  242. if (empty($model)) {
  243. throw new \Exception('该次卡适用门店为0,不允许上架');
  244. }
  245. }
  246. $secondary_card->is_on_sales = $is_on_sales;
  247. $res = $secondary_card->save();
  248. $t->commit();
  249. return true;
  250. } catch (\Exception $e) {
  251. $t->rollBack();
  252. throw new \Exception($e->getMessage());
  253. }
  254. }
  255. public static function getStorePageList($params)
  256. {
  257. if (!MallAddons::isInstall($params['mall_id'], AddonsEnum::ADDONS_NAME_STORE)) throw new \Exception('没有安装o2o门店插件');
  258. switch ($params['store_type']) {
  259. case 1:
  260. $where[] = ['mall_id' => $params['mall_id']];
  261. $where[] = ['status' => StatusEnum::ENABLED];
  262. if (!empty($params['keyword'])) {
  263. $where[] = [
  264. 'or',
  265. ['like', 'store_name', trim($params['keyword'])],
  266. ['like', 'shop_owner', trim($params['keyword'])],
  267. ['like', 'shop_mobile', trim($params['keyword'])],
  268. ];
  269. }
  270. $params['where'] = $where;
  271. $params['order'] = 'id desc';
  272. $params['select'] = 'id,store_name,shop_owner,shop_mobile,address';
  273. return Store::listPage($params);
  274. }
  275. }
  276. public static function getSecondaryCardListByDiy($mall_id, $post)
  277. {
  278. $where[] = ['mall_id' => $mall_id];
  279. $where[] = ['status' => StatusEnum::ENABLED];
  280. $where[] = ['is_on_sales' => StatusEnum::ENABLED];
  281. $where[] = ['like', 'name', trim($post['keyword'])];
  282. $params['where'] = $where;
  283. $params['order'] = 'id DESC';
  284. $params['limit'] = 10;
  285. $params['select'] = 'id,name as title,price,original_price,virtual_sales,total_sales,background,background_type,font_color,expire_type,expire_day,
  286. begin_at,end_at,created_at';
  287. return SecondaryCard::listPage($params, false, true);
  288. }
  289. public static function getListByH5($params)
  290. {
  291. $params['where'][] = ['mall_id' => $params['mall_id']];
  292. $params['where'][] = ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]];
  293. $params['where'][] = ['is_on_sales' => StatusEnum::ENABLED];
  294. $time = time();
  295. $params['where'][] = ['or',
  296. ['expire_type' => 1],
  297. ['>=', 'end_at', date('Y-m-d', $time)],
  298. // ['and',
  299. // ['<=', 'end_at', date('Y-m-d', $time)],
  300. // ['>=', 'begin_at', date('Y-m-d', $time)]
  301. // ],
  302. ];
  303. if (!empty($params['name'])) {
  304. $params['where'][] = ['like', 'name', trim($params['name'])];
  305. }
  306. $params['order'] = 'id DESC';
  307. $params['select'] = 'id,name,price,original_price,virtual_sales,total_sales,background,background_type,font_color,expire_type,begin_at,end_at,expire_day
  308. ,sell_time_start,sell_time_end';
  309. $pageData = SecondaryCard::listPage($params, false);
  310. if (!empty($pageData['list'])) {
  311. foreach ($pageData['list'] as &$item) {
  312. $item['sell_time_start'] = $item['sell_time_start'] > 0 ? date('Y-m-d H:i:s', strtotime($item['sell_time_start'])) : "";
  313. $item['sell_time_end'] = $item['sell_time_end'] > 0 ? date('Y-m-d H:i:s', strtotime($item['sell_time_end'])) : "";
  314. }
  315. }
  316. return $pageData;
  317. }
  318. public static function getDetailByH5($params)
  319. {
  320. $mall_id = $params['mall_id'];
  321. $select = 'id,name,price,original_price,virtual_sales,total_sales,service,rule,expire_type,begin_at,end_at,expire_day,store_type,use_type,background,
  322. background_type,font_color,reservation_type,sell_time_start,sell_time_end,is_on_sales';
  323. if (!empty($params['select'])) {
  324. $select = $params['select'];
  325. }
  326. $detail = SecondaryCard::getOne([
  327. ['id' => $params['id']],
  328. ['mall_id' => $mall_id],
  329. ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]
  330. ], true, [], false, $select);
  331. if (empty($detail)) {
  332. throw new \Exception('次卡不存在');
  333. }
  334. if ($detail['expire_type'] == 2 && strtotime($detail['end_at'] . ' 23:59:59') < time()) {
  335. $detail['is_on_sales'] = 0;
  336. SecondaryCard::updateAll(['is_on_sales' => 0], ['id' => $params['id']]);
  337. }
  338. $store = [];
  339. switch ($detail['store_type']) {
  340. case 1:
  341. $store = self::getStoreDetail($params['id'], $mall_id, $params['longitude'], $params['latitude'], $detail['use_type']);
  342. break;
  343. }
  344. $detail['store'] = $store;
  345. if (isset($detail['service'])) $detail['service'] = json_decode($detail['service'], true);
  346. $detail['sell_time_start'] = $detail['sell_time_start'] > 0 ? date('Y-m-d H:i:s', strtotime($detail['sell_time_start'])) : "";
  347. $detail['sell_time_end'] = $detail['sell_time_end'] > 0 ? date('Y-m-d H:i:s', strtotime($detail['sell_time_end'])) : "";
  348. return $detail;
  349. }
  350. private static function getStoreDetail($secondary_card_id, $mall_id, $longitude, $latitude, $use_type)
  351. {
  352. $store = [];
  353. if (!empty($use_type)) {
  354. $relate_store_list = SecondaryCardRelateStore::lists([
  355. 'where' => [
  356. ['secondary_card_id' => $secondary_card_id],
  357. ['status' => StatusEnum::ENABLED],
  358. ],
  359. ]);
  360. $o2o_store_ids = '';
  361. foreach ($relate_store_list as $item) {
  362. $o2o_store_ids .= $item['store_id'] . ',';
  363. }
  364. }
  365. if (MallAddons::isInstall($mall_id, 'Store')) {
  366. $sql = " SELECT id,store_name,shop_mobile,latitude,longitude,logo_img,sales_volume,praise,address,business_time_start,business_time_end,
  367. round(
  368. 2 * 6378.137 * ASIN(
  369. SQRT(
  370. POW(
  371. SIN(
  372. PI() * ({$longitude} - longitude) / 360
  373. ),
  374. 2
  375. ) + COS(PI() * {$latitude} / 180) * COS(latitude * PI() / 180) * POW(
  376. SIN(
  377. PI() * ({$latitude} - latitude) / 360
  378. ),
  379. 2
  380. )
  381. )
  382. )
  383. ,1) AS distance
  384. FROM `qimall_addons_store` WHERE (`mall_id`={$mall_id}) and (`status` = " . StatusEnum::ENABLED . ")";
  385. if (!empty($use_type)) {
  386. if (!empty($o2o_store_ids)) {
  387. $o2o_store_ids = trim($o2o_store_ids, ',');
  388. } else {
  389. $o2o_store_ids = 0;
  390. }
  391. $sql .= " AND (`id` in ({$o2o_store_ids})) ";
  392. }
  393. $sql .= " order by distance asc ";
  394. $result = \Yii::$app->db->createCommand($sql)->queryOne();
  395. if ($result) {
  396. $store = $result;
  397. }
  398. }
  399. return $store;
  400. }
  401. public static function getStoreListByH5($params)
  402. {
  403. $mall_id = $params['mall_id'];
  404. $page = $params['page'] ?? 1;
  405. $limit = $params['limit'] ?? 5;
  406. $select = 'id,store_type,use_type';
  407. $detail = SecondaryCard::getOne([
  408. ['id' => $params['id']],
  409. ['mall_id' => $mall_id],
  410. ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]
  411. ], true, [], false, $select);
  412. switch ($detail['store_type']) {
  413. case 1:
  414. return self::getO2OStoreListByH5($params['id'], $mall_id, $params['longitude'], $params['latitude'], $detail['use_type'], $page, $limit);
  415. }
  416. }
  417. private static function getO2OStoreListByH5($secondary_card_id, $mall_id, $longitude, $latitude, $use_type, $page, $limit)
  418. {
  419. $o2o_store_ids = '';
  420. $o2o_store_id_arr = [];
  421. $list = [];
  422. $page_count = 0;
  423. if (!empty($use_type)) {
  424. $relate_store_list = SecondaryCardRelateStore::lists([
  425. 'where' => [
  426. ['mall_id' => $mall_id],
  427. ['secondary_card_id' => $secondary_card_id],
  428. ['status' => StatusEnum::ENABLED],
  429. ],
  430. ]);
  431. foreach ($relate_store_list as $item) {
  432. $o2o_store_ids .= $item['store_id'] . ',';
  433. $o2o_store_id_arr[] = $item['store_id'];
  434. }
  435. }
  436. if (MallAddons::isInstall($mall_id, 'Store')) {
  437. $offset = ($page - 1) * $limit;
  438. $sql = " SELECT id,store_name,shop_mobile,latitude,longitude,logo_img,sales_volume,praise,address,business_time_start,business_time_end,
  439. round(
  440. 2 * 6378.137 * ASIN(
  441. SQRT(
  442. POW(
  443. SIN(
  444. PI() * ({$longitude} - longitude) / 360
  445. ),
  446. 2
  447. ) + COS(PI() * {$latitude} / 180) * COS(latitude * PI() / 180) * POW(
  448. SIN(
  449. PI() * ({$latitude} - latitude) / 360
  450. ),
  451. 2
  452. )
  453. )
  454. )
  455. ,1) AS distance
  456. FROM `qimall_addons_store` WHERE (`mall_id`={$mall_id}) and (`status` = " . StatusEnum::ENABLED . ")";
  457. if (!empty($use_type)) {
  458. if (!empty($o2o_store_ids)) {
  459. $o2o_store_ids = trim($o2o_store_ids, ',');
  460. } else {
  461. $o2o_store_ids = 0;
  462. }
  463. $sql .= " AND (`id` in ({$o2o_store_ids})) ";
  464. $page_count = ceil(count($o2o_store_id_arr) / $limit);
  465. } else {
  466. $counts = Store::find()->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])->count();
  467. $page_count = ceil($counts / $limit);
  468. }
  469. $sql .= " order by distance asc limit {$limit} offset {$offset} ";
  470. $list = \Yii::$app->db->createCommand($sql)->queryAll();
  471. }
  472. return ['list' => $list, 'page' => $page, 'limit' => $limit, 'page_count' => $page_count];
  473. }
  474. public static function getO2OStoreList($o2o_store_ids)
  475. {
  476. return Store::lists([
  477. 'where' => [
  478. ['id' => $o2o_store_ids],
  479. ],
  480. 'index' => 'id',
  481. 'select' => 'id,store_name'
  482. ]);
  483. }
  484. private static function getStoreCounts($mall_id, $ids)
  485. {
  486. $list = SecondaryCardRelateStore::find()
  487. ->where(['secondary_card_id' => $ids, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])
  488. ->select('count(*) as counts,secondary_card_id')->groupBy('secondary_card_id')->asArray()->all();
  489. return array_column($list, null, 'secondary_card_id');
  490. }
  491. public static function getListByReservationService($mall_id, $user_id, $secondary_card_ids)
  492. {
  493. $params['where'][] = ['sc.mall_id' => $mall_id];
  494. $params['where'][] = ['sc.status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]];
  495. $params['where'][] = ['sc.id' => $secondary_card_ids];
  496. $params['alias'] = 'sc';
  497. $params['order'] = 'sc.id DESC';
  498. $params['select'] = 'sc.id,sc.name,sc.service';
  499. $pageData = SecondaryCard::listPage($params, false);
  500. if (!empty($pageData['list'])) {
  501. $secondary_card_ids = array_column($pageData['list'], 'id');
  502. $secondary_card_reservation_service_list = SecondaryCardReservationService::lists([
  503. 'where' => [
  504. ['secondary_card_id' => $secondary_card_ids],
  505. ['user_id' => $user_id],
  506. ['status' => StatusEnum::ENABLED],
  507. ],
  508. 'index' => 'secondary_card_id'
  509. ]);
  510. foreach ($pageData['list'] as &$item) {
  511. $item['service'] = json_decode($item['service'], true);
  512. $item['is_selected'] = 0;
  513. if (isset($secondary_card_reservation_service_list[$item['id']])) {
  514. $item['is_selected'] = 1;
  515. }
  516. }
  517. }
  518. return $pageData;
  519. }
  520. public static function secondaryCardReservationServiceCreate($mall_id, $user_id, $secondary_card_id_arr, $remove_secondary_card_id_arr)
  521. {
  522. try {
  523. if (!empty($secondary_card_id_arr)) {
  524. foreach ($secondary_card_id_arr as $id) {
  525. $model = SecondaryCardReservationService::findOne(['mall_id' => $mall_id, 'user_id' => $user_id, 'status' => StatusEnum::ENABLED, 'secondary_card_id' => $id]);
  526. if (empty($model)) {
  527. $model = new SecondaryCardReservationService();
  528. $model->loadDefaultValues();
  529. $model->mall_id = $mall_id;
  530. $model->user_id = $user_id;
  531. $model->secondary_card_id = $id;
  532. $model->save();
  533. }
  534. }
  535. }
  536. if (!empty($remove_secondary_card_id_arr)) {
  537. SecondaryCardReservationService::deleteAll(['mall_id' => $mall_id, 'user_id' => $user_id, 'status' => StatusEnum::ENABLED, 'secondary_card_id' => $remove_secondary_card_id_arr]);
  538. }
  539. return ['ids' => $secondary_card_id_arr];
  540. } catch (\Exception $e) {
  541. return $e->getMessage();
  542. }
  543. }
  544. public static function getSourceName($secondary_card)
  545. {
  546. $order_source = \Yii::$app->services->setting->mall->get($secondary_card['mall_id'], 'basic.name');
  547. switch ($secondary_card['create_source_type']) {
  548. case 1:
  549. if ($secondary_card['use_type'] == 1) {
  550. $store = Store::findOne(['id' => $secondary_card['create_source_id']]);
  551. $order_source = $store['store_name'] ?? '';
  552. }
  553. break;
  554. }
  555. return $order_source;
  556. }
  557. public static function getServiceTypeText($secondary_card)
  558. {
  559. //服务方式:1:上门服务;2:到店服务;3:上门/到店
  560. $service_type_text = '到店服务';
  561. if ($secondary_card['reservation_model'] == 1) {
  562. return $service_type_text;
  563. }
  564. switch ($secondary_card['reservation_service_type']) {
  565. case 1:
  566. $service_type_text = '上门服务';
  567. break;
  568. case 2:
  569. $service_type_text = '到店服务';
  570. break;
  571. case 3:
  572. $service_type_text = '上门/到店';
  573. break;
  574. }
  575. return $service_type_text;
  576. }
  577. /**
  578. * 后台-次卡管理-适用门店列表
  579. * @Author:hua
  580. * @Date:2024-03-11 14:46
  581. * @Copyright:copyright(c)2024 广东七件事集团
  582. * @param $params
  583. * @return array|false|mixed|void
  584. */
  585. public static function canClerkStoreList($params)
  586. {
  587. $secondary_card = SecondaryCard::findOne(['id' => $params['id'], 'mall_id' => $params['mall_id']]);
  588. if (empty($secondary_card)) {
  589. throw new \Exception('次卡不存在');
  590. }
  591. switch ($secondary_card['store_type']) {
  592. case 1:
  593. if ($secondary_card['use_type'] == 1) {
  594. $where = [];
  595. $where[] = ['mall_id' => $params['mall_id']];
  596. $where[] = ['status' => StatusEnum::ENABLED];
  597. $where[] = ['store_type' => $secondary_card['store_type']];
  598. $where[] = ['secondary_card_id' => $secondary_card['id']];
  599. $params['where'] = $where;
  600. $params['order'] = 'store_id asc';
  601. $params['select'] = 'store_id';
  602. $params['where'] = $where;
  603. $list = SecondaryCardRelateStore::listPage($params);
  604. if (!empty($list['list'])) {
  605. $store_ids = array_column($list['list'], 'store_id');
  606. $store_list = Store::lists(['where' => [['id' => $store_ids]], 'select' => 'id,store_name,shop_owner,shop_mobile,address', 'index' => 'id']);
  607. foreach ($list['list'] as &$item) {
  608. if (isset($store_list[$item['store_id']])) {
  609. $store = $store_list[$item['store_id']];
  610. $item['id'] = $store['id'];
  611. $item['store_name'] = $store['store_name'];
  612. $item['shop_owner'] = $store['shop_owner'];
  613. $item['shop_mobile'] = $store['shop_mobile'];
  614. $item['address'] = $store['address'];
  615. $item['type_text'] = 'o2o门店';
  616. }
  617. }
  618. }
  619. $pageData = $list;
  620. } else {
  621. $params['where'][] = ['mall_id' => $params['mall_id']];
  622. $params['where'][] = ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]];
  623. $params['order'] = 'id asc';
  624. $params['select'] = 'id,store_name,shop_owner,shop_mobile,address';
  625. $pageData = Store::listPage($params, false);
  626. if (!empty($pageData['list'])) {
  627. foreach ($pageData['list'] as &$item) {
  628. $item['type_text'] = 'o2o门店';
  629. }
  630. }
  631. }
  632. break;
  633. }
  634. return $pageData;
  635. }
  636. /**
  637. * 小程序二维码
  638. * @Author:hua
  639. * @Date:2024-03-15 15:16
  640. * @Copyright:copyright(c)2024 广东七件事集团
  641. * @param $params
  642. * @return array
  643. */
  644. public static function showMiniPromotionCode($params)
  645. {
  646. $model = SecondaryCard::findOne(['id' => $params['id'], 'mall_id' => $params['mall_id']]);
  647. if (empty($model['applet_code'])) {
  648. $mall = $params['mall'];
  649. $content = [
  650. 'mall_id' => $params['mall_id'],
  651. 'id' => $params['id'],
  652. 'mall_sign' => $mall['mall_sign'],
  653. ];
  654. $content = json_encode($content);
  655. $page = '/customAddons/SecondaryCard/cardDetail';
  656. $code = md5($content);
  657. $obj = new MiniQrCode();
  658. $applet_code = $obj->getAppletQrCode($params['mall_id'], $page, $code);
  659. $params['code'] = $code;
  660. $params['content'] = $content;
  661. $params['applet_code'] = $applet_code;
  662. $model->applet_code = $applet_code;
  663. $model->save();
  664. } else {
  665. $applet_code = $model->applet_code;
  666. }
  667. return ['applet_code' => $applet_code];
  668. }
  669. public static function getStoreCateList($params)
  670. {
  671. $list = StoreCate::lists([
  672. 'where' => [
  673. ['mall_id' => $params['mall_id']],
  674. ['status' => StatusEnum::ENABLED]
  675. ],
  676. 'select' => 'id,name']);
  677. return $list;
  678. }
  679. public static function getEmployeeSelection($mall_id, $store_id)
  680. {
  681. $employee_selection = 1;
  682. if (MallAddons::isInstall($mall_id, 'Store')) {
  683. $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $mall_id, 'store_id' => $store_id]))->detail();
  684. $employee_selection = $store_reserve_setting['employee_selection'] ?? 1;
  685. }
  686. return $employee_selection;
  687. }
  688. }