3.1 KiB
3.1 KiB
订单详情保险保障卡片补「退保」按钮
日期: 2026-04-24 Issue: #1384 类型: ui (前端改动, 后端零改动)
摘要
用户截图反馈订单详情 → 合同保险 tab → 保险保障卡片 (状态「已承保」) 只有「查看保单」按钮, 没有退保入口。后端 POST /admin/insurance/cancel/{id} 历史已就位 (保游网 /Insurance/CancelIns 封装完整, 状态机 INSURED→CANCELLED 已跑通, 该订单历史也有 CANCELLED 记录), 独立「保险订单列表」页据说已有退保按钮, 仅是订单详情嵌入的保险卡片组件漏了。
后端接口
已有 (无需改动):
POST /admin/insurance/cancel/{insuranceOrderId}
→ Result<InsuranceOrderDetailVO>
业务规则:
- 仅允许 status == INSURED 的保险订单调用
- 调保游网 /Insurance/CancelIns 后, 成功或返回「正在退保中」都把 DB status 改为 CANCELLED
- 其他失败抛 BusinessException 带保游网错误文案
前端改动
订单详情页合同保险 tab → 保险保障卡片组件, 右下角「查看保单」旁加一个「退保」按钮:
<template>
<!-- 保险保障卡片底部 action 区 -->
<div class="card-actions">
<n-button text type="info" @click="handleViewPolicy(insurance.insuranceOrderId)">
查看保单
</n-button>
<!-- 新增:仅 INSURED 显示 -->
<n-button
v-if="insurance.status === 'INSURED'"
text
type="error"
@click="handleRefund(insurance.insuranceOrderId)"
>
退保
</n-button>
</div>
</template>
<script setup>
import { useDialog, useMessage } from 'naive-ui'
import { adminInsuranceCancel } from '@/api/insurance' // 复用保险订单列表页已有的 api
const dialog = useDialog()
const message = useMessage()
const emit = defineEmits(['refresh'])
async function handleRefund(insuranceOrderId) {
dialog.warning({
title: '确认退保',
content: '将调保游网撤单, 成功后订单状态变为「已退保」。此操作不可逆。',
positiveText: '确认退保',
negativeText: '取消',
onPositiveClick: async () => {
try {
await adminInsuranceCancel(insuranceOrderId)
message.success('退保成功')
emit('refresh') // 刷新订单详情
} catch (e) {
message.error(e?.message || '退保失败')
}
}
})
}
</script>
显示规则
| 保险 status | 显示「查看保单」 | 显示「退保」 |
|---|---|---|
| PENDING | ❌ (无保单) | ❌ |
| INSURING | ❌ | ❌ |
| INSURED | ✅ | ✅ |
| CANCELLED | ✅ (可下载历史保单) | ❌ |
| FAILED | ❌ | ❌ |
验收点
- 订单
2047252402389598209详情 → 合同保险 tab → 保险保障卡片右下角出现「退保」按钮 - 点击弹二次确认, 确认后调
POST /admin/insurance/cancel/2047591721386098690 - 响应成功 → 卡片状态角标由「已承保」变「已退保」, 自动刷新
- 响应失败 (保游网错误) → toast 显示错误原因, 状态不变
- CANCELLED / FAILED / PENDING 状态不显示退保按钮