CustomDistController.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. namespace console\controllers;
  3. use biz\shop\classes\ShopClass;
  4. use bizGhs\custom\models\Custom;
  5. use bizGhs\order\classes\OrderClass;
  6. use bizGhs\order\models\Order;
  7. use common\components\dict;
  8. use Yii;
  9. use yii\console\Controller;
  10. use yii\console\ExitCode;
  11. /**
  12. * 按 mainId 补更新 xhGhsOrder.customDistId
  13. *
  14. * 流程:
  15. * 1. 查出 mainId 下所有门店
  16. * 2. 查出各门店客户及 distId
  17. * 3. 更新该门店、该客户订单的 customDistId
  18. *
  19. * 用法:
  20. * php yii custom-dist/fill-ghs-order
  21. * php yii custom-dist/fill-ghs-order --dryRun=1
  22. * php yii custom-dist/fill-ghs-order --batchSize=200 --sleepMs=100
  23. *
  24. * mainId 在下方 $fillMainIds 中配置。
  25. */
  26. class CustomDistController extends Controller
  27. {
  28. /**
  29. * 需要补更新 customDistId 的 mainId 列表(在此填写)
  30. * @var int[]
  31. */
  32. private static $fillMainIds = [
  33. 25119, 2644,10652,2084,89473,50
  34. ];
  35. /** @var int 每批处理的客户数 */
  36. public $batchSize = 200;
  37. /** @var int 每批之间的休眠毫秒数 */
  38. public $sleepMs = 100;
  39. /** @var int 是否仅预览,1=是 */
  40. public $dryRun = 0;
  41. /** @var int 是否强制全部覆盖,1=是(默认只修不一致的) */
  42. public $all = 0;
  43. /** @var int 每个 mainId 最多更新订单条数,0=不限制 */
  44. public $limit = 0;
  45. public function options($actionID)
  46. {
  47. return array_merge(parent::options($actionID), [
  48. 'batchSize',
  49. 'sleepMs',
  50. 'dryRun',
  51. 'all',
  52. 'limit',
  53. ]);
  54. }
  55. public function actionFillGhsOrder()
  56. {
  57. ini_set('memory_limit', '512M');
  58. set_time_limit(0);
  59. $mainIdList = array_values(array_unique(array_filter(array_map('intval', self::$fillMainIds))));
  60. if (empty($mainIdList)) {
  61. $this->stderr("请在 CustomDistController::\$fillMainIds 中配置 mainId\n");
  62. return ExitCode::UNSPECIFIED_ERROR;
  63. }
  64. if ($this->batchSize < 1) {
  65. $this->stderr("batchSize 必须大于 0\n");
  66. return ExitCode::UNSPECIFIED_ERROR;
  67. }
  68. $this->stdout(sprintf(
  69. "开始补更新 %s.customDistId,mainIds: %s,batchSize: %d,dryRun: %d,all: %d\n",
  70. Order::tableName(),
  71. implode(',', $mainIdList),
  72. $this->batchSize,
  73. (int)$this->dryRun,
  74. (int)$this->all
  75. ));
  76. $totalUpdated = 0;
  77. foreach ($mainIdList as $mainId) {
  78. $updated = $this->fillMainId((int)$mainId);
  79. $totalUpdated += $updated;
  80. $this->stdout("mainId={$mainId} 完成,更新订单 {$updated} 条\n");
  81. }
  82. $this->stdout("全部完成,合计更新订单 {$totalUpdated} 条\n");
  83. return ExitCode::OK;
  84. }
  85. private function fillMainId($mainId)
  86. {
  87. $ghsPtStyle = dict::getDict('ptStyle', 'ghs');
  88. $shopList = ShopClass::getAllByCondition(
  89. ['mainId' => $mainId, 'ptStyle' => $ghsPtStyle],
  90. null,
  91. 'id,shopName',
  92. null,
  93. true
  94. );
  95. if (empty($shopList)) {
  96. $this->stdout("mainId={$mainId} 没有找到门店,跳过\n");
  97. return 0;
  98. }
  99. $updated = 0;
  100. foreach ($shopList as $shop) {
  101. if ($this->limit > 0 && $updated >= $this->limit) {
  102. break;
  103. }
  104. $shopId = (int)($shop->id ?? 0);
  105. if ($shopId <= 0) {
  106. continue;
  107. }
  108. $shopName = $shop->shopName ?? '';
  109. $this->stdout("mainId={$mainId} shopId={$shopId} {$shopName} 开始处理客户\n");
  110. $shopUpdated = $this->fillShop($mainId, $shopId, $updated);
  111. $updated += $shopUpdated;
  112. $this->stdout("mainId={$mainId} shopId={$shopId} 更新订单 {$shopUpdated} 条\n");
  113. }
  114. return $updated;
  115. }
  116. private function fillShop($mainId, $shopId, $mainUpdated)
  117. {
  118. $updated = 0;
  119. $query = new \yii\db\Query();
  120. $query->from(Custom::tableName());
  121. $query->where(['ownShopId' => $shopId]);
  122. $query->orderBy('id asc');
  123. foreach ($query->batch($this->batchSize) as $customerList) {
  124. if ($this->limit > 0 && ($mainUpdated + $updated) >= $this->limit) {
  125. break;
  126. }
  127. if (empty($customerList)) {
  128. continue;
  129. }
  130. foreach ($customerList as $custom) {
  131. $customId = (int)($custom['id'] ?? 0);
  132. $distId = (int)($custom['distId'] ?? 0);
  133. if ($customId <= 0) {
  134. continue;
  135. }
  136. $countWhere = $this->buildOrderCountWhere($mainId, $shopId, $customId, $distId);
  137. $updateWhere = $this->buildOrderUpdateWhere($mainId, $shopId, $customId, $distId);
  138. if ($this->dryRun) {
  139. $count = (int)OrderClass::getCount($countWhere);
  140. if ($count > 0) {
  141. $customName = $custom['name'] ?? '';
  142. $this->stdout("[dryRun] mainId={$mainId} shopId={$shopId} customId={$customId} {$customName} distId={$distId} 订单 {$count} 条\n");
  143. $updated += $count;
  144. }
  145. continue;
  146. }
  147. $affected = Order::updateAll(['customDistId' => $distId], $updateWhere);
  148. if ($affected > 0) {
  149. $updated += (int)$affected;
  150. }
  151. if ($this->limit > 0 && ($mainUpdated + $updated) >= $this->limit) {
  152. break 2;
  153. }
  154. }
  155. if ($this->sleepMs > 0) {
  156. usleep($this->sleepMs * 1000);
  157. }
  158. }
  159. return $updated;
  160. }
  161. /**
  162. * updateAll 用的 Yii 标准条件
  163. */
  164. private function buildOrderUpdateWhere($mainId, $shopId, $customId, $distId)
  165. {
  166. $base = [
  167. 'mainId' => $mainId,
  168. 'shopId' => $shopId,
  169. 'customId' => $customId,
  170. ];
  171. if ($this->all) {
  172. return $base;
  173. }
  174. return ['and', $base, ['!=', 'customDistId', $distId]];
  175. }
  176. /**
  177. * conditionQuery 用的等值/不等条件(仅 dryRun 统计)
  178. */
  179. private function buildOrderCountWhere($mainId, $shopId, $customId, $distId)
  180. {
  181. $where = [
  182. 'mainId' => $mainId,
  183. 'shopId' => $shopId,
  184. 'customId' => $customId,
  185. ];
  186. if (!$this->all) {
  187. $where['customDistId!='] = $distId;
  188. }
  189. return $where;
  190. }
  191. }