123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- <?php
- // +----------------------------------------------------------------------
- // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
- // +----------------------------------------------------------------------
- // | Author: 萤火科技 <admin@yiovo.com>
- // +----------------------------------------------------------------------
- declare (strict_types=1);
- namespace app\api\model;
- use app\api\model\Setting as SettingModel;
- use app\api\service\User as UserService;
- use app\api\model\OrderGoods as OrderGoodsModel;
- use app\common\model\order\RefundHis as RefundHisModel;
- use app\common\model\order\RefundHis;
- use app\common\model\OrderRefund as OrderRefundModel;
- use app\common\enum\order\refund\RefundType as RefundTypeEnum;
- use app\common\enum\order\refund\AuditStatus as AuditStatusEnum;
- use app\common\enum\order\refund\RefundStatus as RefundStatusEnum;
- use app\common\enum\order\refund\FinanceRefundStatus as FinanceRefundStatusEnum;
- use app\common\exception\BaseException;
- use app\common\service\Kuaidi as KuaidiService;
- use app\common\model\Express as ExpressModel;
- use app\store\model\OrderGoods;
- /**
- * 售后单模型
- * Class OrderRefund
- * @package app\api\model
- */
- class OrderRefund extends OrderRefundModel
- {
- /**
- * 隐藏字段
- * @var array
- */
- protected $hidden = [
- 'store_id',
- 'update_time'
- ];
- /**
- * 追加字段
- * @var array
- */
- protected $append = [
- 'state_text', // 售后单状态
- 'dfh_time', // 待用户发货倒计时
- ];
- /**
- * 售后单状态文字描述
- * @param $value
- * @param $data
- * @return string
- */
- public function getStateTextAttr($value, $data)
- {
- if($data['delivery_type']==10){
- // 已完成
- if ($data['status'] == RefundStatusEnum::COMPLETED) {
- return ['value'=>1,'name'=>'退款成功'];
- }
- // 已取消
- if ($data['status'] == RefundStatusEnum::CANCELLED) {
- return ['value'=>2,'name'=>'已取消'];
- }
- // 已拒绝
- if ($data['status'] == RefundStatusEnum::REJECTED) {
- return ['value'=>3,'name'=>'平台已拒绝'];
- }
- //已关闭 -用户超时未退货,系统自动关闭售后单
- if ($data['status'] == RefundStatusEnum::CLOSE) {
- return ['value'=>7,'name'=>'已关闭'];
- }
- // 进行中
- if ($data['status'] == RefundStatusEnum::NORMAL) {
- //退货退款
- if ($data['type'] == RefundTypeEnum::RETURN) {
- if (isset($data['audit_status_zg'])&&$data['audit_status_zg'] == AuditStatusEnum::WAIT) {
- return ['value'=>0,'name'=>'待审核'];
- }
- if(isset($data['is_user_send'])&&$data['is_user_send']){ //已发货
- if($data['is_receipt']==1){//已收货
- return ['value'=>6,'name'=>'待退款'];
- }
- if ($data['is_receipt']==2) {
- return ['value'=>8,'name'=>'仓库拒绝收货'];
- }else{
- return ['value'=>5,'name'=>'待仓库收货'];
- }
-
- }else{
- return ['value'=>4,'name'=>'待买家退货'];
- }
- }else{
- if (isset($data['audit_status'])&&$data['audit_status'] == AuditStatusEnum::WAIT) { //仅退款不需要主管审核
- return ['value'=>0,'name'=>'待审核'];
- }
- if($data['finance_refund'] == FinanceRefundStatusEnum::WAIT){
- return ['value'=>6,'name'=>'待退款'];
- }
- }
- }
- }
- if($data['delivery_type']==20){
- if ($data['status'] == RefundStatusEnum::COMPLETED) {
- return ['value'=>1,'name'=>'退款成功'];
- }
- //已关闭 -用户超时未退货,系统自动关闭售后单
- if ($data['status'] == RefundStatusEnum::CLOSE) {
- return ['value'=>7,'name'=>'已关闭'];
- }
- if ($data['status'] == RefundStatusEnum::NORMAL) {
- if (isset($data['audit_status'])&&$data['audit_status'] == AuditStatusEnum::WAIT) {
- return ['value'=>0,'name'=>'待审核'];
- }
- if ($data['audit_status'] == AuditStatusEnum::REVIEWED&&$data['finance_refund']==0) {
- return ['value'=>6,'name'=>'待退款'];
- }
- }
- }
-
- return $value;
- }
- /**
- * 待用户发货倒计时时间戳
- * @param $value
- * @param $data
- * @return int
- * @author: zjwhust
- * @Time: 2021/10/8 17:06
- */
- public function getDfhTimeAttr($value,$data){
- if (
- $data['type'] == RefundTypeEnum::RETURN
- && $data['audit_status'] == AuditStatusEnum::REVIEWED
- && $data['audit_status_zg'] == AuditStatusEnum::REVIEWED
- && $data['is_user_send'] == 0
- && $data['status'] == RefundStatusEnum::NORMAL
- ) {
- $now = time();
- $delay_time = 86400 * 7;//获取待发货时间
- if(env('SERVE_ENV')=='test'){
- $delay_time = 300;//测试超时退款5分钟
- }
- if(($now-$data['approved_time'])<$delay_time){ //
- return $data['approved_time']+$delay_time-$now;
- }
- }
- return 0;
- }
- /**
- * 获取用户售后单列表
- * @param int $state 售后单状态 -1为全部
- * @return \think\Paginator
- * @throws \app\common\exception\BaseException
- * @throws \think\db\exception\DbException
- */
- public function getList(int $state = -1)
- {
- // 检索查询条件
- $filter = [];
- // 售后单状态
- $state > -1 && $filter[] = ['status', '=', $state];
- // 当前用户ID
- $userId = UserService::getCurrentLoginUserId();
- // 查询列表记录
- return $this->with(['orderGoods.image', 'orderGoodsAll.image'])
- ->where($filter)
- ->where('user_id', '=', $userId)
- ->order(['create_time' => 'desc'])
- ->paginate(15)
- ->each(function($item) {
- if (!$item['order_goods_id']) {
- // 整单退款
- $orderGoods = $item['orderGoodsAll'];
- } else {
- $orderGoods = [$item['orderGoods']];
- }
- unset($item['orderGoods'], $item['orderGoodsAll']);
- $item['orderGoods'] = $orderGoods;
- });
- }
- /**
- * 获取数量
- * @return int
- * @throws BaseException
- */
- public function getCount()
- {
- // 当前用户ID
- $userId = UserService::getCurrentLoginUserId();
- return $this->where('user_id', '=', $userId)
- ->where('status', '=', 0)
- ->count();
- }
- /**
- * 获取当前用户的售后单详情
- * @param int $orderRefundId 售后单ID
- * @param bool $isWith 是否关联
- * @return static|null
- * @throws BaseException
- */
- public static function getDetail(int $orderRefundId, $isWith = false)
- {
- // 关联查询
- $with = $isWith ? ['orderGoods' => ['image'], 'orderGoodsAll' => ['image'], 'address','shops'] : [];
- // 获取记录
- $detail = static::detail([
- 'user_id' => UserService::getCurrentLoginUserId(),
- 'order_refund_id' => $orderRefundId
- ], $with);
- // $detail = static::where("order_refund_id",$orderRefundId)->find();
- if (empty($detail)) throwError('未找到该售后单');
- if (!$detail['order_goods_id']) {
- // 整单退款
- $orderGoods = $detail['orderGoodsAll'];
- } else {
- $orderGoods = [$detail['orderGoods']];
- }
- unset($detail['orderGoods'], $detail['orderGoodsAll']);
- $detail['orderGoods'] = $orderGoods;
- return $detail;
- }
- /**
- * 订单商品详情
- * @param int $orderGoodsId 订单商品ID
- * @return \app\common\model\OrderGoods|null
- * @throws BaseException
- */
- public function getRefundGoods(int $orderGoodsId)
- {
- $goods = OrderGoodsModel::detail($orderGoodsId);
- if (isset($goods['refund']) && !empty($goods['refund'])) {
- throwError('当前商品已申请售后');
- }
- return $goods;
- }
- /**
- * 用户撤销申请
- * @param $data
- * @return false|int
- */
- public function revoke()
- {
- $user = UserService::getCurrentLoginUser(true);
- $type = false;
- if($this['status'] == RefundStatusEnum::REJECTED){//已拒绝
- $type = true;
- }else{
- if($this['status'] == RefundStatusEnum::NORMAL){//进行中&待审核
- if($this['delivery_type']==10){
- if ($this['type'] == RefundTypeEnum::RETURN) {
- if ($this['audit_status_zg'] == AuditStatusEnum::WAIT) {
- $type = true;
- }
- }else{
- if ($this['audit_status'] == AuditStatusEnum::WAIT) { //仅退款不需要主管审核
- $type = true;
- }
- }
- }
- //自提单 当门店未审核时可以撤回
- if($this['delivery_type']==20){
- if ($this['audit_status'] == AuditStatusEnum::WAIT) { //仅退款不需要主管审核
- $type = true;
- }
- }
- }
- }
- if($type){
- return $this->transaction(function () use ($user) {
- if($this['delivery_type']==10){
- $this->save([
- 'status' => RefundStatusEnum::CANCELLED,
- ]);
- }
- //门店自提单自动关闭
- if($this['delivery_type']==20){
- $this->save([
- 'status' => RefundStatusEnum::CLOSE,
- ]);
- }
-
- //订单商品解冻
- OrderGoodsModel::updateBase(['frozen_status'=>0], ['order_goods_id'=>$this['order_goods_id']]);
- $json_str = json_encode(["买家已撤销申请,退款已关闭"]);
- (new RefundHisModel())->add($this['order_refund_id'],$user['nick_name'],4,$json_str,'','买家','撤销申请');
- return true;
- });
- }
- $this->error = '当前售后单不合法,不允许该操作';
- return false;
- }
- /**
- * 用户发货
- * @param $data
- * @return false|int
- */
- public function delivery(array $data)
- {
- if (
- $this['type'] != RefundTypeEnum::RETURN
- || $this['audit_status_zg'] != AuditStatusEnum::REVIEWED
- || $this['is_user_send'] != 0
- ) {
- $this->error = '当前售后单不合法,不允许该操作';
- return false;
- }
- if ($data['expressId'] <= 0) {
- $this->error = '请选择物流公司';
- return false;
- }
- if (empty($data['expressNo'])) {
- $this->error = '请填写物流单号';
- return false;
- }
- if (empty($data['expressCompany'])) {
- $this->error = '请填写物流公司名称';
- return false;
- }
- if (isset($data['expressDesc']) && mb_strlen($data['expressDesc'])>50) {
- $this->error = '退货字数上限超过了50字';
- return false;
- }
- $express = ExpressModel::detail($data['expressId']);
- // 请求快递100订阅接口
- $subscribe = KuaidiService::subscribe($data['expressNo'], 2,$express['kuaidi100_code']??'');
- if(!$subscribe->result){
- if(stripos($subscribe->message,"重复订阅") === false){ //重复订阅允许提交物流
- $this->error = '物流单号订阅异常:'.$subscribe->message;
- return false;
- }
- }
- $user = UserService::getCurrentLoginUser(true);
- return $this->transaction(function () use ($data,$user) {
- $this->save([
- 'is_user_send' => 1,
- 'send_time' => time(),
- 'express_id' => (int)$data['expressId'],
- 'express_no' => $data['expressNo'],
- 'express_company' => $data['expressCompany'],
- 'express_desc' => $data['expressDesc']??'',
- ]);
- $json_str = json_encode(["买家寄回商品","快递公司:".$data['expressCompany'],"物流单号:".$data['expressNo']]);
- (new RefundHisModel())->add($this['order_refund_id'],$user['nick_name'],7,$json_str,'','买家','买家填写物流单号');
- return true;
- });
- }
- /**
- * 门店审核售后单
- * @param $data
- * @return false|int
- */
- public function auditStatus($param,$user){
- // 验证订单是否合法
- // 条件1: 门店审核状态不在审核中
- // 条件2: 售后单状态不在进行中
- if ($this['audit_status'] != 0 || $this['status'] != 0) {
- $this->error = '该售后单已经处理';
- return false;
- }
- return $this->transaction(function () use ($param,$user) {
- // 更新售后单状态
- $status = $this->save([
- 'audit_status' => $param['audit_status'],
- 'refuse_desc' => $param['audit_status']==20 ? $param['refuse_desc'] : '',
- 'refuse_images' => $param['audit_status']==20 ? $param['refuse_images']??'' : '',
- 'status' => $param['audit_status']==20 ? 40 : 0,
- 'hx_refund_time' => time(),
- 'hx_refund_user_id' => UserService::getCurrentLoginUserId(),
- 'is_user_send' => 1,
- 'is_receipt' => 1,
- ]);
- if($this['order_goods_id']>0) {
- // OrderGoodsModel::where('order_goods_id', $this['order_goods_id'])->update(['frozen_status' => 0]);
- }
- if($param['audit_status']==20){
- $json_str = json_encode(["处理结果:拒绝","拒绝理由:".$param['refuse_desc'],"门店拒绝退货,退款单关闭"]);
- $his_type = 13;
- $name = $this['shops']['shop_name'];
- $pf_operator = $user['nick_name']."(".$user['mobile'].")";
- (new RefundHis())->add($this['order_refund_id'],$name,$his_type,$json_str,$param['refuse_images'],$pf_operator,'拒绝并关闭退货单');
- }else{
- $json_str = json_encode(["处理结果:同意","门店同意退货,等待财务退款"]);
- $his_type = 12;
- $name = $this['shops']['shop_name'];
- $pf_operator = $user['nick_name']."(".$user['mobile'].")";
- (new RefundHis())->add($this['order_refund_id'],$name,$his_type,$json_str,'',$pf_operator,'同意退货并确认收货');
- }
- return $status;
- });
- }
- /**
- * 新增售后单记录
- * @param int $orderGoodsId 订单商品ID
- * @param array $data 用户提交的表单数据
- * @return mixed
- * @throws BaseException
- */
- public function apply(int $orderGoodsId, array $data)
- {
- // 订单商品详情
- $goods = $this->getRefundGoods($orderGoodsId);
- return $this->transaction(function () use ($orderGoodsId, $data, $goods) {
- // 新增售后单记录
- $this->save([
- 'order_goods_id' => $orderGoodsId,
- 'order_id' => $goods['order_id'],
- 'user_id' => UserService::getCurrentLoginUserId(),
- 'type' => $data['type'],
- 'apply_desc' => $data['content'],
- 'audit_status' => AuditStatusEnum::WAIT,
- 'status' => 0,
- 'store_id' => self::$storeId
- ]);
- // 记录凭证图片关系
- if (isset($data['images']) && !empty($data['images'])) {
- $this->saveImages((int)$this['order_refund_id'], $data['images']);
- }
- return true;
- });
- }
- /**
- * 记录售后单图片
- * @param int $orderRefundId 售后单ID
- * @param array $images 图片列表
- * @return bool
- */
- private function saveImages(int $orderRefundId, array $images)
- {
- // 生成评价图片数据
- $data = [];
- foreach ($images as $imageId) {
- $data[] = [
- 'order_refund_id' => $orderRefundId,
- 'image_id' => $imageId,
- 'store_id' => self::$storeId
- ];
- }
- return !empty($data) && (new OrderRefundImage)->addAll($data) !== false;
- }
- }
|