193 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			193 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			PHP
		
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								namespace app\traits\order;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use app\exception\RepositoryException;
							 | 
						||
| 
								 | 
							
								use app\model\Order;
							 | 
						||
| 
								 | 
							
								use app\model\OrderAfterSale;
							 | 
						||
| 
								 | 
							
								use app\repository\OrderRepository;
							 | 
						||
| 
								 | 
							
								use Exception;
							 | 
						||
| 
								 | 
							
								use think\db\exception\DataNotFoundException;
							 | 
						||
| 
								 | 
							
								use think\db\exception\DbException;
							 | 
						||
| 
								 | 
							
								use think\db\exception\ModelNotFoundException;
							 | 
						||
| 
								 | 
							
								use think\facade\Db;
							 | 
						||
| 
								 | 
							
								use think\Model;
							 | 
						||
| 
								 | 
							
								use think\Paginator;
							 | 
						||
| 
								 | 
							
								use think\service\PaginatorService;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * 订单售后服务
							 | 
						||
| 
								 | 
							
								 * Trait AfterSale
							 | 
						||
| 
								 | 
							
								 * @package app\traits\order
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								trait AfterSaleTrait
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 获取售后处理状态文本描述
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return string[]
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static function getAfterSaleStatusTextList(): array
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return [
							 | 
						||
| 
								 | 
							
								            OrderAfterSale::STATUS_WAITING => '待处理',
							 | 
						||
| 
								 | 
							
								            OrderAfterSale::STATUS_DOING   => '处理中',
							 | 
						||
| 
								 | 
							
								            OrderAfterSale::STATUS_DONE    => '已处理',
							 | 
						||
| 
								 | 
							
								        ];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 添加售后服务申请
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param int $orderId
							 | 
						||
| 
								 | 
							
								     * @param int $accountId
							 | 
						||
| 
								 | 
							
								     * @param array $applyData
							 | 
						||
| 
								 | 
							
								     * @throws RepositoryException
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function addAfterSaleApply(int $orderId, int $accountId, array $applyData = [])
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        Db::startTrans();
							 | 
						||
