diff --git a/frontend/src/views/partners/PartnerList.test.js b/frontend/src/views/partners/PartnerList.test.js
index b28e2ccd..af1aa6fa 100644
--- a/frontend/src/views/partners/PartnerList.test.js
+++ b/frontend/src/views/partners/PartnerList.test.js
@@ -73,6 +73,90 @@ async function clickSave(wrapper) {
await flushPromises()
}
+function businessRoleCheckboxes(wrapper) {
+ const item = wrapper.findAll('.el-form-item').find(
+ node => node.find('.el-form-item__label').text() === '业务分类'
+ )
+ expect(item.text()).toContain('客户')
+ expect(item.text()).toContain('供应商')
+ return item.findAll('input[type="checkbox"]')
+}
+
+describe('伙伴客户和供应商身份多选', () => {
+ beforeEach(() => {
+ partnersApi.list.mockReset().mockResolvedValue({ data: { items: [], total: 0 } })
+ partnersApi.create.mockReset().mockResolvedValue({ data: {} })
+ partnersApi.update.mockReset().mockResolvedValue({ data: {} })
+ })
+ afterEach(() => { vi.restoreAllMocks() })
+
+ test.each([['supplier', '供应商', false, true], ['customer', '客户', true, false]])(
+ '%s 新增默认当前身份,可双选并提交两个身份', async (role, title, customer, supplier) => {
+ const wrapper = mountPartner(role, title)
+ await flushPromises()
+ await openCreateDialog(wrapper, title)
+ const checkboxes = businessRoleCheckboxes(wrapper)
+ expect(checkboxes[0].element.checked).toBe(customer)
+ expect(checkboxes[1].element.checked).toBe(supplier)
+ for (const checkbox of checkboxes) await checkbox.setValue(true)
+ await inputByLabel(wrapper, '伙伴编码').setValue('BOTH-001')
+ await inputByLabel(wrapper, '企业名称').setValue('双身份公司')
+ await clickSave(wrapper)
+ expect(partnersApi.create).toHaveBeenCalledWith(expect.objectContaining({ is_customer: true, is_supplier: true }))
+ wrapper.unmount()
+ }
+ )
+
+ test.each([['supplier', '供应商', true, false], ['customer', '客户', false, true]])(
+ '%s 编辑回显双身份并允许取消当前页面身份', async (role, title, customer, supplier) => {
+ const row = { id: 7, partner_code: 'BOTH-001', legal_name: '双身份公司', is_customer: true, is_supplier: true,
+ customer_status: 'suspended', supplier_status: 'active' }
+ partnersApi.list.mockResolvedValue({ data: { items: [row], total: 1 } })
+ const wrapper = mountPartner(role, title)
+ await flushPromises()
+ await findButton(wrapper, '编辑').trigger('click')
+ await flushPromises()
+ const checkboxes = businessRoleCheckboxes(wrapper)
+ expect(checkboxes.every(checkbox => checkbox.element.checked)).toBe(true)
+ await checkboxes[0].setValue(customer)
+ await checkboxes[1].setValue(supplier)
+ expect(row.is_customer).toBe(true)
+ expect(row.is_supplier).toBe(true)
+ await clickSave(wrapper)
+ expect(partnersApi.update).toHaveBeenCalledWith(7, expect.objectContaining({ is_customer: customer, is_supplier: supplier,
+ customer_status: 'suspended', supplier_status: 'active' }))
+ await openCreateDialog(wrapper, title)
+ const reset = businessRoleCheckboxes(wrapper)
+ expect(reset[0].element.checked).toBe(role === 'customer')
+ expect(reset[1].element.checked).toBe(role === 'supplier')
+ wrapper.unmount()
+ }
+ )
+
+ test.each(['create', 'edit'])('%s 不允许取消所有业务分类', async mode => {
+ const warnSpy = vi.spyOn(ElMessage, 'warning').mockImplementation(() => {})
+ partnersApi.list.mockResolvedValue({ data: { items: [{ id: 7, partner_code: 'SUP-001', legal_name: '示例公司',
+ is_supplier: true, is_customer: false }], total: 1 } })
+ const wrapper = mountPartner()
+ await flushPromises()
+ if (mode === 'create') {
+ await openCreateDialog(wrapper, '供应商')
+ await inputByLabel(wrapper, '伙伴编码').setValue('SUP-002')
+ await inputByLabel(wrapper, '企业名称').setValue('示例公司')
+ } else {
+ await findButton(wrapper, '编辑').trigger('click')
+ await flushPromises()
+ }
+ for (const checkbox of businessRoleCheckboxes(wrapper)) await checkbox.setValue(false)
+ await clickSave(wrapper)
+ expect(warnSpy).toHaveBeenCalledWith('请至少选择一项业务分类')
+ expect(partnersApi.create).not.toHaveBeenCalled()
+ expect(partnersApi.update).not.toHaveBeenCalled()
+ expect(findButton(wrapper, '保存')).toBeDefined()
+ wrapper.unmount()
+ })
+})
+
describe('伙伴表单必填校验', () => {
let warnSpy
@@ -264,7 +348,7 @@ describe('伙伴列表分页', () => {
})
})
-describe('伙伴业务分类多选', () => {
+describe('伙伴合作范围多选', () => {
beforeEach(() => {
partnersApi.list.mockReset().mockResolvedValue({ data: { items: [], total: 0 } })
partnersApi.create.mockReset().mockResolvedValue({ data: {} })
@@ -279,8 +363,8 @@ describe('伙伴业务分类多选', () => {
await openCreateDialog(wrapper, title)
await inputByLabel(wrapper, '伙伴编码').setValue('PARTNER-001')
await inputByLabel(wrapper, '企业名称').setValue('示例公司')
- const item = wrapper.findAll('.el-form-item').find(node => node.text().includes('业务分类'))
- expect(item, '表单提供业务分类多选').toBeDefined()
+ const item = wrapper.findAll('.el-form-item').find(node => node.text().includes('合作范围'))
+ expect(item, '表单提供合作范围多选').toBeDefined()
for (const checkbox of item.findAll('input[type="checkbox"]')) await checkbox.setValue(true)
await clickSave(wrapper)
expect(partnersApi.create).toHaveBeenCalledWith(expect.objectContaining({
@@ -311,8 +395,8 @@ describe('伙伴业务分类多选', () => {
await flushPromises()
await findButton(wrapper, '编辑').trigger('click')
await flushPromises()
- const item = wrapper.findAll('.el-form-item').find(node => node.text().includes('业务分类'))
- expect(item, '表单提供业务分类多选').toBeDefined()
+ const item = wrapper.findAll('.el-form-item').find(node => node.text().includes('合作范围'))
+ expect(item, '表单提供合作范围多选').toBeDefined()
const checkboxes = item.findAll('input[type="checkbox"]')
await checkboxes[0].setValue(false)
await checkboxes[1].setValue(true)
@@ -323,7 +407,7 @@ describe('伙伴业务分类多选', () => {
expect(wrapper.find('.el-table__body tbody tr').text()).not.toContain('成品级(经营买卖)')
await findButton(wrapper, '编辑').trigger('click')
await flushPromises()
- const reopened = wrapper.findAll('.el-form-item').find(node => node.text().includes('业务分类')).findAll('input[type="checkbox"]')
+ const reopened = wrapper.findAll('.el-form-item').find(node => node.text().includes('合作范围')).findAll('input[type="checkbox"]')
expect(reopened[0].element.checked).toBe(true)
expect(reopened[1].element.checked).toBe(false)
await reopened[0].setValue(false)
@@ -331,7 +415,8 @@ describe('伙伴业务分类多选', () => {
await clickSave(wrapper)
expect(partnersApi.update).toHaveBeenCalledWith(1, expect.objectContaining({ supplier_categories: ['finished_product'], customer_categories: ['finished_product'] }))
await openCreateDialog(wrapper, '供应商')
- expect(wrapper.findAll('input[type="checkbox"]').every(input => !input.element.checked)).toBe(true)
+ const ranges = wrapper.findAll('.el-form-item').find(node => node.text().includes('合作范围'))
+ expect(ranges.findAll('input[type="checkbox"]').every(input => !input.element.checked)).toBe(true)
wrapper.unmount()
})
@@ -341,8 +426,8 @@ describe('伙伴业务分类多选', () => {
await flushPromises()
await wrapper.find('.btn-next').trigger('click')
await flushPromises()
- const filter = wrapper.findAllComponents(SelectStub).find(select => select.props('placeholder') === '全部业务分类')
- expect(filter, '列表提供业务分类筛选').toBeDefined()
+ const filter = wrapper.findAllComponents(SelectStub).find(select => select.props('placeholder') === '全部合作范围')
+ expect(filter, '列表提供合作范围筛选').toBeDefined()
filter.vm.$emit('update:modelValue', 'material')
filter.vm.$emit('change', 'material')
await flushPromises()
diff --git a/frontend/src/views/partners/PartnerList.vue b/frontend/src/views/partners/PartnerList.vue
index 149ee09a..4ab2108a 100644
--- a/frontend/src/views/partners/PartnerList.vue
+++ b/frontend/src/views/partners/PartnerList.vue
@@ -5,7 +5,7 @@