Order.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. <?php
  2. namespace app\common\model;
  3. use think\Hook;
  4. use app\common\model\store\shop\Order as ShopOrder;
  5. use app\common\service\Order as OrderService;
  6. use app\common\service\order\Complete as OrderCompleteService;
  7. use app\common\enum\OrderType as OrderTypeEnum;
  8. use app\common\enum\DeliveryType as DeliveryTypeEnum;
  9. use app\common\enum\order\PayType as PayTypeEnum;
  10. use app\common\enum\order\PayStatus as PayStatusEnum;
  11. use app\common\library\helper;
  12. /**
  13. * 订单模型
  14. * Class Order
  15. * @package app\common\model
  16. */
  17. class Order extends BaseModel
  18. {
  19. protected $name = 'order';
  20. protected $alias = 'order';
  21. /**
  22. * 追加字段
  23. * @var array
  24. */
  25. protected $append = [
  26. 'state_text', // 售后单状态文字描述
  27. ];
  28. /**
  29. * 订单模型初始化
  30. */
  31. public static function init()
  32. {
  33. parent::init();
  34. // 监听订单处理事件
  35. $static = new static;
  36. Hook::listen('order', $static);
  37. }
  38. /**
  39. * 订单商品列表
  40. * @return \think\model\relation\HasMany
  41. */
  42. public function goods()
  43. {
  44. $module = self::getCalledModule() ?: 'common';
  45. return $this->hasMany("app\\{$module}\\model\\OrderGoods");
  46. }
  47. /**
  48. * 关联订单收货地址表
  49. * @return \think\model\relation\HasOne
  50. */
  51. public function address()
  52. {
  53. $module = self::getCalledModule() ?: 'common';
  54. return $this->hasOne("app\\{$module}\\model\\OrderAddress");
  55. }
  56. /**
  57. * 关联订单收货地址表
  58. * @return \think\model\relation\HasOne
  59. */
  60. public function extract()
  61. {
  62. $module = self::getCalledModule() ?: 'common';
  63. return $this->hasOne("app\\{$module}\\model\\OrderExtract");
  64. }
  65. /**
  66. * 关联自提门店表
  67. * @return \think\model\relation\BelongsTo
  68. */
  69. public function extractShop()
  70. {
  71. $module = self::getCalledModule() ?: 'common';
  72. return $this->belongsTo("app\\{$module}\\model\\store\\Shop", 'extract_shop_id');
  73. }
  74. /**
  75. * 关联门店店员表
  76. * @return \think\model\relation\BelongsTo
  77. */
  78. public function extractClerk()
  79. {
  80. $module = self::getCalledModule() ?: 'common';
  81. return $this->belongsTo("app\\{$module}\\model\\store\\shop\\Clerk", 'extract_clerk_id');
  82. }
  83. /**
  84. * 关联用户表
  85. * @return \think\model\relation\BelongsTo
  86. */
  87. public function user()
  88. {
  89. $module = self::getCalledModule() ?: 'common';
  90. return $this->belongsTo("app\\{$module}\\model\\User");
  91. }
  92. /**
  93. * 关联物流公司表
  94. * @return \think\model\relation\BelongsTo
  95. */
  96. public function express()
  97. {
  98. $module = self::getCalledModule() ?: 'common';
  99. return $this->belongsTo("app\\{$module}\\model\\Express");
  100. }
  101. /**
  102. * 订单状态文字描述
  103. * @param $value
  104. * @param $data
  105. * @return string
  106. */
  107. public function getStateTextAttr($value, $data)
  108. {
  109. // 订单状态
  110. if (in_array($data['order_status'], [20, 30])) {
  111. $orderStatus = [20 => '已取消', 30 => '已完成'];
  112. return $orderStatus[$data['order_status']];
  113. }
  114. // 付款状态
  115. if ($data['pay_status'] == 10) {
  116. return '待付款';
  117. }
  118. // 订单类型:单独购买
  119. if ($data['delivery_status'] == 10) {
  120. return '已付款,待发货';
  121. }
  122. if ($data['receipt_status'] == 10) {
  123. return '已发货,待收货';
  124. }
  125. return $value;
  126. }
  127. /**
  128. * 获取器:订单金额(含优惠折扣)
  129. * @param $value
  130. * @param $data
  131. * @return string
  132. */
  133. public function getOrderPriceAttr($value, $data)
  134. {
  135. // 兼容旧数据:订单金额
  136. if ($value == 0) {
  137. return helper::bcadd(helper::bcsub($data['total_price'], $data['coupon_money']), $data['update_price']);
  138. }
  139. return $value;
  140. }
  141. /**
  142. * 改价金额(差价)
  143. * @param $value
  144. * @return array
  145. */
  146. public function getUpdatePriceAttr($value)
  147. {
  148. return [
  149. 'symbol' => $value < 0 ? '-' : '+',
  150. 'value' => sprintf('%.2f', abs($value))
  151. ];
  152. }
  153. /**
  154. * 付款状态
  155. * @param $value
  156. * @return array
  157. */
  158. public function getPayTypeAttr($value)
  159. {
  160. return ['text' => PayTypeEnum::data()[$value]['name'], 'value' => $value];
  161. }
  162. /**
  163. * 付款状态
  164. * @param $value
  165. * @return array
  166. */
  167. public function getPayStatusAttr($value)
  168. {
  169. return ['text' => PayStatusEnum::data()[$value]['name'], 'value' => $value];
  170. }
  171. /**
  172. * 发货状态
  173. * @param $value
  174. * @return array
  175. */
  176. public function getDeliveryStatusAttr($value)
  177. {
  178. $status = [10 => '待发货', 20 => '已发货'];
  179. return ['text' => $status[$value], 'value' => $value];
  180. }
  181. /**
  182. * 收货状态
  183. * @param $value
  184. * @return array
  185. */
  186. public function getReceiptStatusAttr($value)
  187. {
  188. $status = [10 => '待收货', 20 => '已收货'];
  189. return ['text' => $status[$value], 'value' => $value];
  190. }
  191. /**
  192. * 收货状态
  193. * @param $value
  194. * @return array
  195. */
  196. public function getOrderStatusAttr($value)
  197. {
  198. $status = [10 => '进行中', 20 => '已取消', 21 => '待取消', 30 => '已完成'];
  199. return ['text' => $status[$value], 'value' => $value];
  200. }
  201. /**
  202. * 配送方式
  203. * @param $value
  204. * @return array
  205. */
  206. public function getDeliveryTypeAttr($value)
  207. {
  208. return ['text' => DeliveryTypeEnum::data()[$value]['name'], 'value' => $value];
  209. }
  210. /**
  211. * 生成订单号
  212. * @return string
  213. */
  214. public function orderNo()
  215. {
  216. return OrderService::createOrderNo();
  217. }
  218. /**
  219. * 订单详情
  220. * @param array|int $where
  221. * @param array $with
  222. * @return null|static
  223. * @throws \think\exception\DbException
  224. */
  225. public static function detail($where, $with = [
  226. 'user',
  227. 'address',
  228. 'goods' => ['image'],
  229. 'extract',
  230. 'express',
  231. 'extract_shop.logo',
  232. 'extract_clerk'
  233. ])
  234. {
  235. is_array($where) ? $filter = $where : $filter['order_id'] = (int)$where;
  236. return self::get($filter, $with);
  237. }
  238. /**
  239. * 批量获取订单列表
  240. * @param $orderIds
  241. * @param array $with 关联查询
  242. * @return array
  243. * @throws \think\db\exception\DataNotFoundException
  244. * @throws \think\db\exception\ModelNotFoundException
  245. * @throws \think\exception\DbException
  246. */
  247. public function getListByIds($orderIds, $with = [])
  248. {
  249. $data = $this->getListByInArray('order_id', $orderIds, $with);
  250. return helper::arrayColumn2Key($data, 'order_id');
  251. }
  252. /**
  253. * 批量获取订单列表
  254. * @param string $field
  255. * @param array $data
  256. * @param array $with
  257. * @return false|\PDOStatement|string|\think\Collection
  258. * @throws \think\db\exception\DataNotFoundException
  259. * @throws \think\db\exception\ModelNotFoundException
  260. * @throws \think\exception\DbException
  261. */
  262. private function getListByInArray($field, $data, $with = [])
  263. {
  264. return $this->with($with)
  265. ->where($field, 'in', $data)
  266. ->where('is_delete', '=', 0)
  267. ->select();
  268. }
  269. /**
  270. * 根据订单号批量查询
  271. * @param $orderNos
  272. * @param array $with
  273. * @return false|\PDOStatement|string|\think\Collection
  274. * @throws \think\db\exception\DataNotFoundException
  275. * @throws \think\db\exception\ModelNotFoundException
  276. * @throws \think\exception\DbException
  277. */
  278. public function getListByOrderNos($orderNos, $with = [])
  279. {
  280. return $this->getListByInArray('order_no', $orderNos, $with);
  281. }
  282. /**
  283. * 批量更新订单
  284. * @param $orderIds
  285. * @param $data
  286. * @return false|int
  287. */
  288. public function onBatchUpdate($orderIds, $data)
  289. {
  290. return $this->isUpdate(true)->save($data, ['order_id' => ['in', $orderIds]]);
  291. }
  292. /**
  293. * 确认核销(自提订单)
  294. * @param int $extractClerkId 核销员id
  295. * @return bool|false|int
  296. */
  297. public function verificationOrder($extractClerkId)
  298. {
  299. if (
  300. $this['pay_status']['value'] != 20
  301. || $this['delivery_type']['value'] != DeliveryTypeEnum::EXTRACT
  302. || $this['delivery_status']['value'] == 20
  303. || in_array($this['order_status']['value'], [20, 21])
  304. ) {
  305. $this->error = '该订单不满足核销条件';
  306. return false;
  307. }
  308. return $this->transaction(function () use ($extractClerkId) {
  309. // 更新订单状态:已发货、已收货
  310. $status = $this->save([
  311. 'extract_clerk_id' => $extractClerkId, // 核销员
  312. 'delivery_status' => 20,
  313. 'delivery_time' => time(),
  314. 'receipt_status' => 20,
  315. 'receipt_time' => time(),
  316. 'order_status' => 30
  317. ]);
  318. // 新增订单核销记录
  319. ShopOrder::add(
  320. $this['order_id'],
  321. $this['extract_shop_id'],
  322. $this['extract_clerk_id'],
  323. OrderTypeEnum::MASTER
  324. );
  325. // 执行订单完成后的操作
  326. $OrderCompleteService = new OrderCompleteService(OrderTypeEnum::MASTER);
  327. $OrderCompleteService->complete([$this], static::$wxapp_id);
  328. return $status;
  329. });
  330. }
  331. }