OrderItemClass.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. <?php
  2. namespace bizGhs\order\classes;
  3. use biz\product\classes\XjClass;
  4. use bizGhs\book\classes\BookItemClass;
  5. use bizGhs\custom\classes\CustomClass;
  6. use bizGhs\ghs\classes\GhsClass;
  7. use bizGhs\product\classes\ProductClass;
  8. use bizGhs\shop\classes\ShopClass;
  9. use bizGhs\stock\classes\StockRecordClass;
  10. use bizHd\purchase\classes\PurchaseClass;
  11. use bizHd\purchase\classes\PurchaseItemClass;
  12. use common\components\dict;
  13. use common\components\imgUtil;
  14. use common\components\noticeUtil;
  15. use common\components\orderSn;
  16. use common\components\util;
  17. use Yii;
  18. use bizGhs\base\classes\BaseClass;
  19. class OrderItemClass extends BaseClass
  20. {
  21. public static $baseFile = '\bizGhs\order\models\OrderItem';
  22. //预订单删除花材项 ssh 20240123
  23. public static function delBookItem($order, $smallId, $params = [])
  24. {
  25. $son = self::getById($smallId, true);
  26. if (empty($son)) {
  27. util::fail('没有找到花材');
  28. }
  29. $ptItemId = $son->itemId ?? 0;
  30. $son->delete();
  31. $productId = $son->productId ?? 0;
  32. $cgId = $order->purchaseId ?? 0;
  33. $cg = PurchaseClass::getById($cgId, true);
  34. if (empty($cg)) {
  35. util::fail('没有采购单');
  36. }
  37. $cgOrderSn = $cg->orderSn ?? '';
  38. $cgList = PurchaseItemClass::getAllByCondition(['orderSn' => $cgOrderSn], null, '*', null, true);
  39. if (empty($cgList)) {
  40. util::fail('没有采购的花材');
  41. }
  42. $cgHasDelOk = 0;
  43. foreach ($cgList as $cgIt) {
  44. $itemId = $cgIt->itemId ?? 0;
  45. if ($itemId == $ptItemId) {
  46. $cgIt->delete();
  47. $cgHasDelOk = 1;
  48. }
  49. }
  50. if ($cgHasDelOk == 0) {
  51. util::fail('删除失败');
  52. }
  53. //删除预订
  54. $num = $son->xhNum ?? 0;
  55. $delData = [['productId' => $productId, 'num' => $num, 'last' => 0]];
  56. BookItemClass::delBathItem($delData, $order, $params);
  57. }
  58. //预订单添加花材项 ssh 20240123
  59. public static function addBookItemFn($order, $itemList, $params = [])
  60. {
  61. $orderSn = $order->orderSn ?? '';
  62. $addIds = array_column($itemList, 'productId');
  63. $existList = self::getAllByCondition(['orderSn' => $orderSn], null, '*');
  64. foreach ($existList as $ex) {
  65. $productId = $ex['productId'] ?? 0;
  66. $name = $ex['name'] ?? '';
  67. if (in_array($productId, $addIds)) {
  68. util::fail($name . ' 已经存在');
  69. }
  70. }
  71. $addInfo = ProductClass::getByIds($addIds, null, 'id');
  72. if (empty($addInfo)) {
  73. util::fail('没有花材');
  74. }
  75. $productList = [];
  76. $thisBookData = [];
  77. foreach ($itemList as $item) {
  78. $num = $item['num'] ?? 0;
  79. $price = $item['price'] ?? 0;
  80. $productId = $item['productId'] ?? 0;
  81. $info = $addInfo[$productId] ?? [];
  82. $current = [];
  83. $current['name'] = $info['name'] ?? '';
  84. $current['cover'] = $info['cover'] ?? '';
  85. $current['orderSn'] = $orderSn;
  86. $ptItemId = $info['itemId'] ?? 0;
  87. $current['itemId'] = $ptItemId;
  88. $current['productId'] = $productId;
  89. $classId = $info['classId'] ?? 0;
  90. $current['classId'] = $classId;
  91. $current['variety'] = $info['variety'] ?? 0;
  92. $current['shopId'] = $info['shopId'] ?? 0;
  93. $current['mainId'] = $info['mainId'] ?? 0;
  94. $current['smallUnit'] = $info['smallUnit'] ?? 0;
  95. $current['bigUnit'] = $info['bigUnit'] ?? 0;
  96. $current['price'] = 0;
  97. $current['unitWeight'] = $info['weight'] ?? 0;
  98. $current['cost'] = $info['cost'] ?? 0;
  99. $current['num'] = $num;
  100. $current['bigNum'] = $num;
  101. $current['preNum'] = $num;
  102. $current['preBigNum'] = $num;
  103. $current['ratio'] = $info['ratio'] ?? 0;
  104. $current['variety'] = $info['variety'] ?? 0;
  105. $current['xhNum'] = $num;
  106. $current['xhUnitName'] = $info['bigUnit'] ?? '';
  107. $current['xhUnitType'] = 0;
  108. $current['xhPreNum'] = $num;
  109. $current['xhPreUnitName'] = $info['bigUnit'] ?? '';
  110. $current['xhPreUnitType'] = 0;
  111. if ($price > 0) {
  112. $current['xhUnitPrice'] = $price;
  113. $current['xhPreUnitPrice'] = $price;
  114. }
  115. $current['itemInfo'] = '';
  116. $belongCost = $info['belongCost'] ?? 0;
  117. $current['belongCost'] = $belongCost;
  118. self::add($current);
  119. $productList[] = [
  120. 'productId' => $productId,
  121. 'num' => $num,
  122. 'bigNum' => $num,
  123. 'smallNum' => 0,
  124. 'classId' => $classId,
  125. 'itemId' => $ptItemId,
  126. 'userPrice' => 0,
  127. ];
  128. $thisBookData[] = ['productId' => $productId, 'num' => $num, 'lastNum' => $num];
  129. }
  130. BookItemClass::addBatchItem($thisBookData, $order, $params);
  131. $cgId = $order->purchaseId ?? 0;
  132. $cg = PurchaseClass::getById($cgId, true);
  133. if (empty($cg)) {
  134. util::fail('没有采购信息');
  135. }
  136. $shopId = $cg->shopId ?? 0;
  137. $sjId = $cg->sjId ?? 0;
  138. $mainId = $cg->mainId ?? 0;
  139. $ghsId = $cg->ghsId ?? 0;
  140. $ghs = GhsClass::getById($ghsId, true);
  141. if (empty($ghs)) {
  142. util::fail('供货商无效');
  143. }
  144. $productList = ProductClass::toggleProductList($productList, $shopId, $sjId, $mainId, $ghs);
  145. $cgProductIds = array_column($productList, 'productId');
  146. $cgProductInfoList = ProductClass::getByIds($cgProductIds, null, 'id');
  147. $cgOrderSn = $cg->orderSn ?? '';
  148. foreach ($productList as $key => $val) {
  149. $productId = $val['productId'] ?? 0;
  150. $num = $val['num'] ?? 0;
  151. $ghsProductId = $val['ghsProductId'] ?? 0;
  152. $thisInfo = $cgProductInfoList[$productId] ?? [];
  153. $newItem = [];
  154. $name = $thisInfo['name'] ?? '';
  155. $cover = $thisInfo['cover'] ?? '';
  156. $newItem['name'] = $name;
  157. $newItem['cover'] = $cover;
  158. $newItem['orderSn'] = $cgOrderSn;
  159. $newItem['productId'] = $productId;
  160. $newItem['itemId'] = $thisInfo['itemId'] ?? 0;
  161. $newItem['mainId'] = $cg->mainId ?? 0;
  162. $newItem['ghsId'] = $ghsId;
  163. $newItem['itemNum'] = $num;
  164. $newItem['preItemNum'] = $num;
  165. $newItem['ghsProductId'] = $ghsProductId;
  166. $ratio = $thisInfo['ratio'] ?? 0;
  167. $bigUnit = $thisInfo['bigUnit'] ?? '';
  168. $smallUnit = $thisInfo['smallUnit'] ?? '';
  169. $newItem['ratio'] = $ratio;
  170. $newItem['price'] = 0;
  171. $newItem['variety'] = $thisInfo['variety'] ?? 0;
  172. $newItem['unitWeight'] = $thisInfo['weight'] ?? 0;
  173. $newItem['xhNum'] = $num;
  174. $newItem['xhUnitName'] = $thisInfo['bigUnit'] ?? '';
  175. $newItem['xhUnitType'] = 0;
  176. $newItem['xhPreNum'] = $num;
  177. $newItem['xhPreUnitName'] = $thisInfo['bigUnit'] ?? '';
  178. $newItem['xhPreUnitType'] = 0;
  179. $newItem['itemInfo'] = '';
  180. $itemInfo = [
  181. 'itemName' => $name,
  182. 'itemCover' => $cover,
  183. 'bigNum' => $num,
  184. 'smallNum' => 0,
  185. 'bigNumStock' => 0,
  186. 'smallNumStock' => 0,
  187. 'itemUnit' => $ratio ? 2 : 1,
  188. 'ratio' => $ratio,
  189. 'rank' => '',
  190. 'bigUnit' => $bigUnit,
  191. 'smallUnit' => $smallUnit,
  192. ];
  193. $newItem['itemInfo'] = json_encode($itemInfo);
  194. PurchaseItemClass::add($newItem);
  195. }
  196. }
  197. public static function giveItem($order, $orderItem, $product, $num, $data)
  198. {
  199. $productId = $product->id ?? 0;
  200. $ptItemId = $product->itemId ?? 0;
  201. $name = $product->name ?? '';
  202. $cover = $product->cover ?? '';
  203. $ratio = $product->ratio ?? 20;
  204. $ratioType = $product->ratioType ?? 0;
  205. $mainId = $product->mainId ?? 0;
  206. $targetId = $order->id ?? 0;
  207. $targetSonId = $orderItem->id ?? 0;
  208. $orderItem->giveNum = bcadd($orderItem->giveNum, $num);
  209. $orderItem->save();
  210. $orderSn = orderSn::getGiveSn();
  211. $giveData = [
  212. 'orderSn' => $orderSn,
  213. 'mainId' => $mainId,
  214. 'productId' => $productId,
  215. 'name' => $name,
  216. 'cover' => $cover,
  217. 'ratio' => $ratio,
  218. 'ratioType' => $ratioType,
  219. 'ptItemId' => $ptItemId,
  220. 'giveNum' => $num,
  221. 'targetId' => $targetId,
  222. 'targetSonId' => $targetSonId,
  223. 'staffId' => $data['staffId'] ?? 0,
  224. 'staffName' => $data['staffName'] ?? '',
  225. 'ghsId' => $order->ghsId ?? 0,
  226. 'customId' => $order->customId ?? 0,
  227. 'customName' => $order->customName ?? '',
  228. 'customNamePy' => $order->customNamePy ?? '',
  229. 'customAvatar' => $order->customAvatar ?? '',
  230. 'customMobile' => $order->customMobile ?? '',
  231. ];
  232. $giveInfo = GiveClass::add($giveData, true);
  233. $stockInfo = ProductClass::decreaseStock($productId, $num, 0, true);
  234. $oldStock = $stockInfo['oldStock'];
  235. $newStock = $stockInfo['newStock'];
  236. $stockItem = [[
  237. 'productId' => $productId,
  238. 'itemId' => $ptItemId,
  239. 'itemNum' => $num,
  240. 'oldStock' => $oldStock,
  241. 'itemStock' => $oldStock,
  242. 'newStock' => $newStock,
  243. 'bigNum' => $num,
  244. 'smallNum' => 0,
  245. ]];
  246. $stockData = [];
  247. $stockData['shopId'] = $data['shopId'];
  248. $stockData['relateName'] = $data['staffName'] ?? '';
  249. $stockData['ptStyle'] = dict::getDict('ptStyle', 'ghs');
  250. $stockData['orderSn'] = $orderSn;
  251. $stockData['sjId'] = $data['sjId'] ?? 0;
  252. $stockData['itemInfo'] = $stockItem;
  253. $stockData['relateName'] = $order->customName ?? '';
  254. StockRecordClass::addRecordByOrder($stockData, StockRecordClass::STOCK_RECORD_TYPE_GIVE);
  255. return $giveInfo;
  256. }
  257. //获取订单的花材 ssh 2021.3.2
  258. public static function getOrderItem($orderSn)
  259. {
  260. $list = self::getAllByCondition(['orderSn' => $orderSn], 'id ASC', '*');
  261. return self::groupInfo($list);
  262. }
  263. //组合信息 ssh 2021.3.2
  264. public static function groupInfo($list)
  265. {
  266. if (empty($list)) {
  267. return [];
  268. }
  269. $productIds = array_unique(array_filter(array_column($list, 'productId')));
  270. $productData = ProductClass::getProductByIds($productIds);
  271. $productData = array_column($productData, NULL, 'id');
  272. foreach ($list as $key => $val) {
  273. $shortCover = $val['cover'] ?? '';
  274. $list[$key]['cover'] = imgUtil::groupImg($shortCover) . "?x-oss-process=image/resize,m_fill,h_130,w_130";
  275. $list[$key]['bigCover'] = imgUtil::groupImg($shortCover) . "?x-oss-process=image/resize,m_fill,h_700,w_700";
  276. if (!$val['ratio']) {
  277. $ratio = $productData[$val['productId']]['ratio'] ?? 1;
  278. $list[$key]['ratio'] = $ratio;
  279. }
  280. //保存实时成本,预订单到货时使用
  281. $list[$key]['currentCost'] = $productData[$val['productId']]['cost'] ?? 0;
  282. }
  283. return $list;
  284. }
  285. /**
  286. * 替换订单(orderSn)下所有商品项为指定的 product 列表,并根据参数处理附加商详(如每支鲜花 xj)、校验及扣减库存、更新限购等。
  287. *
  288. * 步骤说明:
  289. * 1. 根据 customId 获取客户等级和属性,格式化 products 信息;
  290. * 2. 先删除该订单下历史商品项,再批量插入新 products 项;
  291. * 3. 若包含 xj(每支鲜花)信息,批量关联并校验单支库存、同步写入;
  292. * 4. 处理每项商品的限购、本次扣减库存(如 stockMayChange 为 true),并记录出库流水。
  293. * 5. 返回本次批量插入及处理后的汇总结果(带总重量)。
  294. *
  295. * 用于订单商品整体替换的核心业务方法。
  296. * @param $orderSn
  297. * @param $products
  298. * @param null $post
  299. * @param bool $stockMayChange
  300. * @param array $moreParams
  301. * @return array|void
  302. * @throws \Exception
  303. */
  304. public static function replaceItem($orderSn, $products, $post = null, $stockMayChange = false, $moreParams = [])
  305. {
  306. $customId = intval($post['customId']);
  307. $custom = CustomClass::getById($customId, true);
  308. if (empty($custom)) {
  309. return util::fail('没有找到客户');
  310. }
  311. $level = $custom->level ?? 0;
  312. $live = isset($custom->live) ? $custom->live : 1;
  313. $shopId = $post['shopId'] ?? 0;
  314. $skipLimitBuy = false;
  315. if (!empty($shopId)) {
  316. $shop = ShopClass::getById($shopId, true, 'id, skCustomId');
  317. $skipLimitBuy = !empty($shop->skCustomId) && intval($shop->skCustomId) == $customId;
  318. }
  319. $moreParams['skipLimitBuy'] = $skipLimitBuy;
  320. $respond = ProductClass::formatProductInfo($products, $level, $live, $moreParams);
  321. $products = $respond['product'];
  322. $weight = 0;
  323. $mainId = $post['mainId'] ?? 0;
  324. // --- 开始:死锁预防机制 ---
  325. // 为了防止在高并发场景下,不同订单包含相同商品但顺序不同导致交叉死锁
  326. // 我们提前提取所有涉及的花材ID,按照ID升序排列后统一加锁(SELECT FOR UPDATE)
  327. if ($stockMayChange == true) {
  328. $lockProductIds = [];
  329. foreach ($products as $p) {
  330. if (!empty($p['productId'])) {
  331. $lockProductIds[] = $p['productId'];
  332. }
  333. }
  334. if (!empty($lockProductIds)) {
  335. $lockProductIds = array_unique($lockProductIds);
  336. sort($lockProductIds);
  337. foreach ($lockProductIds as $lockPId) {
  338. ProductClass::getLockById($lockPId);
  339. }
  340. }
  341. // 同样为多颜色(xj)库存扣减做死锁预防
  342. if (!empty($post['xj']) && is_array($post['xj'])) {
  343. $lockXjIds = [];
  344. foreach ($post['xj'] as $xjArr) {
  345. if (is_array($xjArr)) {
  346. foreach ($xjArr as $xjItem) {
  347. if (!empty($xjItem['id'])) {
  348. $lockXjIds[] = $xjItem['id'];
  349. }
  350. }
  351. }
  352. }
  353. if (!empty($lockXjIds)) {
  354. $lockXjIds = array_unique($lockXjIds);
  355. sort($lockXjIds);
  356. foreach ($lockXjIds as $lockXjId) {
  357. XjClass::getLockById($lockXjId);
  358. }
  359. }
  360. }
  361. }
  362. // --- 结束:死锁预防机制 ---
  363. self::deleteByCondition(['orderSn' => $orderSn]);
  364. foreach ($products as $key => $p) {
  365. $p['orderSn'] = $orderSn;
  366. $p['mainId'] = $mainId;
  367. $item = self::add($p, true);
  368. $currentPtItemId = $item->itemId;
  369. $unitPrice = $p['unitPrice'];
  370. if (isset($post['xj'][$currentPtItemId]) && !empty($post['xj'][$currentPtItemId])) {
  371. $xjArr = $post['xj'][$currentPtItemId];
  372. if (is_array($xjArr)) {
  373. $ids = array_column($xjArr, 'id');
  374. $sjInfo = XjClass::getByIds($ids, null, 'id');
  375. $xjData = [];
  376. foreach ($xjArr as $xjItem) {
  377. $id = $xjItem['id'] ?? 0;
  378. $num = $xjItem['num'] ?? 0;
  379. $name = $sjInfo[$id]['name'] ?? '';
  380. $cover = $sjInfo[$id]['cover'] ?? '';
  381. $stock = $sjInfo[$id]['stock'] ?? -1;
  382. if ($stock == -1) {
  383. } else {
  384. if ($stock < $num) {
  385. util::fail($name . ' 库存不足 ' . $num);
  386. } else {
  387. $newStock = bcsub($stock, $num);
  388. $status = $newStock == 0 ? 2 : 1;
  389. XjClass::updateById($id, ['stock' => $newStock, 'status' => $status]);
  390. }
  391. }
  392. $xjData[] = ['xjId' => $id, 'name' => $name, 'ptItemId' => $currentPtItemId,
  393. 'num' => $num, 'price' => $unitPrice, 'itemId' => $item->id, 'cover' => $cover];
  394. }
  395. OrderXjClass::batchAdd($xjData);
  396. $item->variety = 1;
  397. $item->save();
  398. }
  399. }
  400. $productId = $p['productId'] ?? 0;
  401. if (!empty($post['treeData'][$currentPtItemId])) {
  402. $treeData = $post['treeData'][$currentPtItemId];
  403. if (is_array($treeData)) {
  404. foreach ($treeData as $treeItem) {
  405. $treeNum = $treeItem['num'] ?? 0;
  406. $treeParam = [
  407. 'orderSn' => $orderSn,
  408. 'productId' => $productId,
  409. 'num' => $treeNum,
  410. ];
  411. OrderTreeClass::add($treeParam);
  412. }
  413. $dishNum = count($treeData);
  414. $item->dishNum = $dishNum;
  415. $item->save();
  416. }
  417. }
  418. $ratio = $p['ratio'] ?? 0;
  419. $bigNum = $p['bigNum'] ?? 0;
  420. $smallNum = $p['smallNum'] ?? 0;
  421. $itemNum = ProductClass::mergeItemNum($bigNum, $smallNum, $ratio);
  422. $w = bcmul($itemNum, $p['weight'], 2);
  423. $weight = bcadd($w, $weight, 2);
  424. $limitBuy = $p['limitBuy'];
  425. if ($limitBuy > 0 && $skipLimitBuy == false) {
  426. ProductClass::handleLimitBuy($p, $customId, floatval($itemNum));
  427. }
  428. if ($stockMayChange == true) {
  429. if ($itemNum > 0) {
  430. $productId = $p['productId'];
  431. $checkStock = true;
  432. //如果是虚拟客户,说明自己也是虚拟批发店,虚拟批发店不用考虑库存
  433. if ($live == 0) {
  434. $checkStock = false;
  435. }
  436. $stockInfo = ProductClass::decreaseStock($productId, $bigNum, $smallNum, $checkStock);
  437. $recordData = [];
  438. $recordData['sjId'] = $post['sjId'] ?? 0;
  439. $recordData['shopId'] = $post['shopId'] ?? 0;
  440. $recordData['mainId'] = $post['mainId'] ?? 0;
  441. $recordData['itemId'] = $p['itemId'] ?? 0;
  442. $recordData['itemNum'] = $itemNum;
  443. $recordData['oldStock'] = $stockInfo['oldStock'];
  444. $recordData['newStock'] = $stockInfo['newStock'];
  445. $recordData['productId'] = $productId;
  446. $recordData['orderSn'] = $orderSn;
  447. $recordData['relateName'] = $post['customName'] ?? '';
  448. $recordData['ptStyle'] = dict::getDict('ptStyle', 'ghs');
  449. StockRecordClass::addSellStockOrderRecord($recordData);
  450. }
  451. }
  452. }
  453. $respond['weight'] = $weight;
  454. return $respond;
  455. }
  456. public static function getOrderInfoList($where)
  457. {
  458. $respond = self::getList('orderSn,id', $where, 'id DESC');
  459. if (isset($respond['list']) && !empty($respond['list'])) {
  460. $orderSnData = array_unique(array_filter(array_column($respond['list'], 'orderSn')));
  461. $orderInfoList = OrderClass::getOrderInfoBySnList($orderSnData);
  462. foreach ($respond['list'] as $key => $val) {
  463. $orderSn = $val['orderSn'] ?? '';
  464. $orderInfo = $orderInfoList[$orderSn] ?? [];
  465. $respond['list'][$key]['orderInfo'] = $orderInfo;
  466. }
  467. }
  468. return $respond;
  469. }
  470. public static function refreshBelongCost()
  471. {
  472. $customerCachedKey = 'change_belong_cost_item_list';
  473. $belongList = [];
  474. while ($count = Yii::$app->redis->executeCommand('LLEN', [$customerCachedKey])) {
  475. $string = Yii::$app->redis->executeCommand('RPOP', [$customerCachedKey]);
  476. $arr = explode('_', $string);
  477. if (count($arr) == 2) {
  478. $belongList[] = ['id' => $arr[0], 'belongCost' => $arr[1]];
  479. }
  480. }
  481. if (empty($belongList)) {
  482. return false;
  483. }
  484. foreach ($belongList as $info) {
  485. $id = $info['id'];
  486. $belongCost = $info['belongCost'];
  487. noticeUtil::push('变更单独统计' . $id . ' ' . $belongCost, '15280215347');
  488. self::updateByCondition(['productId' => $id], ['belongCost' => $belongCost]);
  489. PurchaseOrderItemClass::updateByCondition(['productId' => $id], ['belongCost' => $belongCost]);
  490. \bizHd\order\classes\OrderItemClass::updateByCondition(['itemId' => $id], ['belongCost' => $belongCost]);
  491. }
  492. }
  493. //导出excel ssh 20241127
  494. public static function exportExcel($order, $orderList, $mainId)
  495. {
  496. $customName = $order->customName ?? '';
  497. $orderSn = $order->orderSn ?? '';
  498. $fileTitle = $customName . '_' . $orderSn;
  499. if (empty($orderList)) {
  500. util::fail('没有数据需要导出');
  501. }
  502. $phpExcelFile = Yii::getAlias("@vendor/phpoffice/phpexcel/");
  503. require_once($phpExcelFile . 'Classes/PHPExcel.php');
  504. $objPHPExcel = new \PHPExcel();
  505. $objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
  506. ->setLastModifiedBy("Maarten Balliauw")
  507. ->setTitle("Office 2007 XLSX Document")
  508. ->setSubject("Office 2007 XLSX Document")
  509. ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
  510. ->setKeywords("office 2007 openxml php")
  511. ->setCategory("file");
  512. $ghsTitle = '花材列表';
  513. $objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader(date('n月j日') . " " . $ghsTitle);
  514. $objPHPExcel->getActiveSheet()->getPageMargins()->setTop(0.7);
  515. $objPHPExcel->getActiveSheet()->getPageMargins()->setBottom(0.1);
  516. $objPHPExcel->getActiveSheet()->getPageMargins()->setLeft(0.5);
  517. $objPHPExcel->getActiveSheet()->getPageMargins()->setRight(0);
  518. $objPHPExcel->getActiveSheet()->getPageMargins()->setHeader(0.1);
  519. $objPHPExcel->getActiveSheet()->getPageMargins()->setFooter(0);
  520. //设置宽度
  521. $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(15);
  522. $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25);
  523. $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(15);
  524. $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(15);
  525. $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(20);
  526. $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(16);
  527. $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(16);
  528. $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(16);
  529. //加粗
  530. $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(13)->setBold(true);
  531. $objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setSize(13)->setBold(true);
  532. $objPHPExcel->getActiveSheet()->getStyle('C1')->getFont()->setSize(13)->setBold(true);
  533. $objPHPExcel->getActiveSheet()->getStyle('D1')->getFont()->setSize(13)->setBold(true);
  534. $objPHPExcel->getActiveSheet()->getStyle('E1')->getFont()->setSize(13)->setBold(true);
  535. $objPHPExcel->getActiveSheet()->getStyle('F1')->getFont()->setSize(13)->setBold(true);
  536. $objPHPExcel->getActiveSheet()->getStyle('G1')->getFont()->setSize(13)->setBold(true);
  537. $objPHPExcel->getActiveSheet()->getStyle('H1')->getFont()->setSize(13)->setBold(true);
  538. $objPHPExcel->getActiveSheet()->getStyle('I1')->getFont()->setSize(13)->setBold(true);
  539. $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  540. $objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  541. $objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  542. $objPHPExcel->getActiveSheet()->getStyle('D1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  543. $objPHPExcel->getActiveSheet()->getStyle('E1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  544. $objPHPExcel->getActiveSheet()->getStyle('F1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  545. $objPHPExcel->getActiveSheet()->getStyle('G1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  546. $objPHPExcel->getActiveSheet()->getStyle('H1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  547. $objPHPExcel->getActiveSheet()->getStyle('I1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  548. $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  549. $objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  550. $objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  551. $objPHPExcel->getActiveSheet()->getStyle('D1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  552. $objPHPExcel->getActiveSheet()->getStyle('E1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  553. $objPHPExcel->getActiveSheet()->getStyle('F1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  554. $objPHPExcel->getActiveSheet()->getStyle('G1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  555. $objPHPExcel->getActiveSheet()->getStyle('H1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  556. $objPHPExcel->getActiveSheet()->getStyle('I1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
  557. $objPHPExcel->getActiveSheet()->setCellValue('A1', '花材ID');
  558. $objPHPExcel->getActiveSheet()->setCellValue('B1', '花材名称');
  559. $objPHPExcel->getActiveSheet()->setCellValue('C1', '数量');
  560. $objPHPExcel->getActiveSheet()->setCellValue('D1', '单价');
  561. $objPHPExcel->getActiveSheet()->setCellValue('E1', '总价');
  562. $objPHPExcel->getActiveSheet()->setCellValue('F1', '备注');
  563. $objPHPExcel->getActiveSheet()->setCellValue('G1', '预留1');
  564. $objPHPExcel->getActiveSheet()->setCellValue('H1', '预留2');
  565. $objPHPExcel->getActiveSheet()->setCellValue('I1', '预留3');
  566. $baseRow = 2;
  567. foreach ($orderList as $key => $order) {
  568. $i = $baseRow + $key;
  569. $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, $order['productId']);
  570. $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, $order['name']);
  571. $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, $order['xhNum']);
  572. $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, $order['xhUnitPrice']);
  573. $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, $order['xhPrice']);
  574. $objPHPExcel->getActiveSheet()->setCellValue('F' . $i, $order['remark']);
  575. $objPHPExcel->getActiveSheet()->setCellValue('G' . $i, '');
  576. $objPHPExcel->getActiveSheet()->setCellValue('H' . $i, '');
  577. $objPHPExcel->getActiveSheet()->setCellValue('I' . $i, '');
  578. //居中
  579. $objPHPExcel->getActiveSheet()->getStyle('A' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  580. $objPHPExcel->getActiveSheet()->getStyle('B' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  581. $objPHPExcel->getActiveSheet()->getStyle('C' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  582. $objPHPExcel->getActiveSheet()->getStyle('D' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  583. $objPHPExcel->getActiveSheet()->getStyle('E' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  584. $objPHPExcel->getActiveSheet()->getStyle('F' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  585. $objPHPExcel->getActiveSheet()->getStyle('G' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  586. $objPHPExcel->getActiveSheet()->getStyle('H' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  587. $objPHPExcel->getActiveSheet()->getStyle('I' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  588. $objPHPExcel->getActiveSheet()->getStyle('A' . $i)->getFont()->setSize(13);
  589. $objPHPExcel->getActiveSheet()->getStyle('B' . $i)->getFont()->setSize(13);
  590. $objPHPExcel->getActiveSheet()->getStyle('C' . $i)->getFont()->setSize(13);
  591. $objPHPExcel->getActiveSheet()->getStyle('D' . $i)->getFont()->setSize(13);
  592. $objPHPExcel->getActiveSheet()->getStyle('E' . $i)->getFont()->setSize(13);
  593. $objPHPExcel->getActiveSheet()->getStyle('F' . $i)->getFont()->setSize(13);
  594. $objPHPExcel->getActiveSheet()->getStyle('G' . $i)->getFont()->setSize(13);
  595. $objPHPExcel->getActiveSheet()->getStyle('H' . $i)->getFont()->setSize(13);
  596. $objPHPExcel->getActiveSheet()->getStyle('I' . $i)->getFont()->setSize(13);
  597. }
  598. $fileName = $fileTitle;
  599. $objPHPExcel->getActiveSheet()->setTitle($fileName);
  600. $objPHPExcel->setActiveSheetIndex(0);
  601. $dir = './orderItemExcel/' . $mainId;
  602. if (file_exists($dir) == false) {
  603. mkdir($dir, 0777, true);
  604. }
  605. $date = $fileName;
  606. $file = $date . '.xls';
  607. $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
  608. if (file_exists($dir . '/' . $file)) {
  609. unlink($dir . '/' . $file);
  610. }
  611. $objWriter->save($dir . '/' . $file);
  612. $fileUrl = Yii::$app->params['ghsHost'] . '/orderItemExcel/' . $mainId . '/' . $file;
  613. util::success(['file' => $fileUrl, 'shortFile' => $file]);
  614. }
  615. }