Orders.php 9.8 KB

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