HangingOrderForm.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models\cashier;
  8. use app\models\Attr;
  9. use app\models\AttrGroup;
  10. use app\models\Goods;
  11. use app\models\HangingOrder;
  12. use app\models\HangingOrderDetail;
  13. use app\models\User;
  14. use app\modules\client\models\v1\common\CommonGoods;
  15. use yii\base\Model;
  16. use yii\helpers\Json;
  17. class HangingOrderForm extends Model
  18. {
  19. public $store_id;
  20. public $md_id;
  21. public $user_id;
  22. public $goods_list;//[{goods_id:2,num:1,attr:[{"attr_id":1,"attr_group_id":1}]}]
  23. public $id = 0;// 可以是挂单ID 也可以是挂单商品ID
  24. public $order_no;
  25. public $dateStart;
  26. public $dateEnd;
  27. public $goods_name;
  28. /**
  29. * 订单挂单
  30. * @return array
  31. * User: hankaige
  32. * DATE TIME: 2022/12/5 13:36
  33. */
  34. public function hangingOrder(): array
  35. {
  36. $t = \Yii::$app->db->beginTransaction();
  37. // 需要下检测一下商品
  38. $totalPrice = 0;
  39. $orderGoods = [];
  40. // var_dump($this->goods_list);die;
  41. foreach($this->goods_list as $value){
  42. // 商品数据
  43. $goods = Goods::findOne($value['goods_id']);
  44. // 购买商品的规格数据
  45. $attr = [];
  46. foreach ($value['attr'] as $attrItem) {
  47. if (!empty($attrItem['attr_id'])) {
  48. $attr[] = intval($attrItem['attr_id']);
  49. }
  50. }
  51. // 根据规格获取商品的库存及规格价格信息
  52. $attr_info = $goods->getAttrInfo($attr);
  53. if ($value['new_price'] > 0) {
  54. $goods->price = $attr_info['price'] = $value['new_price'];
  55. }
  56. $goodsPrice = sprintf('%.2f',($goods->use_attr ? $attr_info['price'] : $goods->price) * $value['num']);
  57. // 整理detail数据
  58. $dataItem = [
  59. 'goods_id' => $goods->id,
  60. 'goods_name' => $goods->name,
  61. 'num' => $value['num'],
  62. 'total_price' => $goodsPrice,
  63. 'attr' => json_encode($attr, JSON_UNESCAPED_UNICODE),
  64. 'new_price' => $value['new_price'] ?: 0
  65. ];
  66. $orderGoods[] = $dataItem;
  67. // 商品的价格乘以商品的数量
  68. $totalPrice += $goodsPrice;
  69. }
  70. try {
  71. if($this->id > 0){
  72. $hangingOrder = HangingOrder::findOne($this->id);
  73. }else{
  74. $hangingOrder = new HangingOrder();
  75. }
  76. if (!$this->user_id) {
  77. return [
  78. 'code' => 1,
  79. 'msg' => '生成挂单记录失败,挂单用户id不能为空'
  80. ];
  81. }
  82. $hangingOrder->store_id = $this->store_id;
  83. $hangingOrder->user_id = $this->user_id;
  84. $hangingOrder->md_id = $this->md_id > 0 ? $this->md_id : 0;
  85. if($this->id <= 0){
  86. // 不修改原来的挂单订单编号
  87. $hangingOrder->order_no = self::createOrderNo();
  88. }
  89. $hangingOrder->total_price = $totalPrice;
  90. $hangingOrder->create_at = time();
  91. $hangingOrder->is_delete = 0;
  92. $hangingOrder->status = 0;
  93. if(!$hangingOrder->save()){
  94. $t->rollBack();
  95. return [
  96. 'code' => 1,
  97. 'msg' => '生成挂单记录失败',
  98. 'data' => $hangingOrder->getErrors()
  99. ];
  100. }
  101. // 先删除之前所有挂单商品
  102. if($this->id > 0){
  103. HangingOrderDetail::updateAll(['is_delete'=>1],['order_id'=>$hangingOrder->id]);
  104. }
  105. // 处理挂单商品信息
  106. foreach($orderGoods as $detailItem){
  107. $hangingOrderDetail = new HangingOrderDetail();
  108. $hangingOrderDetail->order_id = $hangingOrder->id;
  109. $hangingOrderDetail->goods_id = $detailItem['goods_id'];
  110. $hangingOrderDetail->num = $detailItem['num'];
  111. $hangingOrderDetail->attr = $detailItem['attr'];
  112. $hangingOrderDetail->total_price = $detailItem['total_price'];
  113. $hangingOrderDetail->new_price = $detailItem['new_price'];
  114. $hangingOrderDetail->is_delete = 0;
  115. if(!$hangingOrderDetail->save()){
  116. $t->rollBack();
  117. return [
  118. 'code' => 1,
  119. 'data' => $hangingOrderDetail->getErrors()
  120. ];
  121. }
  122. }
  123. $t->commit();
  124. return [
  125. 'code' => 0,
  126. 'data' => '订单已挂起'
  127. ];
  128. }catch (\Exception $e){
  129. $t->rollBack();
  130. return [
  131. 'code' => 1,
  132. 'msg' => $e->getMessage()
  133. ];
  134. }
  135. }
  136. /**
  137. * 生成订单号
  138. * @return string
  139. * User: hankaige
  140. * DATE TIME: 2022/12/5 15:11
  141. */
  142. private static function createOrderNo(): string{
  143. $order_no = null;
  144. while (true) {
  145. $order_no = HangingOrder::ORDER_PREFIX.date('YmdHis') . mt_rand(100000, 999999);
  146. $exist_order_no = HangingOrder::find()->where(['order_no' => $order_no])->exists();
  147. if (!$exist_order_no) {
  148. break;
  149. }
  150. }
  151. return $order_no;
  152. }
  153. /**
  154. * 获取挂单订单列表
  155. * @return array
  156. * User: hankaige
  157. * DATE TIME: 2022/12/6 09:31
  158. */
  159. public function getList(): array{
  160. $query = HangingOrder::find()->with(['orderDetail','user'])->where(['is_delete'=>0,'store_id'=>$this->store_id]);
  161. if($this->user_id > 0){
  162. $query->andWhere(['user_id'=>$this->user_id]);
  163. }
  164. if($this->order_no){
  165. $query->andWhere(['like','order_no' , $this->order_no]);
  166. }
  167. if($this->dateStart){
  168. $query->andWhere(['>=', 'create_at', strtotime($this->dateStart)]);
  169. }
  170. if($this->dateEnd){
  171. $query->andWhere(['<=', 'create_at', strtotime($this->dateEnd)]);
  172. }
  173. if($this->md_id){
  174. $query->andWhere(['md_id' => $this->md_id]);
  175. }
  176. $query->orderBy('create_at DESC');
  177. $list = pagination_make($query);
  178. foreach($list['list'] as &$item){
  179. foreach ($item['orderDetail'] as &$value){
  180. $goods = Goods::findOne([
  181. 'id' => $value['goods_id'],
  182. 'is_delete' => 0,
  183. 'status' => 1,
  184. ]);
  185. if (!$goods) {
  186. continue;
  187. }
  188. $goods_id_list[] = $value['goods_id'];
  189. $attr_list = Attr::find()->alias('a')
  190. ->select('ag.attr_group_name,a.attr_name,a.id as attr_id,a.attr_group_id')
  191. ->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id')
  192. ->where(['a.id' => json_decode($value['attr'], true)])
  193. ->asArray()->all();
  194. $attr = $goods->attr;
  195. $price = $goods->price;
  196. $goodsData = [
  197. 'attr' => $attr,
  198. 'price' => $price,
  199. 'is_level' => $goods->is_level,
  200. 'use_attr' => $goods->use_attr,
  201. ];
  202. $user_id = $item['user_id'];
  203. $user = User::findOne($user_id);
  204. if ($user) {
  205. \Yii::$app->jwt->setUser($user);
  206. }
  207. $goods_attr_info = CommonGoods::currentGoodsAttr($goodsData, (array) json_decode($value['attr'], true));
  208. $goods_pic = isset($goods_attr_info['pic']) && !empty($goods_attr_info['pic']) ? $goods->getGoodsPic(0)->pic_url : $goods->cover_pic;
  209. $value['total_price'] = sprintf('%.2f', ($goods_attr_info['level_price'] * $value['num']));
  210. $value['goods_name'] = $goods->name;
  211. $value['attr_list'] = $attr_list;
  212. $value['goods_pic'] = $goods_pic;
  213. }
  214. $total_price_arr = array_column($item['orderDetail'], 'total_price');
  215. $item['total_price'] = round(array_sum($total_price_arr), 2);
  216. $item['create_at'] = date('Y-m-d H:i:s',$item['create_at']);
  217. }
  218. return [
  219. 'code' => 0,
  220. 'data' => $list
  221. ];
  222. }
  223. // 获取挂单商品列表
  224. public function getOrderDetail(){
  225. if(empty($this->id)){
  226. return ['code' => 1,'msg' => '挂单订单ID有误'];
  227. }
  228. $query = HangingOrderDetail::find()->alias('hod')->leftJoin(['g'=>Goods::tableName()],'hod.goods_id = g.id')->where(['hod.order_id'=>$this->id,'hod.is_delete'=>0]);
  229. if($this->goods_name){
  230. $query->andWhere(['like','g.name',$this->goods_name]);
  231. }
  232. $list = $query->select('hod.*,g.name')->asArray()->all();
  233. $hangingOrder = HangingOrder::findOne($this->id);
  234. if ($hangingOrder) {
  235. $user_id = $hangingOrder->user_id;
  236. $user = User::findOne($user_id);
  237. if ($user) {
  238. \Yii::$app->jwt->setUser($user);
  239. }
  240. }
  241. foreach ($list as &$value){
  242. $goods = Goods::findOne([
  243. 'id' => $value['goods_id'],
  244. 'is_delete' => 0,
  245. 'status' => 1,
  246. ]);
  247. if (!$goods) {
  248. continue;
  249. }
  250. $goods_id_list[] = $value['goods_id'];
  251. $attr_list = Attr::find()->alias('a')
  252. ->select('ag.attr_group_name,a.attr_name,a.id as attr_id,a.attr_group_id')
  253. ->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id')
  254. ->where(['a.id' => json_decode($value['attr'], true)])
  255. ->asArray()->all();
  256. $attr = $goods->attr;
  257. $price = $goods->price;
  258. if ($value['new_price'] > 0) {
  259. $mch_attr_id = json_decode($value['attr'], true);
  260. sort($mch_attr_id);
  261. $attr_ = json_decode($attr, true);
  262. foreach ($attr_ as &$goods_attr_item) {
  263. $goods_attr_id = array_column($goods_attr_item['attr_list'], 'attr_id');
  264. sort($goods_attr_id);
  265. if (!array_diff($goods_attr_id, $mch_attr_id)) {
  266. $goods_attr_item['price'] = $value['new_price'];
  267. }
  268. }
  269. $attr = json_encode($attr_, JSON_UNESCAPED_UNICODE);
  270. $price = $value['new_price'];
  271. }
  272. $goodsData = [
  273. 'attr' => $attr,
  274. 'price' => $price,
  275. 'is_level' => $goods->is_level,
  276. 'use_attr' => $goods->use_attr,
  277. ];
  278. $goods_attr_info = CommonGoods::currentGoodsAttr($goodsData, (array) json_decode($value['attr'], true));
  279. $goods_pic = isset($goods_attr_info['pic']) && !empty($goods_attr_info['pic']) ? $goods->getGoodsPic(0)->pic_url : $goods->cover_pic;
  280. $value['goods_name'] = $goods->name;
  281. $value['attr_list'] = $attr_list;
  282. $value['price'] = isset($goods_attr_info['level_price']) && !empty($goods_attr_info['level_price']) ? $goods_attr_info['level_price'] : $goods->price;
  283. foreach($attr_list as $m){
  284. $value['attr_text'] .= $m['attr_name'].' ';
  285. }
  286. $warn_goods_timeout = Goods::warn_goods_timeout($goods->store_id);
  287. $value['timeout_day'] = $goods->time_made_day ? date('Y-m-d', $goods->time_made_day + 86400 * $goods->time_shelf_life) : '--';
  288. $value['is_warn_goods_timeout'] = ($goods->time_made_day && ($goods->time_made_day + 86400 * $goods->time_shelf_life) < (time() + $warn_goods_timeout * 86400)) ? 1 : 0;
  289. $value['total_price'] = $value['price'] * $value['num'];
  290. $value['pic'] = $goods_pic;
  291. }
  292. return [
  293. 'code' => 0,
  294. 'data' => $list
  295. ];
  296. }
  297. /**
  298. * 删除挂单订单
  299. * @return array
  300. * User: hankaige
  301. * DATE TIME: 2022/12/6 09:36
  302. */
  303. public function delHanging(): array
  304. {
  305. if(empty($this->id)){
  306. return ['code' => 1,'msg'=>'订单ID错误'];
  307. }
  308. $hangingModel = HangingOrder::findOne($this->id);
  309. if(!$hangingModel){
  310. return ['code' => 1, 'msg' => '挂单不存在,请刷新再试'];
  311. }
  312. $t = \Yii::$app->db->beginTransaction();
  313. try {
  314. $hangingModel->is_delete = 1;
  315. if(!$hangingModel->save()){
  316. $t->rollBack();
  317. return ['code' => 1, 'msg' => '删除失败'];
  318. }
  319. HangingOrderDetail::updateAll(['is_delete'=>1],['order_id'=>$this->id]);
  320. $t->commit();
  321. return ['code' => 0, 'msg' => '挂单订单删除成功'];
  322. }catch (\Exception $e){
  323. $t->rollBack();
  324. return ['code' => 1, 'msg' => '系统错误', 'data' => $e->getMessage()];
  325. }
  326. }
  327. /**
  328. * 删除挂单订单商品
  329. * @return array
  330. * User: hankaige
  331. * DATE TIME: 2022/12/6 14:16
  332. */
  333. public function delHangingOrderDetail(): array
  334. {
  335. if(empty($this->id)){
  336. return ['code' => 1,'msg'=>'订单商品ID错误'];
  337. }
  338. $hangingOrderDetail = HangingOrderDetail::findOne($this->id);
  339. if(empty($hangingOrderDetail)){
  340. return ['code' => 1,'msg'=>'挂单订单商品不存在'];
  341. }
  342. $t = \Yii::$app->db->beginTransaction();
  343. try {
  344. $hangingOrderDetail->is_delete = 1;
  345. if(!$hangingOrderDetail->save()){
  346. $t->rollBack();
  347. return ['code'=>1,'msg'=>'挂单商品不存在'];
  348. }
  349. // 修改挂单
  350. $hangingOrderDetailAll = HangingOrderDetail::find()->where(['order_id'=>$hangingOrderDetail->order_id,'is_delete'=>0])->asArray()->all();
  351. $hangingOrder = HangingOrder::findOne($hangingOrderDetail->order_id);
  352. $hangingOrder->total_price = array_sum(array_column($hangingOrderDetailAll,'total_price'));
  353. if(!$hangingOrder->save()){
  354. $t->rollBack();
  355. return ['code'=>1,'msg'=>'修改挂单信息失败'];
  356. }
  357. $t->commit();
  358. return ['code'=>0,'msg'=>'删除挂单商品成功','data'=>['total_price'=>$hangingOrder->total_price]];
  359. }catch (\Exception $e){
  360. $t->rollBack();
  361. return ['code' => 1, 'msg' => '系统错误', 'data' => $e->getMessage()];
  362. }
  363. }
  364. /**
  365. * 取出挂单商品信息
  366. * @return array
  367. * User: hankaige
  368. * DATE TIME: 2022/12/6 14:47
  369. */
  370. public function getHangingOrder(){
  371. if(empty($this->id)){
  372. return ['code' => 1,'msg'=>'订单ID错误'];
  373. }
  374. $hangingOrder = HangingOrder::find()->where(['id'=>$this->id])->with(['orderDetail','user'])->asArray()->one();
  375. if ($hangingOrder) {
  376. $user_id = $hangingOrder['user_id'];
  377. $user = User::findOne($user_id);
  378. if ($user) {
  379. \Yii::$app->jwt->setUser($user);
  380. }
  381. }
  382. // 处理商品规格
  383. foreach($hangingOrder['orderDetail'] as &$item){
  384. $goods = Goods::findOne($item['goods_id']);
  385. $item['attr_list'] = Attr::find()->alias('a')
  386. ->select('ag.attr_group_name,a.attr_name,a.id as attr_id,a.attr_group_id')
  387. ->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id')
  388. ->where(['a.id' => json_decode($item['attr'], true)])
  389. ->asArray()->all();
  390. $attr = $goods->attr;
  391. $price = $goods->price;
  392. $mch_attr_id = json_decode($item['attr'], true);
  393. sort($mch_attr_id);
  394. $attr_ = json_decode($attr, true);
  395. foreach ($attr_ as &$goods_attr_item) {
  396. $goods_attr_id = array_column($goods_attr_item['attr_list'], 'attr_id');
  397. sort($goods_attr_id);
  398. if (!array_diff($goods_attr_id, $mch_attr_id)) {
  399. $goods_attr_item['price'] = $item['new_price'];
  400. if ($goods_attr_item['old_price']) {
  401. $item['old_price'] = $goods_attr_item['old_price'];
  402. }
  403. }
  404. }
  405. $attr = json_encode($attr_, JSON_UNESCAPED_UNICODE);
  406. // $price = $item['new_price'];
  407. $goodsData = [
  408. 'attr' => $attr,
  409. 'price' => $price,
  410. 'is_level' => $goods->is_level,
  411. 'use_attr' => $goods->use_attr,
  412. ];
  413. $goods_attr_info = CommonGoods::currentGoodsAttr($goodsData, (array) json_decode($item['attr'], true));
  414. $item['pic'] = isset($goods_attr_info['pic']) && !empty($goods_attr_info['pic']) ? $goods->getGoodsPic(0)->pic_url : $goods->cover_pic;
  415. $item['name'] = $goods->name;
  416. $item['price'] = isset($goods_attr_info['price']) && !empty($goods_attr_info['price']) ? $goods_attr_info['price'] : $goods->price;
  417. $item['goods_id'] = $goods->id;
  418. $item['level_price'] = sprintf('%.2f', $goods_attr_info['level_price']);
  419. }
  420. return [
  421. 'code'=>0,
  422. 'msg' => '获取数据成功',
  423. 'data'=> $hangingOrder
  424. ];
  425. }
  426. }