# 问题分析:service-detail.uvue 点击"提交预约"后未出现付款页面
> 文件:`医疗-consumer/pages/mall/consumer/home-service/service-detail.uvue`
> 关联文件:`order-detail.uvue`、`payment.uvue`、`serviceOrderService.uts`、`homeServiceService.uts`
> 日期:2026-06-02
---
## 一、现象描述
用户在 `service-detail.uvue`(服务单详情/预约页)填写完地址、时间、服务对象等信息后,点击底部"提交预约"按钮:
- 页面提示"预约已提交"
- 自动跳转到 `order-detail.uvue`(服务单详情页)
- 订单状态显示为 **"待付款"**
- **但用户从未进入过付款页面 (`payment.uvue`)**
- 在 `order-detail.uvue` 中也**找不到任何"去付款"按钮**
---
## 二、根因分析(代码层面)
### 2.1 问题点 ①:submitBooking 后直接跳 order-detail,未经过 payment
**文件**:`service-detail.uvue` 第 933~1012 行
```uts
async function submitBooking() {
// ... 表单校验 ...
const created = await createHomeServiceApplication(draft)
if (created == null) {
uni.showToast({ title: '预约提交失败,请稍后重试', icon: 'none' })
return
}
uni.showToast({ title: '预约已提交', icon: 'success' })
// ❌ 直接跳转到订单详情,没有经过付款页
uni.navigateTo({ url: '/pages/mall/consumer/home-service/order-detail?id=' + created.id })
}
```
**预期行为**:预约提交成功后,应携带订单信息跳转到 `payment.uvue`,让用户完成支付。
**实际行为**:直接 `uni.navigateTo` 到 `order-detail.uvue`,付款流程被完全跳过。
---
### 2.2 问题点 ②:order-detail.uvue 没有"去付款"按钮
**文件**:`order-detail.uvue` 第 89~96 行
```uts
再次预约
再次预约
去验收反馈
重新选择时间
重新派单
联系客服
```
**缺失**:当订单状态为 **"待付款"**(`paymentStatus == 1 && status == 'created'`)时,action row 没有任何"去付款"或"立即支付"的入口。
用户一旦从预约页离开,再回到订单详情,也无法完成付款。
---
### 2.3 问题点 ③:createServiceOrder 的双轨逻辑
**文件**:`serviceOrderService.uts` 第 1125~1179 行
```uts
export async function createServiceOrder(params: CreateServiceOrderParams): Promise {
// 非套餐单 → 走 ec_care_tasks 新链(前端直接 INSERT,无支付概念)
if (params.packageInfo.id == '') {
const newTask = await tryCreateCareTask(params)
if (newTask != null) {
return newTask
}
}
// 套餐单 → 走 hss_service_orders 旧链(有 payment_status 字段)
const response = await supa.from('hss_service_orders').insert({
// ... 包含 payable_amount、payment_status: 1 等字段
status: 'created',
payment_status: 1,
// ...
}).execute()
}
```
**现状**:
- 如果用户选择了套餐(`packageInfo.id != ''`),订单写入 `hss_service_orders`,`payment_status = 1`(未付款)
- 如果用户没有选择套餐(`packageInfo.id == ''`),订单写入 `ec_care_tasks`,**没有支付概念**
截图中的订单有价格(¥260)且显示"待付款",说明走的是 `hss_service_orders` 旧链。
---
### 2.4 问题点 ④:payment.uvue 的 source 推断对 UUID 不友好(潜在风险)
**文件**:`payment.uvue` 第 1678~1683 行
```uts
if (source.value == '') {
// so- 前缀 → service,其他(包括 UUID)→ goods
source.value = orderId.value.startsWith('so-') ? 'service' : 'goods'
}
```
**风险**:如果未来 `service-detail.uvue` 创建的是 `ec_care_tasks`(UUID 格式 id),跳转到 `payment.uvue` 时,`source` 会被误判为 `'goods'`,导致:
- 支付成功后走商品发货流程,而非服务派单流程
- `dispatchPaidHomecareOrder` 对 UUID 订单返回"同步中"提示,但 UI 可能显示商品订单的完成页
---
## 三、数据流全景图
```
用户填写预约信息
↓
点击【提交预约】
↓
submitBooking()
↓
createHomeServiceApplication(draft)
↓
createServiceOrder(params)
↓
┌─────────────────┬─────────────────┐
│ packageInfo.id │ packageInfo.id │
│ == '' │ != '' │
│ (非套餐) │ (套餐) │
└─────────────────┴─────────────────┘
↓ ↓
tryCreateCareTask insert hss_service_orders
(insert ec_care_tasks) payment_status = 1 (未付款)
↓ ↓
无支付概念 有支付概念
↓ ↓
但都被直接 但也被直接
跳 order-detail 跳 order-detail
↓ ↓
❌ 无付款入口 ❌ 无付款入口
```
---
## 四、修复方案
### 方案 A:提交预约后自动跳转付款页(最符合用户预期)
**修改文件**:`service-detail.uvue` `submitBooking()`
```uts
async function submitBooking() {
// ... 原有校验逻辑保持不变 ...
const created = await createHomeServiceApplication(draft)
if (created == null) {
uni.showToast({ title: '预约提交失败,请稍后重试', icon: 'none' })
return
}
// 判断是否需要支付(仅 hss_service_orders 旧链有支付概念)
if (shouldUseCareTaskPath(created.id)) {
// ec_care_tasks 新链:无支付,直接到详情
uni.showToast({ title: '预约已提交', icon: 'success' })
uni.navigateTo({ url: '/pages/mall/consumer/home-service/order-detail?id=' + created.id })
return
}
// hss_service_orders 旧链:需要支付,跳转到 payment.uvue
uni.showToast({ title: '预约成功,请完成支付', icon: 'success' })
uni.navigateTo({
url: '/pages/mall/consumer/payment?orderId=' + created.id
+ '&source=service'
+ '&bizType=service'
+ '&amount=' + created.amount
// + '&orderNo=' + created.caseNo // 如需
})
}
```
**注意事项**:
- `shouldUseCareTaskPath(id)` 即 `isUuidLike(id)`,用于区分 ec_care_tasks(UUID)和 hss_service_orders(`so-` 前缀)
- 如果 `created` 对象中没有 `amount`,需要从 `draft` 或 `selectedPackage` 中取 `price`
---
### 方案 B:order-detail.uvue 增加"去付款"按钮(兜底补偿)
**修改文件**:`order-detail.uvue` action row
```uts
再次预约
再次预约
去付款
去验收反馈
重新选择时间
重新派单
联系客服
```
**新增方法**:
```uts
function goPayment() {
if (detail.value == null) {
return
}
uni.navigateTo({
url: '/pages/mall/consumer/payment?orderId=' + detail.value.id
+ '&source=service'
+ '&bizType=service'
+ '&amount=' + detail.value.amount
})
}
```
---
### 方案 C(推荐组合):A + B 同时实施
- **A 解决主流程**:用户预约后自然进入支付环节
- **B 解决兜底场景**:用户中途退出、支付失败、从订单列表重新进入等情况下,仍能在详情页找到付款入口
---
## 五、与刚才完善的双轨逻辑如何配合
### 5.1 当前已完善的逻辑
1. **`dispatchPaidHomecareOrder`**(`serviceOrderService.uts`):
- 对 UUID 格式订单(ec_care_tasks):返回 `{ success: true, code: 'SYNC_IN_PROGRESS', message: '付款成功,服务安排信息正在同步中...' }`
- 对 `so-` 前缀订单(hss_service_orders):调用旧 `rpc_homecare_auto_dispatch`
2. **`payment.uvue` 支付成功后的派单**:
- `source == 'service'` 时,调用 `dispatchPaidHomecareOrder`
- 成功则跳 `order-detail`
- 失败则显示重试弹窗
### 5.2 修复后配合方式
```
用户提交预约(选择了套餐)
↓
createServiceOrder → 写入 hss_service_orders(payment_status=1)
↓
跳转 payment.uvue(携带 orderId + source=service + amount)
↓
用户完成支付
↓
payment.uvue 调用 dispatchPaidHomecareOrder(orderId)
↓
orderId 是 so- 前缀 → 调用 rpc_homecare_auto_dispatch(旧链派单)
↓
派单成功 → 跳转 order-detail.uvue
↓
用户看到"已派单"或"服务人员已接单"
```
**如果后端补齐了 `rpc_payment_callback_activate_care_task`**:
- 可将 `createServiceOrder` 改为统一创建 `ec_care_tasks`
- `payment.uvue` 支付成功后,调用新 RPC 激活 care task
- 届时 `service-detail.uvue` 的 `submitBooking` 可统一跳 `payment.uvue`,无需区分 `so-` / UUID
---
## 六、需要修改的文件清单
| 文件 | 修改内容 | 优先级 |
|------|---------|--------|
| `service-detail.uvue` | `submitBooking()` 成功后跳 `payment.uvue`(旧链订单) | P0 |
| `order-detail.uvue` | action row 增加"待付款" → "去付款"按钮 | P0 |
| `order-detail.uvue` | 新增 `goPayment()` 方法 | P0 |
| `service-detail.uvue` | 确保 `created` 对象包含 `amount` / `price`,或从 draft 取 | P1 |
---
## 七、验证方式
1. 进入 `service-detail.uvue`,选择套餐,填写信息,点击"提交预约"
2. **预期**:跳转到 `payment.uvue`,显示订单金额、支付方式、倒计时
3. 完成支付
4. **预期**:自动派单,跳转到 `order-detail.uvue`,状态变为"已派单"或"待接单"
5. 测试中途退出场景:在 `order-detail.uvue` 点击"去付款",应能重新进入 `payment.uvue`