- 下单页新增计价方式选择;自主定价填写总价,师傅报价单进入报价大厅 - 用户订单详情展示师傅报价列表并可选定师傅;选定后同步师傅、金额与订单状态 - 师傅大厅新增用户定价筛选与按价接单;报价单禁止直接抢单 - 后端订单新增 custom 价态、金额口径统一由 calcAmount 输出 - 报价中状态纳入用户可取消范围;超时回流重新开放报价 - 新增 fa_order.price_type custom 枚举迁移脚本(schema_phase6)
146 行
4.9 KiB
PHP
146 行
4.9 KiB
PHP
<?php
|
||
|
||
namespace app\common\library;
|
||
|
||
/**
|
||
* 订单状态机
|
||
* 统一维护状态常量、文案与合法流转关系,前后端与后台共用同一套口径
|
||
*/
|
||
class OrderStatus
|
||
{
|
||
const PENDING_PAY = 0; // 待支付
|
||
const PENDING_ACCEPT = 1; // 待接单(进入订单大厅)
|
||
const QUOTING = 2; // 报价中(竞价单)
|
||
const ACCEPTED = 3; // 已接单
|
||
const SCHEDULED = 4; // 待上门(已约时间)
|
||
const ARRIVED = 5; // 已到达(师傅定位打卡)
|
||
const WORKING = 6; // 服务中(已开工)
|
||
const PENDING_VERIFY = 7; // 待验收(师傅完工)
|
||
const COMPLETED = 8; // 已完成(用户验收/自动验收)
|
||
const CANCELLED = 9; // 已取消
|
||
const AFTERSALE = 10; // 售后中
|
||
|
||
/** 状态文案 */
|
||
protected static $labels = [
|
||
self::PENDING_PAY => '待支付',
|
||
self::PENDING_ACCEPT => '待接单',
|
||
self::QUOTING => '报价中',
|
||
self::ACCEPTED => '已接单',
|
||
self::SCHEDULED => '待上门',
|
||
self::ARRIVED => '已到达',
|
||
self::WORKING => '服务中',
|
||
self::PENDING_VERIFY => '待验收',
|
||
self::COMPLETED => '已完成',
|
||
self::CANCELLED => '已取消',
|
||
self::AFTERSALE => '售后中',
|
||
];
|
||
|
||
/** 合法流转:from => [to, to, ...] */
|
||
protected static $transitions = [
|
||
self::PENDING_PAY => [self::PENDING_ACCEPT, self::QUOTING, self::CANCELLED],
|
||
self::PENDING_ACCEPT => [self::QUOTING, self::ACCEPTED, self::CANCELLED],
|
||
self::QUOTING => [self::ACCEPTED, self::CANCELLED],
|
||
self::ACCEPTED => [self::SCHEDULED, self::ARRIVED, self::PENDING_ACCEPT, self::CANCELLED],
|
||
self::SCHEDULED => [self::ARRIVED, self::PENDING_ACCEPT, self::CANCELLED],
|
||
self::ARRIVED => [self::WORKING],
|
||
self::WORKING => [self::PENDING_VERIFY],
|
||
self::PENDING_VERIFY => [self::COMPLETED, self::WORKING, self::AFTERSALE],
|
||
self::COMPLETED => [self::AFTERSALE],
|
||
self::AFTERSALE => [self::COMPLETED, self::CANCELLED],
|
||
];
|
||
|
||
/** 进行中(用户端"我的订单-进行中"、师傅端"待处理") */
|
||
protected static $activeStatus = [1, 2, 3, 4, 5, 6, 7];
|
||
|
||
/** 状态提示文案(前后端统一由后端下发,避免两套口径) */
|
||
protected static $tips = [
|
||
self::PENDING_PAY => '请尽快完成支付',
|
||
self::PENDING_ACCEPT => '已进入接单大厅,等待师傅接单',
|
||
self::QUOTING => '师傅报价中,请稍候',
|
||
self::ACCEPTED => '师傅已接单,将尽快与您联系',
|
||
self::SCHEDULED => '已约定上门时间',
|
||
self::ARRIVED => '师傅已到达现场',
|
||
self::WORKING => '服务进行中',
|
||
self::PENDING_VERIFY => '师傅已完工,请确认验收',
|
||
self::COMPLETED => '订单已完成,感谢您的信任',
|
||
self::CANCELLED => '订单已取消',
|
||
self::AFTERSALE => '售后处理中',
|
||
];
|
||
|
||
/**
|
||
* 状态提示文案
|
||
*/
|
||
public static function tip($status)
|
||
{
|
||
$status = (int)$status;
|
||
return isset(self::$tips[$status]) ? self::$tips[$status] : '';
|
||
}
|
||
|
||
/**
|
||
* 取状态文案
|
||
*/
|
||
public static function label($status)
|
||
{
|
||
$status = (int)$status;
|
||
return isset(self::$labels[$status]) ? self::$labels[$status] : '未知状态';
|
||
}
|
||
|
||
/**
|
||
* 全部状态(供前端渲染筛选 Tab)
|
||
*/
|
||
public static function all()
|
||
{
|
||
$ret = [];
|
||
foreach (self::$labels as $k => $v) {
|
||
$ret[] = ['value' => $k, 'label' => $v];
|
||
}
|
||
return $ret;
|
||
}
|
||
|
||
/**
|
||
* 判断是否允许从 $from 流转到 $to
|
||
*/
|
||
public static function can($from, $to)
|
||
{
|
||
$from = (int)$from;
|
||
$to = (int)$to;
|
||
if (!isset(self::$transitions[$from])) {
|
||
return false;
|
||
}
|
||
return in_array($to, self::$transitions[$from], true);
|
||
}
|
||
|
||
/**
|
||
* 某状态可流转到的下一批状态
|
||
*/
|
||
public static function next($from)
|
||
{
|
||
$from = (int)$from;
|
||
return isset(self::$transitions[$from]) ? self::$transitions[$from] : [];
|
||
}
|
||
|
||
/**
|
||
* 是否进行中
|
||
*/
|
||
public static function isActive($status)
|
||
{
|
||
return in_array((int)$status, self::$activeStatus, true);
|
||
}
|
||
|
||
/**
|
||
* 进行中的状态集合(用于 SQL in 查询)
|
||
*/
|
||
public static function activeValues()
|
||
{
|
||
return self::$activeStatus;
|
||
}
|
||
|
||
/**
|
||
* 用户是否可以取消
|
||
*/
|
||
public static function canCancelByUser($status)
|
||
{
|
||
return in_array((int)$status, [self::PENDING_PAY, self::PENDING_ACCEPT, self::QUOTING, self::ACCEPTED, self::SCHEDULED], true);
|
||
}
|
||
}
|