报销系统中JavaScript动态增删明细的核心是前端用数组维护本地明细列表、实时同步UI、提交前统一校验并组装结构化数据;新增生成临时ID并push,删除用filter,输入变更通过data-id定位更新,提交时校验后按后端格式封装payload发送。

在报销系统中,JavaScript 处理接口请求时的动态增删明细,核心是:前端维护本地明细列表、实时同步 UI、提交前组装结构化数据。不需要每次增删都调用接口,而是等最终提交时统一发送。
一、用数组管理报销明细(状态驱动)
把每条明细当作一个对象,存入一个数组(如 expenseItems),每项至少包含:id(临时 ID,用于删除定位)、itemName、amount、date、receiptUrl 等字段。
示例初始化:
let expenseItems = [
{ id: 'temp-1', itemName: '打车费', amount: 28.5, date: '2024-05-20' },
{ id: 'temp-2', itemName: '午餐', amount: 65.0, date: '2024-05-21' }
];
新增时生成唯一临时 ID(可用 Date.now() + Math.random()),推入数组;删除时用 filter 按 id 移除。
二、绑定 DOM 操作实现动态增删
用事件委托或为每个“删除”按钮绑定点击 handler,避免重复绑定。关键点:
- 新增按钮触发函数,创建新对象并
push到 expenseItems,再调用 renderList() 更新列表 - 删除按钮传入当前行的
id,从数组中过滤掉该条目,再重新渲染 - 输入框变更(如金额修改)建议用
data-id关联,通过find定位并更新对应字段
不推荐直接操作 DOM 内容去读写值——容易和状态不同步,应始终以数组为单一数据源。
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
三、提交前校验并组装请求数据
点击“提交报销”时,先遍历 expenseItems 做基础校验(如金额 > 0、日期非空),任一失败则提示并中断。
校验通过后,按后端要求格式组装数据。常见结构如下:
const payload = {
applicantId: 'U12345',
totalAmount: expenseItems.reduce((sum, i) => sum + parseFloat(i.amount), 0),
items: expenseItems.map(item => ({
itemName: item.itemName.trim(),
amount: parseFloat(item.amount).toFixed(2),
date: item.date,
receiptUrl: item.receiptUrl || null
}))
};
然后用 fetch 或 axios 发送 POST 请求:
fetch('/api/expenses/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
四、注意临时 ID 与后端 ID 的区分
前端用的 id 是临时标识,仅用于本地操作;后端返回成功响应后,应将每条明细的 id 替换为服务端分配的真实 ID(如有需要)。若后续支持编辑已提交单据,需保留原始服务端 ID 并区分新增/已存在项(例如加 isExisting: true 字段)。
上传凭证图片可提前用 FileReader 转为 base64,或更推荐用独立上传接口获取 URL 后再填入 receiptUrl 字段——避免大文件塞进主提交请求。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










