hookehuyr

fix(plan): 修复计划书提交错误信息传递问题

- 移除 fn() 中的自动 toast,避免双重提示
- 扩展 toast 显示时长从 2 秒到 3 秒
- PlanFormContainer emit 时包含 message 字段
- 所有父组件使用 result.message 传递后端错误信息到结果页面
- 修复 index.vue 中硬编码错误消息的问题
......@@ -24,14 +24,24 @@ export const fn = (api) => {
if (res_data && res_data.code === 1) {
return res_data
}
// 失败兜底:优先返回后端响应,同时做 toast 提示
// 失败兜底:返回后端响应,由调用方统一处理 toast 提示
console.warn('接口请求失败:', res)
if (res_data && res_data.show === false) return res_data
Taro.showToast({
title: (res_data && res_data.msg) ? res_data.msg : '请求失败',
icon: 'none',
duration: 2000
})
// 🔍 调试:打印 res_data 的详细内容
console.log('[fn] res_data:', res_data)
console.log('[fn] res_data.code:', res_data?.code)
console.log('[fn] res_data.msg:', res_data?.msg)
console.log('[fn] res_data.data:', res_data?.data)
// ❌ 移除自动 toast,避免双重提示
// Taro.showToast({
// title: (res_data && res_data.msg) ? res_data.msg : '请求失败',
// icon: 'none',
// duration: 2000
// })
// 返回:如果是 res_data 就返回,否则返回兜底对象
return res_data || { code: 0, data: null, msg: '请求失败' }
})
.catch(err => {
......
......@@ -486,9 +486,13 @@ const onConfirm = () => {
// 将元转换为分,保留两位小数
let yuan = parseFloat(inputValue.value || '0')
if (!Number.isNaN(yuan)) {
// 先保留两位小数,再转换为分
const formattedYuan = parseFloat(yuan.toFixed(2))
const cents = Math.round(formattedYuan * 100)
// 先保留两位小数(字符串形式),再转换为分
// 使用 toFixed(2) 确保留两位小数,然后 * 100 并四舍五入
const formattedYuanStr = yuan.toFixed(2)
const cents = Math.round(parseFloat(formattedYuanStr) * 100)
// 调试日志(可以移除)
console.log('[AmountKeyboard] 输入值:', inputValue.value, '元:', yuan, '格式化:', formattedYuanStr, '分:', cents)
emit('update:modelValue', cents)
}
......
......@@ -234,7 +234,7 @@ const submit = async () => {
Taro.showToast({
title: '产品数据为空',
icon: 'none',
duration: 2000
duration: 3000
})
return false
}
......@@ -281,7 +281,14 @@ const submit = async () => {
if (apiField) {
// 有映射:使用映射后的字段名
requestData[apiField] = formData.value[key]
// 特殊处理:coverage(分)需要转换为元
if (key === 'coverage') {
const coverageInYuan = (formData.value[key] / 100).toFixed(2)
console.log(`[PlanFormContainer] coverage 转换: ${key} (${formData.value[key]} ) ${apiField} (${coverageInYuan} )`)
requestData[apiField] = coverageInYuan
} else {
requestData[apiField] = formData.value[key]
}
} else if (key === 'total_amount') {
// 特殊处理:总保费(分 → 元)
requestData.total_premium = (formData.value[key] / 100).toFixed(2)
......@@ -311,7 +318,7 @@ const submit = async () => {
Taro.showToast({
title: '提交成功',
icon: 'success',
duration: 2000
duration: 3000
})
// 发送提交成功事件(携带 order_id)
......@@ -326,18 +333,28 @@ const submit = async () => {
} else {
Taro.hideLoading()
// 🔍 调试:完整响应数据
console.log('[PlanFormContainer] API 完整响应:', res)
console.log('[PlanFormContainer] res.data:', res.data)
console.log('[PlanFormContainer] res.msg:', res.msg)
console.log('[PlanFormContainer] res.data?.msg:', res.data?.msg)
// 失败时,尝试从 res.data 或 res.msg 中获取错误信息
// 注意:fn() 函数会将 res.data 设置为 null,但 res.msg 保留了
const errorMsg = res.data?.msg || res.msg || '提交失败,请稍后重试'
console.log('[PlanFormContainer] 最终错误信息:', errorMsg)
Taro.showToast({
title: errorMsg,
icon: 'none',
duration: 2000
duration: 3000
})
// 返回失败结果(不包含 order_id)
// 返回失败结果,传递错误信息给父组件
emit('submit', {
success: false
success: false,
message: errorMsg
})
return false
......@@ -350,7 +367,7 @@ const submit = async () => {
Taro.showToast({
title: '网络异常,请重试',
icon: 'none',
duration: 2000
duration: 3000
})
return false
......
......@@ -85,17 +85,28 @@
<!-- 指定提取金额模式 -->
<template v-if="form.withdrawal_mode === '指定提取金额'">
<!-- 按年岁/按保单年度选择 -->
<!-- 提取方式:只有按年岁 -->
<PlanFieldRadio
v-model="form.specified_amount_type"
label="提取方式"
:options="['按年岁', '按保单年度']"
:options="['按年岁']"
:required="true"
class="mb-5"
/>
<!-- 按年岁 -->
<template v-if="form.specified_amount_type === '按年岁'">
<!-- 提取金额币种(只读) -->
<div class="mb-5">
<div class="text-sm text-gray-600 mb-2 flex items-center">
<span class="text-red-500 mr-1">*</span>
<span>提取金额币种</span>
</div>
<div class="px-4 py-3 bg-gray-50 rounded-lg border border-gray-200">
<span class="text-gray-900">{{ currencyLabel }}</span>
</div>
</div>
<!-- 由几岁开始 -->
<PlanFieldAgePicker
v-model="form.withdrawal_start_age"
......@@ -129,28 +140,6 @@
/>
</div>
</template>
<!-- 按保单年度 -->
<template v-if="form.specified_amount_type === '按保单年度'">
<!-- 由几岁开始 -->
<PlanFieldAgePicker
v-model="form.withdrawal_start_age"
label="由几岁开始"
placeholder="请输入开始提取年龄"
:required="true"
class="mb-5"
/>
<!-- 提取期(年) -->
<PlanFieldSelect
v-model="form.withdrawal_period"
label="提取期(年)"
placeholder="请选择提取期"
:options="withdrawalPeriods"
:required="true"
class="mb-5"
/>
</template>
</template>
<!-- 最高固定提取金额模式 -->
......@@ -282,7 +271,8 @@ const initializeForm = (value) => {
// 默认值
withdrawal_enabled: value.withdrawal_enabled || '否',
withdrawal_mode: value.withdrawal_mode || '指定提取金额',
specified_amount_type: value.specified_amount_type || '按年岁'
specified_amount_type: value.specified_amount_type || '按年岁',
withdrawal_currency: value.withdrawal_currency || props.config?.withdrawal_plan?.default_currency || 'HKD'
})
}
......@@ -313,7 +303,8 @@ watch(
// 默认值
withdrawal_enabled: newVal.withdrawal_enabled || '否',
withdrawal_mode: newVal.withdrawal_mode || '指定提取金额',
specified_amount_type: newVal.specified_amount_type || '按年岁'
specified_amount_type: newVal.specified_amount_type || '按年岁',
withdrawal_currency: newVal.withdrawal_currency || props.config?.withdrawal_plan?.default_currency || 'HKD'
})
previousModelValue = newVal
}
......@@ -331,11 +322,19 @@ watch(
)
/**
* 默认币种(从配置读取
* 提取金额币种标签(用于显示
* @type {ComputedRef<string>}
* @description 显示币种的完整名称,如"港币 HKD"
*/
const defaultCurrency = computed(() => {
return props.config?.withdrawal_plan?.default_currency || 'HKD'
const currencyLabel = computed(() => {
const currencyCode = props.config?.withdrawal_plan?.default_currency || 'HKD'
const currencyNames = {
'HKD': '港币',
'USD': '美元',
'CNY': '人民币',
'EUR': '欧元'
}
return `${currencyNames[currencyCode] || currencyCode} ${currencyCode}`
})
/**
......@@ -367,28 +366,15 @@ const onWithdrawalModeChange = (mode) => {
if (mode === '最高固定提取金额') {
// 最高固定金额模式不需要指定金额的相关字段
delete form.specified_amount_type
delete form.withdrawal_currency
delete form.annual_amount
delete form.increase_rate
} else if (mode === '指定提取金额') {
// 指定提取金额模式,等待用户选择按年岁或按保单年度
// 保留现有字段
// 指定提取金额模式(按年岁),保留现有字段
}
}
/**
* 监听指定提取金额方式变化
* @description 当用户在"按年岁"和"按保单年度"之间切换时,清理不相关字段
*/
watch(
() => form.specified_amount_type,
(newType) => {
// 两种方式都不需要 annual_amount 和 increase_rate(小程序端不需要)
delete form.annual_amount
delete form.increase_rate
}
)
/**
* 监听提取计划启用状态变化
* @description 当用户选择"否"时,清除所有提取计划相关字段
*/
......@@ -399,6 +385,7 @@ watch(
// 清除所有提取计划相关字段
delete form.withdrawal_mode
delete form.specified_amount_type
delete form.withdrawal_currency
delete form.withdrawal_start_age
delete form.withdrawal_period
delete form.annual_amount
......@@ -468,6 +455,10 @@ const validate = () => {
}
if (form.specified_amount_type === '按年岁') {
if (!form.withdrawal_currency) {
Taro.showToast({ title: '请选择提取金额币种', icon: 'none' })
return false
}
if (form.increase_rate === undefined || form.increase_rate === '') {
Taro.showToast({ title: '请输入每年递增提取之百分比', icon: 'none' })
return false
......
......@@ -243,9 +243,9 @@ const handlePlanSubmit = (result) => {
success: result.success ? 'true' : 'false'
};
// 失败时可以传递错误信息(可选)
if (!result.success) {
params.message = '提交失败,请稍后重试';
// 失败时传递后端返回的错误信息
if (!result.success && result.message) {
params.message = result.message;
}
// 延迟跳转,确保 PlanFormContainer 的 toast 显示完毕
......
......@@ -520,11 +520,13 @@ const handlePlanSubmit = (result) => {
success: result.success ? 'true' : 'false'
}
// 失败时可以传递错误信息(可选)
if (!result.success) {
params.message = '提交失败,请稍后重试'
// 失败时传递后端返回的错误信息
if (!result.success && result.message) {
params.message = result.message
}
console.log('[Product Center] 跳转到结果页面,参数:', params)
// 延迟跳转,确保 PlanFormContainer 的 toast 显示完毕
setTimeout(() => {
Taro.navigateTo({
......
......@@ -239,11 +239,13 @@ const handlePlanSubmit = (result) => {
success: result.success ? 'true' : 'false'
}
// 失败时可以传递错误信息(可选)
if (!result.success) {
params.message = '提交失败,请稍后重试'
// 失败时传递后端返回的错误信息
if (!result.success && result.message) {
params.message = result.message
}
console.log('[Product Detail] 跳转到结果页面,参数:', params)
// 延迟跳转,确保 PlanFormContainer 的 toast 显示完毕
setTimeout(() => {
Taro.navigateTo({
......
......@@ -480,11 +480,13 @@ const handlePlanSubmit = (result) => {
success: result.success ? 'true' : 'false'
}
// 失败时可以传递错误信息(可选)
if (!result.success) {
params.message = '提交失败,请稍后重试'
// 失败时传递后端返回的错误信息
if (!result.success && result.message) {
params.message = result.message
}
console.log('[Search Page] 跳转到结果页面,参数:', params)
// 延迟跳转,确保 PlanFormContainer 的 toast 显示完毕
setTimeout(() => {
go('/pages/plan-submit-result/index', params)
......