# 前端数据契约 - 销售发货的订单来源产品在编辑初始化、重新选择时,必须在清空 `id` 前保留 `orderProductId || id`;换仓和换批次只改变实际库存身份,不能覆盖订单明细身份。不同订单行即使物品和批次相同,也分别使用各自剩余额度;同一订单行拆为多条发货明细时累计校验,雪花ID保持字符串。 - 库存台账返回的 `provenance` 是展示字符串;向 EOM 发货接口提交产地时,使用 `purchaseOrigins` 产地编码数组转换为字符串数组。替代料与普通发货物品均需遵守此契约,不能把库存记录中的 `"[]"` 原样提交给 `JSONArray` 字段。 - 客户抽屉内打开客户历史版本详情时,详情 `ele-modal` 必须设置 `append-to-body`,避免弹窗遮罩受抽屉层叠上下文影响而覆盖弹窗内容。 - 客户与供应商共用 `saleManage/contact/components/addContactDialog.vue` 的新建并提交入口;保存主档后必须等待新建证照的 `saveOrEdit` 请求全部成功,再开启 `contact_approve` 提交弹窗。证照保存失败须提示并停止提交,避免服务端按已持久化证照校验时误判。 - `saleManage/contact` 的“我的”、员工公海、管理员公海三个列表都有独立的单行删除入口;删除链接需要权限与状态控制,点击时直接调用确认框并在确认后请求 `/eom/contact/delete`,避免表格行刷新后 `el-popconfirm` 的引用节点失效。若服务端返回“数据已被其他业务关联”,先核对该客户实际 `if_relation` 与关联业务记录;客户修改本身不调用 `updateRelationStatus`,不得直接清除关联标记或放宽后端删除保护。 - 客户编辑弹窗读取 `/eom/contact/getById/{id}` 后,银行信息表格数据必须保持数组;详情缺少 `bankList` 或返回空值时初始化为 `[]`,否则“添加”操作会报错。提交时沿用该数组作为 `bankList`。 - 客户银行信息的编辑弹窗和详情抽屉使用 Vue 2,`data` 中的列定义使用 `bankColumnsDef`,不能用 `_bankColumns` 后通过 `this._bankColumns` 读取:Vue 2 不代理 `_`、`$` 开头的字段,会使计算列为 `undefined`,即使添加方法已增加数据,表格也没有输入列。回归需用真实 Vue 实例验证计算列和新增后的渲染,不能只直接调用方法检查数组长度。详情抽屉银行户名来自 `base.name`,保存后重新读取详情版本;已指派客户的保存限制沿用服务端规则。 - 2026-10-21 本地页面回归:客户 `KH20261021001` 的编辑弹窗、详情抽屉两个银行信息入口均完成“添加→输入→删除”验证,输入框数量均为 `4→8→4`,新增户名正确带出客户名称;未提交保存,此证据仅覆盖页面交互,不代表保存接口回归通过。