feat: support customer and supplier role selection for partners
This commit is contained in:
parent
1c316d0105
commit
8dd0427adb
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<el-button type="primary" @click="openCreate">新增{{ title }}</el-button>
|
||||
</div>
|
||||
<div class="filters">
|
||||
<el-select v-model="categoryFilter" placeholder="全部业务分类" clearable @change="load(1)">
|
||||
<el-select v-model="categoryFilter" placeholder="全部合作范围" clearable @change="load(1)">
|
||||
<el-option v-for="(label, value) in CATEGORY_LABELS" :key="value" :label="label" :value="value" />
|
||||
<el-option label="未分类" value="unclassified" />
|
||||
</el-select>
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
>
|
||||
<el-table-column prop="partner_code" label="伙伴编码" width="140" />
|
||||
<el-table-column prop="legal_name" label="企业名称" min-width="180" />
|
||||
<el-table-column label="业务分类" min-width="220">
|
||||
<el-table-column label="合作范围" min-width="220">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row[categoriesField]?.length">
|
||||
<el-tag v-for="category in row[categoriesField]" :key="category" class="category-tag">{{ CATEGORY_LABELS[category] || category }}</el-tag>
|
||||
|
|
@ -40,7 +40,13 @@
|
|||
<el-form :model="form" label-width="130px">
|
||||
<el-form-item label="伙伴编码" required><el-input v-model="form.partner_code" :disabled="Boolean(editingId)" /></el-form-item>
|
||||
<el-form-item label="企业名称" required><el-input v-model="form.legal_name" /></el-form-item>
|
||||
<el-form-item label="业务分类">
|
||||
<el-form-item label="业务分类" required>
|
||||
<el-checkbox-group v-model="businessRoles">
|
||||
<el-checkbox value="customer">客户</el-checkbox>
|
||||
<el-checkbox value="supplier">供应商</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="合作范围">
|
||||
<el-checkbox-group v-model="form[categoriesField]">
|
||||
<el-checkbox v-for="(label, value) in CATEGORY_LABELS" :key="value" :value="value">{{ label }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
|
|
@ -75,6 +81,7 @@ const loading = ref(false)
|
|||
const saving = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
const editingId = ref(null)
|
||||
const businessRoles = ref([])
|
||||
|
||||
// 伙伴新增/编辑弹窗开着时切换公司会丢弃未保存内容,先确认。
|
||||
useOrganizationSwitchGuard(() => dialogVisible.value)
|
||||
|
|
@ -111,9 +118,15 @@ async function load(currentPage = pagination.currentPage) {
|
|||
watch(() => props.role, () => { categoryFilter.value = ''; load(1) })
|
||||
// 用 replaceAllKeys 而不是 Object.assign:后者删不掉上次编辑残留的 id,
|
||||
// 新增时会把别人的 id 一起提交上去。
|
||||
function openCreate() { editingId.value = null; replaceAllKeys(form, emptyForm()); dialogVisible.value = true }
|
||||
function openCreate() {
|
||||
editingId.value = null
|
||||
replaceAllKeys(form, emptyForm())
|
||||
businessRoles.value = [props.role]
|
||||
dialogVisible.value = true
|
||||
}
|
||||
function openEdit(row) {
|
||||
editingId.value = row.id
|
||||
businessRoles.value = ['customer', 'supplier'].filter(role => row[`is_${role}`])
|
||||
replaceAllKeys(form, { ...emptyForm(), ...row, status: row[statusField.value] || 'active',
|
||||
supplier_categories: [...(row.supplier_categories || [])], customer_categories: [...(row.customer_categories || [])] })
|
||||
dialogVisible.value = true
|
||||
|
|
@ -121,14 +134,15 @@ function openEdit(row) {
|
|||
function payload() {
|
||||
return {
|
||||
...form,
|
||||
is_supplier: form.is_supplier || props.role === 'supplier',
|
||||
is_customer: form.is_customer || props.role === 'customer',
|
||||
is_supplier: businessRoles.value.includes('supplier'),
|
||||
is_customer: businessRoles.value.includes('customer'),
|
||||
[`${props.role}_status`]: form.status
|
||||
}
|
||||
}
|
||||
async function save() {
|
||||
if (!form.partner_code.trim()) { ElMessage.warning('请填写伙伴编码'); return }
|
||||
if (!form.legal_name.trim()) { ElMessage.warning('请填写企业名称'); return }
|
||||
if (!businessRoles.value.length) { ElMessage.warning('请至少选择一项业务分类'); return }
|
||||
saving.value = true
|
||||
// 保存后停在第几页由 load 的默认参数决定:留在当前页,不把用户甩回第一页
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user