<?php namespace app\common\model; use think\Model; use think\Db; class Order extends Model { // 开启自动写入时间戳字段 protected $autoWriteTimestamp = 'int'; // 定义时间戳字段名 protected $createTime = 'createtime'; protected $updateTime = 'updatetime'; protected $append = [ 'type', ]; // 错误提示 public $error = ''; /** * 订单商品列表 */ public function goods() { return $this->hasMany('OrderGoods'); } /** * 关联订单收货地址表 */ public function address() { return $this->hasOne('OrderAddress'); } /** * 关联售后表 */ public function refund() { return $this->hasOne('OrderRefund'); } /** * 订单状态 */ public function getTypeAttr($value,$data){ $type = ['name'=>'待支付','value'=>'payment']; if($data['refund_status'] > '0'){ if($this['refund']['type'] == '1'){ $refund_status_arr = ['1'=>'退款申请中','2'=>'已退款','3'=>'已拒绝']; $type = [ 'name' => $refund_status_arr[$data['refund_status']], 'value' => 'refund_'.$data['refund_status'] ]; }else{ $refund_status_arr = ['1'=>'退货申请中','2'=>'已退款','3'=>'已拒绝']; $type = [ 'name' => $refund_status_arr[$data['refund_status']], 'value' => 'return_goods_'.$data['refund_status'] ]; } }else{ if($data['pay_status'] == '0'){ $type = [ 'name' => '待支付', 'value' => 'payment' ]; }else{ if($data['delivery_status'] == '0'){ $type = [ 'name' => '待发货', 'value' => 'delivery' ]; }else{ if($data['receive_status'] == '0'){ $type = [ 'name' => '待收货', 'value' => 'receive' ]; }else{ if($data['appraise_status'] == '0'){ $type = [ 'name' => '待评价', 'value' => 'appraise' ]; }else{ $type = [ 'name' => '已完成', 'value' => 'completed' ]; } } } } } return $type; } /** * 新增订单 */ public function add($user_id, $order) { if (empty($order['address'])) { $this->error = '请先选择收货地址'; return false; } Db::startTrans(); // 记录订单信息 $this->save([ 'user_id' => $user_id, 'order_no' => date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8), 'total_price' => $order['total_price'], 'order_price' => $order['order_price'], 'express_price' => $order['express_price'], 'reduce_price' => $order['reduce_price'], 'user_coupon_id' => $order['coupon']['user_coupon_id'], 'coupon_price' => $order['coupon']['coupon_price'], 'score' => $order['score']['score_price'] > 0 ? $order['score']['use_score'] : 0, 'score_price' => $order['score']['score_price'] ]); // 订单商品列表 $goodsList = []; foreach ($order['goods_list'] as $goods) { $goodsList[] = [ 'goods_id' => $goods['goods_id'], 'goods_name' => $goods['goods']['goods_name'], 'goods_image' => $goods['goods']['goods_image'], 'goods_price' => $goods['goods_price'], 'goods_num' => $goods['goods_num'], 'user_size_id' => !empty($goods['user_size']) ? $goods['user_size']['id'] : 0, 'make_type' => $goods['make_type'], 'goods_style' => $goods['goods_style'], 'spec_sku_id' => $goods['goods_sku']['spec_sku_id'], 'goods_attr' => $goods['goods_sku']['goods_attr'], 'goods_total_price' => $goods['goods_total_price'] ]; } // 保存订单商品信息 $this->goods()->saveAll($goodsList); // 记录收货地址 $this->address()->save([ 'user_address_id' => $order['address']['id'], 'name' => $order['address']['name'], 'phone' => $order['address']['phone'], 'province_id' => $order['address']['province_id'], 'city_id' => $order['address']['city_id'], 'district_id' => $order['address']['district_id'], 'detail' => $order['address']['detail'], ]); // 用掉优惠券 if($order['coupon']['user_coupon_id'] > 0){ UserCoupon::where('id',$order['coupon']['user_coupon_id'])->setField('status','2'); } // 用掉积分 if($order['score']['use_score'] > 0){ User::score(-$order['score']['use_score'],$user_id,'订单支付-使用积分'); } Db::commit(); return true; } /** * 用户中心订单列表 */ public function getList($user_id, $type = 'all') { // 筛选条件 $filter = []; // 排序方式 $order = ['createtime' => 'desc']; // 订单数据类型 switch ($type) { case 'all': break; case 'payment';//待支付 $filter['pay_status'] = '0'; $filter['refund_status'] = '0'; $order = ['createtime' => 'asc']; break; case 'delivery';//待发货 $filter['pay_status'] = '1'; $filter['delivery_status'] = '0'; $filter['refund_status'] = '0'; break; case 'receive';//待收货 $filter['pay_status'] = '1'; $filter['delivery_status'] = '1'; $filter['receive_status'] = '0'; $filter['refund_status'] = '0'; break; case 'appraise';//待评价 $filter['pay_status'] = '1'; $filter['delivery_status'] = '1'; $filter['receive_status'] = '1'; $filter['appraise_status'] = '0'; $filter['refund_status'] = '0'; break; } return $this->with(['goods'=>['user_size'],'address']) ->where('user_id', $user_id) ->where('order_status', '<>', '2') ->where($filter) ->order($order) ->select(); } /** * 订单详情 */ public function getUserOrderDetail($order_id, $user_id) { if (!$order = $this->get([ 'id' => $order_id, 'user_id' => $user_id, 'order_status' => ['<>', '2'] ], ['goods' => ['goods','user_size','spec'], 'address', 'refund'])) { $this->setError('订单不存在'); return false; } return $order; } /** * 取消订单 */ public function cancel() { if ($this['pay_status'] == '1') { $this->setError('已付款订单不可取消'); return false; } // 退回优惠券 if($this['user_coupon_id'] > 0){ UserCoupon::where('id',$this['user_coupon_id'])->setField('status','1'); } // 退回积分 if($this['score'] > 0){ User::score(-$this['score'],$this['user_id'],'取消订单,退回积分'); } return $this->save(['order_status' => '2']); } /** * 提醒发货 */ public function remind() { if ($this['delivery_status'] == '1') { $this->setError('订单已发货'); return false; } if(cache('remind_'.$this['id'])){ $this->setError('您已提醒发货,请稍后再提醒'); return false; } cache('remind_'.$this['id'],$this['id'],60); return true; } /** * 查询物流 */ public function orderTraces() { if ($this['delivery_status'] == '0') { $this->setError('该订单不合法'); return false; } $kdniao = new \addons\kdniao\library\Kdniao(); $wuliu = $kdniao->getOrderTracesByJson($this['express_code'], $this['express_no']); if($wuliu == -1){ $this->setError('未设置接口配置!请在插件管理中配置!'); return false; } $wuliu = json_decode($wuliu, true); return isset($wuliu['Traces']) && count($wuliu['Traces']) ? array_reverse($wuliu['Traces']) : [['AcceptStation' => '暂无物流信息', 'AcceptTime' => date('Y-m-d H:i:s', time())]]; } /** * 申请退款 */ public function toRefund($post) { if($this['pay_status'] == '0'){ $this->setError('未支付非法订单!'); return false; } if(empty($post['reason'])){ $this->setError('请选择退款原因!'); return false; } if($this['refund_status'] == '2'){ $this->setError('订单已退款!'); return false; } if($this['refund_status'] == '1'){ $this->setError('正在申请退款中!'); return false; } if($this['delivery_status'] == '1'){ $this->setError('订单当前无法退款!'); return false; } Db::startTrans(); if(!$this['refund']){ $this->refund()->save(array_merge([ 'type' => '1' ],$post)); }else{ $this['refund']->save($post); } $this->save(['refund_status'=>'1']); Db::commit(); return true; } /** * 申请退货 */ public function returnGoods($post) { if(empty($post['reason'])){ $this->setError('请选择退货原因!'); return false; } if($this['refund_status'] == '2'){ $this->setError('订单已退货!'); return false; } if($this['refund_status'] == '1'){ $this->setError('正在申请退货中!'); return false; } if($this['receive_status'] == '1'){ $this->setError('订单当前无法退货!'); return false; } Db::startTrans(); if(!$this['refund']){ $this->refund()->save(array_merge([ 'type' => '2' ],$post)); }else{ $this['refund']->save($post); } $this->save(['refund_status'=>'1']); Db::commit(); return true; } /** * 确认收货 */ public function receive() { if ($this['delivery_status'] == '0' || $this['receive_status'] == '1') { $this->setError('该订单不合法'); return false; } return $this->save([ 'receive_status' => '1', 'receive_time' => time(), 'order_status' => '3' ]); } /** * 判断商品库存不足 (未付款订单) */ public function checkGoodsStatusFromOrder($goodsList) { foreach ($goodsList as $order_goods) { $goods = Goods::get($order_goods['goods_id'],['spec_rel.spec']); // 判断商品是否下架 if ($goods['issale'] != '1') { $this->setError('很抱歉,商品 [' . $goods['goods_name'] . '] 已下架'); return false; } // 付款减库存 if ($goods['ismake'] == '0' && $goods->getGoodsSku($order_goods['spec_sku_id'])['stock_num'] < 1) { $this->setError('很抱歉,商品 [' . $goods['goods_name'] . '] 库存不足'); return false; } } return true; } /** * 待支付订单时效为24小时,超时将成为无效订单,系统自动将订单从待付款页面移出。 */ public function checkPaymentOrder($user_id) { $list = $this->getList($user_id,'payment'); foreach($list as $v){ $v->cancel(); } return true; } /** * 设置错误信息 * @param $error */ private function setError($error) { empty($this->error) && $this->error = $error; } /** * 是否存在错误 * @return bool */ private function hasError() { return !empty($this->error); } /** * 获取错误信息 * @return string */ public function getError() { return $this->error; } }