fix(pl): 运输证解析回填客户,并将证面引用改名为关联购买证。
运输证按收货单位精确匹配系统客户;Web 与移动 H5 同步改名与回填逻辑。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
c460386583
commit
a6fc0aa0f3
7 files changed
+46
-35
No files matched your search
@@ -645,7 +645,7 @@ test('referenced bindings and references cannot be edited or removed', async ()
|
||||
s.removeReference(0)
|
||||
s.addReference()
|
||||
assert.equal(s.form.value.purchaseRefs.length, 1)
|
||||
assert.ok(h.messages.some((m) => m.includes('不能新增或移除证面引用')))
|
||||
assert.ok(h.messages.some((m) => m.includes('不能新增或移除关联购买证')))
|
||||
assert.equal(s.referenceRowLocked(s.form.value.purchaseRefs[0]), false)
|
||||
} finally {
|
||||
h.stop()
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<ViewKvTable :fields="group.fields" mode="dual" />
|
||||
</section>
|
||||
<section v-if="tab.kind === 'transport'" class="quota-face-group">
|
||||
<h4>证面引用</h4>
|
||||
<h4>关联购买证</h4>
|
||||
<el-table
|
||||
v-if="tab.cert.purchaseRefs?.length"
|
||||
:data="tab.cert.purchaseRefs"
|
||||
@@ -125,7 +125,7 @@
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<p v-else class="quota-note">没有证面引用。</p>
|
||||
<p v-else class="quota-note">没有关联购买证。</p>
|
||||
</section>
|
||||
<section v-if="tab.cert.attachmentUrls" class="quota-face-group">
|
||||
<h4>证件附件</h4>
|
||||
|
||||
@@ -122,8 +122,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="face.kind === 'transport'">
|
||||
<h3>证面引用</h3>
|
||||
<p v-if="!face.cert.purchaseRefs?.length" class="plan-empty-hint">没有证面引用。</p>
|
||||
<h3>关联购买证</h3>
|
||||
<p v-if="!face.cert.purchaseRefs?.length" class="plan-empty-hint">没有关联购买证。</p>
|
||||
<article
|
||||
v-for="(refRow, index) in face.cert.purchaseRefs || []"
|
||||
:key="refRow.id || index"
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
</article>
|
||||
</section>
|
||||
<section v-if="kind === 'transport'" class="mp-wv-section">
|
||||
<h3>证面引用</h3>
|
||||
<p v-if="!(cert.purchaseRefs || []).length" class="plan-empty-hint">没有证面引用。</p>
|
||||
<h3>关联购买证</h3>
|
||||
<p v-if="!(cert.purchaseRefs || []).length" class="plan-empty-hint">没有关联购买证。</p>
|
||||
<article v-for="(row, index) in cert.purchaseRefs || []" :key="row.id || index" class="mp-cert-block">
|
||||
<div class="detail-field-grid">
|
||||
<div class="mp-wv-kv">
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<section class="mp-wv-section">
|
||||
<h3>证件附件</h3>
|
||||
<p class="plan-empty-hint"
|
||||
>一次仅上传并解析一张证件图片或 PDF。解析只补充还没手工填写的空字段。删除证件附件后,证面信息、绑定合同产品和证面引用会清空。</p
|
||||
>一次仅上传并解析一张证件图片或 PDF。解析只补充还没手工填写的空字段。删除证件附件后,证面信息、绑定合同产品和关联购买证会清空。</p
|
||||
>
|
||||
<AttachmentUploadField
|
||||
ref="attachments"
|
||||
@@ -305,7 +305,7 @@
|
||||
</section>
|
||||
|
||||
<section v-if="kind === 'transport'" class="mp-wv-section">
|
||||
<h3>证面引用</h3>
|
||||
<h3>关联购买证</h3>
|
||||
<p v-if="form.referencesEditable === false" class="plan-empty-hint">
|
||||
已有额度流水。尚未关联购买证档案的引用可以补全;已关联的引用不能修改或移除。
|
||||
</p>
|
||||
@@ -921,7 +921,7 @@
|
||||
}
|
||||
function addReference() {
|
||||
if (form.value.referencesEditable === false) {
|
||||
ElMessage.warning('已有额度流水,不能新增或移除证面引用')
|
||||
ElMessage.warning('已有额度流水,不能新增或移除关联购买证')
|
||||
return
|
||||
}
|
||||
form.value.purchaseRefs = [
|
||||
@@ -1034,17 +1034,17 @@
|
||||
touch('categoryId')
|
||||
categoryOpen.value = false
|
||||
}
|
||||
async function matchBuyerCustomer(name: string, current: number) {
|
||||
const buyer = name.trim()
|
||||
if (!buyer) return
|
||||
async function matchBuyerCustomer(name: string, current: number, partyLabel = '证面单位') {
|
||||
const party = name.trim()
|
||||
if (!party) return
|
||||
try {
|
||||
const result = await fetchCustomerOptions({ keyword: buyer, limit: 200 })
|
||||
const result = await fetchCustomerOptions({ keyword: party, limit: 200 })
|
||||
if (current !== epoch) return
|
||||
const matches = exactCustomerMatches(extractCustomers(result), buyer)
|
||||
const matches = exactCustomerMatches(extractCustomers(result), party)
|
||||
if (matches.length === 1) {
|
||||
const matched = {
|
||||
id: String(matches[0].id),
|
||||
customerName: matches[0].customerName || buyer
|
||||
customerName: matches[0].customerName || party
|
||||
}
|
||||
if (!systemCustomer.value.id) {
|
||||
systemCustomer.value = matched
|
||||
@@ -1058,8 +1058,8 @@
|
||||
}
|
||||
ElMessage.warning(
|
||||
matches.length
|
||||
? '有多个客户与购买单位同名,请手工选择'
|
||||
: '未找到与购买单位完全一致的客户,请手工选择'
|
||||
? `有多个客户与${partyLabel}同名,请手工选择`
|
||||
: `未找到与${partyLabel}完全一致的客户,请手工选择`
|
||||
)
|
||||
} catch {
|
||||
if (current === epoch) ElMessage.warning('客户匹配失败,请手工选择')
|
||||
@@ -1544,10 +1544,14 @@
|
||||
if (targetKind === 'purchase') {
|
||||
const buyer = String(form.value.buyerName || '').trim()
|
||||
const productName = String(form.value.productNameOnCert || '').trim()
|
||||
if (buyer) await matchBuyerCustomer(buyer, current)
|
||||
if (buyer) await matchBuyerCustomer(buyer, current, '购买单位')
|
||||
if (productName) await matchCertCategory(productName, current)
|
||||
}
|
||||
if (targetKind === 'transport') await linkRecognizedPurchaseCerts(current, targetKind, image)
|
||||
if (targetKind === 'transport') {
|
||||
const consignee = String(form.value.consigneeName || '').trim()
|
||||
if (consignee) await matchBuyerCustomer(consignee, current, '收货单位')
|
||||
await linkRecognizedPurchaseCerts(current, targetKind, image)
|
||||
}
|
||||
if (current !== epoch || kind.value !== targetKind || recognitionImage.value !== image) return
|
||||
ElMessage.success(
|
||||
Object.keys(result.invalidFields || {}).length
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
<template #beside>
|
||||
<div class="cert-upload-notes">
|
||||
<p>一次仅上传并解析一张证件图片或 PDF;保存成功后自动清空,继续处理下一张</p>
|
||||
<p>删除证件附件后,证面信息、绑定合同产品和证面引用会清空</p>
|
||||
<p>删除证件附件后,证面信息、绑定合同产品和关联购买证会清空</p>
|
||||
<p v-if="form.entryMode === 'image_parse' || !!form.attachmentUrls"
|
||||
>请核对证号、数量、单位、有效次数和引用关系。解析只补充未编辑的空字段。</p
|
||||
>
|
||||
@@ -421,7 +421,7 @@
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
<section v-if="formKind === 'transport'" class="view-section">
|
||||
<h3 class="dialog-section-title">证面引用</h3>
|
||||
<h3 class="dialog-section-title">关联购买证</h3>
|
||||
<el-button
|
||||
class="mb-3"
|
||||
type="primary"
|
||||
@@ -808,23 +808,27 @@
|
||||
}
|
||||
|
||||
/** 解析后回填【客户与品类】系统客户:名称完全一致且唯一才选中。 */
|
||||
async function matchSystemCustomer(name: string, protectedFields: Set<string>) {
|
||||
const buyer = name.trim()
|
||||
if (!buyer || form.value.customerId || protectedFields.has('customerId')) return
|
||||
async function matchSystemCustomer(
|
||||
name: string,
|
||||
protectedFields: Set<string>,
|
||||
partyLabel = '证面单位'
|
||||
) {
|
||||
const party = name.trim()
|
||||
if (!party || form.value.customerId || protectedFields.has('customerId')) return
|
||||
try {
|
||||
const result = await fetchCustomerOptions({ keyword: buyer, limit: 200 })
|
||||
const result = await fetchCustomerOptions({ keyword: party, limit: 200 })
|
||||
if (form.value.customerId || protectedFields.has('customerId')) return
|
||||
const matches = exactCustomerMatches(extractCustomerRows(result), buyer)
|
||||
const matches = exactCustomerMatches(extractCustomerRows(result), party)
|
||||
if (matches.length === 1) {
|
||||
await ensureCustomerOption(matches[0].id, matches[0].customerName || buyer)
|
||||
await ensureCustomerOption(matches[0].id, matches[0].customerName || party)
|
||||
form.value.customerId = matches[0].id
|
||||
edited.add('customerId')
|
||||
return
|
||||
}
|
||||
ElMessage.warning(
|
||||
matches.length
|
||||
? '有多个客户与购买单位同名,请手工选择系统客户'
|
||||
: '未找到与购买单位完全一致的客户,请手工选择系统客户'
|
||||
? `有多个客户与${partyLabel}同名,请手工选择系统客户`
|
||||
: `未找到与${partyLabel}完全一致的客户,请手工选择系统客户`
|
||||
)
|
||||
} catch {
|
||||
ElMessage.warning('系统客户匹配失败,请手工选择')
|
||||
@@ -1059,7 +1063,7 @@
|
||||
{ title: '证件附件', fields: [], slot: 'attachment' }
|
||||
)
|
||||
if (kind.value === 'transport') {
|
||||
sections.push({ title: '证面引用', fields: [], slot: 'references' })
|
||||
sections.push({ title: '关联购买证', fields: [], slot: 'references' })
|
||||
}
|
||||
} else {
|
||||
sections.push({ title: '', fields: [], slot: 'contracts' })
|
||||
@@ -1626,14 +1630,17 @@
|
||||
if (targetKind === 'purchase') {
|
||||
const buyer = String(form.value.buyerName || '').trim()
|
||||
const productName = String(form.value.productNameOnCert || '').trim()
|
||||
if (buyer) await matchSystemCustomer(buyer, protectedFields)
|
||||
if (buyer) await matchSystemCustomer(buyer, protectedFields, '购买单位')
|
||||
if (productName) await matchCertCategory(productName, protectedFields)
|
||||
if (form.value.bindingsEditable !== false && buyer) {
|
||||
await purchaseBinder.value?.matchBuyerCustomer(buyer)
|
||||
}
|
||||
}
|
||||
if (targetKind === 'transport')
|
||||
if (targetKind === 'transport') {
|
||||
const consignee = String(form.value.consigneeName || '').trim()
|
||||
if (consignee) await matchSystemCustomer(consignee, protectedFields, '收货单位')
|
||||
await linkRecognizedPurchaseCerts(session, targetKind, targetImage)
|
||||
}
|
||||
if (
|
||||
session !== editSession ||
|
||||
!formVisible.value ||
|
||||
@@ -1746,7 +1753,7 @@
|
||||
}
|
||||
function referencesLocked() {
|
||||
if (form.value.referencesEditable !== false) return false
|
||||
ElMessage.warning('已有额度流水,不能新增或移除证面引用')
|
||||
ElMessage.warning('已有额度流水,不能新增或移除关联购买证')
|
||||
return true
|
||||
}
|
||||
function addReference() {
|
||||
|
||||
@@ -170,7 +170,7 @@ export function newCert(kind: CertType): CertBody {
|
||||
return body as unknown as CertBody
|
||||
}
|
||||
|
||||
/** 删除当前证件附件后,清掉证面、合同绑定和证面引用,保留备注与录入方式。 */
|
||||
/** 删除当前证件附件后,清掉证面、合同绑定和关联购买证,保留备注与录入方式。 */
|
||||
export function clearCertAfterAttachmentRemoved<T extends Record<string, any>>(
|
||||
kind: CertType,
|
||||
form: T
|
||||
|
||||
Reference in new issue
Block a user