|
|
@@ -0,0 +1,265 @@
|
|
|
+<?php
|
|
|
+/**
|
|
|
+ * 用途:配送方式配置业务逻辑类
|
|
|
+ * 谁用:供货商系统
|
|
|
+ * 解决什么问题:处理配送方式的查询、保存、默认初始化等业务逻辑
|
|
|
+ */
|
|
|
+
|
|
|
+namespace bizGhs\order\classes;
|
|
|
+
|
|
|
+use bizGhs\base\classes\BaseClass;
|
|
|
+use common\components\dict;
|
|
|
+use Yii;
|
|
|
+
|
|
|
+class ShMethodClass extends BaseClass
|
|
|
+{
|
|
|
+ public static $baseFile = '\bizGhs\order\models\ShMethod';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取所有配送方式的排序和别名信息
|
|
|
+ * @param int $mainId 商户ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getSorts($mainId)
|
|
|
+ {
|
|
|
+ $list = [];
|
|
|
+ $aliases = [
|
|
|
+ 0 => '送货',
|
|
|
+ 1 => '自取',
|
|
|
+ 2 => '跑腿',
|
|
|
+ 3 => '物流',
|
|
|
+ 4 => '快递'
|
|
|
+ ];
|
|
|
+ for ($style = 0; $style <= 4; $style++) {
|
|
|
+ $config = self::getByCondition(['mainId' => $mainId, 'style' => $style]);
|
|
|
+ $sort = 0;
|
|
|
+ $alias = $aliases[$style];
|
|
|
+ $status = 1;
|
|
|
+ if (!empty($config)) {
|
|
|
+ $sort = isset($config['sort']) ? (int)$config['sort'] : 0;
|
|
|
+ $alias = !empty($config['name']) ? $config['name'] : $aliases[$style];
|
|
|
+ $status = isset($config['status']) ? (int)$config['status'] : 1;
|
|
|
+ }
|
|
|
+ $list[] = [
|
|
|
+ 'style' => $style,
|
|
|
+ 'name' => $alias,
|
|
|
+ 'sort' => $sort,
|
|
|
+ 'status' => $status
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ return $list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定门店和类型的配送方式配置,若不存在则进行默认初始化
|
|
|
+ * @param int $shopId 门店ID
|
|
|
+ * @param int $mainId 商户ID
|
|
|
+ * @param int $style 配送类型 (0: 送货, 1: 自取, 2: 跑腿, 3: 物流, 4: 快递)
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getConfig($shopId, $mainId, $style)
|
|
|
+ {
|
|
|
+ // 复杂分支/关键逻辑:优化。后端的查询全部由 shopId 改为 mainId,只根据 mainId 和 style 进行查询。
|
|
|
+ $config = self::getByCondition(['mainId' => $mainId, 'style' => $style]);
|
|
|
+ if (empty($config)) {
|
|
|
+ // 从字典配置中读取对应类型的默认配置
|
|
|
+ $defaultConfig = dict::getDict('shMethod', $style);
|
|
|
+
|
|
|
+ $initData = array_merge([
|
|
|
+ 'shopId' => $shopId, // shopId 仅作为保存预留字段存入
|
|
|
+ 'mainId' => $mainId,
|
|
|
+ 'style' => $style,
|
|
|
+ ], $defaultConfig);
|
|
|
+
|
|
|
+ $config = self::add($initData, true);
|
|
|
+ $config = $config->toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取关联的说明项
|
|
|
+ $config['explains'] = ShExplainClass::getAllByCondition(
|
|
|
+ ['methodId' => $config['id']],
|
|
|
+ 'sort ASC, id ASC'
|
|
|
+ );
|
|
|
+
|
|
|
+ // 如果 is_跑腿 (style为2),获取关联的满减规则
|
|
|
+ if ($style == 2) {
|
|
|
+ $config['reduceRules'] = ShReduceRuleClass::getAllByCondition(
|
|
|
+ ['methodId' => $config['id']],
|
|
|
+ 'sort ASC, id ASC'
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ $config['reduceRules'] = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ return $config;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 一次性获取商户所有的5种配送方式配置,减少数据库查询交互。
|
|
|
+ * 如果数据库里没有对应配置,则自动采用 dict.php 里的默认参数进行填充并完成入库。
|
|
|
+ * @param int $shopId 门店ID
|
|
|
+ * @param int $mainId 商户ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getAllConfigs($shopId, $mainId)
|
|
|
+ {
|
|
|
+ // 1. 一次性从数据库中查询当前商户的所有配送方式配置
|
|
|
+ $configsMap = self::getAllByCondition(['mainId' => $mainId], null, '*', 'style', true);
|
|
|
+
|
|
|
+ // 2. 补齐缺失的配送方式,并做初始化入库
|
|
|
+ for ($style = 0; $style <= 4; $style++) {
|
|
|
+ if (!isset($configsMap[$style])) {
|
|
|
+ $defaultConfig = dict::getDict('shMethod', $style);
|
|
|
+ $initData = array_merge([
|
|
|
+ 'shopId' => $shopId, // shopId 仅作为保存预留字段存入
|
|
|
+ 'mainId' => $mainId,
|
|
|
+ 'style' => $style,
|
|
|
+ ], $defaultConfig);
|
|
|
+
|
|
|
+ $configObj = self::add($initData, true);
|
|
|
+ $configsMap[$style] = $configObj;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将 ActiveRecord 统一转换为 array,并提取 methodIds 用于批量子表查询
|
|
|
+ $configsArray = [];
|
|
|
+ $methodIds = [];
|
|
|
+ foreach ($configsMap as $style => $configObj) {
|
|
|
+ $configArr = $configObj instanceof \yii\db\ActiveRecord ? $configObj->toArray() : $configObj;
|
|
|
+ $configsArray[$style] = $configArr;
|
|
|
+ $methodIds[] = (int)$configArr['id'];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 批量查询所有的说明项 (xhShExplain) - 仅 1 次查询
|
|
|
+ $allExplains = [];
|
|
|
+ if (!empty($methodIds)) {
|
|
|
+ $allExplains = ShExplainClass::getAllByCondition(['methodId' => ['in', $methodIds]], 'sort ASC, id ASC');
|
|
|
+ }
|
|
|
+ $explainsMap = [];
|
|
|
+ foreach ($allExplains as $exp) {
|
|
|
+ $explainsMap[(int)$exp['methodId']][] = $exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 批量查询所有的跑腿满减规则 (xhShReduceRule) - 仅 1 次查询
|
|
|
+ $allReduceRules = [];
|
|
|
+ if (!empty($methodIds)) {
|
|
|
+ $allReduceRules = ShReduceRuleClass::getAllByCondition(['methodId' => ['in', $methodIds]], 'sort ASC, id ASC');
|
|
|
+ }
|
|
|
+ $reduceRulesMap = [];
|
|
|
+ foreach ($allReduceRules as $rule) {
|
|
|
+ $reduceRulesMap[(int)$rule['methodId']][] = $rule;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 将批量查出的说明项和规则,合并填充到 5 个配送方式中
|
|
|
+ $result = [];
|
|
|
+ for ($style = 0; $style <= 4; $style++) {
|
|
|
+ $config = $configsArray[$style];
|
|
|
+ $methodId = (int)$config['id'];
|
|
|
+
|
|
|
+ $config['explains'] = $explainsMap[$methodId] ?? [];
|
|
|
+ $config['reduceRules'] = ($style == 2) ? ($reduceRulesMap[$methodId] ?? []) : [];
|
|
|
+
|
|
|
+ $result[] = $config;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存配送方式配置,包含说明项和满减规则
|
|
|
+ * @param int $shopId 门店ID
|
|
|
+ * @param int $mainId 商户ID
|
|
|
+ * @param array $data 配置数据
|
|
|
+ * @return bool
|
|
|
+ * @throws \Exception
|
|
|
+ */
|
|
|
+ public static function saveConfig($shopId, $mainId, $data)
|
|
|
+ {
|
|
|
+ $id = $data['id'] ?? 0;
|
|
|
+ $style = $data['style'] ?? 0;
|
|
|
+
|
|
|
+ $config = null;
|
|
|
+ if ($id > 0) {
|
|
|
+ // 复杂分支/关键逻辑:优化。后端的查询全部由 shopId 改为 mainId。
|
|
|
+ $config = self::getByCondition(['id' => $id, 'mainId' => $mainId], true);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (empty($config)) {
|
|
|
+ // 复杂分支/关键逻辑:优化。后端的查询全部由 shopId 改为 mainId。
|
|
|
+ $config = self::getByCondition(['mainId' => $mainId, 'style' => $style], true);
|
|
|
+ }
|
|
|
+
|
|
|
+ $saveData = [
|
|
|
+ 'name' => $data['name'] ?? '',
|
|
|
+ 'status' => isset($data['status']) ? (int)$data['status'] : 1,
|
|
|
+ 'sort' => isset($data['sort']) ? (int)$data['sort'] : 0,
|
|
|
+ 'minAmount' => isset($data['minAmount']) ? (float)$data['minAmount'] : 0.00,
|
|
|
+ 'minNum' => isset($data['minNum']) ? (int)$data['minNum'] : 0,
|
|
|
+ 'unMeet' => isset($data['unMeet']) ? (int)$data['unMeet'] : 0,
|
|
|
+ 'unMeetFee' => isset($data['unMeetFee']) ? (float)$data['unMeetFee'] : 0.00,
|
|
|
+ 'startKm' => isset($data['startKm']) ? (float)$data['startKm'] : 0.00,
|
|
|
+ 'startPrice' => isset($data['startPrice']) ? (float)$data['startPrice'] : 0.00,
|
|
|
+ 'perKmPrice' => isset($data['perKmPrice']) ? (float)$data['perKmPrice'] : 0.00,
|
|
|
+ 'changeRate' => isset($data['changeRate']) ? (float)$data['changeRate'] : 0.00,
|
|
|
+ ];
|
|
|
+
|
|
|
+ $transaction = Yii::$app->db->beginTransaction();
|
|
|
+ try {
|
|
|
+ if (empty($config)) {
|
|
|
+ $saveData['shopId'] = $shopId; // shopId 作为保存预留字段存入
|
|
|
+ $saveData['mainId'] = $mainId;
|
|
|
+ $saveData['style'] = $style;
|
|
|
+ $config = self::add($saveData, true);
|
|
|
+ } else {
|
|
|
+ self::updateByCondition(['id' => $config->id], $saveData);
|
|
|
+ }
|
|
|
+
|
|
|
+ $methodId = $config->id;
|
|
|
+
|
|
|
+ // 1. 保存说明项 (xhShExplain)
|
|
|
+ ShExplainClass::deleteByCondition(['methodId' => $methodId]);
|
|
|
+ if (!empty($data['explains']) && is_array($data['explains'])) {
|
|
|
+ $explainRows = [];
|
|
|
+ foreach ($data['explains'] as $index => $exp) {
|
|
|
+ if (empty($exp['explain'])) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $explainRows[] = [
|
|
|
+ 'methodId' => $methodId,
|
|
|
+ 'explain' => $exp['explain'],
|
|
|
+ 'color' => isset($exp['color']) ? (int)$exp['color'] : 1,
|
|
|
+ 'fontWeight' => isset($exp['fontWeight']) ? (int)$exp['fontWeight'] : 1,
|
|
|
+ 'sort' => isset($exp['sort']) ? (int)$exp['sort'] : $index,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ if (!empty($explainRows)) {
|
|
|
+ ShExplainClass::batchAdd($explainRows);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 保存跑腿满减规则 (xhShReduceRule)
|
|
|
+ ShReduceRuleClass::deleteByCondition(['methodId' => $methodId]);
|
|
|
+ if ($style == 2 && !empty($data['reduceRules']) && is_array($data['reduceRules'])) {
|
|
|
+ $ruleRows = [];
|
|
|
+ foreach ($data['reduceRules'] as $index => $rule) {
|
|
|
+ $ruleRows[] = [
|
|
|
+ 'methodId' => $methodId,
|
|
|
+ 'meetNum' => isset($rule['meetNum']) ? (int)$rule['meetNum'] : 0,
|
|
|
+ 'meetAmount' => isset($rule['meetAmount']) ? (float)$rule['meetAmount'] : 0.00,
|
|
|
+ 'freeKm' => isset($rule['freeKm']) ? (float)$rule['freeKm'] : 0.00,
|
|
|
+ 'sort' => isset($rule['sort']) ? (int)$rule['sort'] : $index,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ if (!empty($ruleRows)) {
|
|
|
+ ShReduceRuleClass::batchAdd($ruleRows);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $transaction->commit();
|
|
|
+ return true;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ $transaction->rollBack();
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|