Orders.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. <?php
  2. namespace app\common\model;
  3. use app\common\service\UserSvc;
  4. use think\db\Query;
  5. use think\Model;
  6. use Yansongda\Supports\Arr;
  7. /**
  8. * @property OrderInfo info
  9. * @property User user
  10. * @property bool is_wait_pay
  11. * @property Payment payment
  12. * @property int user_id
  13. * @property int status
  14. * @property int admin_id
  15. * @method static static payed()
  16. * @method Query hasGoods($goods_id)
  17. */
  18. class Orders extends Model
  19. {
  20. protected $type=[
  21. 'tax'=>'json',
  22. ];
  23. #未支付过期时间
  24. const EXP_PAY=1800;
  25. #线下付款超时
  26. const EXP_PAY_OFFLINE=3*86400;
  27. #代付超时
  28. const EXP_PAY_DF=3*86400;
  29. #待收货过期时间
  30. const EXP_REC=30*86400;
  31. #已完成可售后时间
  32. const EXP_OVER=7*86400;
  33. const PT_QYWY=1;
  34. const PT_WX=2;
  35. const PT_ZFB=3;
  36. const PT_YL=4;
  37. const PT_DF=5;
  38. const PT_OFF=6;
  39. public static $pay_types=[
  40. self::PT_QYWY=>'企业网银',
  41. self::PT_WX=>'微信',
  42. self::PT_ZFB=>'支付宝',
  43. self::PT_YL=>'银联',
  44. self::PT_DF=>'代付',
  45. self::PT_OFF=>'线下支付',
  46. ];
  47. const S_WAIT_PAY=0;
  48. const S_WAIT_SEND=5;
  49. const S_WAIT_REC=10;
  50. const S_OVER=20;
  51. const S_CANCEL=30;
  52. //const S_REFUND=40;
  53. public static $status=[
  54. self::S_WAIT_PAY=>'待支付',
  55. self::S_WAIT_SEND=>'待发货',
  56. self::S_WAIT_REC=>'待收货',
  57. self::S_OVER=>'已完成',
  58. self::S_CANCEL=>'已取消',
  59. //self::S_REFUND=>'退款退货',
  60. ];
  61. /**
  62. * @return string[]
  63. */
  64. public static function getStatus(): array
  65. {
  66. return self::$status;
  67. }
  68. protected $autoWriteTimestamp=true;
  69. public function info(){
  70. return $this->hasMany(OrderInfo::class,'order_id');
  71. }
  72. public function user(){
  73. return $this->belongsTo(User::class);
  74. }
  75. public function payment(){
  76. return $this->belongsTo(Payment::class);
  77. }
  78. public function address(){
  79. return $this->hasOne(OrderAddress::class,'order_id');
  80. }
  81. public function logistics(){
  82. return $this->hasOne(OrderLogistics::class,'order_id');
  83. }
  84. public function voucher(){
  85. return $this->hasOne(OrderVoucher::class,'order_id');
  86. }
  87. /*public function getGoodsAttr(){
  88. $info=$this->info()->with(['goodsBak'])->find();
  89. $goods=$info['goodsBak'];
  90. return [
  91. 'goods'=>$goods['goods'],
  92. 'sku'=>$goods['sku'],
  93. ];
  94. }*/
  95. public function getIsWaitPayAttr($_,$model){
  96. return $model['status']==self::S_WAIT_PAY;
  97. }
  98. public function getIsEvaledAttr($_,$model){
  99. $goodsIds=array_unique(OrderInfo::where('order_id',$model['id'])->column('goods_id'));
  100. $has=GoodsEval::where('order_id',$model['id'])->whereIn('goods_id',$goodsIds)->count();
  101. return $has==count($goodsIds);
  102. }
  103. public function getPayTypeTextAttr($_,$model){
  104. if(empty($model['pay_type'])){
  105. return null;
  106. }
  107. return self::getPayTypes()[$model['pay_type']];
  108. }
  109. /**
  110. * @return string[]
  111. */
  112. public static function getPayTypes(): array
  113. {
  114. return self::$pay_types;
  115. }
  116. public static function continue($status){
  117. $now=time();
  118. return self::where('status',$status)->limit(20)->where('continue_expire_time','<',$now);
  119. }
  120. #未支付过期
  121. public function makeCancel(){
  122. $this['status']=self::S_CANCEL;
  123. $this['cancel_time']=time();
  124. foreach ($this->info as $orderInfo){
  125. Goods::where('id',$orderInfo['goods_id'])->setDec('num_sell',$orderInfo['num']);
  126. GoodsSku::where('id',$orderInfo['goods_sku_id'])->setDec('num_sell',$orderInfo['num']);
  127. }
  128. $this->save();
  129. }
  130. #待收货过期
  131. public function makeRec(){
  132. $this['status']=self::S_OVER;
  133. $this['rec_time']=time();
  134. $this->save();
  135. }
  136. #支付
  137. public function makePayInfo($pay_type){
  138. $user=$this->user;
  139. if($pay_type==self::PT_OFF){
  140. $this['continue_expire_time']=strtotime(date('Y-m-d 00:00:00'))+self::EXP_PAY_OFFLINE+86400-1;
  141. $this->save();
  142. return [
  143. 'account_name'=>config('site.account_name'),
  144. 'bank_no'=>config('site.account_bank_no'),
  145. 'bank_name'=>config('site.accout_bank_name'),
  146. ];
  147. }elseif($pay_type==self::PT_DF){
  148. $this['continue_expire_time']=strtotime(date('Y-m-d 00:00:00'))+self::EXP_PAY_DF+86400-1;
  149. $this->save();
  150. return [
  151. 'expire'=>$this['continue_expire_time'],
  152. ];
  153. }else{
  154. $this['continue_expire_time']=time()+self::EXP_PAY;
  155. $this->save();
  156. }
  157. if($pay_type==self::PT_OFF){
  158. return [
  159. 'account_name'=>config('site.account_name'),
  160. 'bank_no'=>config('site.account_bank_no'),
  161. 'bank_name'=>config('site.accout_bank_name'),
  162. ];
  163. }
  164. return Payment::pay(
  165. $user,
  166. $pay_type,
  167. $this['amount_pay'],
  168. $this['id'],
  169. "订单【{$this['order_no']}】付款",
  170. $this->getTable(),
  171. );
  172. }
  173. #支付后
  174. public static function makePayed(Payment $payment){
  175. $order=Orders::find($payment['payment_id']);
  176. if(!$order){
  177. return false;
  178. }
  179. if(!$order->isNotPay()){
  180. return false;
  181. }
  182. $order['payment_id']=$payment['id'];
  183. #代付
  184. if($order['user_id']!=$payment->user_id){
  185. }
  186. $order->save();
  187. $order->makePay($payment['pay_type']);
  188. return true;
  189. }
  190. public function makePay($payType=self::PT_OFF){
  191. $order=$this;
  192. $order['status']=self::S_WAIT_SEND;
  193. $order['pay_time']=time();
  194. $order['pay_type']=$payType;
  195. $order->save();
  196. }
  197. #发货
  198. public function makeSend($logistics,$data){
  199. $newData=Arr::only($data,['com_id','trans_no','remark']);
  200. if(!$logistics) {
  201. $this->logistics()->save($newData);
  202. $this['status']=self::S_WAIT_REC;
  203. $this['send_time']=time();
  204. $this->save();
  205. }else{
  206. $logistics->save($newData);
  207. }
  208. }
  209. #确认收货
  210. public function makeOver(){
  211. $this['status']=self::S_OVER;
  212. $this->save();
  213. }
  214. #发放提成
  215. public function makeSendCommission(){
  216. if($this->admin_id){
  217. }
  218. }
  219. /*
  220. * 是否未支付
  221. */
  222. public function isNotPay(){
  223. return $this['status']===self::S_WAIT_PAY;
  224. }
  225. /**
  226. * 是否允许退款
  227. */
  228. public function allowRefund(){
  229. return !in_array($this['status'],[
  230. self::S_WAIT_PAY,
  231. self::S_CANCEL,
  232. ]);
  233. }
  234. /**
  235. * 是否允许取消
  236. */
  237. public function allowCancel(){
  238. return in_array($this['status'],[
  239. self::S_WAIT_PAY,
  240. ]);
  241. }
  242. /**
  243. * 是否允许确认收货
  244. */
  245. public function allowOver(){
  246. return in_array($this['status'],[
  247. self::S_WAIT_REC,
  248. ]);
  249. }
  250. public function scopePayed(Query $query){
  251. $query->whereNotIn('status',[self::S_CANCEL,self::S_WAIT_PAY]);
  252. }
  253. public function scopeHasGoods(Query $query,$goods_id){
  254. $query->whereExists(
  255. OrderInfo::whereRaw("orders.id=order_info.order_id and order_info.goods_id={$goods_id}")->buildSql()
  256. );
  257. }
  258. protected static function init()
  259. {
  260. self::beforeInsert(function (self $orders){
  261. #优惠总金额
  262. //$orders['amount_discount']=bcAddAll($orders['amount_coupon']??0,$orders['amount_coupon_kill']);
  263. #过期时间
  264. $orders['continue_expire_time']=time()+self::EXP_PAY;
  265. #去除无发票的
  266. if(empty($orders['tax']) || !in_array($orders['tax']['paper_type']??0,[1,2])){
  267. $orders['tax']=null;
  268. }
  269. #属于哪个销售员
  270. $orders['admin_id']=UserSvc::getSellerId($orders->user_id);
  271. });
  272. self::afterInsert(function (self $orders){
  273. #添加发票
  274. UserTax::fromOrder($orders);
  275. #合同链接
  276. $contract_link=request()->root(true)."/contract/view/show/{$orders['id']}";
  277. $orders->where('id',$orders['id'])->update([
  278. 'contract_link'=>$contract_link,
  279. ]);
  280. });
  281. self::beforeUpdate(function (self $order){
  282. $data=$order->getChangedData();
  283. if(!empty($data['status'])){
  284. #已完成可售后时间
  285. if($data['status']==self::S_OVER){
  286. $order['continue_expire_time']=time()+self::EXP_OVER;
  287. }
  288. #待收货过期时间
  289. elseif ($data['status']==self::S_WAIT_REC){
  290. $order['continue_expire_time']=time()+self::EXP_REC;
  291. }
  292. }
  293. });
  294. self::afterUpdate(function (self $orders){
  295. if(!empty($orders->status) && $orders->status==self::S_WAIT_SEND){
  296. Transaction::addTransaction($orders);
  297. }
  298. #如果已完成发放提成
  299. if(!empty($orders->status) && $orders->status==self::S_OVER){
  300. }
  301. });
  302. }
  303. }