MobileOrder.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. <?php
  2. namespace app\common\model;
  3. use app\admin\model\Admin;
  4. use app\admin\model\MobileOrderAdmin;
  5. use app\common\library\MobileConstant;
  6. use app\common\service\Refund;
  7. use app\common\service\SmsSend;
  8. use think\Db;
  9. use think\db\Query;
  10. use think\Model;
  11. /**
  12. * 配置模型
  13. * @method static static payed()
  14. * @method static static filterSaled()
  15. * @method static static expired()
  16. * @method $this filterShow($type)
  17. * @method $this waitPay()
  18. */
  19. class MobileOrder extends Model
  20. {
  21. use TraitModel;
  22. const STATUS_WAIT_SEND=10;
  23. const STATUS_CAN_SEND=15;
  24. const STATUS_REFUND=30;
  25. const STATUS_REFUNDED=90;
  26. public static $status=[
  27. 0=>'待付款',
  28. self::STATUS_WAIT_SEND=>'已付款',
  29. self::STATUS_CAN_SEND=>'可发货',
  30. 17=>'有号码未发货',
  31. 20=>'已发货待激活',
  32. 25=>'已完成',
  33. self::STATUS_REFUND=>'申请退款',
  34. 50=>'已关闭',
  35. 60=>'无号码',
  36. 70=>'换卡',
  37. 80=>'争议单',
  38. self::STATUS_REFUNDED=>'已退款',
  39. ];
  40. public static $refundAllowStatus=[
  41. self::STATUS_WAIT_SEND,
  42. 15,
  43. 17,
  44. 20,
  45. 60,
  46. 70,
  47. ];
  48. public static $flowStatus=[
  49. 0=>'待付款',//待付款
  50. 10=>'已付款未处理',//已付款未处理
  51. 15=>'待处理',//待处理
  52. 20=>'已提交运营商',//已提交运营商
  53. 23=>'已发货',//已发货
  54. 25=>'已完结',//已激活/已完结
  55. 110=>'审核失败',//审核失败
  56. ];
  57. public static $frontStatus=[
  58. 0,
  59. self::STATUS_WAIT_SEND,
  60. self::STATUS_CAN_SEND,
  61. 17,20,25,30,90,50,
  62. ];
  63. public static $payTypes=[
  64. 1=>'微信',
  65. 2=>'支付宝',
  66. 3=>'京东',
  67. ];
  68. protected $hidden=[
  69. 'status_bak',
  70. ];
  71. // 自动写入时间戳字段
  72. protected $autoWriteTimestamp = true;
  73. public function mobile(){
  74. return $this->belongsTo(Mobile::class);
  75. }
  76. public function info(){
  77. return $this->hasOne(MobileOrderInfo::class);
  78. }
  79. public function mind(){
  80. return $this->hasOne(MobileOrderMind::class);
  81. }
  82. public function operation(){
  83. return $this->hasMany(MobileOrderOperation::class)->order('mobile_order_operation.id','desc');
  84. }
  85. public function admin(){
  86. return $this->hasMany(MobileOrderAdmin::class);
  87. }
  88. public function status(){
  89. return $this->hasMany(MobileOrderStatus::class);
  90. }
  91. public function refundLog(){
  92. return $this->hasMany(MobileOrderRefundLog::class);
  93. }
  94. public function rules(){
  95. return $this->hasMany(MobileOrderRules::class);
  96. }
  97. public function proxy(){
  98. $columns=Admin::getTableInfo()['fields'];
  99. unset($columns['password']);
  100. return $this->belongsTo(Admin::class)->field($columns);
  101. }
  102. public function getAddressAttr($a,$b){
  103. return Area::getNameString($b['city']).$a;
  104. }
  105. public function setCityAttr($a){
  106. if(is_array($a)){
  107. return implode(',',$a);
  108. }
  109. return $a;
  110. }
  111. public function saveRules(){
  112. if($this['type']==1) {
  113. $mobile=$this['mobile'];
  114. $filters=MobileConstant::getFilters();
  115. $rules=[];
  116. foreach ($filters as $rule=>$filter){
  117. $fit=false;
  118. foreach ($filter as $column){
  119. if($mobile[$column]){
  120. $fit=true;
  121. break;
  122. }
  123. }
  124. if($fit){
  125. $rules[]=$rule;
  126. }
  127. }
  128. $this->rules()->saveAll($rules);
  129. }
  130. }
  131. protected static function init()
  132. {
  133. self::beforeInsert(function (self $mobileOrder){
  134. $mobileOrder['order_no']=order_no();
  135. $mobileOrder['expire_time']=time()+86400;
  136. $mobileOrder['s_id']=$mobileOrder['mobile']['s_id'];
  137. $mobileOrder['brand']=$mobileOrder['mobile']['brand'];
  138. #计算盈利
  139. $mobileOrder['amount_profit']=bcsub($mobileOrder['amount'],$mobileOrder['amount_di']);
  140. });
  141. self::afterInsert(function (self $mobileOrder){
  142. $mobileOrder->info()->save([
  143. 'mobile'=>$mobileOrder['mobile'],
  144. 'info'=>$mobileOrder['mobile']['info'],
  145. ]);
  146. #保存规律
  147. $mobileOrder->saveRules();
  148. });
  149. self::beforeUpdate(function (self $mobileOrder){
  150. $data=$mobileOrder->getChangedData();
  151. #记录status
  152. if(isset($data['status'])){
  153. $mobileOrder->status()->save([
  154. 'status'=>$mobileOrder->origin['status'],
  155. ]);
  156. }
  157. #物流信息
  158. if(!empty($data['trans_id'])){
  159. $mobileOrder['trans_name']=LogisticsCompany::getNameById($data['trans_id']);
  160. }
  161. if(isset($data['trans_id']) && !$data['trans_id']){
  162. $mobileOrder['trans_name']=null;
  163. }
  164. });
  165. }
  166. public function sendNotifyToUser(){
  167. $mobileOrder=$this;
  168. if($mobileOrder['trans_name'] && $mobileOrder['trans_no']) {
  169. SmsSend::orderSend($mobileOrder['phone'], $mobileOrder['trans_name'], $mobileOrder['trans_no']);
  170. }
  171. }
  172. public function scopeExpired(Query $query){
  173. $query->where('status',0)->where('expire_time','<',time())->where('amount','>',0);
  174. }
  175. public function cancel(){
  176. if($this['pay_time'] || $this['pay_time']!=0){
  177. return;
  178. }
  179. $this['status']=50;
  180. $this->save();
  181. }
  182. public function continuePay(){
  183. if($this['expire_time']<time()){
  184. throw_user('订单已过期');
  185. }
  186. if($this['status']!=0){
  187. throw_user('订单状态有误');
  188. }
  189. if($this['type']!=1){
  190. throw_user('该产品无需支付');
  191. }
  192. if(!$this['mobile']){
  193. throw_user('手机号不存在或已下架');
  194. }
  195. $this['mobile']->shouldBuy();
  196. }
  197. public function paySuccessCallback($payment=null,$data=[],$type='wechat'){
  198. $mobileOrder=$this;
  199. if(!empty($mobileOrder['pay_time'])){
  200. throw_user("手机订单已支付");
  201. }
  202. if($mobileOrder['type']==1) {
  203. $mobileOrder['status'] = MobileOrder::STATUS_WAIT_SEND;
  204. }else{
  205. $mobileOrder['status'] = 10;
  206. }
  207. if($payment) {
  208. $payConfig=get_addon_config('epay');
  209. $mobileOrder['pay_time'] = $payment['pay_time'];
  210. if ($type == 'wechat') {
  211. $mobileOrder['pay_type'] = 1;
  212. $mobileOrder['pay_no'] = $data['transaction_id'];
  213. $mobileOrder['pay_mid_wechat']=$payConfig['wechat']['mch_id'];
  214. } elseif ($type == 'alipay') {
  215. $mobileOrder['pay_type'] = 2;
  216. $mobileOrder['pay_no'] = $data['trade_no'];
  217. $mobileOrder['pay_mid_alipay']=$payConfig['alipay']['app_id'];
  218. }
  219. $mobileOrder['payment_id'] = $payment['id'];
  220. SmsSend::orderPayed($mobileOrder['phone']);
  221. }else{
  222. $mobileOrder['pay_time']=time();
  223. }
  224. if (!$mobileOrder->save()) {
  225. throw_user("订单保存失败");
  226. }
  227. Mobile::whenOrderPayed($mobileOrder->mobile);
  228. }
  229. public function scopePayed(Query $query){
  230. $query->where('status','>=',self::STATUS_WAIT_SEND);
  231. }
  232. public function originData(){
  233. return $this->origin;
  234. }
  235. public function checkAllowRefund(){
  236. if(!in_array($this['status'],self::$refundAllowStatus)){
  237. throw_user('当前状态不允许退款');
  238. }
  239. }
  240. public function makeUserRefund($reason){
  241. $this['status_bak']=$this['status'];
  242. $this['status']=self::STATUS_REFUND;
  243. $this['refund_reason']=$reason;
  244. $this->save();
  245. }
  246. public static function flowStatus(){
  247. $s=self::$flowStatus;
  248. return $s;
  249. }
  250. public function frontStatus(){
  251. return self::$frontStatus;
  252. }
  253. public function scopeFilterShow(Query $query,$type){
  254. if ($type==1){
  255. $query->whereIn('mobile_order.status',$this->frontStatus());
  256. }else{
  257. $query->whereIn('mobile_order.status',array_keys(self::flowStatus()));
  258. }
  259. }
  260. public function makeRefund($from,$user,$data){
  261. $model=$this;
  262. $model['amount_refund'] = $data['amount'];
  263. $model['refund_no'] = session_create_id();
  264. $model['refund_reason']=$data['refund_reason'];
  265. $statusBak=$model['status_bak'];
  266. $model['status_bak']=$model['status'];
  267. if ($data['pass']) {
  268. if ($data['amount'] > $model['amount']) {
  269. throw_user('退款金额不能大于付款金额');
  270. }
  271. Refund::setType($model)->refund();
  272. $model['status'] = self::STATUS_REFUNDED;
  273. SmsSend::orderRefund($model['phone']);
  274. #退款盈利哦
  275. $model['amount_profit']=bcsub($model['amount'],$model['amount_refund']);
  276. }else{
  277. $model['amount_refund']=0;
  278. $model['status'] = $statusBak;
  279. }
  280. $model->save();
  281. $model->refundLog()->save(MobileOrderRefundLog::withRefund($from,$user,$data));
  282. }
  283. public function flowOrderSubmit(){
  284. $this['status']=15;
  285. }
  286. public function scopeWaitPay(Query $query){
  287. $query->where('status',0);
  288. }
  289. #销售金额
  290. public function scopeFilterSaled(Query $query){
  291. $query->where('status','>',0);
  292. }
  293. #发货
  294. public function dealSend($trans_no,$trans_id){
  295. $this['trans_no']=$trans_no;
  296. $this['trans_id']=$trans_id;
  297. if($this['type']==1){
  298. $this['status']=20;
  299. }else{
  300. $this['status']=23;
  301. }
  302. $this->save();
  303. $this->sendNotifyToUser();
  304. }
  305. }