db->beginTransaction(); try { $params['service'] = json_encode($params['service']); $params['reservation_day'] = json_encode($params['reservation_day']); $params['reservation_time'] = json_encode($params['reservation_time']); $params['sell_time_start'] = strtotime($params['sell_time_start']); $params['sell_time_end'] = strtotime($params['sell_time_end']); $res = $secondary_card = SecondaryCard::setData($params); if (empty($res)) { throw new \Exception(SecondaryCard::getStaticError()); } if (!empty($params['use_type'])) { $res = SecondaryCardRelateStore::setData($params['mall_id'], $secondary_card['id'], $params['store_ids'], $secondary_card['create_source_type'], $secondary_card['store_type']); if (empty($res)) { throw new \Exception(SecondaryCardRelateStore::getStaticError()); } } $t->commit(); return ['id' => $secondary_card['id']]; } catch (\Exception $e) { $t->rollBack(); throw new \Exception($e->getMessage()); } } public static function getOne($id, $mall_id) { $secondary_card = SecondaryCard::getOne([['id' => $id, 'mall_id' => $mall_id]], true); $store_ids = []; $store_list = []; // switch ($secondary_card['store_type']) { // case 1: // if (!empty($secondary_card['use_type'])) { // $list = SecondaryCardRelateStore::lists(['where' => [['secondary_card_id' => $id], ['status' => StatusEnum::ENABLED]]]); // $o2o_store_ids = []; // foreach ($list as $item) { // $o2o_store_ids[] = $item['store_id']; // } // if (!empty($o2o_store_ids) && MallAddons::isInstall($mall_id, 'Store')) { // $o2o_store_list = Store::lists([ // 'where' => [['id' => $o2o_store_ids]], // 'select' => 'id,store_name,shop_owner,shop_mobile']); // $store_list = array_merge($store_list, $o2o_store_list); // $store_ids = array_merge($store_ids, $o2o_store_ids); // } // // } // break; // // } $secondary_card['store_ids'] = $store_ids; $secondary_card['store_list'] = $store_list; $secondary_card['sell_time_start'] = $secondary_card['sell_time_start'] > 0 ? date('Y-m-d H:i:s', $secondary_card['sell_time_start']) : ''; $secondary_card['sell_time_end'] = $secondary_card['sell_time_end'] > 0 ? date('Y-m-d H:i:s', $secondary_card['sell_time_end']) : ''; $secondary_card['service'] = json_decode($secondary_card['service'], true); $secondary_card['reservation_day'] = json_decode($secondary_card['reservation_day'], true); $secondary_card['reservation_time'] = json_decode($secondary_card['reservation_time'], true); return $secondary_card; } public static function getList($params) { $params['where'][] = ['sc.mall_id' => $params['mall_id']]; $params['where'][] = ['sc.status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]; if (isset($params['is_on_sales']) && $params['is_on_sales'] !== '') { $params['where'][] = ['sc.is_on_sales' => $params['is_on_sales']]; } if (!empty($params['name'])) { $params['where'][] = ['like', 'sc.name', trim($params['name'])]; } if (!empty($params['date_time'][0])) { $params['where'][] = ['>=', 'sc.created_at', strtotime($params['date_time'][0])]; } if (!empty($params['date_time'][1])) { $params['where'][] = ['<=', 'sc.created_at', strtotime($params['date_time'][1])]; } if (!empty($params['create_source_id'])) { $params['where'][] = [ 'or', ['sc.use_type' => 0], ['scrs.store_id' => $params['create_source_id'], 'scrs.store_type' => $params['store_type']] ]; $params['join'] = [['left join', SecondaryCardRelateStore::tableName() . ' as scrs', 'sc.id = scrs.secondary_card_id']]; } $params['order'] = 'sc.id DESC'; if (!empty($params['sort_column']) && !empty($params['sort_order'])) { $sort_order = $params['sort_order'] == 'ascending' ? 'asc' : 'desc'; $params['order'] = 'sc.' . $params['sort_column'] . ' ' . $sort_order; } $params['alias'] = 'sc'; $pageData = SecondaryCard::listPage($params, false); if (!empty($pageData['list'])) { $o2o_store_ids = []; $o2o_store_list = []; $ids = []; foreach ($pageData['list'] as $item) { $ids[] = $item['id']; switch ($item['create_source_type']) { case 1: $o2o_store_ids[] = $item['create_source_id']; break; } } if (!empty($o2o_store_ids) && MallAddons::isInstall($params['mall_id'], 'Store')) { $o2o_store_list = self::getO2OStoreList($o2o_store_ids); } $store_counts_arr = self::getStoreCounts($params['mall_id'], $ids); $mall_name = \Yii::$app->services->setting->mall->get($params['mall_id'], 'basic.name'); $H5Url = MallHost::getHost($params['mall_id'], 'h5_url'); $mall = Mall::findOne(['id' => $params['mall_id']]); $mall_sign = $mall['mall_sign']; foreach ($pageData['list'] as &$item) { if (empty($item['use_type'])) { $item['store_counts'] = '全部门店'; } else { $item['store_counts'] = $store_counts_arr[$item['id']]['counts'] ?? 0; } $item['source'] = ''; switch ($item['create_source_type']) { case 0: $item['source'] = $mall_name; break; case 1: $item['source'] = $o2o_store_list[$item['create_source_id']]['store_name'] ?? ''; break; } $item['promotion_code'] = $H5Url . '/#/customAddons/SecondaryCard/cardDetail?id=' . $item['id'] . "&sign={$mall_sign}"; } } return $pageData; } public static function changeIsOnSales($id, $mall_id, $is_on_sales, $create_source_id = 0,$create_source_type = 0) { set_time_limit(0); $t = \Yii::$app->db->beginTransaction(); try { $secondary_card = SecondaryCard::findOne(['id' => $id, 'mall_id' => $mall_id, 'status' => [StatusEnum::ENABLED]]); if ($create_source_type == 0) {//平台执行上下架 $secondary_card->is_on_sales = $is_on_sales; $res = $secondary_card->save(); } else {//门店执行上下架 if ($secondary_card->create_source_id == $create_source_id && $secondary_card->create_source_type == $create_source_type) { $secondary_card->is_on_sales = $is_on_sales; $res = $secondary_card->save(); } else { if ($is_on_sales == 1) { throw new \Exception('无权限操作'); } if ($secondary_card->use_type == SecondaryCardEnum::USE_TYPE_ALL) { self::allToBeStore($secondary_card, $create_source_id); } else { self::operate($secondary_card, $create_source_id, $is_on_sales); } } } $t->commit(); return true; } catch (\Exception $e) { $t->rollBack(); throw new \Exception($e->getMessage()); } } public static function operate($secondary_card, $create_source_id, $is_on_sales) { $model = SecondaryCardRelateStore::findOne([ 'create_source_type' => $secondary_card['create_source_type'], 'store_type' => $secondary_card->store_type, 'secondary_card_id' => $secondary_card['id'], 'store_id' => $create_source_id, ]); $res = $model->delete(); if (empty($res)) { throw new \Exception($model->getError()); } $model = SecondaryCardRelateStore::findOne([ 'create_source_type' => $secondary_card['create_source_type'], 'store_type' => $secondary_card['store_type'], 'secondary_card_id' => $secondary_card['id'], 'store_id' => $create_source_id, ]); if (empty($model)) { $secondary_card->is_on_sales = $is_on_sales; $res = $secondary_card->save(); } } public static function allToBeStore($secondary_card, $create_source_id) { $secondary_card->use_type = SecondaryCardEnum::USE_TYPE_STORE; $secondary_card->save(); switch ($secondary_card->store_type) { case SecondaryCardEnum::STORE_TYPE_O2O: $i = 1; $page_size = 1000; while ($store_list = Store::find() ->where(['mall_id' => $secondary_card['mall_id'], 'status' => StatusEnum::ENABLED]) ->andWhere(['!=', 'id', $create_source_id]) ->orderBy('id asc') ->offset(($i - 1) * $page_size)->limit($page_size)->all()) { if ($store_list) { $store_ids = array_column($store_list, 'id'); $res = SecondaryCardRelateStore::setData($secondary_card['mall_id'], $secondary_card['id'], $store_ids, $secondary_card['create_source_type'], $secondary_card['store_type']); if (empty($res)) { throw new \Exception(SecondaryCardRelateStore::getStaticError()); } } $i++; } break; } } public static function uploadIsOnSales($id, $mall_id, $is_on_sales, $create_source_id = 0) { $t = \Yii::$app->db->beginTransaction(); try { $secondary_card = SecondaryCard::findOne(['id' => $id, 'mall_id' => $mall_id, 'status' => [StatusEnum::ENABLED]]); if (empty($secondary_card)) throw new \Exception('次卡不存在'); if ($secondary_card['use_type'] == SecondaryCardEnum::USE_TYPE_STORE) { $model = SecondaryCardRelateStore::findOne([ 'store_type' => $secondary_card['store_type'], 'secondary_card_id' => $secondary_card['id'], ]); if (empty($model)) { throw new \Exception('该次卡适用门店为0,不允许上架'); } } $secondary_card->is_on_sales = $is_on_sales; $res = $secondary_card->save(); $t->commit(); return true; } catch (\Exception $e) { $t->rollBack(); throw new \Exception($e->getMessage()); } } public static function getStorePageList($params) { if (!MallAddons::isInstall($params['mall_id'], AddonsEnum::ADDONS_NAME_STORE)) throw new \Exception('没有安装o2o门店插件'); switch ($params['store_type']) { case 1: $where[] = ['mall_id' => $params['mall_id']]; $where[] = ['status' => StatusEnum::ENABLED]; if (!empty($params['keyword'])) { $where[] = [ 'or', ['like', 'store_name', trim($params['keyword'])], ['like', 'shop_owner', trim($params['keyword'])], ['like', 'shop_mobile', trim($params['keyword'])], ]; } $params['where'] = $where; $params['order'] = 'id desc'; $params['select'] = 'id,store_name,shop_owner,shop_mobile,address'; return Store::listPage($params); } } public static function getSecondaryCardListByDiy($mall_id, $post) { $where[] = ['mall_id' => $mall_id]; $where[] = ['status' => StatusEnum::ENABLED]; $where[] = ['is_on_sales' => StatusEnum::ENABLED]; $where[] = ['like', 'name', trim($post['keyword'])]; $params['where'] = $where; $params['order'] = 'id DESC'; $params['limit'] = 10; $params['select'] = 'id,name as title,price,original_price,virtual_sales,total_sales,background,background_type,font_color,expire_type,expire_day, begin_at,end_at,created_at'; return SecondaryCard::listPage($params, false, true); } public static function getListByH5($params) { $params['where'][] = ['mall_id' => $params['mall_id']]; $params['where'][] = ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]; $params['where'][] = ['is_on_sales' => StatusEnum::ENABLED]; $time = time(); $params['where'][] = ['or', ['expire_type' => 1], ['>=', 'end_at', date('Y-m-d', $time)], // ['and', // ['<=', 'end_at', date('Y-m-d', $time)], // ['>=', 'begin_at', date('Y-m-d', $time)] // ], ]; if (!empty($params['name'])) { $params['where'][] = ['like', 'name', trim($params['name'])]; } $params['order'] = 'id DESC'; $params['select'] = 'id,name,price,original_price,virtual_sales,total_sales,background,background_type,font_color,expire_type,begin_at,end_at,expire_day ,sell_time_start,sell_time_end'; $pageData = SecondaryCard::listPage($params, false); if (!empty($pageData['list'])) { foreach ($pageData['list'] as &$item) { $item['sell_time_start'] = $item['sell_time_start'] > 0 ? date('Y-m-d H:i:s', strtotime($item['sell_time_start'])) : ""; $item['sell_time_end'] = $item['sell_time_end'] > 0 ? date('Y-m-d H:i:s', strtotime($item['sell_time_end'])) : ""; } } return $pageData; } public static function getDetailByH5($params) { $mall_id = $params['mall_id']; $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, background_type,font_color,reservation_type,sell_time_start,sell_time_end,is_on_sales'; if (!empty($params['select'])) { $select = $params['select']; } $detail = SecondaryCard::getOne([ ['id' => $params['id']], ['mall_id' => $mall_id], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]] ], true, [], false, $select); if (empty($detail)) { throw new \Exception('次卡不存在'); } if ($detail['expire_type'] == 2 && strtotime($detail['end_at'] . ' 23:59:59') < time()) { $detail['is_on_sales'] = 0; SecondaryCard::updateAll(['is_on_sales' => 0], ['id' => $params['id']]); } $store = []; switch ($detail['store_type']) { case 1: $store = self::getStoreDetail($params['id'], $mall_id, $params['longitude'], $params['latitude'], $detail['use_type']); break; } $detail['store'] = $store; if (isset($detail['service'])) $detail['service'] = json_decode($detail['service'], true); $detail['sell_time_start'] = $detail['sell_time_start'] > 0 ? date('Y-m-d H:i:s', strtotime($detail['sell_time_start'])) : ""; $detail['sell_time_end'] = $detail['sell_time_end'] > 0 ? date('Y-m-d H:i:s', strtotime($detail['sell_time_end'])) : ""; return $detail; } private static function getStoreDetail($secondary_card_id, $mall_id, $longitude, $latitude, $use_type) { $store = []; if (!empty($use_type)) { $relate_store_list = SecondaryCardRelateStore::lists([ 'where' => [ ['secondary_card_id' => $secondary_card_id], ['status' => StatusEnum::ENABLED], ], ]); $o2o_store_ids = ''; foreach ($relate_store_list as $item) { $o2o_store_ids .= $item['store_id'] . ','; } } if (MallAddons::isInstall($mall_id, 'Store')) { $sql = " SELECT id,store_name,shop_mobile,latitude,longitude,logo_img,sales_volume,praise,address,business_time_start,business_time_end, round( 2 * 6378.137 * ASIN( SQRT( POW( SIN( PI() * ({$longitude} - longitude) / 360 ), 2 ) + COS(PI() * {$latitude} / 180) * COS(latitude * PI() / 180) * POW( SIN( PI() * ({$latitude} - latitude) / 360 ), 2 ) ) ) ,1) AS distance FROM `qimall_addons_store` WHERE (`mall_id`={$mall_id}) and (`status` = " . StatusEnum::ENABLED . ")"; if (!empty($use_type)) { if (!empty($o2o_store_ids)) { $o2o_store_ids = trim($o2o_store_ids, ','); } else { $o2o_store_ids = 0; } $sql .= " AND (`id` in ({$o2o_store_ids})) "; } $sql .= " order by distance asc "; $result = \Yii::$app->db->createCommand($sql)->queryOne(); if ($result) { $store = $result; } } return $store; } public static function getStoreListByH5($params) { $mall_id = $params['mall_id']; $page = $params['page'] ?? 1; $limit = $params['limit'] ?? 5; $select = 'id,store_type,use_type'; $detail = SecondaryCard::getOne([ ['id' => $params['id']], ['mall_id' => $mall_id], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]] ], true, [], false, $select); switch ($detail['store_type']) { case 1: return self::getO2OStoreListByH5($params['id'], $mall_id, $params['longitude'], $params['latitude'], $detail['use_type'], $page, $limit); } } private static function getO2OStoreListByH5($secondary_card_id, $mall_id, $longitude, $latitude, $use_type, $page, $limit) { $o2o_store_ids = ''; $o2o_store_id_arr = []; $list = []; $page_count = 0; if (!empty($use_type)) { $relate_store_list = SecondaryCardRelateStore::lists([ 'where' => [ ['mall_id' => $mall_id], ['secondary_card_id' => $secondary_card_id], ['status' => StatusEnum::ENABLED], ], ]); foreach ($relate_store_list as $item) { $o2o_store_ids .= $item['store_id'] . ','; $o2o_store_id_arr[] = $item['store_id']; } } if (MallAddons::isInstall($mall_id, 'Store')) { $offset = ($page - 1) * $limit; $sql = " SELECT id,store_name,shop_mobile,latitude,longitude,logo_img,sales_volume,praise,address,business_time_start,business_time_end, round( 2 * 6378.137 * ASIN( SQRT( POW( SIN( PI() * ({$longitude} - longitude) / 360 ), 2 ) + COS(PI() * {$latitude} / 180) * COS(latitude * PI() / 180) * POW( SIN( PI() * ({$latitude} - latitude) / 360 ), 2 ) ) ) ,1) AS distance FROM `qimall_addons_store` WHERE (`mall_id`={$mall_id}) and (`status` = " . StatusEnum::ENABLED . ")"; if (!empty($use_type)) { if (!empty($o2o_store_ids)) { $o2o_store_ids = trim($o2o_store_ids, ','); } else { $o2o_store_ids = 0; } $sql .= " AND (`id` in ({$o2o_store_ids})) "; $page_count = ceil(count($o2o_store_id_arr) / $limit); } else { $counts = Store::find()->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])->count(); $page_count = ceil($counts / $limit); } $sql .= " order by distance asc limit {$limit} offset {$offset} "; $list = \Yii::$app->db->createCommand($sql)->queryAll(); } return ['list' => $list, 'page' => $page, 'limit' => $limit, 'page_count' => $page_count]; } public static function getO2OStoreList($o2o_store_ids) { return Store::lists([ 'where' => [ ['id' => $o2o_store_ids], ], 'index' => 'id', 'select' => 'id,store_name' ]); } private static function getStoreCounts($mall_id, $ids) { $list = SecondaryCardRelateStore::find() ->where(['secondary_card_id' => $ids, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]) ->select('count(*) as counts,secondary_card_id')->groupBy('secondary_card_id')->asArray()->all(); return array_column($list, null, 'secondary_card_id'); } public static function getListByReservationService($mall_id, $user_id, $secondary_card_ids) { $params['where'][] = ['sc.mall_id' => $mall_id]; $params['where'][] = ['sc.status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]; $params['where'][] = ['sc.id' => $secondary_card_ids]; $params['alias'] = 'sc'; $params['order'] = 'sc.id DESC'; $params['select'] = 'sc.id,sc.name,sc.service'; $pageData = SecondaryCard::listPage($params, false); if (!empty($pageData['list'])) { $secondary_card_ids = array_column($pageData['list'], 'id'); $secondary_card_reservation_service_list = SecondaryCardReservationService::lists([ 'where' => [ ['secondary_card_id' => $secondary_card_ids], ['user_id' => $user_id], ['status' => StatusEnum::ENABLED], ], 'index' => 'secondary_card_id' ]); foreach ($pageData['list'] as &$item) { $item['service'] = json_decode($item['service'], true); $item['is_selected'] = 0; if (isset($secondary_card_reservation_service_list[$item['id']])) { $item['is_selected'] = 1; } } } return $pageData; } public static function secondaryCardReservationServiceCreate($mall_id, $user_id, $secondary_card_id_arr, $remove_secondary_card_id_arr) { try { if (!empty($secondary_card_id_arr)) { foreach ($secondary_card_id_arr as $id) { $model = SecondaryCardReservationService::findOne(['mall_id' => $mall_id, 'user_id' => $user_id, 'status' => StatusEnum::ENABLED, 'secondary_card_id' => $id]); if (empty($model)) { $model = new SecondaryCardReservationService(); $model->loadDefaultValues(); $model->mall_id = $mall_id; $model->user_id = $user_id; $model->secondary_card_id = $id; $model->save(); } } } if (!empty($remove_secondary_card_id_arr)) { SecondaryCardReservationService::deleteAll(['mall_id' => $mall_id, 'user_id' => $user_id, 'status' => StatusEnum::ENABLED, 'secondary_card_id' => $remove_secondary_card_id_arr]); } return ['ids' => $secondary_card_id_arr]; } catch (\Exception $e) { return $e->getMessage(); } } public static function getSourceName($secondary_card) { $order_source = \Yii::$app->services->setting->mall->get($secondary_card['mall_id'], 'basic.name'); switch ($secondary_card['create_source_type']) { case 1: if ($secondary_card['use_type'] == 1) { $store = Store::findOne(['id' => $secondary_card['create_source_id']]); $order_source = $store['store_name'] ?? ''; } break; } return $order_source; } public static function getServiceTypeText($secondary_card) { //服务方式:1:上门服务;2:到店服务;3:上门/到店 $service_type_text = '到店服务'; if ($secondary_card['reservation_model'] == 1) { return $service_type_text; } switch ($secondary_card['reservation_service_type']) { case 1: $service_type_text = '上门服务'; break; case 2: $service_type_text = '到店服务'; break; case 3: $service_type_text = '上门/到店'; break; } return $service_type_text; } /** * 后台-次卡管理-适用门店列表 * @Author:hua * @Date:2024-03-11 14:46 * @Copyright:copyright(c)2024 广东七件事集团 * @param $params * @return array|false|mixed|void */ public static function canClerkStoreList($params) { $secondary_card = SecondaryCard::findOne(['id' => $params['id'], 'mall_id' => $params['mall_id']]); if (empty($secondary_card)) { throw new \Exception('次卡不存在'); } switch ($secondary_card['store_type']) { case 1: if ($secondary_card['use_type'] == 1) { $where = []; $where[] = ['mall_id' => $params['mall_id']]; $where[] = ['status' => StatusEnum::ENABLED]; $where[] = ['store_type' => $secondary_card['store_type']]; $where[] = ['secondary_card_id' => $secondary_card['id']]; $params['where'] = $where; $params['order'] = 'store_id asc'; $params['select'] = 'store_id'; $params['where'] = $where; $list = SecondaryCardRelateStore::listPage($params); if (!empty($list['list'])) { $store_ids = array_column($list['list'], 'store_id'); $store_list = Store::lists(['where' => [['id' => $store_ids]], 'select' => 'id,store_name,shop_owner,shop_mobile,address', 'index' => 'id']); foreach ($list['list'] as &$item) { if (isset($store_list[$item['store_id']])) { $store = $store_list[$item['store_id']]; $item['id'] = $store['id']; $item['store_name'] = $store['store_name']; $item['shop_owner'] = $store['shop_owner']; $item['shop_mobile'] = $store['shop_mobile']; $item['address'] = $store['address']; $item['type_text'] = 'o2o门店'; } } } $pageData = $list; } else { $params['where'][] = ['mall_id' => $params['mall_id']]; $params['where'][] = ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]; $params['order'] = 'id asc'; $params['select'] = 'id,store_name,shop_owner,shop_mobile,address'; $pageData = Store::listPage($params, false); if (!empty($pageData['list'])) { foreach ($pageData['list'] as &$item) { $item['type_text'] = 'o2o门店'; } } } break; } return $pageData; } /** * 小程序二维码 * @Author:hua * @Date:2024-03-15 15:16 * @Copyright:copyright(c)2024 广东七件事集团 * @param $params * @return array */ public static function showMiniPromotionCode($params) { $model = SecondaryCard::findOne(['id' => $params['id'], 'mall_id' => $params['mall_id']]); if (empty($model['applet_code'])) { $mall = $params['mall']; $content = [ 'mall_id' => $params['mall_id'], 'id' => $params['id'], 'mall_sign' => $mall['mall_sign'], ]; $content = json_encode($content); $page = '/customAddons/SecondaryCard/cardDetail'; $code = md5($content); $obj = new MiniQrCode(); $applet_code = $obj->getAppletQrCode($params['mall_id'], $page, $code); $params['code'] = $code; $params['content'] = $content; $params['applet_code'] = $applet_code; $model->applet_code = $applet_code; $model->save(); } else { $applet_code = $model->applet_code; } return ['applet_code' => $applet_code]; } public static function getStoreCateList($params) { $list = StoreCate::lists([ 'where' => [ ['mall_id' => $params['mall_id']], ['status' => StatusEnum::ENABLED] ], 'select' => 'id,name']); return $list; } public static function getEmployeeSelection($mall_id, $store_id) { $employee_selection = 1; if (MallAddons::isInstall($mall_id, 'Store')) { $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $mall_id, 'store_id' => $store_id]))->detail(); $employee_selection = $store_reserve_setting['employee_selection'] ?? 1; } return $employee_selection; } }