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();
 | |
|     }
 | |
| 
 | |
| } |