Order.php 12 KB

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