MobileOrder.php 9.9 KB

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