Order.php 12 KB

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