Orders.php 8.1 KB

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