feat(order): 下单支持一口价/师傅报价竞价/用户自主定价三种方式
- 下单页新增计价方式选择;自主定价填写总价,师傅报价单进入报价大厅 - 用户订单详情展示师傅报价列表并可选定师傅;选定后同步师傅、金额与订单状态 - 师傅大厅新增用户定价筛选与按价接单;报价单禁止直接抢单 - 后端订单新增 custom 价态、金额口径统一由 calcAmount 输出 - 报价中状态纳入用户可取消范围;超时回流重新开放报价 - 新增 fa_order.price_type custom 枚举迁移脚本(schema_phase6)
这个提交包含在:
@@ -98,6 +98,7 @@ class Home extends Base
|
||||
|
||||
/**
|
||||
* 费用试算(基础价 + 楼层费 + 加急费 - 优惠)
|
||||
* 支持下单页实时切换:一口价 / 师傅报价 / 用户自主定价
|
||||
*/
|
||||
public function calc()
|
||||
{
|
||||
@@ -110,28 +111,48 @@ class Home extends Base
|
||||
'floor' => (int)$this->request->param('floor', 1),
|
||||
'has_elevator' => (int)$this->request->param('has_elevator', 1),
|
||||
'urgent' => (int)$this->request->param('urgent', 0),
|
||||
], (int)$this->request->param('coupon_id', 0), $this->uid());
|
||||
], (int)$this->request->param('coupon_id', 0), $this->uid(),
|
||||
(string)$this->request->param('price_type', ''),
|
||||
(float)$this->request->param('user_price', 0));
|
||||
|
||||
$this->success('', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 金额计算(下单与试算共用,保证前后端口径一致)
|
||||
*
|
||||
* @param array $service 服务行
|
||||
* @param array $params floor / has_elevator / urgent
|
||||
* @param int $couponId 用户优惠券 id
|
||||
* @param int $uid 用户 id
|
||||
* @param string $priceType 计价方式:fixed 一口价 / quote 师傅报价 / custom 用户自主定价
|
||||
* @param float $userPrice 用户自主定价金额(总价,含楼层/加急)
|
||||
*/
|
||||
public static function calcAmount($service, $params, $couponId = 0, $uid = 0)
|
||||
public static function calcAmount($service, $params, $couponId = 0, $uid = 0, $priceType = '', $userPrice = 0)
|
||||
{
|
||||
$allowTypes = ['fixed', 'quote', 'range', 'custom'];
|
||||
$type = in_array($priceType, $allowTypes, true) ? $priceType : $service['price_type'];
|
||||
|
||||
$base = (float)$service['base_price'];
|
||||
$floor = max(0, (int)$params['floor']);
|
||||
$freeFloor = (int)$service['free_floor'];
|
||||
$floorFee = (float)$service['floor_fee'];
|
||||
|
||||
$floorAmount = 0;
|
||||
if ((int)$params['has_elevator'] === 0 && $floor > $freeFloor) {
|
||||
$floorAmount = ($floor - $freeFloor) * $floorFee;
|
||||
}
|
||||
$urgentAmount = 0;
|
||||
|
||||
$urgentAmount = (int)$params['urgent'] === 1 ? round($base * 0.2, 2) : 0;
|
||||
$total = round($base + $floorAmount + $urgentAmount, 2);
|
||||
if ($type === 'custom') {
|
||||
// 用户自主定价:出价即订单总价,已包含楼层费/加急费,师傅按此价接单
|
||||
$base = max(0, round((float)$userPrice, 2));
|
||||
$total = $base;
|
||||
} else {
|
||||
$floor = max(0, (int)$params['floor']);
|
||||
$freeFloor = (int)$service['free_floor'];
|
||||
$floorFee = (float)$service['floor_fee'];
|
||||
|
||||
if ((int)$params['has_elevator'] === 0 && $floor > $freeFloor) {
|
||||
$floorAmount = ($floor - $freeFloor) * $floorFee;
|
||||
}
|
||||
|
||||
$urgentAmount = (int)$params['urgent'] === 1 ? round($base * 0.2, 2) : 0;
|
||||
$total = round($base + $floorAmount + $urgentAmount, 2);
|
||||
}
|
||||
|
||||
$discount = 0;
|
||||
$couponInfo = null;
|
||||
@@ -151,7 +172,8 @@ class Home extends Base
|
||||
}
|
||||
|
||||
return [
|
||||
'price_type' => $service['price_type'],
|
||||
'price_type' => $type,
|
||||
'user_price' => $type === 'custom' ? round($base, 2) : 0,
|
||||
'base_amount' => round($base, 2),
|
||||
'floor_amount' => round($floorAmount, 2),
|
||||
'urgent_amount' => round($urgentAmount, 2),
|
||||
@@ -159,8 +181,8 @@ class Home extends Base
|
||||
'discount_amount' => round($discount, 2),
|
||||
'pay_amount' => max(0, round($total - $discount, 2)),
|
||||
'coupon' => $couponInfo,
|
||||
'free_floor' => $freeFloor,
|
||||
'floor_fee' => round($floorFee, 2),
|
||||
'free_floor' => $type === 'custom' ? 0 : (int)$service['free_floor'],
|
||||
'floor_fee' => $type === 'custom' ? 0 : round((float)$service['floor_fee'], 2),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户