feat(pl): 支持证件建档时原子保存多合同产品绑定并保护受限关系。
This commit is contained in:
1 parent
d8a9aef90a
commit
136a85dda7
4 files changed
+484
-11
No files matched your search
@@ -20,6 +20,13 @@ function harness() {
|
||||
writes: any[] = [],
|
||||
parses: any[] = [],
|
||||
messages: string[] = []
|
||||
let certData: any = {}
|
||||
let saveError = false
|
||||
let pendingSave: ReturnType<typeof deferred> | undefined
|
||||
let pendingGet: ReturnType<typeof deferred> | undefined
|
||||
const user = vue.reactive({ accessToken: 'synthetic', getUserInfo: {} })
|
||||
const contractRequests: any[] = []
|
||||
const productRequests: any[] = []
|
||||
let confirmSwitch = true
|
||||
let pendingOptions: ReturnType<typeof deferred> | undefined
|
||||
const env = {
|
||||
@@ -31,7 +38,7 @@ function harness() {
|
||||
usePersistedListColumns,
|
||||
useListTableViewportHeight: () => ({ tableHeight: vue.ref(400) }),
|
||||
useRoute: () => ({ query: {} }),
|
||||
useUserStore: () => ({ accessToken: 'synthetic', getUserInfo: {} }),
|
||||
useUserStore: () => user,
|
||||
onMounted: () => {},
|
||||
onBeforeUnmount: () => {},
|
||||
fetchGetMenuCodes: async () => ({ all: true }),
|
||||
@@ -45,18 +52,37 @@ function harness() {
|
||||
}
|
||||
},
|
||||
quotaCertApi: {
|
||||
contracts: (keyword: string) => {
|
||||
const pending = deferred()
|
||||
contractRequests.push({ keyword, ...pending })
|
||||
return pending.promise
|
||||
},
|
||||
products: (id: string) => {
|
||||
const pending = deferred()
|
||||
productRequests.push({ id, ...pending })
|
||||
return pending.promise
|
||||
},
|
||||
certificateContracts: async () => [
|
||||
{ id: 'old', contractNo: '历史合同', contractName: '真实标签' }
|
||||
],
|
||||
list: async (kind: string) => {
|
||||
reads.push(kind)
|
||||
return pendingOptions ? pendingOptions.promise : []
|
||||
},
|
||||
get: async (kind: string, id: string) => ({
|
||||
...model.newCert(kind as any),
|
||||
id,
|
||||
certNo: 'EXISTING',
|
||||
attachmentUrls: 'a.png,b.png'
|
||||
}),
|
||||
get: async (kind: string, id: string) =>
|
||||
pendingGet
|
||||
? pendingGet.promise
|
||||
: {
|
||||
...model.newCert(kind as any),
|
||||
id,
|
||||
certNo: 'EXISTING',
|
||||
attachmentUrls: 'a.png,b.png',
|
||||
...certData
|
||||
},
|
||||
save: async (kind: string, body: any, id?: string) => {
|
||||
writes.push({ kind, body, id })
|
||||
if (saveError) throw new Error('保存失败')
|
||||
if (pendingSave) await pendingSave.promise
|
||||
},
|
||||
recognize: (kind: string, url: string) => {
|
||||
const pending = deferred()
|
||||
@@ -89,6 +115,17 @@ function harness() {
|
||||
state.formRef.value = { validate: async () => true, clearValidate: () => {} }
|
||||
return {
|
||||
state,
|
||||
user,
|
||||
deferSave: () => (pendingSave = deferred()),
|
||||
deferGet: () => (pendingGet = deferred()),
|
||||
contractRequests,
|
||||
productRequests,
|
||||
setCert: (value: any) => {
|
||||
certData = value
|
||||
},
|
||||
failSave: () => {
|
||||
saveError = true
|
||||
},
|
||||
reads,
|
||||
writes,
|
||||
parses,
|
||||
@@ -264,3 +301,158 @@ test('closed or switched forms reject delayed recognition results', async () =>
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('多合同一次保存且失败保留输入;受限可见关系只展示并省略提交', async () => {
|
||||
const h = harness(),
|
||||
s = h.state
|
||||
const bindings = [
|
||||
{
|
||||
id: 'b',
|
||||
contractId: 'old',
|
||||
linkStatus: 'inactive',
|
||||
remark: '保留',
|
||||
orderNum: 4,
|
||||
products: [
|
||||
{
|
||||
id: 'scope',
|
||||
contractProductId: 'p',
|
||||
scopeStatus: 'inactive',
|
||||
remark: '范围',
|
||||
orderNum: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
try {
|
||||
h.setCert({ contractBindings: bindings, bindingsEditable: true })
|
||||
await s.edit({ id: 'existing' })
|
||||
assert.deepEqual(s.form.value.contractBindings, bindings)
|
||||
assert.equal(s.bindingContracts.value[0].contractNo, '历史合同')
|
||||
s.addContractBinding('new')
|
||||
assert.equal(s.form.value.contractBindings.length, 2)
|
||||
h.failSave()
|
||||
await assert.rejects(s.save(), /保存失败/)
|
||||
assert.equal(h.writes.length, 1)
|
||||
assert.equal(h.writes[0].body.contractBindings[0].products[0].id, 'scope')
|
||||
assert.equal(s.formVisible.value, true)
|
||||
assert.equal(s.form.value.contractBindings.length, 2)
|
||||
s.formVisible.value = false
|
||||
h.setCert({ contractBindings: bindings, bindingsEditable: false })
|
||||
await s.edit({ id: 'limited' })
|
||||
s.addContractBinding('forbidden')
|
||||
assert.equal(s.form.value.contractBindings.length, 1)
|
||||
await assert.rejects(s.save())
|
||||
assert.equal('contractBindings' in h.writes[1].body, false)
|
||||
} finally {
|
||||
h.stop()
|
||||
}
|
||||
})
|
||||
|
||||
test('产品勾选往返保留原范围ID;关闭重开后拒绝旧合同和产品请求', async () => {
|
||||
const h = harness(),
|
||||
s = h.state
|
||||
try {
|
||||
await s.edit()
|
||||
s.addContractBinding('c')
|
||||
s.form.value.contractBindings[0].products = [
|
||||
{ id: 'scope', contractProductId: 'p', scopeStatus: 'inactive' }
|
||||
]
|
||||
s.setBindingProducts(0, ['p', 'p2'])
|
||||
assert.equal(s.form.value.contractBindings[0].products[0].id, 'scope')
|
||||
assert.equal(s.form.value.contractBindings[0].products[0].scopeStatus, 'inactive')
|
||||
const search = s.searchBindingContracts('old')
|
||||
const products = s.loadBindingProducts('c')
|
||||
s.formVisible.value = false
|
||||
await s.edit()
|
||||
h.contractRequests.at(-1).resolve([{ id: 'stale', contractNo: '旧合同' }])
|
||||
h.productRequests.forEach((r) => r.resolve([{ id: 'stale', productName: '旧产品' }]))
|
||||
await Promise.all([search, products])
|
||||
assert.deepEqual(s.bindingContracts.value, [])
|
||||
assert.deepEqual(s.bindingProducts.value, {})
|
||||
} finally {
|
||||
h.stop()
|
||||
}
|
||||
})
|
||||
|
||||
test('移除后重选同一合同保留主关联和产品范围身份', async () => {
|
||||
const h = harness(),
|
||||
s = h.state
|
||||
try {
|
||||
h.setCert({
|
||||
contractBindings: [
|
||||
{
|
||||
id: 'binding',
|
||||
contractId: 'old',
|
||||
linkStatus: 'inactive',
|
||||
products: [{ id: 'scope', contractProductId: 'p', scopeStatus: 'inactive' }]
|
||||
}
|
||||
]
|
||||
})
|
||||
await s.edit({ id: 'cert' })
|
||||
s.removeContractBinding(0)
|
||||
s.addContractBinding('old')
|
||||
assert.equal(s.form.value.contractBindings[0].id, 'binding')
|
||||
assert.equal(s.form.value.contractBindings[0].products[0].id, 'scope')
|
||||
} finally {
|
||||
h.stop()
|
||||
}
|
||||
})
|
||||
|
||||
test('后发合同搜索覆盖先发,租户切换使保存和读取旧结果失效', async () => {
|
||||
const h = harness(),
|
||||
s = h.state
|
||||
try {
|
||||
await s.edit()
|
||||
const first = s.searchBindingContracts('first'),
|
||||
second = s.searchBindingContracts('second')
|
||||
h.contractRequests[1].resolve([{ id: 'second', contractNo: 'SECOND', contractName: '' }])
|
||||
await second
|
||||
h.contractRequests[0].resolve([{ id: 'first', contractNo: 'FIRST', contractName: '' }])
|
||||
await first
|
||||
assert.equal(s.bindingContracts.value[0].id, 'second')
|
||||
const pending = h.deferSave()
|
||||
const saving = s.save()
|
||||
await vue.nextTick()
|
||||
h.user.accessToken = ''
|
||||
pending.resolve({})
|
||||
await saving
|
||||
assert.equal(h.messages.includes('证件已保存'), false)
|
||||
assert.equal(s.formVisible.value, false)
|
||||
const get = h.deferGet(),
|
||||
editing = s.edit({ id: 'old' })
|
||||
h.user.getUserInfo = { tenantNo: 'other' }
|
||||
get.resolve({ ...model.newCert('purchase'), contractBindings: [] })
|
||||
await editing
|
||||
assert.equal(s.formVisible.value, false)
|
||||
} finally {
|
||||
h.stop()
|
||||
}
|
||||
})
|
||||
|
||||
test('新增多合同连同证面成功提交一次,移除全部提交明确空集合', async () => {
|
||||
const h = harness(),
|
||||
s = h.state
|
||||
try {
|
||||
await s.edit()
|
||||
s.addContractBinding('one')
|
||||
s.addContractBinding('two')
|
||||
s.setBindingProducts(0, ['p1'])
|
||||
s.setBindingProducts(1, ['p2'])
|
||||
s.form.value.certNo = 'MULTI'
|
||||
await s.save()
|
||||
assert.equal(h.writes.length, 1)
|
||||
assert.equal(h.writes[0].body.certNo, 'MULTI')
|
||||
assert.deepEqual(
|
||||
h.writes[0].body.contractBindings.map((b: any) => b.contractId),
|
||||
['one', 'two']
|
||||
)
|
||||
assert.equal(s.formVisible.value, false)
|
||||
h.setCert({ contractBindings: [{ id: 'b', contractId: 'one', products: [] }] })
|
||||
await s.edit({ id: 'existing' })
|
||||
s.removeContractBinding(0)
|
||||
await s.save()
|
||||
assert.deepEqual(h.writes[1].body.contractBindings, [])
|
||||
} finally {
|
||||
h.stop()
|
||||
}
|
||||
})
|
||||
Reference in new issue
Block a user