| 
								 | 
							
								        try {
							 | 
						||
| 
								 | 
							
								            $order = Order::findById($orderId);
							 | 
						||
| 
								 | 
							
								            if (empty($order)) {
							 | 
						||
| 
								 | 
							
								                throw new RepositoryException('没有相关的订单记录');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($order['account_id'] != $accountId) {
							 | 
						||
| 
								 | 
							
								                throw new RepositoryException('请求错误');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (!isset($applyData['description']) || empty(trim($applyData['description']))) {
							 | 
						||
| 
								 | 
							
								                throw new RepositoryException('售后申请内容描述不能为空');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $nowDateTime    = date('Y-m-d H:i:s');
							 | 
						||
| 
								 | 
							
								            $applyData['created_at']    = $nowDateTime;
							 | 
						||
| 
								 | 
							
								            $applyData['account_id']    = $accountId;
							 | 
						||
| 
								 | 
							
								            $applyData['coding']      = $order['coding'];
							 | 
						||
| 
								 | 
							
								            $applyData['reply']         = '';
							 | 
						||
| 
								 | 
							
								            $applyData['status']        = OrderAfterSale::STATUS_WAITING;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $newAfterSale = OrderAfterSale::create($applyData);
							 | 
						||
| 
								 | 
							
								            if (!$newAfterSale) {
							 | 
						||
| 
								 | 
							
								                throw new RepositoryException('售后申请信息提交失败');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Order::where('id', $orderId)->update([
							 | 
						||
| 
								 | 
							
								                'after_sale_at' => $nowDateTime,
							 | 
						||
| 
								 | 
							
								                'is_after_sale' => Order::BOOL_TRUE
							 | 
						||
| 
								 | 
							
								            ]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            Db::commit();
							 | 
						||
| 
								 | 
							
								        } catch (RepositoryException $e) {
							 | 
						||
| 
								 | 
							
								            Db::rollback();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException($e->getMessage());
							 | 
						||
| 
								 | 
							
								        } catch (Exception $e) {
							 | 
						||
| 
								 | 
							
								            Db::rollback();
							 | 
						||
| 
								 | 
							
								            OrderRepository::log('订单售后申请失败', $e, 'error', 'order');
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('售后申请信息提交失败');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 获取订单下的售后记录列表
							 | 
						||
| 
								 | 
							
								     * 适用于API
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param string $orderCoding
							 | 
						||
| 
								 | 
							
								     * @param array $where
							 | 
						||
| 
								 | 
							
								     * @param int $page
							 | 
						||
| 
								 | 
							
								     * @param int $limit
							 | 
						||
| 
								 | 
							
								     * @param callable|null $callback
							 | 
						||
| 
								 | 
							
								     * @return array
							 | 
						||
| 
								 | 
							
								     * @throws Exception
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getAfterSaleListByOrder(string $orderCoding = '', array $where = [], int $page = 1, int $limit = 10, callable $callback = null): array
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $searchMap[]    = ['coding', '=', $orderCoding];
							 | 
						||
| 
								 | 
							
								        $searchMap      = array_merge($searchMap, $where);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return OrderAfterSale::findList($searchMap, [], $page, $limit, $callback);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 售后申请处理
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function afterSaleExamine(int $afterSaleId, string $examine='', string $reply = '', int $replyUserId = 0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        try {
							 | 
						||
| 
								 | 
							
								            $afterSale = OrderAfterSale::findById($afterSaleId);
							 | 
						||
| 
								 | 
							
								            if (empty($afterSale)) {
							 | 
						||
| 
								 | 
							
								                throw new RepositoryException('没有相关的售后申请记录');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (!in_array($examine, [OrderAfterSale::STATUS_DOING, OrderAfterSale::STATUS_DONE])) {
							 | 
						||
| 
								 | 
							
								                throw new RepositoryException('请选择处理状态');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $nowDateTime = date('Y-m-d H:i:s');
							 | 
						||
| 
								 | 
							
								            $afterSale->save([
							 | 
						||
| 
								 | 
							
								                'status'        => $examine,
							 | 
						||
| 
								 | 
							
								                'reply_at'      => $nowDateTime,
							 | 
						||
| 
								 | 
							
								                'reply_user_id' => $replyUserId,
							 | 
						||
| 
								 | 
							
								                'reply'         => $reply,
							 | 
						||
| 
								 | 
							
								            ]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($examine == OrderAfterSale::STATUS_DONE) {
							 | 
						||
| 
								 | 
							
								                Order::where('coding', $afterSale['coding'])->update(['after_sale_end_at'=> $nowDateTime]);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } catch (RepositoryException $e) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException($e->getMessage());
							 | 
						||
| 
								 | 
							
								        } catch (Exception $e) {
							 | 
						||
| 
								 | 
							
								            OrderRepository::log('订单售后处理失败', $e, 'error', 'order');
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('订单售后处理失败');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @param array $whereMap ['fields', 'where', 'order', 'size']
							 | 
						||
| 
								 | 
							
								     * @param array $pageParams
							 | 
						||
| 
								 | 
							
								     * @return Paginator|null
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function afterSaleListWithPaginate(array $whereMap = [], array $pageParams = []): ?Paginator
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        try {
							 | 
						||
| 
								 | 
							
								            return OrderAfterSale::findListWithPaginate($whereMap, $pageParams, function ($q) {
							 | 
						||
| 
								 | 
							
								                return $q->withJoin(['account'], 'left');
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        } catch (Exception $e) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 查询售后记录
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param int $afterSaleId
							 | 
						||
| 
								 | 
							
								     * @param bool $lock
							 | 
						||
| 
								 | 
							
								     * @param callable|null $callback
							 | 
						||
| 
								 | 
							
								     * @return array|Model|null
							 | 
						||
| 
								 | 
							
								     * @throws DataNotFoundException
							 | 
						||
| 
								 | 
							
								     * @throws DbException
							 | 
						||
| 
								 | 
							
								     * @throws ModelNotFoundException
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function findAfterSaleById(int $afterSaleId, bool $lock = false, callable $callback = null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $q = OrderAfterSale::where('order_after_sale.id', $afterSaleId)
							 | 
						||
| 
								 | 
							
								            ->withJoin(['account', 'orderItem'], 'left');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($lock) {
							 | 
						||
| 
								 | 
							
								            $q = $q->lock(true);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if ($callback) {
							 | 
						||
| 
								 | 
							
								            $q = $callback($q);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $q->find();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 |