Order.php 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\api\model;
  13. use app\api\model\Goods as GoodsModel;
  14. use app\api\model\kj\KjActivityGood;
  15. use app\api\model\kj\KjActivityJoin;
  16. use app\api\model\OrderGoods as OrderGoodsModel;
  17. use app\api\model\Setting as SettingModel;
  18. use app\api\model\GoodsSku as GoodsSkuModel;
  19. use app\api\model\user\CommissionsDetail as CommissionsDetailApi;
  20. use app\api\model\user\CommissionsDetail;
  21. use app\api\service\User as UserService;
  22. use app\api\service\Payment as PaymentService;
  23. use app\api\service\order\PaySuccess as OrderPaySuccesService;
  24. use app\api\service\order\source\Factory as OrderSourceFactory;
  25. use app\common\enum\order\PayType;
  26. use app\common\enum\order\refund\RefundStatus as RefundStatusEnum;
  27. use app\common\model\Order as OrderModel;
  28. use app\common\service\Order as OrderService;
  29. use app\common\enum\Setting as SettingEnum;
  30. use app\common\enum\OrderType as OrderTypeEnum;
  31. use app\common\enum\order\PayType as OrderPayTypeEnum;
  32. use app\common\enum\order\PayStatus as PayStatusEnum;
  33. use app\common\enum\order\OrderStatus as OrderStatusEnum;
  34. use app\common\enum\order\ReceiptStatus as ReceiptStatusEnum;
  35. use app\common\enum\order\DeliveryStatus as DeliveryStatusEnum;
  36. use app\common\library\helper;
  37. use app\common\exception\BaseException;
  38. use app\common\model\groupbuy\GroupBuyJoin;
  39. use app\common\model\groupbuy\GroupBuyActivity;
  40. use app\common\model\groupbuy\GroupBuyGoods;
  41. use app\common\model\groupbuy\GroupBuyHelp;
  42. use app\common\model\groupbuylb\GroupBuyLbJoin;
  43. use app\common\model\groupbuylb\GroupBuyLbActivity;
  44. use app\common\model\groupbuylb\GroupBuyLbGoods;
  45. use app\common\model\groupbuylb\GroupBuyLbHelp;
  46. use app\common\model\ms\MsActivityGood;
  47. use app\common\model\ms\MsActivity;
  48. use app\common\enum\order\OrderSource as OrderSourceEnum;
  49. use app\api\model\za\{ZaActivityGood,ZaActivityRelation,ZaActivity};
  50. /**
  51. * 订单模型
  52. * Class Order
  53. * @package app\api\model
  54. */
  55. class Order extends OrderModel
  56. {
  57. /**
  58. * 隐藏字段
  59. * @var array
  60. */
  61. protected $hidden = [
  62. 'store_id',
  63. 'update_time'
  64. ];
  65. /**
  66. * 追加字段
  67. * @var array
  68. */
  69. protected $append = [
  70. 'state_text', // 售后单状态文字描述
  71. 'state_value', // 售后状态码 20已取消 30已完成 11待支付 12待收货未发货 13待收货已发货
  72. 'djs_time', // 待支付倒计时(时间戳)
  73. 'dsh_time', // 待收货倒计时(时间戳)
  74. ];
  75. /**
  76. * 待支付订单详情
  77. * @param string $orderNo 订单号
  78. * @return null|static
  79. */
  80. public static function getPayDetail(string $orderNo)
  81. {
  82. return self::detail(['order_no' => $orderNo, 'pay_status' => 10, 'is_delete' => 0], ['goods', 'user']);
  83. }
  84. /**
  85. * 订单支付事件
  86. * @param int $payType
  87. * @return bool
  88. */
  89. public function onPay(int $payType = OrderPayTypeEnum::WECHAT)
  90. {
  91. // 判断订单状态
  92. $orderSource = OrderSourceFactory::getFactory($this['order_source']);
  93. if (!$orderSource->checkOrderStatusOnPay($this)) {
  94. $this->error = $orderSource->getError();
  95. return false;
  96. }
  97. // 余额支付
  98. if ($payType == OrderPayTypeEnum::BALANCE) {
  99. return $this->onPaymentByBalance($this['order_no']);
  100. }
  101. return true;
  102. }
  103. /**
  104. * 构建支付请求的参数
  105. * @param self $order 订单信息
  106. * @param string $payType 订单支付方式
  107. * @return array
  108. * @throws BaseException
  109. * @throws \think\db\exception\DataNotFoundException
  110. * @throws \think\db\exception\DbException
  111. * @throws \think\db\exception\ModelNotFoundException
  112. */
  113. public function onOrderPayment(self $order, int $payType)
  114. {
  115. if ($payType == OrderPayTypeEnum::WECHAT) {
  116. if($order['order_source']!=OrderTypeEnum::ZA){
  117. return $this->onPaymentByWechat($order);
  118. }
  119. return $this->onPrePayByWechat($order,$order['order_source']);
  120. }
  121. return [];
  122. }
  123. // 预调起支付
  124. public function onPrePayByWechat(array $order,$order_type){
  125. return PaymentService::wechat(
  126. $order['order_id'],
  127. $order['order_no'],
  128. $order['pay_price'],
  129. $order_type
  130. // OrderTypeEnum::ORDER
  131. );
  132. }
  133. /**
  134. * 构建微信支付请求
  135. * @param self $order 订单详情
  136. * @return array
  137. * @throws BaseException
  138. * @throws \think\db\exception\DataNotFoundException
  139. * @throws \think\db\exception\DbException
  140. * @throws \think\db\exception\ModelNotFoundException
  141. */
  142. protected function onPaymentByWechat(self $order)
  143. {
  144. return PaymentService::wechat(
  145. $order['order_id'],
  146. $order['order_no'],
  147. $order['pay_price'],
  148. OrderTypeEnum::ORDER
  149. );
  150. }
  151. /**
  152. * 立即购买:获取订单商品列表
  153. * @param int $goodsId 商品ID
  154. * @param string $goodsSkuId 商品SKU
  155. * @param int $goodsNum 购买数量
  156. * @param int $staffUserId 分享链接用户ID 可不传
  157. * @return mixed
  158. * @throws BaseException
  159. */
  160. public function getOrderGoodsListByNow(int $goodsId, string $goodsSkuId, int $goodsNum, int $staffUserId = 0)
  161. {
  162. // 获取商品列表
  163. $model = new GoodsModel;
  164. $goodsList = $model->getListByIdsFromApi([$goodsId]);
  165. if ($goodsList->isEmpty()) {
  166. throwError('未找到商品信息2');
  167. }
  168. // 隐藏冗余的属性
  169. $goodsList->hidden(array_merge($model->hidden, ['content', 'goods_images', 'images']));
  170. // 返回商品处理
  171. // 获取链接分享者的用户ID和店铺ID
  172. $data = $this->getStaffUserId($staffUserId);
  173. foreach ($goodsList as &$item) {
  174. // 商品sku信息
  175. $item['skuInfo'] = GoodsSkuModel::detail($item['goods_id'], $goodsSkuId);
  176. // 商品单价
  177. $item['goods_price'] = $item['skuInfo']['goods_price'];
  178. // 商品购买数量
  179. $item['total_num'] = $goodsNum;
  180. // 商品SKU索引
  181. $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
  182. // 商品购买总金额
  183. $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
  184. $item['staffUserId'] = $data['staffUserId'];
  185. $item['shopId'] = $data['shopId'];
  186. $item['distributorRadio'] = $data['distributorRadio'];
  187. }
  188. return $goodsList;
  189. }
  190. /**
  191. * 立即购买:获取订单商品列表
  192. * @param int $goodsId 商品ID
  193. * @param string $goodsSkuId 商品SKU
  194. * @param int $goodsNum 购买数量
  195. * @param int $bargainId 砍价活动ID
  196. * @return mixed
  197. * @throws BaseException
  198. */
  199. public function getOrderGoodsZaListByNow(int $goodsId, string $goodsSkuId, int $goodsNum, int $zaGoodsId,int $staffUserId = 0,bool $isReceive = false)
  200. {
  201. // 获取商品列表
  202. $model = new GoodsModel;
  203. $goodsList = $model->getListByIdsFromApi([$goodsId]);
  204. if ($goodsList->isEmpty()) {
  205. throwError('未找到商品信息');
  206. }
  207. //获取砍价数据
  208. $user = UserService::getCurrentLoginUser(true);
  209. $zaGoods = ZaActivityGood::where('goods_id',$goodsId)->where('id',$zaGoodsId)->find();
  210. if(empty($zaGoods)){
  211. throwError('未找到买一赠一信息');
  212. }
  213. if(!$isReceive){
  214. if($zaGoods['stock_num']<=1){
  215. throwError('该买一赠一商品库存不足');
  216. }
  217. }
  218. // 隐藏冗余的属性
  219. $goodsList->hidden(array_merge($model->hidden, ['content', 'goods_images', 'images']));
  220. // 返回商品处理
  221. $data = $this->getStaffUserId($staffUserId);
  222. foreach ($goodsList as &$item) {
  223. // 商品sku信息
  224. $item['skuInfo'] = GoodsSkuModel::detail($item['goods_id'], $goodsSkuId);
  225. // 商品单价
  226. $item['goods_price'] = $item['skuInfo']['goods_price'];
  227. // 商品购买数量
  228. $item['total_num'] = $goodsNum;
  229. // 商品SKU索引
  230. $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
  231. // 商品购买总金额
  232. $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
  233. // 获取砍价活动的最终金额
  234. // $item['bargain_price'] = $KjActivityJoin['kj_price'];
  235. // $item['bargain_id'] = $bargainId;
  236. $item['za_goods_id'] = $zaGoods['id'];
  237. $item['staffUserId'] = $data['staffUserId'];
  238. $item['shopId'] = $data['shopId'];
  239. $item['distributorRadio'] = $data['distributorRadio'];
  240. }
  241. return $goodsList;
  242. }
  243. /**
  244. * 立即购买:获取订单商品列表
  245. * @param int $goodsId 商品ID
  246. * @param string $goodsSkuId 商品SKU
  247. * @param int $goodsNum 购买数量
  248. * @param int $bargainId 砍价活动ID
  249. * @return mixed
  250. * @throws BaseException
  251. */
  252. public function getOrderGoodsBargainListByNow(int $goodsId, string $goodsSkuId, int $goodsNum, int $bargainId,int $staffUserId = 0)
  253. {
  254. // 获取商品列表
  255. $model = new GoodsModel;
  256. $goodsList = $model->getListByIdsFromApi([$goodsId]);
  257. if ($goodsList->isEmpty()) {
  258. throwError('未找到商品信息2');
  259. }
  260. //获取砍价数据
  261. $user = UserService::getCurrentLoginUser(true);
  262. $KjActivityJoin = KjActivityJoin::where('user_id',$user['user_id'])->find($bargainId);
  263. if (!$KjActivityJoin) {
  264. throwError('未找到砍价信息');
  265. }
  266. if($KjActivityJoin['is_submit_order']|| (strtotime($KjActivityJoin['end_time'])+3600*48)<time()){
  267. // if($KjActivityJoin['is_submit_order']|| (strtotime($KjActivityJoin['end_time'])+300)<time()){
  268. throwError('该砍价记录已下单或超过下单时间');
  269. }
  270. $KjActivityGood = KjActivityGood::where(['goods_id'=>$goodsId,'activity_id'=>$KjActivityJoin['activity_id']])->find();
  271. if($KjActivityGood['limit_stock']-$KjActivityGood['purchase_stock']<=0){
  272. throwError('该砍价商品没有库存了');
  273. }
  274. // 隐藏冗余的属性
  275. $goodsList->hidden(array_merge($model->hidden, ['content', 'goods_images', 'images']));
  276. // 返回商品处理
  277. $data = $this->getStaffUserId($staffUserId);
  278. foreach ($goodsList as &$item) {
  279. // 商品sku信息
  280. $item['skuInfo'] = GoodsSkuModel::detail($item['goods_id'], $goodsSkuId);
  281. // 商品单价
  282. $item['goods_price'] = $item['skuInfo']['goods_price'];
  283. // 商品购买数量
  284. $item['total_num'] = $goodsNum;
  285. // 商品SKU索引
  286. $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
  287. // 商品购买总金额
  288. $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
  289. // 获取砍价活动的最终金额
  290. $item['bargain_price'] = $KjActivityJoin['kj_price'];
  291. $item['bargain_id'] = $bargainId;
  292. $item['bargain_activity_id'] = $KjActivityJoin['activity_id'];
  293. $item['staffUserId'] = $data['staffUserId'];
  294. $item['shopId'] = $data['shopId'];
  295. $item['distributorRadio'] = $data['distributorRadio'];
  296. }
  297. return $goodsList;
  298. }
  299. //当前秒杀活动商品买了多少件
  300. public function miaoshaHaveBuyCnt($ms_goods_id,$user_id){
  301. $order_id_arr = Order::where('order_source',OrderSourceEnum::MIAOSHA)->where('order_source_id',$ms_goods_id)->where('user_id', $user_id)->where('pay_status',PayStatusEnum::SUCCESS)->column("order_id");
  302. if(count($order_id_arr)==0){
  303. return 0;
  304. }
  305. else if(count($order_id_arr)>0){
  306. $total_num = OrderGoodsModel::where("order_id",'in',$order_id_arr)->sum('total_num');
  307. return $total_num;
  308. }
  309. }
  310. /**
  311. * 立即购买:获取订单商品列表
  312. * @param int $goodsId 商品ID
  313. * @param string $goodsSkuId 商品SKU
  314. * @param int $goodsNum 购买数量
  315. * @param int $bargainId 砍价活动ID
  316. * @return mixed
  317. * @throws BaseException
  318. */
  319. public function getOrderGoodsMiaoshaListByNow(int $goodsId, string $goodsSkuId, int $goodsNum, int $msId,int $staffUserId = 0)
  320. {
  321. // 获取商品列表
  322. $model = new GoodsModel;
  323. $goodsList = $model->getListByIdsFromApi([$goodsId]);
  324. if ($goodsList->isEmpty()) {
  325. throwError('未找到商品信息2');
  326. }
  327. //获取秒杀数据
  328. $user = UserService::getCurrentLoginUser(true);
  329. $msGood = MsActivityGood::where('id',$msId)->find();
  330. if (!$msGood) {
  331. throwError('未找到秒杀信息');
  332. }
  333. if($goodsNum>$msGood->stock_num){
  334. throwError("库存不足");
  335. }
  336. if(time()>strtotime($msGood->end_time)){
  337. throwError("秒杀活动已结束");
  338. }
  339. $activity = MsActivity::where("id",$msGood->ms_activity_id)->find();
  340. if($activity->is_up==0||$activity->audit_status!=1){
  341. throwError("秒杀活动已结束!");
  342. }
  343. if($msGood->limit_mount>0&&$goodsNum>$msGood->limit_mount){
  344. throwError("超过限购数量");
  345. }
  346. if($msGood->limit_mount>0){
  347. $order_id_arr = Order::where('order_source',OrderSourceEnum::MIAOSHA)->where('order_source_id',$msGood->id)->where('user_id', $user->user_id)->where('pay_status',PayStatusEnum::SUCCESS)->column("order_id");
  348. if(count($order_id_arr)>0){
  349. $total_num = OrderGoodsModel::where("order_id",'in',$order_id_arr)->sum('total_num');
  350. if($total_num>=$msGood->limit_mount){
  351. throwError("限购".$msGood->limit_mount."件!");
  352. }
  353. }
  354. }
  355. // 隐藏冗余的属性
  356. $goodsList->hidden(array_merge($model->hidden, ['content', 'goods_images', 'images']));
  357. // 返回商品处理
  358. $data = $this->getStaffUserId($staffUserId);
  359. foreach ($goodsList as &$item) {
  360. // 商品sku信息
  361. $item['skuInfo'] = GoodsSkuModel::detail($item['goods_id'], $goodsSkuId);
  362. // 商品单价
  363. $item['goods_price'] = $item['skuInfo']['goods_price'];
  364. // 商品购买数量
  365. $item['total_num'] = $goodsNum;
  366. // 商品SKU索引
  367. $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
  368. // 商品购买总金额
  369. $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
  370. // 获取秒杀活动的最终金额
  371. $item['ms_price'] = $msGood['ms_price'];
  372. $item['ms_id'] = $msId;
  373. $item['staffUserId'] = $data['staffUserId'];
  374. $item['shopId'] = $data['shopId'];
  375. $item['distributorRadio'] = $data['distributorRadio'];
  376. $item['limit_mount'] = $msGood['limit_mount'];
  377. }
  378. return $goodsList;
  379. }
  380. /**
  381. * 立即购买:获取订单商品列表
  382. * @param int $goodsId 商品ID
  383. * @param string $goodsSkuId 商品SKU
  384. * @param int $goodsNum 购买数量
  385. * @param int $activity_id 拼团活动ID
  386. * @return mixed
  387. * @throws BaseException
  388. */
  389. public function getOrderGoodsGroupListByNow(int $goodsId, string $goodsSkuId, int $goodsNum, int $joinId=0,int $activity_id=0,int $staffUserId = 0)
  390. {
  391. // 获取商品列表
  392. $model = new GoodsModel;
  393. $goodsList = $model->getListByIdsFromApi([$goodsId]);
  394. if ($goodsList->isEmpty()) {
  395. throwError('未找到商品信息');
  396. }
  397. //获取砍价数据
  398. $user = UserService::getCurrentLoginUser(true);
  399. $now = Date("Y-m-d H:i:s",time());
  400. if($joinId>0){
  401. $join = GroupBuyJoin::where('id',$joinId)->lock('for update')->find();
  402. $helpCnt = GroupBuyHelp::where("join_id",$join->id)->where('pay_state','in',[0,1])->count();
  403. $have = GroupBuyHelp::where("join_id",$join->id)->where('user_id',$user->user_id)->where('pay_state','in',[0,1])->find();
  404. if($have&&$have->pay_state==0){
  405. throwError("你有一个待支付的拼团");
  406. }
  407. if($have&&$have->pay_state==1){
  408. throwError("你已经参与该拼团");
  409. }
  410. if($helpCnt>=$join->people_count){
  411. throwError("拼团人数已够");
  412. }
  413. if($now>$join->end_time){
  414. throwError('拼团已结束');
  415. }
  416. if($join->status==1){
  417. throwError("拼团已完成");
  418. }
  419. if($join->status==2){
  420. throwError("拼团结束");
  421. }
  422. $groupgoods = GroupBuyGoods::where('group_buy_activity_id',$join['group_buy_activity_id'])->find();
  423. if(empty($groupgoods)){
  424. throwError('找不到商品');
  425. }
  426. if($groupgoods->goods_id!=$goodsId){
  427. throwError('商品id跟活动商品id对不上');
  428. }
  429. if($goodsNum>$groupgoods->limit_mount){
  430. throwError('超过限购数量');
  431. }
  432. if($goodsNum>$groupgoods->residue_stock){
  433. throwError('拼团活动库存不足');
  434. }
  435. }
  436. else if($activity_id>0){
  437. $activity = GroupBuyActivity::where("id",$activity_id)->find();
  438. if(empty($activity)){
  439. throwError("找不到拼团活动");
  440. }
  441. if($now>$activity->end_time){
  442. throwError('拼团活动已结束');
  443. }
  444. if($activity->audit_status!=1||$activity->status!=1){
  445. throwError('拼团活动不存在');
  446. }
  447. $join = GroupBuyJoin::where('user_id',$user->user_id)->where('group_buy_activity_id',$activity_id)->where('status',0)->where('end_time',">",$now)->find();
  448. if($join){
  449. throwError('你有一个拼团正在进行中');
  450. }
  451. $groupgoods = GroupBuyGoods::where('group_buy_activity_id',$activity_id)->find();
  452. if(empty($groupgoods)){
  453. throwError('找不到商品');
  454. }
  455. if($groupgoods->goods_id!=$goodsId){
  456. throwError('商品id跟活动商品id对不上');
  457. }
  458. if($goodsNum>$groupgoods->limit_mount){
  459. throwError('超过限购数量');
  460. }
  461. //判断库存数量
  462. if($groupgoods->limit_stock - $groupgoods->purchase_stock <=0){
  463. throwError('活动已结束~');
  464. }
  465. }
  466. if(empty($groupgoods)){
  467. throwError("找不到商品");
  468. }
  469. // 隐藏冗余的属性
  470. $goodsList->hidden(array_merge($model->hidden, ['content', 'goods_images', 'images']));
  471. // 返回商品处理
  472. $data = $this->getStaffUserId($staffUserId);
  473. foreach ($goodsList as &$item) {
  474. // 商品sku信息
  475. $item['skuInfo'] = GoodsSkuModel::detail($item['goods_id'], $goodsSkuId);
  476. // 商品单价
  477. $item['goods_price'] = $item['skuInfo']['goods_price'];
  478. // 商品购买数量
  479. $item['total_num'] = $goodsNum;
  480. // 商品SKU索引
  481. $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
  482. // 商品购买总金额
  483. $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
  484. // 获取最终拼团单价金额
  485. $item['group_price'] = $groupgoods['group_price'];
  486. $item['group_buy_id'] = $joinId>0 ? $join['group_buy_activity_id'] : $activity_id;
  487. $item['join_id'] = $joinId;
  488. $item['limit_mount'] = $groupgoods['limit_mount'];
  489. $item['staffUserId'] = $data['staffUserId'];
  490. $item['shopId'] = $data['shopId'];
  491. $item['distributorRadio'] = $data['distributorRadio'];
  492. }
  493. return $goodsList;
  494. }
  495. /**拼团裂变
  496. * 立即购买:获取订单商品列表
  497. * @param int $goodsId 商品ID
  498. * @param string $goodsSkuId 商品SKU
  499. * @param int $goodsNum 购买数量
  500. * @param int $bargainId 砍价活动ID
  501. * @return mixed
  502. * @throws BaseException
  503. */
  504. public function getOrderGoodsGroupLbListByNow(int $goodsId, string $goodsSkuId, int $goodsNum, int $joinId=0,int $activity_id=0)
  505. {
  506. // 获取商品列表
  507. $model = new GoodsModel;
  508. $goodsList = $model->getListByIdsFromApi([$goodsId]);
  509. if ($goodsList->isEmpty()) {
  510. throwError('未找到商品信息');
  511. }
  512. //获取砍价数据
  513. $user = UserService::getCurrentLoginUser(true);
  514. $now = Date("Y-m-d H:i:s",time());
  515. if($joinId>0){
  516. $join = GroupBuyLbJoin::where('id',$joinId)->lock('for update')->find();
  517. $helpCnt = GroupBuyLbHelp::where("join_id",$join->id)->where('pay_state','in',[0,1])->count();
  518. $have = GroupBuyLbHelp::where("join_id",$join->id)->where('user_id',$user->user_id)->where('pay_state','in',[0,1])->find();
  519. if($have&&$have->pay_state==0){
  520. throwError("你有一个待支付的拼团");
  521. }
  522. if($have&&$have->pay_state==1){
  523. throwError("你已经参与该拼团");
  524. }
  525. if($helpCnt>=$join->people_count){
  526. throwError("拼团人数已够");
  527. }
  528. if($now>$join->end_time){
  529. throwError('拼团已结束');
  530. }
  531. if($join->status==1){
  532. throwError("拼团已完成");
  533. }
  534. if($join->status==2){
  535. throwError("拼团结束");
  536. }
  537. $groupgoods = GroupBuyLbGoods::where('group_buy_lb_activity_id',$join['group_buy_lb_activity_id'])->find();
  538. if(empty($groupgoods)){
  539. throwError('找不到商品');
  540. }
  541. if($groupgoods->goods_id!=$goodsId){
  542. throwError('商品id跟活动商品id对不上');
  543. }
  544. if($goodsNum>$groupgoods->limit_mount){
  545. throwError('超过限购数量');
  546. }
  547. }
  548. else if($activity_id>0){
  549. $activity = GroupBuyLbActivity::where("id",$activity_id)->find();
  550. if(empty($activity)){
  551. throwError("找不到拼团活动");
  552. }
  553. if($now>$activity->end_time){
  554. throwError('拼团活动已结束');
  555. }
  556. if($activity->audit_status!=1||$activity->status!=1){
  557. throwError('拼团活动不存在');
  558. }
  559. $join = GroupBuyLbJoin::where('user_id',$user->user_id)->where('group_buy_lb_activity_id',$activity_id)->where('status',0)->where('end_time',">",$now)->find();
  560. if($join){
  561. // throwError('你有一个拼团正在进行中');
  562. }
  563. $groupgoods = GroupBuyLbGoods::where('group_buy_lb_activity_id',$activity_id)->find();
  564. if(empty($groupgoods)){
  565. throwError('找不到商品');
  566. }
  567. if($groupgoods->goods_id!=$goodsId){
  568. throwError('商品id跟活动商品id对不上');
  569. }
  570. if($goodsNum>$groupgoods->limit_mount){
  571. throwError('超过限购数量');
  572. }
  573. //判断库存数量
  574. if($groupgoods->limit_stock - $groupgoods->purchase_stock <=0){
  575. throwError('活动已结束~');
  576. }
  577. }
  578. if(empty($groupgoods)){
  579. throwError("找不到商品");
  580. }
  581. // 隐藏冗余的属性
  582. $goodsList->hidden(array_merge($model->hidden, ['content', 'goods_images', 'images']));
  583. // 返回商品处理
  584. foreach ($goodsList as &$item) {
  585. // 商品sku信息
  586. $item['skuInfo'] = GoodsSkuModel::detail($item['goods_id'], $goodsSkuId);
  587. // 商品单价
  588. $item['goods_price'] = $item['skuInfo']['goods_price'];
  589. // 商品购买数量
  590. $item['total_num'] = $goodsNum;
  591. // 商品SKU索引
  592. $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
  593. // 商品购买总金额
  594. $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
  595. // 获取最终拼团单价金额
  596. $item['group_price'] = $groupgoods['group_price'];
  597. $item['join_id'] = $joinId;
  598. $item['group_buy_lb_id'] = $joinId>0 ? $join['group_buy_lb_activity_id'] : $activity_id;
  599. $item['limit_mount'] = $groupgoods['limit_mount'];
  600. }
  601. return $goodsList;
  602. }
  603. /**
  604. * 余额支付标记订单已支付
  605. * @param string $orderNo 订单号
  606. * @return bool
  607. */
  608. public function onPaymentByBalance(string $orderNo)
  609. {
  610. // 获取订单详情
  611. $service = new OrderPaySuccesService($orderNo);
  612. // 发起余额支付
  613. $status = $service->onPaySuccess(OrderPayTypeEnum::BALANCE);
  614. if (!$status) {
  615. $this->error = $service->getError();
  616. }
  617. return $status;
  618. }
  619. /**
  620. * 积分兑换支付标记订单已支付
  621. * @param string $orderNo 订单号
  622. * @return bool
  623. */
  624. public function onPaymentByAccumulatePoints(string $orderNo)
  625. {
  626. // 获取订单详情
  627. $service = new OrderPaySuccesService($orderNo);
  628. // 发起积分支付
  629. $status = $service->onPaySuccess(OrderPayTypeEnum::EXCHANGE);
  630. if (!$status) {
  631. $this->error = $service->getError();
  632. }
  633. return $status;
  634. }
  635. /**
  636. * 获取用户订单列表
  637. * @param string $type 订单类型 (all全部 payment待付款 delivery待发货 received待收货 completed已完成 comment待评价)
  638. * @param boolean $isExchange 是否积分兑换订单
  639. * @return \think\Paginator
  640. * @throws BaseException
  641. * @throws \think\db\exception\DbException
  642. */
  643. public function getList($type = 'all',$isExchange = false)
  644. {
  645. /* // 筛选条件
  646. $filter = [];
  647. // 订单数据类型
  648. switch ($type) {
  649. case 'all':
  650. break;
  651. case 'payment':
  652. $filter['pay_status'] = PayStatusEnum::PENDING;
  653. $filter['order_status'] = OrderStatusEnum::NORMAL;
  654. break;
  655. // case 'delivery':
  656. // $filter['pay_status'] = PayStatusEnum::SUCCESS;
  657. // $filter['delivery_status'] = DeliveryStatusEnum::NOT_DELIVERED;
  658. // $filter['order_status'] = OrderStatusEnum::NORMAL;
  659. // break;
  660. case 'received':
  661. $filter['pay_status'] = PayStatusEnum::SUCCESS;
  662. // $filter['delivery_status'] = DeliveryStatusEnum::DELIVERED;
  663. $filter['receipt_status'] = ReceiptStatusEnum::NOT_RECEIVED;
  664. $filter['order_status'] = OrderStatusEnum::NORMAL;
  665. break;
  666. case 'completed':
  667. $filter['is_comment'] = 0;
  668. $filter['order_status'] = OrderStatusEnum::COMPLETED;
  669. break;
  670. case 'comment':
  671. $filter['is_comment'] = 0;
  672. $filter['order_status'] = OrderStatusEnum::COMPLETED;
  673. break;
  674. }*/
  675. $filter = $this->getFilter($type);
  676. $rate = 0;
  677. if ($isExchange){
  678. $filter['pay_type'] = PayType::EXCHANGE;
  679. $rate = SettingModel::getItem('points_rate')['points_2_money'];
  680. }
  681. // 当前用户ID
  682. $userId = UserService::getCurrentLoginUserId();
  683. // 查询列表数据
  684. return $this->with(['goods.image'])
  685. ->where($filter)
  686. ->where('user_id', '=', $userId)
  687. ->where('is_delete', '=', 0)
  688. ->order(['create_time' => 'desc'])
  689. ->paginate(15)->each(function($e) use ($isExchange,$rate){
  690. $e['goods_total_num'] = 0;
  691. $e['exchanged_points'] = 0;
  692. if ($isExchange){
  693. $e['exchanged_points'] = bcmul($e['total_price'], $rate,0);
  694. }
  695. foreach ($e['goods'] as $good){
  696. $e['goods_total_num'] += $good['total_num'];
  697. }
  698. $e['za'] =null;
  699. if($e['order_source']==OrderSourceEnum::ZA){
  700. //OrderPayTypeEnum::ACTIVITY 这个类型肯定是领取人
  701. if($e['pay_type']!=OrderPayTypeEnum::ACTIVITY){
  702. $za = ZaActivityRelation::where("order_id",$e['order_id'])->where('is_pay',1)->field('sign_str,receive_state,expire_time,is_pay,za_activity_id')->find();
  703. if($za){
  704. $now = Date("Y-m-d H:i:s",time());
  705. $data['is_expire'] =$now > $za->expire_time ? true: false;
  706. $data['sign_str'] = $za->sign_str;
  707. $data['is_receive'] = $za->receive_state;
  708. $data['expire_time'] = $za->expire_time;
  709. $data['share_title'] = ZaActivity::where("id",$za->za_activity_id)->value("share_title")??'';
  710. $e['za'] = $data;
  711. }
  712. }
  713. }
  714. });
  715. }
  716. public function getFilter($type){
  717. // 筛选条件
  718. $filter = [];
  719. // 订单数据类型
  720. switch ($type) {
  721. case 'all':
  722. break;
  723. case 'payment':
  724. $filter['pay_status'] = PayStatusEnum::PENDING;
  725. $filter['order_status'] = OrderStatusEnum::NORMAL;
  726. break;
  727. // case 'delivery':
  728. // $filter['pay_status'] = PayStatusEnum::SUCCESS;
  729. // $filter['delivery_status'] = DeliveryStatusEnum::NOT_DELIVERED;
  730. // $filter['order_status'] = OrderStatusEnum::NORMAL;
  731. // break;
  732. case 'received':
  733. $filter['pay_status'] = PayStatusEnum::SUCCESS;
  734. // $filter['delivery_status'] = DeliveryStatusEnum::DELIVERED;
  735. $filter['receipt_status'] = ReceiptStatusEnum::NOT_RECEIVED;
  736. $filter['order_status'] = OrderStatusEnum::NORMAL;
  737. break;
  738. case 'completed':
  739. // $filter['is_comment'] = 0;
  740. $filter['order_status'] = OrderStatusEnum::COMPLETED;
  741. break;
  742. case 'comment':
  743. $filter['is_comment'] = 0;
  744. $filter['order_status'] = OrderStatusEnum::COMPLETED;
  745. break;
  746. case 'cancel':
  747. $filter['order_status'] = OrderStatusEnum::CANCELLED;
  748. break;
  749. case 'close':
  750. $filter['order_status'] = OrderStatusEnum::CLOSE;
  751. break;
  752. }
  753. return $filter;
  754. }
  755. /**
  756. * 取消订单
  757. * @return bool|mixed
  758. */
  759. public function cancel()
  760. {
  761. if ($this['pay_status'] == PayStatusEnum::SUCCESS) {
  762. $this->error = '已支付订单不可取消';
  763. return false;
  764. }
  765. if ($this['delivery_status'] == DeliveryStatusEnum::DELIVERED) {
  766. $this->error = '已发货订单不可取消';
  767. return false;
  768. }
  769. // 订单取消事件
  770. return $this->transaction(function () {
  771. // 订单是否已支付
  772. $isPay = $this['pay_status'] == PayStatusEnum::SUCCESS;
  773. // 订单取消事件
  774. $isPay == false && OrderService::cancelEvent($this);
  775. // 更新订单状态: 已付款的订单设置为"待取消", 等待后台审核
  776. return $this->save(['order_status' => $isPay ? OrderStatusEnum::APPLY_CANCEL : OrderStatusEnum::CANCELLED]);
  777. });
  778. }
  779. /**
  780. * 删除指定订单记录
  781. * @return bool
  782. * @throws BaseException
  783. */
  784. public function clear()
  785. {
  786. // 验证订单是否合法
  787. // 条件1: 订单必须已取消
  788. // 条件2: 订单必须已完成
  789. // 条件3: 订单必须已关闭
  790. if ($this['order_status'] != 20 && $this['order_status'] != 30 && $this['order_status'] != 40) {
  791. $this->error = '该订单不能删除';
  792. return false;
  793. }
  794. // 获取当前用户ID
  795. $userId = UserService::getCurrentLoginUserId();
  796. // 设置更新条件
  797. $where = [['user_id', '=', $userId], ['order_id', '=', $this['order_id']]];
  798. // 更新记录
  799. return static::updateBase(['is_delete'=>1],$where);
  800. }
  801. /**
  802. * 确认收货
  803. * @return bool|mixed
  804. */
  805. public function receipt()
  806. {
  807. // 验证订单是否合法
  808. // 条件1: 订单必须已发货
  809. // 条件2: 订单必须未收货
  810. if ($this['delivery_status'] != 20 || $this['receipt_status'] != 10) {
  811. $this->error = '该订单不合法';
  812. return false;
  813. }
  814. return $this->transaction(function () {
  815. // 更新订单状态
  816. $status = $this->save([
  817. 'receipt_status' => 20,
  818. 'receipt_time' => time(),
  819. 'order_status' => $this['order_status']==10 ? 30 : $this['order_status'],
  820. ]);
  821. // 执行订单完成后的操作
  822. // $OrderCompleteService = new OrderCompleteService(OrderTypeEnum::ORDER);
  823. // $OrderCompleteService->complete([$this], static::$storeId);
  824. return $status;
  825. });
  826. }
  827. /**
  828. * 确认核销并确认收货
  829. * @return bool|mixed
  830. */
  831. public function writeOff()
  832. {
  833. // 验证订单是否合法
  834. // 条件1: 订单必须未过提货截止时间
  835. if ($this['pickup_deadline'] < date('Y-m-d H:i:s')) {
  836. $this->error = '该订单已超过提货截止时间';
  837. return false;
  838. }
  839. // 条件1: 订单必须未核销
  840. // 条件2: 订单必须未收货
  841. if ($this['hx_status'] != 10 || $this['receipt_status'] != 10) {
  842. $this->error = '该订单已核销';
  843. return false;
  844. }
  845. if ($this['refund'] && $this['refund']['status'] == 0) {
  846. $this->error = '该订单在售后中';
  847. return false;
  848. }
  849. if ($this['order_status'] != 10) {
  850. $this->error = '该订单已取消或已退款';
  851. return false;
  852. }
  853. return $this->transaction(function () {
  854. // 更新订单状态
  855. $status = $this->save([
  856. 'receipt_status' => ReceiptStatusEnum::RECEIVED,//收货状态(10未收货 20已收货)
  857. 'receipt_time' => time(),//收货时间
  858. 'delivery_status' => DeliveryStatusEnum::DELIVERED, // 发货状态(10未发货 20已发货)
  859. 'delivery_time' => time(), // 发货时间
  860. 'order_status' => 30,//订单状态(10进行中 20取消 21待取消 30已完成)
  861. 'hx_status' => 20,//核销状态(10未核销 20已核销)',
  862. 'pickup_time' => time(),//提货时间
  863. 'hx_user_id' => UserService::getCurrentLoginUserId(),//核销人用户ID
  864. ]);
  865. $orderGoodsIds = helper::getArrayColumn($this['goods'],'order_goods_id');
  866. static::setSignTime($orderGoodsIds,$this['order_id']);
  867. return $status;
  868. });
  869. }
  870. /**
  871. * 核销后结算时间
  872. * @param $orderGoodsIds
  873. * @param $orderId
  874. * @throws \think\db\exception\DataNotFoundException
  875. * @throws \think\db\exception\DbException
  876. * @throws \think\db\exception\ModelNotFoundException
  877. * @author: zjwhust
  878. * @Time: 2021/12/10 14:48
  879. */
  880. public static function setSignTime($orderGoodsIds,$orderId){
  881. // 自动关闭订单的分钟数
  882. $provider_days = SettingModel::getItem('provider_settlement')['provider_days'];//供应商结算时间
  883. $refund = SettingModel::getItem('shops');//门店自提订单配置
  884. $data = [
  885. 'provider_settlement_time' => time()+$provider_days*86400,
  886. 'commission_settlement_time' => time()+$refund['commission_days']*86400,
  887. 'refund_time' => time()+$refund['refund_days']*86400,
  888. 'auto_receipt_time' => time(),
  889. 'sign_time' => time(),
  890. 'receipt_status' => ReceiptStatusEnum::RECEIVED,//收货状态(10未收货 20已收货)
  891. 'receipt_time' => time(),//收货时间
  892. 'delivery_status' => DeliveryStatusEnum::DELIVERED, // 发货状态(10未发货 20已发货)
  893. 'delivery_time' => time(), // 发货时间
  894. ];
  895. $dataOrder = [
  896. 'commission_settlement_time' => time()+$refund['commission_days']*86400,
  897. 'refund_time' => time()+$refund['refund_days']*86400,
  898. ];
  899. //添加测试的时间
  900. if(env('SERVE_ENV')=='test') {
  901. $data = [
  902. 'provider_settlement_time' => time() + 300,//供应商结算开始时间5分钟后
  903. 'commission_settlement_time' => time() + 600,//分佣结算开始时间10分钟后
  904. 'refund_time' => time() + 300,//关闭售后时间5分钟
  905. 'auto_receipt_time' => time(),//自动收货最晚时间5分钟后
  906. 'sign_time' => time(),//记录签到时间
  907. 'receipt_status' => 20,//收货状态(10未收货 20已收货)
  908. 'receipt_time' => time(),//收货时间
  909. 'delivery_status' => DeliveryStatusEnum::DELIVERED, // 发货状态(10未发货 20已发货)
  910. 'delivery_time' => time(), // 发货时间
  911. //售后退款用户退货发货超时5分钟
  912. ];
  913. $dataOrder = [
  914. 'commission_settlement_time' => time() + 600,//分佣结算开始时间10分钟后
  915. 'refund_time' => time() + 300,//关闭售后时间5分钟
  916. ];
  917. }
  918. OrderGoodsModel::updateBase($data, [['order_goods_id', 'in', $orderGoodsIds]]);
  919. self::updateBase($dataOrder,['order_id'=>$orderId]);
  920. }
  921. /**
  922. * 获取当前用户订单数量
  923. * @param string $type 订单类型 (all全部 payment待付款 received待发货 deliver待收货 comment待评价)
  924. * @return int
  925. * @throws BaseException
  926. */
  927. public function getCount($type = 'all')
  928. {
  929. // 筛选条件
  930. $filter = [];
  931. // 订单数据类型
  932. switch ($type) {
  933. case 'all':
  934. break;
  935. case 'payment':
  936. $filter['pay_status'] = PayStatusEnum::PENDING;
  937. break;
  938. case 'received':
  939. $filter['pay_status'] = PayStatusEnum::SUCCESS;
  940. $filter['delivery_status'] = DeliveryStatusEnum::DELIVERED;
  941. $filter['receipt_status'] = ReceiptStatusEnum::NOT_RECEIVED;
  942. break;
  943. case 'delivery':
  944. $filter['pay_status'] = PayStatusEnum::SUCCESS;
  945. $filter['delivery_status'] = DeliveryStatusEnum::NOT_DELIVERED;
  946. $filter['order_status'] = OrderStatusEnum::NORMAL;
  947. break;
  948. case 'comment':
  949. $filter['is_comment'] = 0;
  950. $filter['order_status'] = OrderStatusEnum::COMPLETED;
  951. break;
  952. }
  953. // 当前用户ID
  954. $userId = UserService::getCurrentLoginUserId();
  955. // 查询数据
  956. return $this->where('user_id', '=', $userId)
  957. ->where('order_status', '<>', 20)
  958. ->where($filter)
  959. ->where('is_delete', '=', 0)
  960. ->count();
  961. }
  962. /**
  963. * 获取分享链接的用户ID
  964. * @param int $staffUserId
  965. * @return mixed
  966. * @author: zjwhust
  967. * @Time: 2021/9/30 13:32
  968. */
  969. private function getStaffUserId( int $staffUserId)
  970. {
  971. // 获取当前用户ID
  972. $user = UserService::getCurrentLoginUser(true);
  973. $is_staff = 1;
  974. if($staffUserId<=0 || $staffUserId==$user['user_id']){
  975. if(in_array($user['role'],[1,99])){
  976. $staffUserId = $user['upper_user_id'];
  977. $is_staff = 0;
  978. }else{
  979. $staffUserId = 0;
  980. }
  981. }
  982. $data['staffUserId'] = $staffUserId;
  983. $data['shopId'] = 0;
  984. $data['distributorRadio'] = 0;
  985. if ($staffUserId>0) {
  986. // 获取分享链接的用户信息
  987. $user_staff = User::detail($staffUserId);
  988. if($user_staff){
  989. $data['shopId'] = !in_array($user_staff['role'],[1,99]) ? $user_staff['shop_id'] : $user_staff['bind_shop_id'];//获取分享链接用户的shop_id
  990. if($user['role']==99){
  991. $data['distributorRadio'] = SettingModel::getItem(SettingEnum::DISTRIBUTOR)['shopping_discount'];
  992. }else{
  993. if($user_staff['role'] == 99 && $is_staff){
  994. $data['distributorRadio'] = SettingModel::getItem(SettingEnum::DISTRIBUTOR)['shopping_discount'];
  995. }
  996. }
  997. }else{
  998. if($user['role']==99){
  999. $data['distributorRadio'] = SettingModel::getItem(SettingEnum::DISTRIBUTOR)['shopping_discount'];
  1000. }
  1001. }
  1002. }else{
  1003. if($user['role']==99){
  1004. $data['distributorRadio'] = SettingModel::getItem(SettingEnum::DISTRIBUTOR)['shopping_discount'];
  1005. }
  1006. }
  1007. return $data;
  1008. }
  1009. /**
  1010. * 获取用户订单详情(含关联数据)
  1011. * @param int $orderId 订单ID
  1012. * @return Order|array|null
  1013. * @throws BaseException
  1014. * @throws \think\db\exception\DataNotFoundException
  1015. * @throws \think\db\exception\DbException
  1016. * @throws \think\db\exception\ModelNotFoundException
  1017. */
  1018. public static function getUserOrderDetail(int $orderId)
  1019. {
  1020. // 关联查询
  1021. $with = [
  1022. 'goods' => ['image', 'refund', 'package'],
  1023. 'address', 'express', 'shops', 'hxUser'
  1024. ];
  1025. // 查询订单记录
  1026. $order = static::getDetail($orderId, $with);
  1027. //重整订单列表结构
  1028. // static::restructureGoods($order);
  1029. //添加订单商品售后状态
  1030. static::refundStatus($order);
  1031. // 订单商品总数量
  1032. $order['orderTotalNum'] = helper::getArrayColumnSum($order['goods'], 'total_num');
  1033. // 该订单是否允许申请售后
  1034. // $order['isAllowRefund'] = static::isAllowRefund($order);
  1035. // 订单是否允许申请开票
  1036. $order['isAllowInvoice'] = static::isAllowInvoice($order);
  1037. return $order;
  1038. }
  1039. // 订单是否允许申请开票
  1040. public static function isAllowInvoice(self $order) {
  1041. if($order['order_source']==OrderSourceEnum::ZA&&$order['pay_type']==OrderPayTypeEnum::ACTIVITY){
  1042. return false;
  1043. }
  1044. if ($order['invoice_deadline'] > 0 && ($order['invoice_deadline'] - time()) > 0) {
  1045. return true;
  1046. }
  1047. return false;
  1048. }
  1049. //重构订单列表逻辑
  1050. public static function restructureGoods(self $order){
  1051. $mj_send_goods_list = [];
  1052. foreach($order['goods'] as $key=>$goods){
  1053. if($goods['master_order_goods_id']>0){
  1054. $mj_send_goods_list[$goods['master_order_goods_id']][] = $goods;
  1055. unset($order['goods'][$key]);
  1056. }
  1057. }
  1058. foreach ($order['goods'] as $good){
  1059. $good['mj_send_goods_list'] = [];
  1060. foreach ($mj_send_goods_list as $key => $list){
  1061. if($good['order_goods_id']==$key){
  1062. $good['mj_send_goods_list'] = $list;
  1063. }
  1064. }
  1065. }
  1066. }
  1067. //处理订单商品当前的售后状态
  1068. public static function refundStatus(self $order){
  1069. $order['is_full_refund'] = true;
  1070. $order['total_amount'] = helper::bcadd($order['total_price'],$order['express_price']);
  1071. foreach($order['goods'] as $goods){
  1072. $goods['order_refund_status_text'] = '';
  1073. $goods['order_refund_status'] = 0;
  1074. if($order['pay_status']==PayStatusEnum::SUCCESS && in_array($order['order_status'],[OrderStatusEnum::NORMAL,OrderStatusEnum::COMPLETED]) && $goods['goods_type']!=20) { //已支付并且不是赠品
  1075. if($goods['is_export'] || $goods['delivery_status'] == DeliveryStatusEnum::DELIVERED){
  1076. $order['is_full_refund'] = false;
  1077. }
  1078. if(($order['is_full_send']==1||$order['is_qc_send_send']==1) && $goods['delivery_status'] == DeliveryStatusEnum::NOT_DELIVERED) {//如果是满就送订单或者全场满件送订单,并且订单商品未发货
  1079. }else{
  1080. $order_refund_status_text = $goods['delivery_status'] == DeliveryStatusEnum::DELIVERED ? '申请售后' : '申请退款';
  1081. if (empty($goods['refund_time']) || $goods['refund_time'] > time()) {//申请售后的时间未过期
  1082. if ($goods['refund']) {
  1083. $order['is_full_refund'] = false;//有了退款申请就不能在全部退款了
  1084. // if ($goods['is_export'] && $goods['refund']['status'] == 0){//导出并且在已退款中
  1085. // $goods['order_refund_status_text'] = '退款中';
  1086. // $goods['order_refund_status'] = 2;
  1087. // }elseif($goods['is_export']){//导出不显示退款按钮
  1088. // $goods['order_refund_status'] = 0;
  1089. // }else
  1090. if ($goods['refund']['status'] == RefundStatusEnum::CANCELLED || $goods['refund']['status'] == RefundStatusEnum::CLOSE) {
  1091. //导出未发货时不显示申请退款状态
  1092. if($goods['is_export'] && $goods['delivery_status'] == DeliveryStatusEnum::NOT_DELIVERED ) continue;
  1093. $goods['order_refund_status_text'] = $order_refund_status_text;
  1094. $goods['order_refund_status'] = 1;
  1095. } elseif($goods['refund']['status'] == RefundStatusEnum::COMPLETED ) {//已完成 不在给第二次申请的机会
  1096. $goods['order_refund_status_text'] = '退款成功';
  1097. $goods['order_refund_status'] = 3;
  1098. }else{
  1099. $goods['order_refund_status_text'] = '退款中';
  1100. $goods['order_refund_status'] = 2;
  1101. }
  1102. } else {
  1103. //导出未发货时不显示申请退款状态
  1104. if($goods['is_export'] && $goods['delivery_status'] == DeliveryStatusEnum::NOT_DELIVERED ) {
  1105. $order['is_full_refund'] = false;
  1106. continue;
  1107. }
  1108. // 门店自提订单未核销时不显示申请退款状态
  1109. if ($order['delivery_type'] == 20 && $order['hx_status'] == 10 && count($order['goods']) > 1) {
  1110. continue;
  1111. }
  1112. $goods['order_refund_status_text'] = $order_refund_status_text;
  1113. $goods['order_refund_status'] = 1;
  1114. }
  1115. } else { //不在申请售后时间内
  1116. $order['is_full_refund'] = false;
  1117. if ($goods['refund']) {
  1118. if ($goods['refund']['status'] == RefundStatusEnum::CANCELLED || $goods['refund']['status'] == RefundStatusEnum::CLOSE) {
  1119. $goods['order_refund_status_text'] = '已关闭';
  1120. $goods['order_refund_status'] = 3;
  1121. } elseif($goods['refund']['status'] == RefundStatusEnum::COMPLETED ) {//已完成 不在给第二次申请的机会
  1122. $goods['order_refund_status_text'] = '退款成功';
  1123. $goods['order_refund_status'] = 3;
  1124. } else {
  1125. $goods['order_refund_status_text'] = '退款中';
  1126. $goods['order_refund_status'] = 2;
  1127. }
  1128. }
  1129. }
  1130. }
  1131. }
  1132. //
  1133. if($order['order_source']==OrderSourceEnum::ZA&&$order['pay_type']==OrderPayTypeEnum::ACTIVITY){
  1134. $goods['order_refund_status_text'] = '';
  1135. $goods['order_refund_status'] = 0;
  1136. }
  1137. }
  1138. return $order;
  1139. }
  1140. /**
  1141. * 获取用户订单详情(仅订单记录)
  1142. * @param int $orderId
  1143. * @param array $with
  1144. * @return Order|array|null
  1145. * @throws BaseException
  1146. */
  1147. public static function getDetail(int $orderId, $with = [])
  1148. {
  1149. // var_dump(UserService::getCurrentLoginUserId());
  1150. // die();
  1151. // 查询订单记录
  1152. $order = static::detail([
  1153. 'order_id' => $orderId,
  1154. 'user_id' => UserService::getCurrentLoginUserId(),
  1155. ], $with);
  1156. empty($order) && throwError('订单不存在');
  1157. return $order;
  1158. }
  1159. /**
  1160. * 当前订单是否允许申请售后
  1161. * @param Order $order
  1162. * @return bool
  1163. * @throws \think\db\exception\DataNotFoundException
  1164. * @throws \think\db\exception\DbException
  1165. * @throws \think\db\exception\ModelNotFoundException
  1166. */
  1167. private static function isAllowRefund(self $order)
  1168. {
  1169. // 必须是已发货的订单
  1170. if ($order['delivery_status'] != DeliveryStatusEnum::DELIVERED) {
  1171. return false;
  1172. }
  1173. // 允许申请售后期限(天)
  1174. $refundDays = SettingModel::getItem(SettingEnum::TRADE)['order']['refund_days'];
  1175. // 不允许售后
  1176. if ($refundDays == 0) {
  1177. return false;
  1178. }
  1179. // 当前时间超出允许申请售后期限
  1180. if (
  1181. $order['receipt_status'] == ReceiptStatusEnum::RECEIVED
  1182. && time() > ($order->getData('receipt_time') + ((int)$refundDays * 86400))
  1183. ) {
  1184. return false;
  1185. }
  1186. return true;
  1187. }
  1188. /**
  1189. * 获取当前用户待处理的订单数量
  1190. * @return array
  1191. * @throws BaseException
  1192. */
  1193. public function getTodoCounts()
  1194. {
  1195. return [
  1196. 'payment' => $this->getCount('payment'), // 待付款
  1197. 'delivery' => $this->getCount('received') + $this->getCount('delivery'), // 待收货(包括待发货
  1198. 'comment' => $this->getCount('comment'), // 待评价
  1199. 'refund' => (new OrderRefund())->getCount() // 售后/退款订单数
  1200. ];
  1201. }
  1202. /**
  1203. * 待支付订单倒计时时间戳
  1204. * @param $value
  1205. * @param $data
  1206. * @return int
  1207. * @author: zjwhust
  1208. * @Time: 2021/10/8 17:06
  1209. */
  1210. public function getDjsTimeAttr($value, $data){
  1211. if(isset($data['pay_status']) && $data['pay_status']==10){ //待支付
  1212. $now = time();
  1213. $djs_time = 60 * (int)SettingModel::getItem('order_cancel', $this->storeId)['close_minutes'];
  1214. // $delay_time = 60* (int)$this->getTradeSetting()['close_days'];
  1215. if($now-$data['create_time']<$djs_time){
  1216. return $data['create_time']+$djs_time-$now;
  1217. }
  1218. }
  1219. return 0;
  1220. }
  1221. /**
  1222. * 待收货订单倒计时时间戳
  1223. * @param $value
  1224. * @param $data
  1225. * @return int
  1226. * @author: zjwhust
  1227. * @Time: 2021/10/8 17:06
  1228. */
  1229. public function getDshTimeAttr($value,$data){
  1230. if(isset($data['delivery_status']) && $data['delivery_status']==20&&$data['receipt_status']==10){ //已发货待收货状态
  1231. $now = time();
  1232. $delay_time = 86400 * (int)SettingModel::getItem('refund', $this->storeId)['receive_days'];
  1233. // $delay_time = 60 * (int)$this->getTradeSetting()['receive_days'];
  1234. if(($now-$data['delivery_time'])<$delay_time){ //发货时间15天内
  1235. return $data['delivery_time']+$delay_time-$now;
  1236. }
  1237. }
  1238. return 0;
  1239. }
  1240. /**
  1241. * 设置错误信息
  1242. * @param $error
  1243. */
  1244. protected function setError($error)
  1245. {
  1246. empty($this->error) && $this->error = $error;
  1247. }
  1248. /**
  1249. * 是否存在错误
  1250. * @return bool
  1251. */
  1252. public function hasError()
  1253. {
  1254. return !empty($this->error);
  1255. }
  1256. public function dailySalesTj($shopId,$from,$to){
  1257. //统计前一天的数据
  1258. $res = $this->where('staff_shop_id',$shopId)
  1259. ->where('pay_status',20)
  1260. ->whereBetweenTime('create_time',$from,$to)//mysql 对int类型的 between and包含左右边界
  1261. ->field('sum(total_price + express_price) as total_price,sum(total_price) as total_goods_price,sum(pay_price + rice_card_money) as total_pay_price,sum(coupon_money) as coupon_money,count(order_id) as order_count,sum(express_price) as express_price')
  1262. ->find();
  1263. $res['total_price'] = $res['total_price']?:0;
  1264. $res['total_goods_price'] = $res['total_goods_price']?:0;
  1265. $res['total_pay_price'] = $res['total_pay_price']?:0;
  1266. $res['coupon_money'] = $res['coupon_money']?:0;
  1267. $res['express_price'] = $res['express_price']?:0;
  1268. //店老板基本分佣
  1269. $res['boss_comm_money'] = CommissionsDetailApi::sumUserCommission($shopId,User::SHOP_BOSS,$from,$to);
  1270. //店长基本分佣
  1271. $res['mg_comm_money'] = CommissionsDetailApi::sumUserCommission($shopId,User::SHOP_MG,$from,$to);
  1272. //店员基本分佣
  1273. $res['seller_comm_money'] = CommissionsDetailApi::sumUserCommission($shopId,User::SHOP_SELLER,$from,$to);
  1274. return $res->toArray();
  1275. }
  1276. /**
  1277. * 商城统计时间区间的销售额和订单数
  1278. * @param $from
  1279. * @param $to
  1280. * @return Order|array|\think\Model|null
  1281. * @throws \think\db\exception\DataNotFoundException
  1282. * @throws \think\db\exception\DbException
  1283. * @throws \think\db\exception\ModelNotFoundException
  1284. */
  1285. public function dailyStoreSaleVolumeSt($from,$to){
  1286. $res = $this->whereBetweenTime('create_time',$from,$to)//mysql 对int类型的 between and包含左右边界
  1287. ->where('pay_status',20)
  1288. ->field('sum(pay_price + rice_card_money) as sale_volume,count(order_id) as order_count')
  1289. ->find();
  1290. $res['sale_volume'] = $res['sale_volume']?:0;
  1291. $res['order_count'] = $res['order_count']?:0;
  1292. return $res;
  1293. }
  1294. /**
  1295. * 统计成功支付的订单数1.3.92,2022年5月11日 18:31:31
  1296. * @param $shopId
  1297. * @param $from
  1298. * @param $to
  1299. * @return int
  1300. */
  1301. public static function getUserOrderCount39($shopId,$from,$to,$monthly=false)
  1302. {
  1303. $model = CommissionsDetail::field( 'distinct order_id')
  1304. ->where('shop_id',$shopId)
  1305. ->where('commission_level',1);//6.推荐官直接推广的订单计入奖励金,间接推广的订单不计入。
  1306. if($monthly == true){
  1307. $model->where('clearing_status',1);
  1308. }else{
  1309. $model->where('clearing_status','<',2);
  1310. }
  1311. $orderIds = $model->whereBetweenTime('order_create_time', $from, $to)->column('order_id');
  1312. return count(array_unique($orderIds));
  1313. }
  1314. }