Order.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <?php
  2. namespace app\common\model\order;
  3. use app\common\enum\order\OrderSourceEnum;
  4. use app\common\model\BaseModel;
  5. use app\common\enum\settings\DeliveryTypeEnum;
  6. use app\common\enum\order\OrderPayStatusEnum;
  7. use app\common\enum\order\OrderTypeEnum;
  8. use app\common\enum\order\OrderPayTypeEnum;
  9. use app\common\library\helper;
  10. use app\common\service\order\OrderService;
  11. use app\common\service\order\OrderCompleteService;
  12. use app\common\model\store\Order as StoreOrderModel;
  13. /**
  14. * 订单模型模型
  15. */
  16. class Order extends BaseModel
  17. {
  18. protected $pk = 'order_id';
  19. protected $name = 'order';
  20. /**
  21. * 追加字段
  22. * @var string[]
  23. */
  24. protected $append = [
  25. 'state_text',
  26. 'order_source_text',
  27. ];
  28. /**
  29. * 订单商品列表
  30. */
  31. public function product()
  32. {
  33. return $this->hasMany('app\\common\\model\\order\\OrderProduct', 'order_id', 'order_id')->hidden(['content']);
  34. }
  35. /**
  36. * 关联订单收货地址表
  37. */
  38. public function address()
  39. {
  40. return $this->hasOne('app\\common\\model\\order\\OrderAddress');
  41. }
  42. /**
  43. * 关联自提订单联系方式
  44. */
  45. public function extract()
  46. {
  47. return $this->hasOne('app\\common\\model\\order\\OrderExtract');
  48. }
  49. /**
  50. * 关联物流公司表
  51. */
  52. public function express()
  53. {
  54. return $this->belongsTo('app\\common\\model\\settings\\Express', 'express_id', 'express_id');
  55. }
  56. /**
  57. * 关联自提门店表
  58. */
  59. public function extractStore()
  60. {
  61. return $this->belongsTo('app\\common\\model\\store\\Store', 'extract_store_id', 'store_id');
  62. }
  63. /**
  64. * 关联门店店员表
  65. */
  66. public function extractClerk()
  67. {
  68. return $this->belongsTo('app\\common\\model\\store\\Clerk', 'extract_clerk_id');
  69. }
  70. /**
  71. * 关联用户表
  72. */
  73. public function user()
  74. {
  75. return $this->belongsTo('app\\common\\model\\user\\User', 'user_id', 'user_id');
  76. }
  77. /**
  78. * 关联用户表
  79. */
  80. public function room()
  81. {
  82. return $this->belongsTo('app\\common\\model\\plus\\live\\Room', 'room_id', 'room_id');
  83. }
  84. /**
  85. * 关联供应商表
  86. */
  87. public function supplier()
  88. {
  89. return $this->belongsTo('app\\common\\model\\supplier\\Supplier', 'shop_supplier_id', 'shop_supplier_id')->field(['shop_supplier_id', 'name','user_id']);
  90. }
  91. /**
  92. * 订单状态文字描述
  93. * @param $value
  94. * @param $data
  95. * @return string
  96. */
  97. public function getStateTextAttr($value, $data)
  98. {
  99. // 订单状态
  100. if (in_array($data['order_status'], [20, 30])) {
  101. $orderStatus = [20 => '已取消', 30 => '已完成'];
  102. return $orderStatus[$data['order_status']];
  103. }
  104. // 付款状态
  105. if ($data['pay_status'] == 10) {
  106. return '待付款';
  107. }
  108. // 拼团状态
  109. if($data['order_source'] == OrderSourceEnum::ASSEMBLE){
  110. $assemble_status = $this->getAssembleStatus($data);
  111. if($assemble_status != ''){
  112. return $assemble_status;
  113. }
  114. }
  115. // 发货状态
  116. if ($data['delivery_status'] == 10) {
  117. return '已付款,待发货';
  118. }
  119. if ($data['receipt_status'] == 10) {
  120. return '已发货,待收货';
  121. }
  122. return $value;
  123. }
  124. /**
  125. * 拼团订单状态
  126. */
  127. private function getAssembleStatus($data){
  128. // 发货状态
  129. if ($data['assemble_status'] == 10) {
  130. return '已付款,未成团';
  131. }
  132. if ($data['assemble_status'] == 20 && $data['delivery_status'] == 10) {
  133. return '拼团成功,待发货';
  134. }
  135. if ($data['assemble_status'] == 30) {
  136. return '拼团失败';
  137. }
  138. return '';
  139. }
  140. /**
  141. * 付款状态
  142. * @param $value
  143. * @return array
  144. */
  145. public function getPayTypeAttr($value)
  146. {
  147. return ['text' => OrderPayTypeEnum::data()[$value]['name'], 'value' => $value];
  148. }
  149. /**
  150. * 订单来源
  151. * @param $value
  152. * @return array
  153. */
  154. public function getOrderSourceTextAttr($value, $data)
  155. {
  156. return OrderSourceEnum::data()[$data['order_source']]['name'];
  157. }
  158. /**
  159. * 付款状态
  160. * @param $value
  161. * @return array
  162. */
  163. public function getPayStatusAttr($value)
  164. {
  165. return ['text' => OrderPayStatusEnum::data()[$value]['name'], 'value' => $value];
  166. }
  167. /**
  168. * 改价金额(差价)
  169. * @param $value
  170. * @return array
  171. */
  172. public function getUpdatePriceAttr($value)
  173. {
  174. return [
  175. 'symbol' => $value < 0 ? '-' : '+',
  176. 'value' => sprintf('%.2f', abs($value))
  177. ];
  178. }
  179. /**
  180. * 发货状态
  181. * @param $value
  182. * @return array
  183. */
  184. public function getDeliveryStatusAttr($value)
  185. {
  186. $status = [10 => '待发货', 20 => '已发货'];
  187. return ['text' => $status[$value], 'value' => $value];
  188. }
  189. /**
  190. * 收货状态
  191. * @param $value
  192. * @return array
  193. */
  194. public function getReceiptStatusAttr($value)
  195. {
  196. $status = [10 => '待收货', 20 => '已收货'];
  197. return ['text' => $status[$value], 'value' => $value];
  198. }
  199. /**
  200. * 收货状态
  201. * @param $value
  202. * @return array
  203. */
  204. public function getOrderStatusAttr($value)
  205. {
  206. $status = [10 => '进行中', 20 => '已取消', 21 => '待取消', 30 => '已完成'];
  207. return ['text' => $status[$value], 'value' => $value];
  208. }
  209. /**
  210. * 配送方式
  211. * @param $value
  212. * @return array
  213. */
  214. public function getDeliveryTypeAttr($value)
  215. {
  216. return ['text' => DeliveryTypeEnum::data()[$value]['name'], 'value' => $value];
  217. }
  218. /**
  219. * 订单详情
  220. * @param $where
  221. * @param string[] $with
  222. * @return array|\think\Model|null
  223. * @throws \think\db\exception\DataNotFoundException
  224. * @throws \think\db\exception\DbException
  225. * @throws \think\db\exception\ModelNotFoundException
  226. */
  227. public static function detail($where, $with = ['user', 'address', 'product' => ['image', 'refund'], 'extract', 'express', 'extractStore.logo', 'extractClerk', 'supplier'])
  228. {
  229. is_array($where) ? $filter = $where : $filter['order_id'] = (int)$where;
  230. return (new static())->with($with)->where($filter)->find();
  231. }
  232. /**
  233. * 订单详情
  234. */
  235. public static function detailByNo($order_no, $with = ['user', 'address', 'product' => ['image', 'refund'], 'extract', 'express', 'extractStore.logo', 'extractClerk', 'supplier'])
  236. {
  237. return (new static())->with($with)->where('order_no', '=', $order_no)->find();
  238. }
  239. /**
  240. * 批量获取订单列表
  241. */
  242. public function getListByIds($orderIds, $with = [])
  243. {
  244. $data = $this->getListByInArray('order_id', $orderIds, $with);
  245. return helper::arrayColumn2Key($data, 'order_id');
  246. }
  247. /**
  248. * 批量更新订单
  249. */
  250. public function onBatchUpdate($orderIds, $data)
  251. {
  252. return $this->where('order_id', 'in', $orderIds)->save($data);
  253. }
  254. /**
  255. * 批量获取订单列表
  256. */
  257. private function getListByInArray($field, $data, $with = [])
  258. {
  259. return $this->with($with)
  260. ->where($field, 'in', $data)
  261. ->where('is_delete', '=', 0)
  262. ->select();
  263. }
  264. /**
  265. * 生成订单号
  266. */
  267. public function orderNo()
  268. {
  269. return OrderService::createOrderNo();
  270. }
  271. /**
  272. * 确认核销(自提订单)
  273. */
  274. public function verificationOrder($extractClerkId)
  275. {
  276. if (
  277. $this['pay_status']['value'] != 20
  278. || $this['delivery_type']['value'] != DeliveryTypeEnum::EXTRACT
  279. || $this['delivery_status']['value'] == 20
  280. || in_array($this['order_status']['value'], [20, 21])
  281. ) {
  282. $this->error = '该订单不满足核销条件';
  283. return false;
  284. }
  285. return $this->transaction(function () use ($extractClerkId) {
  286. // 更新订单状态:已发货、已收货
  287. $status = $this->save([
  288. 'extract_clerk_id' => $extractClerkId, // 核销员
  289. 'delivery_status' => 20,
  290. 'delivery_time' => time(),
  291. 'receipt_status' => 20,
  292. 'receipt_time' => time(),
  293. 'order_status' => 30
  294. ]);
  295. // 新增订单核销记录
  296. StoreOrderModel::add(
  297. $this['order_id'],
  298. $this['extract_store_id'],
  299. $this['extract_clerk_id'],
  300. $this['shop_supplier_id'],
  301. OrderTypeEnum::MASTER
  302. );
  303. // 执行订单完成后的操作
  304. $OrderCompleteService = new OrderCompleteService(OrderTypeEnum::MASTER);
  305. $OrderCompleteService->complete([$this], static::$app_id);
  306. return $status;
  307. });
  308. }
  309. /**
  310. * 获取已付款订单总数 (可指定某天)
  311. */
  312. public function getOrderData($startDate = null, $endDate = null, $type, $shop_supplier_id = 0)
  313. {
  314. $model = $this;
  315. !is_null($startDate) && $model = $model->where('pay_time', '>=', strtotime($startDate));
  316. if(is_null($endDate)){
  317. !is_null($startDate) && $model = $model->where('pay_time', '<', strtotime($startDate) + 86400);
  318. }else{
  319. $model = $model->where('pay_time', '<', strtotime($endDate) + 86400);
  320. }
  321. if($shop_supplier_id > 0){
  322. $model = $model->where('shop_supplier_id', '=', $shop_supplier_id);
  323. }
  324. $model = $model->where('is_delete', '=', 0)
  325. ->where('pay_status', '=', 20)
  326. ->where('order_status', '<>', 20);
  327. if($type == 'order_total'){
  328. // 订单数量
  329. return $model->count();
  330. }else if($type == 'order_total_price'){
  331. // 订单总金额
  332. return $model->sum('pay_price');
  333. }else if($type == 'order_user_total'){
  334. // 支付用户数
  335. return count($model->distinct(true)->column('user_id'));
  336. }
  337. return 0;
  338. }
  339. /**
  340. * 修改订单价格
  341. */
  342. public function updatePrice($data)
  343. {
  344. if ($this['pay_status']['value'] != 10) {
  345. $this->error = '该订单不合法';
  346. return false;
  347. }
  348. if ($this['order_source'] != 10) {
  349. $this->error = '该订单不合法';
  350. return false;
  351. }
  352. // 实际付款金额
  353. $payPrice = bcadd($data['update_price'], $data['update_express_price'], 2);
  354. if ($payPrice <= 0) {
  355. $this->error = '订单实付款价格不能为0.00元';
  356. return false;
  357. }
  358. return $this->save([
  359. 'order_no' => $this->orderNo(), // 修改订单号, 否则微信支付提示重复
  360. 'order_price' => $data['update_price'],
  361. 'pay_price' => $payPrice,
  362. 'update_price' => helper::bcsub($data['update_price'], helper::bcsub($this['total_price'], $this['coupon_money'])),
  363. 'express_price' => $data['update_express_price']
  364. ]) !== false;
  365. }
  366. }