From 7f19a3759189c2fb6d3d9d8fce9bccc0caca7e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=87=E7=9D=BF=20=E5=BC=A0?= Date: Mon, 21 Sep 2026 15:16:22 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=96=B0=E5=A2=9E=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E9=87=8D=E7=BD=AE=E4=B8=BA=E5=B9=B2=E5=87=80=E7=8A=B6=E6=80=81?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=86=8D=E6=8A=8A=E4=B8=8A=E4=B8=80=E6=AC=A1?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E7=9A=84=20id=20=E5=B8=A6=E8=BF=9B=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/master-data/MasterDataSettings.vue | 11 ++++-- .../src/views/partners/PartnerList.test.js | 35 +++++++++++++++++++ frontend/src/views/partners/PartnerList.vue | 8 ++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/frontend/src/views/master-data/MasterDataSettings.vue b/frontend/src/views/master-data/MasterDataSettings.vue index 2a393906..ecf49be3 100644 --- a/frontend/src/views/master-data/MasterDataSettings.vue +++ b/frontend/src/views/master-data/MasterDataSettings.vue @@ -150,9 +150,16 @@ async function ensureCategories() { categories.value = response.data || [] } +// 与 PartnerList.vue 同理:Object.assign 删不掉上一次编辑残留的 id, +// 新增前必须把表单整体清空。 +function resetForm(values) { + Object.keys(form).forEach(key => { delete form[key] }) + Object.assign(form, values) +} + async function openCreate() { editingId.value = null - Object.assign(form, defaultForm()) + resetForm(defaultForm()) if (activeTab.value === 'rules') await ensureCategories() dialogVisible.value = true } @@ -166,7 +173,7 @@ async function openEdit(row) { async function save() { // :rules 在本项目不生效,校验一律手写。编码规则的必填项与其他 tab 不同 - // (分类 + 前缀,见 SaveCodeRule),所以按 tab 分支。 + // (分类 + 前缀,见 prepareCodeRule),所以按 tab 分支。 if (activeTab.value === 'rules') { if (!form.category_id) { ElMessage.warning('请选择物料分类'); return } if (!form.prefix.trim()) { ElMessage.warning('请填写编码前缀'); return } diff --git a/frontend/src/views/partners/PartnerList.test.js b/frontend/src/views/partners/PartnerList.test.js index c0ce8500..4f73212d 100644 --- a/frontend/src/views/partners/PartnerList.test.js +++ b/frontend/src/views/partners/PartnerList.test.js @@ -156,3 +156,38 @@ describe('伙伴列表的合作状态显示', () => { wrapper.unmount() }) }) + +describe('新增伙伴不发生表单残留', () => { + beforeEach(() => { + partnersApi.list.mockReset().mockResolvedValue({ + data: [{ id: 1, partner_code: 'SUP-001', legal_name: '某某钢材有限公司', supplier_status: 'active' }] + }) + partnersApi.create.mockReset().mockResolvedValue({ data: {} }) + partnersApi.update.mockReset().mockResolvedValue({ data: {} }) + }) + + afterEach(() => { vi.restoreAllMocks() }) + + test('先编辑再新增时,请求体不能带上一条记录的 id', async () => { + const wrapper = mountPartner() + await flushPromises() + + // 先点「编辑」,让表单沾上 id=1 + await findButton(wrapper, '编辑').trigger('click') + await flushPromises() + // 关掉弹窗,再点「新增」 + await findButton(wrapper, '取消').trigger('click') + await flushPromises() + await openCreateDialog(wrapper, '供应商') + + await inputByLabel(wrapper, '伙伴编码').setValue('SUP-009') + await inputByLabel(wrapper, '企业名称').setValue('某某轴承厂') + await clickSave(wrapper) + + expect(partnersApi.update).not.toHaveBeenCalled() + expect(partnersApi.create).toHaveBeenCalledTimes(1) + const body = partnersApi.create.mock.calls[0][0] + expect(body.id).toBeUndefined() + wrapper.unmount() + }) +}) diff --git a/frontend/src/views/partners/PartnerList.vue b/frontend/src/views/partners/PartnerList.vue index 7d21dc30..f4946426 100644 --- a/frontend/src/views/partners/PartnerList.vue +++ b/frontend/src/views/partners/PartnerList.vue @@ -54,7 +54,13 @@ const form = reactive(emptyForm()) function emptyForm() { return { partner_code: '', legal_name: '', unified_credit_code: '', contact_name: '', contact_phone: '', address: '', status: 'active', is_supplier: false, is_customer: false } } async function load() { loading.value = true; try { const response = await partnersApi.list(props.role); rows.value = response.data || [] } finally { loading.value = false } } -function openCreate() { editingId.value = null; Object.assign(form, emptyForm()); dialogVisible.value = true } +// Object.assign 只覆盖已存在的键,不会删掉上次编辑残留的 id, +// 所以这里先清空再整体赋值,保证新增提交的是一张干净的表单。 +function resetForm(values) { + Object.keys(form).forEach(key => { delete form[key] }) + Object.assign(form, values) +} +function openCreate() { editingId.value = null; resetForm(emptyForm()); dialogVisible.value = true } function openEdit(row) { editingId.value = row.id; Object.assign(form, row, { status: row[statusField.value] || 'active' }); dialogVisible.value = true } function payload() { return {