You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yanzong/app/api/model/OrderRefund.php

269 lines
9.3 KiB

<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\model\OrderGoods as OrderGoodsModel;
use app\api\service\User as UserService;
use app\common\enum\order\refund\AuditStatus as AuditStatusEnum;
use app\common\enum\order\refund\RefundStatus as RefundStatusEnum;
use app\common\enum\order\refund\RefundType as RefundTypeEnum;
use app\common\model\OrderRefund as OrderRefundModel;
use cores\exception\BaseException;
/**
* 售后单模型
* Class OrderRefund
* @package app\api\model
*/
class OrderRefund extends OrderRefundModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'update_time'
];
/**
* 追加字段
* @var array
*/
protected $append = [
'state_text', // 售后单状态文字描述
];
/**
* 售后单状态文字描述
* @param $value
* @param $data
* @return string
*/
public function getStateTextAttr($value, $data): string
{
// 已完成
if ($data['status'] == RefundStatusEnum::COMPLETED) {
$text = [RefundTypeEnum::RETURN => '已同意退货并已退款', RefundTypeEnum::EXCHANGE => '已同意换货', RefundTypeEnum::RETURNPRICE => '已同意退款'];
return $text[$data['type']];
}
// 已取消
if ($data['status'] == RefundStatusEnum::CANCELLED) {
return '已取消';
}
// 已拒绝
if ($data['status'] == RefundStatusEnum::REJECTED) {
// return '已拒绝';
if ($data['type'] == RefundTypeEnum::RETURN) {
return '已拒绝退货退款';
} elseif ($data['type'] == RefundTypeEnum::EXCHANGE) {
return '已拒绝换货';
} else {
return '已拒绝退款';
}
}
// 进行中
if ($data['status'] == RefundStatusEnum::NORMAL) {
if ($data['audit_status'] == AuditStatusEnum::WAIT) {
return '等待审核中';
}
if ($data['type'] == RefundTypeEnum::RETURN) {
return $data['is_user_send'] ? '已发货,待平台确认' : '已同意退货,请及时发货';
}
if ($data['type'] == RefundTypeEnum::EXCHANGE) {
return $data['is_user_send'] ? '已发货,待平台确认' : '已同意换货,请及时发货';
}
}
return $value;
}
/**
* 获取用户售后单列表
* @param int $state 售后单状态
* @return \think\Paginator
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function getList(int $state = -1): \think\Paginator
{
// 检索查询条件
$filter = [];
// 售后单状态
$state > -1 && $filter[] = ['status', '=', $state];
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 查询列表记录
return $this->with(['orderGoods.image'])
->where($filter)
->where('user_id', '=', $userId)
->order(['create_time' => 'desc'])
->paginate(15);
}
/**
* 获取当前用户的售后单详情
* @param int $orderRefundId 售后单ID
* @param bool $isWith 是否关联
* @return static|null
* @throws BaseException
*/
public static function getDetail(int $orderRefundId, bool $isWith = false): ?self
{
// 关联查询
$with = $isWith ? ['orderGoods' => ['image'], 'images.file', 'address', 'express'] : [];
// 获取记录
$detail = static::detail([
'user_id' => UserService::getCurrentLoginUserId(),
'order_refund_id' => $orderRefundId
], $with);
empty($detail) && throwError('未找到该售后单');
return $detail;
}
/**
* 获取当前用户的售后单数量(进行中的)
* @return int
* @throws BaseException
*/
public static function getCountByUnderway($dealer_order_ids = []): int
{
$userId = UserService::getCurrentLoginUserId();
$query = (new static)->where('user_id', '=', $userId);
if ($dealer_order_ids) {
$query->whereIn('order_id', $dealer_order_ids);
}
return $query->where('status', '=', 0)
->count();
}
/**
* 订单商品详情
* @param int $orderGoodsId
* @return OrderGoods|array|null
* @throws BaseException
*/
public function getRefundGoods(int $orderGoodsId)
{
$goods = OrderGoodsModel::detail($orderGoodsId);
if (isset($goods['refund']) && !empty($goods['refund'])) {
//是否已经同意
if (!empty($goods['refund']['audit_status']) && $goods['refund']['audit_status'] == AuditStatusEnum::REVIEWED) {
throwError('当前商品已申请售后');
}
}
return $goods;
}
/**
* 用户发货
* @param array $data
* @return bool|false
*/
public function delivery(array $data): bool
{
if (
!in_array($this['type'],[RefundTypeEnum::RETURN,RefundTypeEnum::EXCHANGE])
|| $this['audit_status'] != 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;
}
return $this->save([
'is_user_send' => 1,
'send_time' => time(),
'express_id' => (int)$data['expressId'],
'express_no' => $data['expressNo'],
]);
}
/**
* 新增售后单记录
* @param int $orderGoodsId 订单商品ID
* @param array $data 用户提交的表单数据
* @return mixed
* @throws BaseException
*/
public function apply(int $orderGoodsId, array $data)
{
// 订单商品详情
$goods = $this->getRefundGoods($orderGoodsId);
if (!empty($goods['refund']) && !empty($goods['refund']['audit_status']) != AuditStatusEnum::REVIEWED) {
if (empty($goods['refund']['order_refund_id'])) {
throwError('当前记录数据异常');
}
return $this->transaction(function () use ($orderGoodsId, $data, $goods) {
$order_refund_id = $goods['refund']['order_refund_id'];
//更新售后单记录
$this->where(['order_refund_id' => $order_refund_id])->update([
'type' => $data['type'],
'apply_desc' => $data['content'],
'audit_status' => AuditStatusEnum::WAIT,
'status' => 0,
]);
// 记录凭证图片关系
if (!empty($data['images'])) {
(new OrderRefundImage)->where(['order_refund_id' => $order_refund_id])->delete();
$this->saveImages((int)$this['order_refund_id'], explode(",", $data['images']));
}
return true;
});
}
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 (!empty($data['images'])) {
$this->saveImages((int)$this['order_refund_id'], explode(",", $data['images']));
}
return true;
});
}
/**
* 记录售后单图片
* @param int $orderRefundId 售后单ID
* @param array $images 图片列表
* @return void
*/
private function saveImages(int $orderRefundId, array $images): void
{
// 生成评价图片数据
$data = [];
foreach ($images as $imageId) {
$data[] = [
'order_refund_id' => $orderRefundId,
'image_id' => $imageId,
'store_id' => self::$storeId
];
}
!empty($data) && (new OrderRefundImage)->addAll($data) !== false;
}
}