ClearController.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. <?php
  2. namespace console\controllers;
  3. use biz\ghs\classes\GhsBackClass;
  4. use bizGhs\clear\classes\OrderCgClearClass;
  5. use bizGhs\clear\models\Clear;
  6. use bizGhs\custom\classes\CustomClass;
  7. use bizGhs\custom\classes\CustomBalanceChangeClass;
  8. use bizGhs\ghs\classes\GhsBalanceChangeClass;
  9. use bizGhs\custom\services\GhsRechargeSettleService;
  10. use bizGhs\ghs\classes\GhsClass;
  11. use bizGhs\ghs\models\Ghs;
  12. use bizGhs\order\classes\OrderClass;
  13. use bizGhs\order\classes\PurchaseOrderClass;
  14. use bizHd\purchase\classes\PurchaseClass;
  15. use yii\console\Controller;
  16. use Yii;
  17. class ClearController extends Controller
  18. {
  19. //补回 xhOrderCgClear
  20. public function actionBc()
  21. {
  22. ini_set('memory_limit', '2045M');
  23. set_time_limit(0);
  24. if (getenv('YII_ENV') == 'production') {
  25. $autoId = 817342;
  26. } else {
  27. $autoId = 1426;
  28. }
  29. $query = new \yii\db\Query();
  30. $query->from(Clear::tableName());
  31. $query->where(['>', 'id', $autoId]);
  32. foreach ($query->batch(500) as $changeList) {
  33. $ids = array_column($changeList, 'id');
  34. $relate = OrderCgClearClass::getAllByCondition(['clearId' => ['in', $ids]], null, '*', 'clearId');
  35. $connection = Yii::$app->db;
  36. $transaction = $connection->beginTransaction();
  37. try {
  38. foreach ($changeList as $clear) {
  39. $clearId = $clear['id'] ?? 0;
  40. $clearSn = $clear['orderSn'] ?? '';
  41. $status = $clear['status'] ?? 1;
  42. $clearAmount = $clear['actPrice'] ?? 0;
  43. $purchaseIds = $clear['purchaseIds'] ?? '';
  44. $saleIds = $clear['saleIds'] ?? '';
  45. $clearStyle = $clear['clearStyle'] ?? 1;
  46. if (!isset($relate[$clearId])) {
  47. if ($clearStyle == 3) {
  48. if (!empty($purchaseIds)) {
  49. $purchaseIdList = explode(',', $purchaseIds);
  50. $purchaseInfo = PurchaseOrderClass::getAllByCondition(['id' => ['in', $purchaseIdList]], null, 'id,orderSn', 'id');
  51. foreach ($purchaseInfo as $purchase) {
  52. $purchaseId = $purchase['id'] ?? 0;
  53. $purchaseOrderSn = $purchase['orderSn'] ?? 0;
  54. $addData = ['orderId' => 0, 'orderSn' => '', 'cgId' => $purchaseId, 'cgSn' => $purchaseOrderSn,
  55. 'clearId' => $clearId, 'clearSn' => $clearSn, 'amount' => $clearAmount, 'status' => $status];
  56. OrderCgClearClass::add($addData);
  57. echo "ghs cg clearId {$clearId} OK ### \n";
  58. }
  59. } else {
  60. echo "供货商采购 clearId {$clearId} 有缺数据 \n";
  61. }
  62. } else {
  63. if (!empty($saleIds) && !empty($purchaseIds)) {
  64. $saleIdList = explode(',', $saleIds);
  65. $purchaseIdList = explode(',', $purchaseIds);
  66. $saleInfo = OrderClass::getAllByCondition(['id' => ['in', $saleIdList]], null, 'id,orderSn,purchaseId');
  67. $purchaseInfo = PurchaseClass::getAllByCondition(['id' => ['in', $purchaseIdList]], null, 'id,orderSn', 'id');
  68. if (!empty($saleInfo)) {
  69. foreach ($saleInfo as $sale) {
  70. $saleId = $sale['id'] ?? 0;
  71. $purchaseId = $sale['purchaseId'] ?? 0;
  72. $saleOrderSn = $sale['orderSn'] ?? '';
  73. $purchase = $purchaseInfo[$purchaseId] ?? [];
  74. if (empty($purchase)) {
  75. echo "purchase {$purchaseId} 没有找到 \n";
  76. exit();
  77. }
  78. $purchaseOrderSn = $purchase['orderSn'] ?? '';
  79. $addData = ['orderId' => $saleId, 'orderSn' => $saleOrderSn, 'cgId' => $purchaseId, 'cgSn' => $purchaseOrderSn,
  80. 'clearId' => $clearId, 'clearSn' => $clearSn, 'amount' => $clearAmount, 'status' => $status];
  81. OrderCgClearClass::add($addData);
  82. }
  83. echo "hd cg clearId {$clearId} OK *** \n";
  84. }
  85. } else {
  86. echo "花店采购 clearId {$clearId} 有缺数据 \n";
  87. }
  88. }
  89. } else {
  90. echo "有记录 {$clearId} \n";
  91. }
  92. }
  93. $transaction->commit();
  94. } catch (\Exception $e) {
  95. $transaction->rollBack();
  96. $msg = $e->getMessage();
  97. echo "报错了:" . $msg . "\n";
  98. }
  99. }
  100. }
  101. public function actionBalance()
  102. {
  103. ini_set('memory_limit', '2045M');
  104. set_time_limit(0);
  105. //$sql = "delete from xhGhsBack";
  106. //Yii::$app->db->createCommand($sql)->execute();
  107. $query = new \yii\db\Query();
  108. $query->from(Ghs::tableName());
  109. $query->where(['ownPtStyle' => 1]);
  110. $query->andWhere(['>', 'balance', 0]);
  111. foreach ($query->batch(500) as $ghsList) {
  112. $connection = Yii::$app->db;
  113. $transaction = $connection->beginTransaction();
  114. try {
  115. foreach ($ghsList as $ghs) {
  116. GhsBackClass::add($ghs);
  117. }
  118. $transaction->commit();
  119. } catch (\Exception $e) {
  120. $transaction->rollBack();
  121. $msg = $e->getMessage();
  122. echo "报错了:" . $msg . "\n";
  123. }
  124. }
  125. }
  126. public function actionBalanceBack()
  127. {
  128. $list = GhsBackClass::getAllByCondition(['id>' => 0], null, '*', 'id', true);
  129. if (!empty($list)) {
  130. $connection = Yii::$app->db;
  131. $transaction = $connection->beginTransaction();
  132. try {
  133. foreach ($list as $ghs) {
  134. $ownPtStyle = $ghs['ownPtStyle'] ?? 1;
  135. $balance = $ghs['balance'] ?? 0;
  136. $customId = $ghs['customId'] ?? 0;
  137. if ($ownPtStyle == 1) {
  138. $custom = CustomClass::getById($customId, true);
  139. if (!empty($custom)) {
  140. $shopId = $ghs['shopId'] ?? 0;
  141. $shop = \bizGhs\shop\classes\ShopClass::getById($shopId, true);
  142. if (!empty($shop)) {
  143. $staff = new \stdClass();
  144. $staff->id = 0;
  145. $staff->name = '';
  146. $params = [
  147. 'remark' => '系统升级恢复',
  148. 'rechargeType' => 0, // 0 代表正常充值
  149. ];
  150. // 模拟商家帮充并自动销挂账,payWay 设为 0 (线下微信)
  151. GhsRechargeSettleService::merchantRechargeWithAutoClear($custom, $balance, $shop, $staff, 0, $params);
  152. echo "customId: {$customId} 充值成功 {$balance} 元\n";
  153. } else {
  154. echo "customId: {$customId} 找不到对应的 shop\n";
  155. }
  156. } else {
  157. echo "customId: {$customId} 找不到对应的 custom\n";
  158. }
  159. }
  160. }
  161. $transaction->commit();
  162. } catch (\Exception $e) {
  163. $transaction->rollBack();
  164. echo "执行失败,整体回滚: " . $e->getMessage() . "\n";
  165. }
  166. }
  167. }
  168. /**
  169. * 安全回滚最新一次“系统升级恢复”产生的多余充值和销账数据
  170. * 支持传参单个 customId 测试:php yii clear/rollback-latest-upgrade 25695
  171. * 批量跑全部:php yii clear/rollback-latest-upgrade
  172. */
  173. public function actionRollbackLatestUpgrade($customId = 0)
  174. {
  175. $connection = Yii::$app->db;
  176. $customId = intval($customId);
  177. // 1. 查找所有备注为 "系统升级恢复" 的充值流水 (按 ID 倒序,最新产生的在最前面)
  178. $query = (new \yii\db\Query())
  179. ->from('xhCustomRecharge')
  180. ->where(['remark' => '系统升级恢复']);
  181. if ($customId > 0) {
  182. $query->andWhere(['customId' => $customId]);
  183. }
  184. $recharges = $query->orderBy('id DESC')->all();
  185. if (empty($recharges)) {
  186. echo "没有找到 '系统升级恢复' 相关的充值记录,无需回滚。\n";
  187. return;
  188. }
  189. // 2. 按客户分组,找到每个客户绝对最新(最后一次运行)的那一笔充值
  190. $latestRecharges = [];
  191. foreach ($recharges as $r) {
  192. $cid = $r['customId'];
  193. if (!isset($latestRecharges[$cid])) {
  194. $latestRecharges[$cid] = $r;
  195. }
  196. }
  197. if ($customId > 0) {
  198. echo "正在回滚指定客户 ID: {$customId} 的最新一笔升级恢复数据...\n";
  199. } else {
  200. echo "共找到 " . count($latestRecharges) . " 个客户的最新充值记录,准备执行批量安全回滚...\n";
  201. }
  202. $transaction = $connection->beginTransaction();
  203. try {
  204. foreach ($latestRecharges as $cr) {
  205. $cId = intval($cr['customId']);
  206. $amount = $cr['amount'];
  207. $clearId = intval($cr['clearId']);
  208. $crId = intval($cr['id']);
  209. $ghsRechargeId = intval($cr['ghsRechargeId'] ?? 0);
  210. // 1) 锁定客户和供货商并扣回多充的余额
  211. $custom = \bizGhs\custom\classes\CustomClass::getLockById($cId);
  212. if (empty($custom)) {
  213. throw new \Exception("找不到客户: " . $cId);
  214. }
  215. $ghsId = $custom->ghsId;
  216. $ghs = \bizGhs\ghs\classes\GhsClass::getLockById($ghsId);
  217. if (empty($ghs)) {
  218. throw new \Exception("找不到供货商, customId: " . $cId);
  219. }
  220. // 扣减多充的值
  221. $custom->balance = bcsub($custom->balance, $amount, 2);
  222. $ghs->balance = bcsub($ghs->balance, $amount, 2);
  223. $custom->save(false);
  224. $ghs->save(false);
  225. // 2) 如果这笔充值关联了自动销账(clearId > 0),精准回退订单待结和结账单状态
  226. if ($clearId > 0) {
  227. $cgClears = \bizGhs\clear\classes\OrderCgClearClass::getAllByCondition(['clearId' => $clearId], null, '*', null, true);
  228. foreach ($cgClears as $cgClear) {
  229. $orderId = intval($cgClear->orderId);
  230. $cgId = intval($cgClear->cgId);
  231. $clearedAmount = $cgClear->amount;
  232. // a. 恢复批发端的订单未结挂账金额和状态 (xhOrder)
  233. if ($orderId > 0) {
  234. $order = \bizGhs\order\classes\OrderClass::getLockById($orderId);
  235. if (!empty($order)) {
  236. $order->remainDebtPrice = bcadd($order->remainDebtPrice, $clearedAmount, 2);
  237. $order->debt = 1; // 重新恢复为挂账状态
  238. if ($order->clearId == $clearId) {
  239. $order->clearId = 0;
  240. $order->clearTime = '0000-00-00 00:00:00';
  241. }
  242. $order->save(false);
  243. }
  244. }
  245. // b. 恢复零售花店端的采购单未结挂账金额和状态 (xhPurchase)
  246. $purchase = null;
  247. if ($cgId > 0) {
  248. $purchase = \bizHd\purchase\classes\PurchaseClass::getLockById($cgId);
  249. } elseif ($orderId > 0) {
  250. $purchase = \bizHd\purchase\classes\PurchaseClass::getByCondition(['saleId' => $orderId], true);
  251. if (!empty($purchase)) {
  252. $purchase = \bizHd\purchase\classes\PurchaseClass::getLockById($purchase->id);
  253. }
  254. }
  255. if (!empty($purchase)) {
  256. $purchase->remainDebtPrice = bcadd($purchase->remainDebtPrice, $clearedAmount, 2);
  257. $purchase->debt = 1; // 恢复挂账状态
  258. if ($purchase->clearId == $clearId) {
  259. $purchase->clearId = 0;
  260. $purchase->clearTime = '0000-00-00 00:00:00';
  261. }
  262. $purchase->save(false);
  263. }
  264. // 删除销账明细纪录
  265. $cgClear->delete();
  266. }
  267. // 将结账单(xhClear)置为已作废状态 (status = 3)
  268. $clearObj = \bizGhs\order\classes\OrderClearClass::getLockById($clearId);
  269. if (!empty($clearObj)) {
  270. $clearObj->status = 3; // 3 代表已作废/已取消
  271. $clearObj->save(false);
  272. }
  273. }
  274. // 3) 删除本次充值产生的余额变动明细纪录
  275. CustomBalanceChangeClass::deleteByCondition(['relateId' => $crId]);
  276. if ($ghsRechargeId > 0) {
  277. GhsBalanceChangeClass::deleteByCondition(['relateId' => $ghsRechargeId]);
  278. }
  279. // 4) 删除充值记录本身
  280. $connection->createCommand()->delete('xhCustomRecharge', ['id' => $crId])->execute();
  281. if ($ghsRechargeId > 0) {
  282. $connection->createCommand()->delete('xhGhsRecharge', ['id' => $ghsRechargeId])->execute();
  283. }
  284. echo "【成功】客户 ID: {$cId} 多余的充值及 {$amount} 元的销账订单已完美退回并删除!\n";
  285. }
  286. $transaction->commit();
  287. echo "【全部完成】数据已成功安全回滚!\n";
  288. } catch (\Exception $e) {
  289. $transaction->rollBack();
  290. echo "【错误】回滚失败,已安全整体撤销。报错原因: " . $e->getMessage() . "\n";
  291. }
  292. }
  293. public function actionGhsGhs()
  294. {
  295. ini_set('memory_limit', '2045M');
  296. set_time_limit(0);
  297. $query = new \yii\db\Query();
  298. $query->from(Ghs::tableName());
  299. $query->where(['ownPtStyle' => 2]);
  300. foreach ($query->batch(500) as $ghsList) {
  301. $connection = Yii::$app->db;
  302. $transaction = $connection->beginTransaction();
  303. try {
  304. foreach ($ghsList as $ghs) {
  305. $ghsId = $ghs['id'] ?? 0;
  306. $balance = PurchaseOrderClass::sum(['ghsId' => $ghsId, 'debt' => 1], 'actPrice');
  307. $debtNum = PurchaseOrderClass::getCount(['ghsId' => $ghsId, 'debt' => 1]);
  308. GhsClass::updateById($ghsId, ['balance' => -$balance, 'debtNum' => $debtNum]);
  309. $customId = $ghs['customId'] ?? 0;
  310. CustomClass::updateById($customId, ['balance' => -$balance, 'debtNum' => $debtNum]);
  311. }
  312. $transaction->commit();
  313. } catch (\Exception $e) {
  314. $transaction->rollBack();
  315. $msg = $e->getMessage();
  316. echo "报错了:" . $msg . "\n";
  317. }
  318. }
  319. }
  320. }