# 2026-09-03 工作日志 ## 合同费用列表(monthlyExpenses)手动添加功能 ### 需求 合同组件(广州版 ContractBody.vue + 湖北版 ContractBodyHubei.vue)的月度费用列表,增加「手动添加费用行」能力:点击添加一行,格式与现有行一致,数据随合同保存、重新打开能解析回显。 ### 实现 - **addMonthlyExpense()**:向 `contractForm.monthlyExpenses` push 空行,标记 `isManual: true`,字段 `{ id: 'manual-'+Date.now(), isManual: true, itemName:'', itemCategoryName:'', actualAmount:'' }` - **removeMonthlyExpense(index)**:splice 删除(仅手动行提供删除入口) - **渲染区分**: - 手动行(`isManual`)名称用 `FieldItem v-model="item.itemName"` 可编辑,后缀 `¥:` - 系统行名称保持纯文本 `{{ item.itemCategoryName+'¥' || item.itemName+'¥' }}` - 金额 `FieldItem v-model="item.actualAmount"` 不变,后缀 `元/月;` - 删除按钮 `el-button link type=danger size=small`(`v-if="item.isManual && !isTextMode"`) - 添加按钮 `el-button link type=primary`「+ 添加费用」(`v-if="!isTextMode"`,打印模式隐藏) - **v-for key** 改为 `item.id ?? 'manual-'+index`(手动行 id 为字符串 `manual-xxx`,避免与系统行冲突/空 key 重复) - 新增 `.expense-del` scoped 样式(margin-left:6px 对齐) ### 保存/解析链路(无需额外改动) - 保存:`saveContract` → `JSON.stringify({...contractForm})`,手动行作为 monthlyExpenses 数组元素完整落库 - 解析:`fetchContractData` → `JSON.parse(contractInfo)` → `Object.assign(contractForm, parsedData)` 整体替换 monthlyExpenses,`isManual` 标记保留,回显正确 - totalFee 自动汇总 watch 遍历 `monthlyExpensesList`,手动行 actualAmount 一并计入总额 ### 涉及文件 - `src/views/elderly/contracts/components/ContractBody.vue`(script 745-760 + template 1411-1449 + style) - `src/views/elderly/contracts/components/ContractBodyHubei.vue`(script 809-824 + template 1466-1504 + style) ### 备注 - 系统行名称表达式 `item.itemCategoryName+'¥' || item.itemName+'¥'` 存在既有逻辑瑕疵(空 category 时 `''+'¥'='¥'` 为 truthy,|| 永远短路返回前者),本次未改动、仅保留原行为 ## 费用名称显示严谨化(后续修复) ### 背景 上一轮遗留的 `displayExpenseName` 函数内 `return category + '¥' || name + '¥' || ''` 仍有短路 bug:`category` 为空时 `''+'¥'='¥'` 为真值,永远返回 `'¥'` 不回退到 `name`;且 category/name 都为空时返回孤零零 `¥`。 ### 修复 - **两个文件 `displayExpenseName`** 统一改为: ```js const label = category || name return label ? `${label}¥` : '' ``` 严谨优先级:类别+项目都存在且不同 → `类别(项目)¥`;否则取非空者;都空返回 `''`。 - **广州版模板** 系统行名称旧表达式 `{{ item.itemCategoryName + '¥' || item.itemName + '¥' }}` → `{{ displayExpenseName(item) }}`,与湖北版及打印渲染处(oneTime/stage 费用)保持一致。 - 已在函数上补注释说明禁用 `category + '¥' || name + '¥'` 的原因,防止后人重蹈。 ## 月度费用金额预览/打印模式去下划线 ### 需求 合同月度费用列表(monthlyExpenses)的金额,在预览/打印(isTextMode)下 FieldItem 的 `.fill-text` 有 `border-bottom: 1px solid #333` 下划线,与上方费用名称(纯文本)不一致,希望去掉下划线。**仅限月度费用这一块,其他费用块(一次性/阶段性)金额横线保留。** ### 实现 - `FieldItem.vue` 新增 `noUnderline?: boolean` prop;isTextMode 下 `.fill-text`/`.fill-blank` 加 `:class="{ 'no-underline': noUnderline }"`;样式新增 `.no-underline { border-bottom: none; }`(放在 `.is-text` 内,仅 isTextMode 生效,编辑模式 input 无影响)。 - 两个合同组件的月度费用金额 FieldItem(`width="120px"`)加 `no-underline`,一次性费用金额(`width="100px"`)不改。 ### 涉及文件 - `src/views/elderly/contracts/components/FieldItem.vue` - `src/views/elderly/contracts/components/ContractBody.vue`(月度费用金额) - `src/views/elderly/contracts/components/ContractBodyHubei.vue`(月度费用金额) ### 补充:手动行「费用名称」也去下划线 用户纠正「金额和名称都要改」。手动添加行(isManual)的费用名称 FieldItem(`width="140px"` `placeholder="请输入费用名称"`)在预览/打印模式下同样带下划线,已给两个合同组件的名称 FieldItem 补 `no-underline`。系统行名称本就是纯文本 `displayExpenseName(item)`,无下划线,无需改。