PsMethodClass.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. <?php
  2. /**
  3. * 用途:花店配送方式配置业务逻辑类
  4. * 谁用:花店系统 hdApp 配送方式设置页
  5. * 解决什么问题:读写 xhPsMethod / xhPsExplain / xhPsReduceRule,与供货商 xhSh* 分离
  6. */
  7. namespace bizHd\order\classes;
  8. use bizHd\base\classes\BaseClass;
  9. use common\components\dict;
  10. use Yii;
  11. class PsMethodClass extends BaseClass
  12. {
  13. public static $baseFile = '\bizHd\order\models\PsMethod';
  14. /**
  15. * 获取所有配送方式的排序和别名信息
  16. * @param int $mainId 商户ID
  17. * @return array
  18. */
  19. public static function getSorts($mainId)
  20. {
  21. $list = [];
  22. $aliases = [
  23. 0 => '送货',
  24. 1 => '自取',
  25. 2 => '跑腿',
  26. 3 => '物流',
  27. 4 => '快递'
  28. ];
  29. for ($style = 0; $style <= 4; $style++) {
  30. $config = self::getByCondition(['mainId' => $mainId, 'style' => $style]);
  31. $sort = 0;
  32. $alias = $aliases[$style];
  33. $status = 1;
  34. if (!empty($config)) {
  35. $sort = isset($config['sort']) ? (int)$config['sort'] : 0;
  36. $alias = !empty($config['name']) ? $config['name'] : $aliases[$style];
  37. $status = isset($config['status']) ? (int)$config['status'] : 1;
  38. }
  39. $list[] = [
  40. 'style' => $style,
  41. 'name' => $alias,
  42. 'sort' => $sort,
  43. 'status' => $status
  44. ];
  45. }
  46. return $list;
  47. }
  48. /**
  49. * 获取指定配送方式的配置(不存在则按字典默认初始化)
  50. * @param int $shopId 门店ID
  51. * @param int $mainId 商户ID
  52. * @param int $style 配送类型 0-4
  53. * @return array
  54. */
  55. public static function getConfig($shopId, $mainId, $style)
  56. {
  57. // 复杂分支/关键逻辑:按 mainId + style 查 xhPsMethod,无记录则写入默认配置
  58. $config = self::getByCondition(['mainId' => $mainId, 'style' => $style]);
  59. if (empty($config)) {
  60. $defaultConfig = dict::getDict('shMethod', $style);
  61. $initData = array_merge([
  62. 'shopId' => $shopId,
  63. 'mainId' => $mainId,
  64. 'style' => $style,
  65. ], $defaultConfig);
  66. $config = self::add($initData, true);
  67. $config = $config->toArray();
  68. }
  69. // 关联说明项 xhPsExplain
  70. $config['explains'] = PsExplainClass::getAllByCondition(
  71. ['methodId' => $config['id']],
  72. 'sort ASC, id ASC'
  73. );
  74. // 跑腿 style=2 时加载满减规则 xhPsReduceRule
  75. if ($style == 2) {
  76. $config['reduceRules'] = PsReduceRuleClass::getAllByCondition(
  77. ['methodId' => $config['id']],
  78. 'sort ASC, id ASC'
  79. );
  80. } else {
  81. $config['reduceRules'] = [];
  82. }
  83. return $config;
  84. }
  85. /**
  86. * 客户 homeRule=1 时,用 xhCustom/xhHd 上的送货上门字段覆盖 style=0 配置
  87. * @param array $config xhPsMethod 送货配置
  88. * @param array $customInfo 客户信息(含 home、homeRule、homeAmount 等)
  89. * @return array
  90. */
  91. public static function applyCustomHomeRule($config, $customInfo)
  92. {
  93. if (empty($config) || empty($customInfo)) {
  94. return $config;
  95. }
  96. if (!isset($customInfo['homeRule']) || (int)$customInfo['homeRule'] !== 1) {
  97. return $config;
  98. }
  99. $config['status'] = isset($customInfo['home']) ? (int)$customInfo['home'] : ($config['status'] ?? 1);
  100. $config['minAmount'] = $customInfo['homeAmount'] ?? ($config['minAmount'] ?? 0);
  101. $config['minNum'] = $customInfo['homeNum'] ?? ($config['minNum'] ?? 0);
  102. $config['unMeet'] = $customInfo['homeUnMeet'] ?? ($config['unMeet'] ?? 0);
  103. $config['unMeetFee'] = $customInfo['homeUnFee'] ?? ($config['unMeetFee'] ?? 0);
  104. return $config;
  105. }
  106. /**
  107. * 一次性获取商户全部配送方式配置(含 xhPsExplain / xhPsReduceRule)
  108. * @param int $shopId 门店ID
  109. * @param int $mainId 商户ID
  110. * @return array
  111. */
  112. public static function getAllConfigs($shopId, $mainId)
  113. {
  114. $configsMap = self::getAllByCondition(['mainId' => $mainId], 'sort asc', '*', 'style', true);
  115. for ($style = 0; $style <= 4; $style++) {
  116. if (!isset($configsMap[$style])) {
  117. $defaultConfig = dict::getDict('shMethod', $style);
  118. $initData = array_merge([
  119. 'shopId' => $shopId,
  120. 'mainId' => $mainId,
  121. 'style' => $style,
  122. ], $defaultConfig);
  123. $configObj = self::add($initData, true);
  124. $configsMap[$style] = $configObj;
  125. }
  126. }
  127. $configsArray = [];
  128. $methodIds = [];
  129. foreach ($configsMap as $style => $configObj) {
  130. $configArr = $configObj instanceof \yii\db\ActiveRecord ? $configObj->toArray() : $configObj;
  131. $configsArray[$style] = $configArr;
  132. $methodIds[] = (int)$configArr['id'];
  133. }
  134. $allExplains = [];
  135. if (!empty($methodIds)) {
  136. $allExplains = PsExplainClass::getAllByCondition(['methodId' => ['in', $methodIds]], 'sort ASC, id ASC');
  137. }
  138. $explainsMap = [];
  139. foreach ($allExplains as $exp) {
  140. $explainsMap[(int)$exp['methodId']][] = $exp;
  141. }
  142. $allReduceRules = [];
  143. if (!empty($methodIds)) {
  144. $allReduceRules = PsReduceRuleClass::getAllByCondition(['methodId' => ['in', $methodIds]], 'sort ASC, id ASC');
  145. }
  146. $reduceRulesMap = [];
  147. foreach ($allReduceRules as $rule) {
  148. $reduceRulesMap[(int)$rule['methodId']][] = $rule;
  149. }
  150. $result = [];
  151. for ($style = 0; $style <= 4; $style++) {
  152. $config = $configsArray[$style];
  153. $methodId = (int)$config['id'];
  154. $config['explains'] = $explainsMap[$methodId] ?? [];
  155. $config['reduceRules'] = ($style == 2) ? ($reduceRulesMap[$methodId] ?? []) : [];
  156. $result[] = $config;
  157. }
  158. usort($result, function ($a, $b) {
  159. $sortCompare = (int)($a['sort'] ?? 0) <=> (int)($b['sort'] ?? 0);
  160. if ($sortCompare !== 0) {
  161. return $sortCompare;
  162. }
  163. return (int)($a['style'] ?? 0) <=> (int)($b['style'] ?? 0);
  164. });
  165. return $result;
  166. }
  167. /**
  168. * 保存指定配送方式配置及关联说明项、满减规则
  169. * @param int $shopId 门店ID
  170. * @param int $mainId 商户ID
  171. * @param array $data 配置数据
  172. * @return bool
  173. * @throws \Exception
  174. */
  175. public static function saveConfig($shopId, $mainId, $data)
  176. {
  177. $id = $data['id'] ?? 0;
  178. $style = $data['style'] ?? 0;
  179. $config = null;
  180. if ($id > 0) {
  181. $config = self::getByCondition(['id' => $id, 'mainId' => $mainId], true);
  182. }
  183. if (empty($config)) {
  184. $config = self::getByCondition(['mainId' => $mainId, 'style' => $style], true);
  185. }
  186. $saveData = [
  187. 'name' => $data['name'] ?? '',
  188. 'status' => isset($data['status']) ? (int)$data['status'] : 1,
  189. 'sort' => isset($data['sort']) ? (int)$data['sort'] : 0,
  190. 'minAmount' => isset($data['minAmount']) ? (float)$data['minAmount'] : 0.00,
  191. 'minNum' => isset($data['minNum']) ? (int)$data['minNum'] : 0,
  192. 'unMeet' => isset($data['unMeet']) ? (int)$data['unMeet'] : 0,
  193. 'unMeetFee' => isset($data['unMeetFee']) ? (float)$data['unMeetFee'] : 0.00,
  194. 'startKm' => isset($data['startKm']) ? (float)$data['startKm'] : 0.00,
  195. 'startPrice' => isset($data['startPrice']) ? (float)$data['startPrice'] : 0.00,
  196. 'perKmPrice' => isset($data['perKmPrice']) ? (float)$data['perKmPrice'] : 0.00,
  197. 'changeRate' => isset($data['changeRate']) ? (float)$data['changeRate'] : 0.00,
  198. ];
  199. $transaction = Yii::$app->db->beginTransaction();
  200. try {
  201. if (empty($config)) {
  202. $saveData['shopId'] = $shopId;
  203. $saveData['mainId'] = $mainId;
  204. $saveData['style'] = $style;
  205. $defaultConfig = dict::getDict('shMethod', $style);
  206. if (!empty($defaultConfig['originName'])) {
  207. $saveData['originName'] = $defaultConfig['originName'];
  208. }
  209. $config = self::add($saveData, true);
  210. } else {
  211. self::updateByCondition(['id' => $config->id], $saveData);
  212. }
  213. $methodId = $config->id;
  214. // 1. 保存说明项 xhPsExplain
  215. PsExplainClass::deleteByCondition(['methodId' => $methodId]);
  216. if (!empty($data['explains']) && is_array($data['explains'])) {
  217. $explainRows = [];
  218. foreach ($data['explains'] as $index => $exp) {
  219. if (empty($exp['explain'])) {
  220. continue;
  221. }
  222. $explainRows[] = [
  223. 'methodId' => $methodId,
  224. 'explain' => $exp['explain'],
  225. 'color' => isset($exp['color']) ? (int)$exp['color'] : 1,
  226. 'fontWeight' => isset($exp['fontWeight']) ? (int)$exp['fontWeight'] : 1,
  227. 'sort' => isset($exp['sort']) ? (int)$exp['sort'] : $index,
  228. ];
  229. }
  230. if (!empty($explainRows)) {
  231. PsExplainClass::batchAdd($explainRows);
  232. }
  233. }
  234. // 2. 保存跑腿满减规则 xhPsReduceRule
  235. PsReduceRuleClass::deleteByCondition(['methodId' => $methodId]);
  236. if ($style == 2 && !empty($data['reduceRules']) && is_array($data['reduceRules'])) {
  237. $ruleRows = [];
  238. foreach ($data['reduceRules'] as $index => $rule) {
  239. $ruleRows[] = [
  240. 'methodId' => $methodId,
  241. 'meetNum' => isset($rule['meetNum']) ? (int)$rule['meetNum'] : 0,
  242. 'meetAmount' => isset($rule['meetAmount']) ? (float)$rule['meetAmount'] : 0.00,
  243. 'freeKm' => isset($rule['freeKm']) ? (float)$rule['freeKm'] : 0.00,
  244. 'sort' => isset($rule['sort']) ? (int)$rule['sort'] : $index,
  245. ];
  246. }
  247. if (!empty($ruleRows)) {
  248. PsReduceRuleClass::batchAdd($ruleRows);
  249. }
  250. }
  251. $transaction->commit();
  252. return true;
  253. } catch (\Exception $e) {
  254. $transaction->rollBack();
  255. throw $e;
  256. }
  257. }
  258. /**
  259. * 合并客户送货上门单独规则(style=0 且 homeRule=1)
  260. * @param array $config xhPsMethod 配置
  261. * @param int $style 配送方式
  262. * @param array $customInfo 客户+花店关系信息
  263. * @return array
  264. */
  265. protected static function mergeCustomHomeRule($config, $style, $customInfo)
  266. {
  267. if ((int)$style === 0 && !empty($customInfo)) {
  268. return self::applyCustomHomeRule($config, $customInfo);
  269. }
  270. return $config;
  271. }
  272. /**
  273. * 判断当前订单是否未达最低消费
  274. * 规则:满 minAmount 或 minNum 任一达标即视为达标;两者均未达标才返回 true
  275. */
  276. public static function isBelowMinimum($itemTotalAmount, $bigNum, $config)
  277. {
  278. $minAmount = isset($config['minAmount']) ? (float)$config['minAmount'] : 0.00;
  279. $minNum = isset($config['minNum']) ? (int)$config['minNum'] : 0;
  280. if ($minAmount <= 0 && $minNum <= 0) {
  281. return false;
  282. }
  283. $amountOk = $minAmount <= 0 || (float)$itemTotalAmount >= $minAmount;
  284. $numOk = $minNum <= 0 || (float)$bigNum >= $minNum;
  285. return !($amountOk || $numOk);
  286. }
  287. /**
  288. * 拼接最低消费门槛文案,如 200元或30扎
  289. */
  290. protected static function buildUnMeetConditionText($config)
  291. {
  292. $parts = [];
  293. $minAmount = isset($config['minAmount']) ? (float)$config['minAmount'] : 0.00;
  294. $minNum = isset($config['minNum']) ? (int)$config['minNum'] : 0;
  295. if ($minAmount > 0) {
  296. $parts[] = $minAmount . '元';
  297. }
  298. if ($minNum > 0) {
  299. $parts[] = $minNum . '扎';
  300. }
  301. return implode('或', $parts);
  302. }
  303. /**
  304. * 判断当天是否已收过包装类附加费(xhPsMethod unMeet=2)
  305. */
  306. public static function isPackPaidToday($customId, $sendType = 0)
  307. {
  308. if (empty($customId)) {
  309. return false;
  310. }
  311. $current = date('Y_m_d');
  312. $key = 'hd_ps_custom_today_has_get_pack_cost_' . (int)$sendType . '_' . $current . '_' . $customId;
  313. $has = Yii::$app->redis->executeCommand('GET', [$key]);
  314. return (!empty($has) && $has == 1);
  315. }
  316. /**
  317. * 当天首单未收包装费时标记(后续单不再收)
  318. */
  319. public static function isPackFeeSkippedToday($customId, $sendType = 0)
  320. {
  321. if (empty($customId)) {
  322. return false;
  323. }
  324. $current = date('Y_m_d');
  325. $key = 'hd_ps_custom_today_skip_pack_cost_' . (int)$sendType . '_' . $current . '_' . $customId;
  326. $has = Yii::$app->redis->executeCommand('GET', [$key]);
  327. return (!empty($has) && $has == 1);
  328. }
  329. /**
  330. * 当天是否已对包装附加费做过决策(已收或首单免收)
  331. */
  332. public static function hasPackFeeDecisionToday($customId, $sendType = 0)
  333. {
  334. return self::isPackPaidToday($customId, $sendType) || self::isPackFeeSkippedToday($customId, $sendType);
  335. }
  336. /**
  337. * 判断当天是否已收过运费类附加费(xhPsMethod unMeet=0)
  338. */
  339. public static function isSendCostPaidToday($customId, $sendType = 0)
  340. {
  341. if (empty($customId)) {
  342. return false;
  343. }
  344. $current = date('Y_m_d');
  345. $key = 'hd_ps_custom_today_has_get_send_cost_' . (int)$sendType . '_' . $current . '_' . $customId;
  346. $has = Yii::$app->redis->executeCommand('GET', [$key]);
  347. return (!empty($has) && $has == 1);
  348. }
  349. /**
  350. * 当天首单未收附加运费时标记(后续单不再收)
  351. */
  352. public static function isSendFeeSkippedToday($customId, $sendType = 0)
  353. {
  354. if (empty($customId)) {
  355. return false;
  356. }
  357. $current = date('Y_m_d');
  358. $key = 'hd_ps_custom_today_skip_send_cost_' . (int)$sendType . '_' . $current . '_' . $customId;
  359. $has = Yii::$app->redis->executeCommand('GET', [$key]);
  360. return (!empty($has) && $has == 1);
  361. }
  362. /**
  363. * 当天是否已对附加运费做过决策(已收或首单免收)
  364. */
  365. public static function hasSendFeeDecisionToday($customId, $sendType = 0)
  366. {
  367. return self::isSendCostPaidToday($customId, $sendType) || self::isSendFeeSkippedToday($customId, $sendType);
  368. }
  369. /**
  370. * 支付成功后标记当天已收附加费,保证同一客户同配送方式每日只收一次
  371. */
  372. public static function markUnMeetFeePaid($customId, $sendType, $packingFee = 0, $unMeetSendCost = 0)
  373. {
  374. self::recordDailyUnMeetFeeState($customId, $sendType, $packingFee, $unMeetSendCost);
  375. }
  376. /**
  377. * 首单支付后记录当日附加费决策:收过则不再收;首单未收则当日后续也不收
  378. */
  379. protected static function recordDailyUnMeetFeeState($customId, $sendType, $packingFee = 0, $unMeetSendCost = 0)
  380. {
  381. if (empty($customId)) {
  382. return;
  383. }
  384. $current = date('Y_m_d');
  385. $style = (int)$sendType;
  386. $ttl = 86400;
  387. if (!self::hasSendFeeDecisionToday($customId, $style)) {
  388. if ((float)$unMeetSendCost > 0) {
  389. $sendKey = 'hd_ps_custom_today_has_get_send_cost_' . $style . '_' . $current . '_' . $customId;
  390. Yii::$app->redis->executeCommand('SETEX', [$sendKey, $ttl, '1']);
  391. } else {
  392. $skipKey = 'hd_ps_custom_today_skip_send_cost_' . $style . '_' . $current . '_' . $customId;
  393. Yii::$app->redis->executeCommand('SETEX', [$skipKey, $ttl, '1']);
  394. }
  395. }
  396. if (!self::hasPackFeeDecisionToday($customId, $style)) {
  397. if ((float)$packingFee > 0) {
  398. $packKey = 'hd_ps_custom_today_has_get_pack_cost_' . $style . '_' . $current . '_' . $customId;
  399. Yii::$app->redis->executeCommand('SETEX', [$packKey, $ttl, '1']);
  400. } else {
  401. $skipKey = 'hd_ps_custom_today_skip_pack_cost_' . $style . '_' . $current . '_' . $customId;
  402. Yii::$app->redis->executeCommand('SETEX', [$skipKey, $ttl, '1']);
  403. }
  404. }
  405. }
  406. /**
  407. * 根据订单信息标记当日附加费(支付成功回调/余额支付)
  408. */
  409. public static function markUnMeetFeePaidFromOrder($order)
  410. {
  411. if (empty($order)) {
  412. return;
  413. }
  414. $orderSn = is_object($order) ? ($order->orderSn ?? '') : ($order['orderSn'] ?? '');
  415. $customId = (int)(is_object($order) ? ($order->customId ?? 0) : ($order['customId'] ?? 0));
  416. $sendType = (int)(is_object($order) ? ($order->sendType ?? 0) : ($order['sendType'] ?? 0));
  417. $packingFee = (float)(is_object($order) ? ($order->packingFee ?? 0) : ($order['packingFee'] ?? 0));
  418. $unMeetSendCost = 0;
  419. if (!empty($orderSn)) {
  420. $unMeetSendKey = 'hd_ps_order_unmeet_send_' . $orderSn;
  421. $cached = Yii::$app->redis->executeCommand('GET', [$unMeetSendKey]);
  422. if (!empty($cached)) {
  423. $unMeetSendCost = (float)$cached;
  424. }
  425. }
  426. self::recordDailyUnMeetFeeState($customId, $sendType, $packingFee, $unMeetSendCost);
  427. }
  428. /**
  429. * 计算未达最低消费时应写入订单的附加运费/包装费
  430. * @return array ['sendCost' => 附加运费, 'packCost' => 附加包装费]
  431. */
  432. public static function calcFee($shopId, $mainId, $sendType, $itemTotalAmount, $bigNum, $customId = 0, $customInfo = [])
  433. {
  434. $costs = ['sendCost' => 0, 'packCost' => 0];
  435. $style = (int)$sendType;
  436. if ($style < 0 || $style > 4) {
  437. return $costs;
  438. }
  439. $config = self::getConfig($shopId, $mainId, $style);
  440. if (empty($config)) {
  441. return $costs;
  442. }
  443. $config = self::mergeCustomHomeRule($config, $style, $customInfo);
  444. if (!self::isBelowMinimum($itemTotalAmount, $bigNum, $config)) {
  445. return $costs;
  446. }
  447. $unMeet = isset($config['unMeet']) ? (int)$config['unMeet'] : 0;
  448. $unMeetFee = isset($config['unMeetFee']) ? (float)$config['unMeetFee'] : 0;
  449. if ($unMeetFee <= 0) {
  450. return $costs;
  451. }
  452. // unMeet: 0 加收运费,2 加收包装费(每客户每购买方式每日至多收一次;首单未收则当日不再收)
  453. if ($unMeet === 0 && !self::hasSendFeeDecisionToday($customId, $style)) {
  454. $costs['sendCost'] = $unMeetFee;
  455. } elseif ($unMeet === 2 && !self::hasPackFeeDecisionToday($customId, $style)) {
  456. $costs['packCost'] = $unMeetFee;
  457. }
  458. return $costs;
  459. }
  460. /**
  461. * 下单前校验配送方式最低消费与附加费是否已正确写入
  462. * @param float $packCost 附加包装费
  463. * @param float $unMeetSendCost 未达门槛附加运费(不含跑腿报价)
  464. * @return string 空字符串表示通过
  465. */
  466. public static function checkLimit($shopId, $mainId, $sendType, $actPrice, $bigNum, $packCost = 0, $unMeetSendCost = 0, $customId = 0, $customInfo = [])
  467. {
  468. $style = (int)$sendType;
  469. if ($style < 0 || $style > 4) {
  470. return '配送方式无效';
  471. }
  472. $config = self::getConfig($shopId, $mainId, $style);
  473. if (empty($config)) {
  474. return '配送方式配置异常';
  475. }
  476. $config = self::mergeCustomHomeRule($config, $style, $customInfo);
  477. $methodName = !empty($config['name']) ? $config['name'] : '该配送方式';
  478. if (isset($config['status']) && (int)$config['status'] === 0) {
  479. return "暂不支持{$methodName},请选其它配送方式";
  480. }
  481. if (!self::isBelowMinimum($actPrice, $bigNum, $config)) {
  482. return '';
  483. }
  484. $minAmount = isset($config['minAmount']) ? (float)$config['minAmount'] : 0.00;
  485. $minNum = isset($config['minNum']) ? (int)$config['minNum'] : 0;
  486. $unMeet = isset($config['unMeet']) ? (int)$config['unMeet'] : 0;
  487. $unMeetFee = isset($config['unMeetFee']) ? (float)$config['unMeetFee'] : 0;
  488. if ($unMeet === 1) {
  489. $conditionText = self::buildUnMeetConditionText($config);
  490. if ($conditionText !== '') {
  491. return "订单不满{$conditionText},不能下单";
  492. }
  493. return '未达到最低消费,不能下单';
  494. }
  495. if (($unMeet === 0 || $unMeet === 2) && $unMeetFee > 0) {
  496. $feeToCheck = $unMeet === 2 ? $packCost : $unMeetSendCost;
  497. if ($unMeet === 2 && self::hasPackFeeDecisionToday($customId, $style)) {
  498. return '';
  499. }
  500. if ($unMeet === 0 && self::hasSendFeeDecisionToday($customId, $style)) {
  501. return '';
  502. }
  503. if (bccomp((string)$feeToCheck, (string)$unMeetFee, 2) < 0) {
  504. $feeLabel = $unMeet === 2 ? '包装费' : '运费';
  505. $conditionText = self::buildUnMeetConditionText($config);
  506. if ($conditionText !== '') {
  507. return "订单不满{$conditionText},加{$feeLabel}{$unMeetFee}元";
  508. }
  509. return "未达最低消费,需加收{$feeLabel}{$unMeetFee}元";
  510. }
  511. }
  512. return '';
  513. }
  514. }