This commit is contained in:
2026-08-11 09:31:42 +08:00
parent 9391c4db09
commit 0a5b3b2cab
21 changed files with 409 additions and 108 deletions
+1 -1
View File
@@ -95,7 +95,7 @@
>
编辑
</el-link>
<el-link type="primary" v-if="permission.cargo_type_delete" @click="rowDel(row)">
<el-link type="danger" v-if="permission.cargo_type_delete" @click="rowDel(row)">
删除
</el-link>
</template>
+1 -1
View File
@@ -68,7 +68,7 @@
编辑
</el-link>
<el-link
type="primary"
type="danger"
v-if="hasPermission('common_address_delete') && !row.readonly"
@click="rowDel(row)"
>
+1 -1
View File
@@ -59,7 +59,7 @@
</el-button>
<el-button
v-if="permission.region_delete"
type="primary"
type="danger"
icon="el-icon-delete"
@click="handleDelete"
>删除
+1 -1
View File
@@ -163,7 +163,7 @@
编辑
</el-link>
<el-link
type="primary"
type="danger"
v-if="hasPermission('common_cargo_delete') && !row.readonly"
@click="rowDel(row)"
>
+1 -1
View File
@@ -132,7 +132,7 @@
编辑
</el-link>
<el-link
type="primary"
type="danger"
v-if="hasPermission('common_route_delete') && !row.readonly"
@click="rowDel(row)"
>
@@ -564,7 +564,7 @@
</el-link>
<el-link
v-if="!dialogReadonly"
type="primary"
type="danger"
@click="removeTransportCargoRow($index)"
>
删除
@@ -1378,7 +1378,7 @@
</el-link>
<el-link
v-if="!dialogReadonly"
type="primary"
type="danger"
@click="removeTransportCargoRow($index)"
>
删除
@@ -1627,8 +1627,21 @@
button-text="上传附件"
@change="handleContractFileChange"
/>
<el-button
type="primary"
:disabled="!contractFileRows.length"
@click="handleContractFileBatchDownload"
>
批量下载
</el-button>
</div>
<el-table :data="contractFileRows" border class="business-crud-page__attachment-table">
<el-table
:data="contractFileRows"
border
class="business-crud-page__attachment-table"
@selection-change="handleContractFileSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" label="序号" width="70" align="center" />
<el-table-column label="文件名" min-width="240" align="center" show-overflow-tooltip>
<template #default="{ row }">{{ row.originalName || row.name }}</template>
@@ -1638,11 +1651,11 @@
</el-table-column>
<el-table-column prop="uploadUserName" label="上传人" width="140" align="center" />
<el-table-column prop="uploadTime" label="上传时间" width="170" align="center" sortable/>
<el-table-column label="操作" width="120" align="center">
<el-table-column label="操作" width="120" align="center" fixed="right">
<template #default="{ row, $index }">
<el-link
v-if="!dialogReadonly"
type="primary"
type="danger"
@click="removeContractFile($index)"
>
删除
@@ -1687,14 +1700,14 @@
align="center"
show-overflow-tooltip
/>
<el-table-column label="操作" width="180" align="center">
<el-table-column label="操作" width="180" align="center" fixed="right">
<template #default="{ row, $index }">
<el-link type="primary" @click="openBillingPlan(row, $index)">
编辑
</el-link>
<el-link
v-if="!dialogReadonly"
type="primary"
type="danger"
@click="removeBillingPlan($index)"
>
删除
@@ -1882,7 +1895,13 @@
批量下载
</el-button>
</div>
<el-table :data="attachmentRows" border class="business-crud-page__attachment-table">
<el-table
:data="attachmentRows"
border
class="business-crud-page__attachment-table"
@selection-change="handleAttachmentSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" label="序号" width="70" align="center" />
<el-table-column label="文件名" min-width="200" align="center" show-overflow-tooltip>
<template #default="{ row }">{{ row.originalName || row.name }}</template>
@@ -1901,11 +1920,11 @@
</el-table-column>
<el-table-column prop="uploadUserName" label="上传人" width="140" align="center" />
<el-table-column prop="uploadTime" label="上传时间" width="160" align="center" sortable/>
<el-table-column label="操作" width="100" align="center">
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="{ row, $index }">
<el-link
v-if="!dialogReadonly"
type="primary"
type="danger"
@click="removeAttachment($index)"
>
删除
@@ -1937,7 +1956,7 @@
show-overflow-tooltip
/>
<el-table-column prop="statusName" label="状态" min-width="140" align="center" />
<el-table-column label="操作" width="120" align="center">
<el-table-column label="操作" width="120" align="center" fixed="right">
<template #default="{ row }">
<el-link type="primary" @click="handleChangeRecordFlow(row)"> 流程 </el-link>
</template>
@@ -2095,7 +2114,7 @@
>
{{ operation.label }}
</el-link>
<el-link type="primary" v-if="canDelete(row)" @click="rowDel(row)">
<el-link type="danger" v-if="canDelete(row)" @click="rowDel(row)">
删除
</el-link>
</template>
@@ -3124,7 +3143,9 @@
:data="dispatchItemAttachmentRows"
border
class="business-crud-page__attachment-table"
@selection-change="handleDispatchItemAttachmentSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" label="序号" width="70" align="center" />
<el-table-column label="文件名" min-width="200" align="center" show-overflow-tooltip>
<template #default="{ row }">{{ row.originalName || row.name }}</template>
@@ -3139,7 +3160,7 @@
</el-table-column>
<el-table-column prop="uploadUserName" label="上传人" width="140" align="center" />
<el-table-column prop="uploadTime" label="上传时间" width="160" align="center" sortable/>
<el-table-column label="操作" width="100" align="center">
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="{ $index }">
<el-link type="danger" @click="removeDispatchItemAttachment($index)">删除</el-link>
</template>
@@ -3364,7 +3385,7 @@
</el-link>
<el-button
v-if="canEditBillingLimit(row) && getBillingLimitRanges(row).length > 1"
type="primary"
type="danger"
text
@click="removeBillingLimitRange(row, rangeIndex)"
>
@@ -3409,7 +3430,7 @@
</el-link>
<el-link
v-if="!dialogReadonly"
type="primary"
type="danger"
@click="removeBillingRule($index)"
>
删除
@@ -4304,8 +4325,11 @@ export default {
dispatchItemIndex: -1,
dispatchItemForm: defaultDispatchRow(),
dispatchItemAttachmentRows: [],
selectedDispatchItemAttachmentRows: [],
attachmentRows: [],
selectedAttachmentRows: [],
contractFileRows: [],
selectedContractFileRows: [],
transportCargoRows: [],
shippingTemplateFreight: defaultShippingTemplateFreight(),
shippingTemplateCurrencyOptions: [],
@@ -5107,6 +5131,7 @@ export default {
this.form.planName = this.form.planName || this.form.templateName || '';
this.selectedProjectId = this.form.projectId || '';
this.attachmentRows = this.parseJsonArray(this.form.attachmentsJson);
this.selectedAttachmentRows = [];
if (this.contractSelectEnabled) {
this.syncCurrentContractOption();
this.loadContractOptionsForProject();
@@ -5810,7 +5835,9 @@ export default {
this.selectedProjectId = '';
this.selectedOrganizationId = '';
this.attachmentRows = [];
this.selectedAttachmentRows = [];
this.contractFileRows = [];
this.selectedContractFileRows = [];
this.shippingPlanOptions = [];
if (this.contractSelectEnabled) {
this.contractOptions = [];
@@ -5861,7 +5888,9 @@ export default {
this.selectedProjectId = this.form.projectId || '';
this.selectedOrganizationId = this.form.organizationId || '';
this.attachmentRows = this.parseJsonArray(this.form.attachmentsJson);
this.selectedAttachmentRows = [];
this.contractFileRows = this.parseJsonArray(this.form.contractFileJson);
this.selectedContractFileRows = [];
this.initTransportPlanFormRows();
this.billingPlanRows = this.parseJsonArray(this.form.billingPlanJson);
this.settlementRuleForm = this.normalizeSettlementRule({
@@ -7630,10 +7659,17 @@ export default {
uploadUserName: item.uploadUserName || userName,
uploadTime: item.uploadTime || uploadTime,
}));
this.selectedAttachmentRows = [];
this.form.attachmentsJson = JSON.stringify(this.attachmentRows);
},
handleAttachmentSelectionChange(rows) {
this.selectedAttachmentRows = rows || [];
},
removeAttachment(index) {
this.attachmentRows.splice(index, 1);
this.selectedAttachmentRows = this.selectedAttachmentRows.filter(item =>
this.attachmentRows.includes(item)
);
this.form.attachmentsJson = JSON.stringify(this.attachmentRows);
},
formatFileSize(size) {
@@ -7652,7 +7688,10 @@ export default {
downloadFileByUrl(url, row.originalName || row.name || '附件');
},
handleBatchDownload() {
this.attachmentRows.forEach(row => this.downloadAttachment(row));
const rows = this.selectedAttachmentRows.length
? this.selectedAttachmentRows
: this.attachmentRows;
rows.forEach(row => this.downloadAttachment(row));
},
handleDispatchItemAttachmentChange(list) {
const userName = this.userInfo?.realName || this.userInfo?.userName || '';
@@ -7663,12 +7702,22 @@ export default {
uploadUserName: item.uploadUserName || userName,
uploadTime: item.uploadTime || uploadTime,
}));
this.selectedDispatchItemAttachmentRows = [];
},
removeDispatchItemAttachment(index) {
this.dispatchItemAttachmentRows.splice(index, 1);
this.selectedDispatchItemAttachmentRows = this.selectedDispatchItemAttachmentRows.filter(item =>
this.dispatchItemAttachmentRows.includes(item)
);
},
handleDispatchItemBatchDownload() {
this.dispatchItemAttachmentRows.forEach(row => this.downloadAttachment(row));
const rows = this.selectedDispatchItemAttachmentRows.length
? this.selectedDispatchItemAttachmentRows
: this.dispatchItemAttachmentRows;
rows.forEach(row => this.downloadAttachment(row));
},
handleDispatchItemAttachmentSelectionChange(rows) {
this.selectedDispatchItemAttachmentRows = rows || [];
},
handleContractFileChange(list) {
const userName = this.userInfo?.realName || this.userInfo?.userName || '';
@@ -7678,12 +7727,25 @@ export default {
uploadUserName: item.uploadUserName || userName,
uploadTime: item.uploadTime || uploadTime,
}));
this.selectedContractFileRows = [];
this.form.contractFileJson = JSON.stringify(this.contractFileRows);
},
handleContractFileSelectionChange(rows) {
this.selectedContractFileRows = rows || [];
},
removeContractFile(index) {
this.contractFileRows.splice(index, 1);
this.selectedContractFileRows = this.selectedContractFileRows.filter(item =>
this.contractFileRows.includes(item)
);
this.form.contractFileJson = JSON.stringify(this.contractFileRows);
},
handleContractFileBatchDownload() {
const rows = this.selectedContractFileRows.length
? this.selectedContractFileRows
: this.contractFileRows;
rows.forEach(row => this.downloadAttachment(row));
},
cloneData(data) {
return JSON.parse(JSON.stringify(data));
},
@@ -8999,6 +9061,7 @@ export default {
this.dispatchItemIndex = -1;
this.dispatchItemForm = defaultDispatchRow();
this.dispatchItemAttachmentRows = [];
this.selectedDispatchItemAttachmentRows = [];
},
buildDispatchRows(plan = {}) {
const goodsRows = this.parseJsonArray(plan.goodsJson);
@@ -9128,6 +9191,7 @@ export default {
this.dispatchItemAttachmentRows = this.parseJsonArray(
index >= 0 ? row.attachmentsJson : this.dispatchRow.attachmentsJson
);
this.selectedDispatchItemAttachmentRows = [];
this.dispatchItemBox = true;
},
handleDispatchCarrierTypeChange(value) {
@@ -9219,11 +9283,13 @@ export default {
this.dispatchItemIndex = -1;
this.dispatchItemForm = defaultDispatchRow();
this.dispatchItemAttachmentRows = [];
this.selectedDispatchItemAttachmentRows = [];
},
resetDispatchItemDialog() {
this.dispatchItemIndex = -1;
this.dispatchItemForm = defaultDispatchRow();
this.dispatchItemAttachmentRows = [];
this.selectedDispatchItemAttachmentRows = [];
},
removeDispatchRow(index) {
this.$confirm('确定删除该调度明细?', '提示', {
+1 -1
View File
@@ -318,7 +318,7 @@
<el-link
v-for="action in rowActions(row)"
:key="action.type"
type="primary"
:type="action.type === 'delete' ? 'danger' : 'primary'"
@click="handleRowAction(action.type, row)"
>{{ action.label }}</el-link>
</div>
+33 -3
View File
@@ -46,6 +46,27 @@
</el-button>
</template>
<template #menu-form-before="{ disabled }">
<template v-if="!dialogReadonly">
<el-button
plain
:loading="disabled"
:disabled="disabled"
@click="handleProcessConfigSave('draft')"
>
保存草稿
</el-button>
<el-button
type="primary"
:loading="disabled"
:disabled="disabled"
@click="handleProcessConfigSave('enabled')"
>
保存并启用
</el-button>
</template>
</template>
<template #status="{ row }">
<el-tag :type="statusTagType(row.status)">
{{ row.statusName || displayStatus(row.status) }}
@@ -382,7 +403,7 @@
停用
</el-link>
<el-link
type="primary"
type="danger"
v-if="canDelete(row)"
@click="rowDel(row)"
>
@@ -502,6 +523,7 @@ export default {
total: 0,
},
selectionList: [],
submitStatus: 1,
};
},
computed: {
@@ -870,9 +892,10 @@ export default {
}
);
},
submitRow(row, done, loading) {
submitRow(row, done, loading, status = this.submitStatus) {
this.submitStatus = 1;
this.syncNodeFields();
const submitRow = this.normalizeRow(row);
const submitRow = this.normalizeRow({ ...row, status });
if (!this.validateRow(submitRow)) {
this.stopSubmitLoading(loading);
return;
@@ -897,6 +920,12 @@ export default {
rowUpdate(row, index, done, loading) {
this.submitRow(row, done, loading);
},
handleProcessConfigSave(mode) {
this.submitStatus = mode === 'draft' ? 2 : 1;
if (this.$refs.crud && typeof this.$refs.crud.rowSave === 'function') {
this.$refs.crud.rowSave();
}
},
rowDel(row) {
this.$confirm('确定将选择数据删除?', {
confirmButtonText: '确定',
@@ -941,6 +970,7 @@ export default {
},
beforeOpen(done, type) {
this.dialogReadonly = type === 'view';
this.submitStatus = 1;
if (type === 'add') {
this.form = {
configName: '',
+20 -6
View File
@@ -78,7 +78,7 @@
>
{{ operation.label }}
</el-link>
<el-link type="primary" v-if="canDelete(row)" @click="rowDel(row)"> 删除 </el-link>
<el-link type="danger" v-if="canDelete(row)" @click="rowDel(row)"> 删除 </el-link>
</template>
</avue-crud>
@@ -481,7 +481,13 @@
show-icon
:title="`缺少必需材料:${missingRequiredAttachmentTypes.join('、')}`"
/>
<el-table :data="attachmentRows" border class="project-apply-form__material-table">
<el-table
:data="attachmentRows"
border
class="project-apply-form__material-table"
@selection-change="handleAttachmentSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" label="序号" width="80" align="center" />
<el-table-column label="附件类型" min-width="160" align="center">
<template #default="{ row }">
@@ -515,7 +521,7 @@
<el-table-column label="操作" width="110" align="center">
<template #default="{ row, $index }">
<el-link type="primary" @click="downloadAttachment(row)">下载</el-link>
<el-link v-if="!dialogReadonly" type="primary" @click="removeAttachment($index)"
<el-link v-if="!dialogReadonly" type="danger" @click="removeAttachment($index)"
>删除</el-link
>
</template>
@@ -910,11 +916,9 @@ export default {
},
],
changeContent: [
{ required: true, message: '请输入变更内容', trigger: 'blur' },
{ max: 2000, message: '变更内容不能超过2000个字符', trigger: 'blur' },
],
changeReason: [
{ required: true, message: '请输入变更原因', trigger: 'blur' },
{ max: 2000, message: '变更原因不能超过2000个字符', trigger: 'blur' },
],
},
@@ -937,6 +941,7 @@ export default {
customerRows: [],
carrierRows: [],
attachmentRows: [],
selectedAttachmentRows: [],
attachmentFileTypes: [
'pdf',
'bmp',
@@ -1285,6 +1290,7 @@ export default {
this.customerRows = [];
this.carrierRows = [];
this.attachmentRows = [];
this.selectedAttachmentRows = [];
this.changeRows = [];
this.selectedCustomerId = [];
this.selectedCarrierIds = [];
@@ -1324,6 +1330,7 @@ export default {
this.customerRows = customerRows;
this.carrierRows = carrierRows;
this.attachmentRows = this.parseJsonArray(displayRow.attachmentsJson);
this.selectedAttachmentRows = [];
this.changeRows = this.buildChangeRows(displayRow);
this.selectedCustomerId = this.customerRows
.map(item => this.getCustomerRowId(item))
@@ -1791,6 +1798,10 @@ export default {
uploadUserName: item.uploadUserName || userName,
uploadTime: item.uploadTime || uploadTime,
}));
this.selectedAttachmentRows = [];
},
handleAttachmentSelectionChange(rows) {
this.selectedAttachmentRows = rows || [];
},
removeAttachment(index) {
this.attachmentRows.splice(index, 1);
@@ -1811,7 +1822,10 @@ export default {
downloadFileByUrl(url, row.originalName || row.name || '附件');
},
handleBatchDownload() {
this.attachmentRows.forEach(row => this.downloadAttachment(row));
const rows = this.selectedAttachmentRows.length
? this.selectedAttachmentRows
: this.attachmentRows;
rows.forEach(row => this.downloadAttachment(row));
},
handleChangeRecordAction() {
this.$message.info('变更记录详情由后端明细能力生成后展示');
+1 -1
View File
@@ -36,7 +36,7 @@
>流程图
</el-link>
<el-link
type="primary"
type="danger"
v-if="permission.flow_manager_remove"
@click.stop="handleSlotDelete(scope.row, scope.index)"
>删除
+1 -1
View File
@@ -51,7 +51,7 @@
>部署
</el-link>
<el-link
type="primary"
type="danger"
size="default"
v-if="permission.flow_model_delete"
@click.stop="handleSlotDelete(scope.row, scope.index)"
+3 -3
View File
@@ -59,7 +59,7 @@
<el-form-item label="名称">
<el-input v-model="carrierQuery.fullName" placeholder="请输入承运商名称" clearable />
</el-form-item>
<el-form-item label="准入标准">
<el-form-item label="准入类型">
<el-select v-model="carrierQuery.accessType" placeholder="全部" clearable>
<el-option label="临时" value="temporary" />
<el-option label="正式" value="formal" />
@@ -92,7 +92,7 @@
<el-table-column prop="customerNature" label="客户性质" min-width="120" />
<el-table-column prop="unifiedCreditCode" label="统一信用代码" min-width="180" />
<el-table-column prop="deptName" label="所属组织" min-width="150" />
<el-table-column prop="accessType" label="准入标准" min-width="110">
<el-table-column prop="accessType" label="准入类型" min-width="110">
<template #default="{ row }">{{ formatAccessType(row.accessType) }}</template>
</el-table-column>
<el-table-column prop="approvalStatus" label="审批状态" min-width="120">
@@ -100,7 +100,7 @@
</el-table-column>
<el-table-column prop="currentNode" label="当前节点" min-width="130" />
<el-table-column prop="currentProcessor" label="当前处理人" min-width="130" />
<el-table-column prop="approvedTime" label="审核通过时间" min-width="170" sortable/>
<el-table-column prop="approvedTime" label="审核通过时间" min-width="170" sortable />
<el-table-column prop="status" label="状态" width="90">
<template #default="{ row }">{{ Number(row.status) === 1 ? '启用' : '停用' }}</template>
</el-table-column>
+1 -1
View File
@@ -97,7 +97,7 @@
</el-link>
<el-link
v-if="this.permissionList.delBtn"
type="primary"
type="danger"
@click="rowDel(row)"
>删除
</el-link>
@@ -233,7 +233,7 @@
<span class="score-unit"></span>
</div>
<el-link
type="primary"
type="danger"
class="option-delete"
v-if="!readonly && itemForm.options.length > 1"
@click="removeOption(index)"
+208 -60
View File
@@ -581,20 +581,11 @@
<template #extra>
<div v-if="!readonly" class="section-actions">
<el-button icon="el-icon-download" @click="downloadAttachments">批量下载</el-button>
<el-button type="primary" icon="el-icon-plus" @click="addAttachment"
>普通上传</el-button
>
<el-button type="primary" icon="el-icon-upload" @click="addAttachment">
OCR上传识别
</el-button>
</div>
</template>
<el-alert
type="info"
:closable="false"
title="支持pdf、bmp、jpeg、png、jpg、doc、docx、ppt、pptx、xlsx、xls、eml、msg、zip的文件格式,单个文件大小限制500M"
class="archive-rule-alert"
/>
<el-alert
v-if="missingQualificationText"
type="error"
@@ -602,29 +593,28 @@
:title="missingQualificationText"
class="archive-rule-alert"
/>
<el-table :data="qualificationFiles" border>
<el-table
:data="qualificationFiles"
border
@selection-change="handleQualificationSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" width="90" align="center" />
<el-table-column label="附件类型" min-width="160">
<template #default="{ row }">
<el-select v-model="row.type" :disabled="readonly" filterable>
<el-option label="法人身份证" value="法人身份证" />
<el-option label="道路运输许可证" value="道路运输许可证" />
<el-option label="其他附件" value="其他附件" />
<el-option
v-for="item in qualificationTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="文件名称" min-width="180">
<template #default="{ row }">
<vehicle-attachment-upload
v-model="row.files"
:readonly="readonly"
:multiple="false"
accept=".pdf,.bmp,.jpeg,.png,.jpg,.doc,.docx,.ppt,.pptx,.xlsx,.xls,.eml,.msg,.zip"
:max-size="500"
button-text="上传文件"
:show-tip="false"
@success="file => handleQualificationUploadSuccess(file, row)"
/>
<span>{{ row.originalName || row.name || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="附件描述" min-width="220">
@@ -655,15 +645,59 @@
</template>
</el-table-column>
</el-table>
<div v-if="!readonly" class="qualification-upload-bar">
<vehicle-attachment-upload
v-model="qualificationUploadFiles"
:multiple="true"
:limit="20"
accept=".pdf,.bmp,.jpeg,.png,.jpg,.doc,.docx,.ppt,.pptx,.xlsx,.xls,.eml,.msg,.zip"
:max-size="500"
button-text="上传附件"
:show-tip="false"
:show-file-list="false"
:show-uploading="true"
@success="handleQualificationUploadSuccess"
/>
<span class="qualification-upload-bar__tip">
支持pdf、bmp、jpeg、png、jpg、doc、docx、ppt、pptx、xlsx、xls、eml、msg、zip,单个文件不超过500M
</span>
</div>
</section-card>
<section-card title="变更记录">
<el-table :data="archiveForm.changeRecords" border>
<el-table-column label="序号" type="index" width="90" align="center" />
<el-table :data="changeRecordPage.records" border>
<el-table-column
label="序号"
type="index"
width="90"
align="center"
:index="changeRecordIndex"
/>
<el-table-column label="变更日期" prop="changeTime" min-width="170" sortable />
<el-table-column label="变更内容" prop="changeContent" min-width="260" />
<el-table-column label="变更字段" prop="changedFields" min-width="180" />
<el-table-column
label="原数据"
prop="beforeData"
min-width="240"
show-overflow-tooltip
:formatter="formatChangeData"
/>
<el-table-column
label="修改后数据"
prop="afterData"
min-width="240"
show-overflow-tooltip
:formatter="formatChangeData"
/>
<el-table-column label="变更内容" prop="changeContent" min-width="180" />
<el-table-column label="变更账号" prop="changeUserName" min-width="160" />
</el-table>
<empty-pagination
:page="changeRecordPage"
always-show
@size-change="handleChangeRecordSizeChange"
@current-change="handleChangeRecordCurrentChange"
/>
</section-card>
<template #footer>
@@ -1067,7 +1101,7 @@
<el-table-column label="得分说明" prop="scoreDescription" min-width="160" />
<el-table-column label="自评得分" width="130" align="center">
<template #default="{ row: detail }">
<span>{{ formatScoreValue(detail.selfScore) }}分</span>
<span>{{ formatScoreValue(getSignedScore(detail, 'selfScore')) }}分</span>
</template>
</el-table-column>
<el-table-column label="复评得分" width="150" align="center">
@@ -1075,9 +1109,13 @@
<el-input
v-model="detail.reviewScore"
maxlength="10"
inputmode="numeric"
:disabled="readonly || !hasPermission('customer_type_re_cert')"
@input="value => handleScoreDetailScoreInput(detail, 'reviewScore', value)"
>
<template v-if="isMinusScoreDetail(detail) && Number(detail.reviewScore) > 0" #prefix>
-
</template>
<template #suffix>分</template>
</el-input>
</template>
@@ -1089,8 +1127,8 @@
<el-table-column min-width="560">
<template #default="{ row }">
<span class="score-category-table__name">{{ row.categoryName }}</span>
<span>自评:{{ row.selfScore }}分</span>
<span>复评:{{ row.reviewScore }}分</span>
<span>自评:{{ getSignedScore(row, 'selfScore') }}分</span>
<span>复评:{{ getSignedScore(row, 'reviewScore') }}分</span>
</template>
</el-table-column>
<el-table-column width="60" align="center">
@@ -1113,12 +1151,17 @@
button-text="上传附件"
button-icon="el-icon-upload"
:show-tip="false"
:show-uploading="true"
@success="handleScoreAttachmentUploadSuccess"
/>
</template>
<el-table :data="scoreAttachmentFiles" border class="score-material-table">
<el-table-column label="序号" type="index" width="90" align="center" />
<el-table-column label="文件名" prop="name" min-width="220" />
<el-table-column label="文件名" min-width="220">
<template #default="{ row }">
{{ row.originalName || row.name || '-' }}
</template>
</el-table-column>
<el-table-column label="附件描述" prop="description" min-width="220" />
<el-table-column label="文件大小" min-width="120" align="center">
<template #default="{ row }">
@@ -1137,7 +1180,7 @@
</el-table-column>
<el-table-column label="操作" width="120" align="center" v-if="!readonly">
<template #default="{ $index }">
<el-link type="primary" @click="deleteScoreAttachment($index)">
<el-link type="danger" @click="deleteScoreAttachment($index)">
删除
</el-link>
</template>
@@ -1164,6 +1207,7 @@
import {
getList,
getDetail,
getChangeRecordList,
submit,
submitApproval,
withdrawApproval,
@@ -1294,6 +1338,13 @@ export default {
pageSize: 10,
pageSizes: [10, 20, 50, 100],
},
changeRecordPage: {
currentPage: 1,
pageSize: 5,
pageSizes: [5],
total: 0,
records: [],
},
contactIndex: -1,
contactForm: this.emptyContact(),
contactMapBox: false,
@@ -1310,6 +1361,8 @@ export default {
invoiceIndex: -1,
invoiceForm: this.emptyInvoice(),
qualificationFiles: [],
qualificationUploadFiles: [],
selectedQualificationFiles: [],
deptTree: [],
deptOptions: [],
regionOptions: [],
@@ -1317,6 +1370,7 @@ export default {
customerTypeOptions: [],
businessScopeOptions: [],
bankListOptions: [],
qualificationTypeOptions: [],
creditLevelOptions: ['A', 'B', 'C', 'D', 'E', 'F'].map(item => ({
label: `${item}级`,
value: `${item}级`,
@@ -1503,7 +1557,7 @@ export default {
dicData: [{ label: '全部', value: '' }],
},
{
label: '准入标准',
label: '准入类型',
prop: 'accessType',
slot: true,
type: 'select',
@@ -1643,14 +1697,14 @@ export default {
},
scoreTableData() {
const start = (this.scorePage.currentPage - 1) * this.scorePage.pageSize;
return this.scoreList
return this.sortScoresByLatest(this.scoreList)
.slice(start, start + this.scorePage.pageSize)
.map((item, index) => ({
...item,
__raw: item,
__rawIndex: start + index,
__index: start + index + 1,
maxCreditLimit: item.maxCreditLimit || '',
.map(({ score, index }, pageIndex) => ({
...score,
__raw: score,
__rawIndex: index,
__index: start + pageIndex + 1,
maxCreditLimit: score.maxCreditLimit || '',
}));
},
contactPaginationPage() {
@@ -1770,6 +1824,43 @@ export default {
this.handleDetailCurrentChange('receipt', 1);
this.handleDetailCurrentChange('invoice', 1);
},
loadChangeRecords() {
if (!this.archiveForm.id) return;
const page = this.changeRecordPage;
getChangeRecordList(this.archiveForm.id, page.currentPage, page.pageSize).then(res => {
const data = res.data.data || {};
page.records = data.records || [];
page.total = Number(data.total || 0);
page.currentPage = Number(data.current || page.currentPage);
});
},
handleChangeRecordCurrentChange(currentPage) {
this.changeRecordPage.currentPage = Number(currentPage) || 1;
this.loadChangeRecords();
},
handleChangeRecordSizeChange(pageSize) {
this.changeRecordPage.pageSize = Number(pageSize) || 5;
this.changeRecordPage.currentPage = 1;
this.loadChangeRecords();
},
resetChangeRecordPage() {
this.changeRecordPage.currentPage = 1;
this.changeRecordPage.total = 0;
this.changeRecordPage.records = [];
},
changeRecordIndex(index) {
return (this.changeRecordPage.currentPage - 1) * this.changeRecordPage.pageSize + index + 1;
},
formatChangeData(row, column, value) {
if (!value) return '-';
try {
return Object.entries(JSON.parse(value))
.map(([field, fieldValue]) => `${field}${fieldValue ?? '-'}`)
.join('');
} catch (error) {
return value;
}
},
emptyContact() {
return {
contactName: '',
@@ -1958,6 +2049,7 @@ export default {
});
this.loadDictOptions('scope_of_business', 'businessScopeOptions');
this.loadDictOptions('bank_list', 'bankListOptions');
this.loadDictOptions('customer_attachment_types', 'qualificationTypeOptions');
},
initScoreQuantificationOptions() {
this.scoreQuantificationLoading = true;
@@ -2611,7 +2703,8 @@ export default {
.filter(item => item.url)
.map(item => ({
type: String(item.type || '').trim(),
name: String(item.name || '').trim(),
originalName: String(item.originalName || item.name || '').trim(),
name: String(item.originalName || item.name || '').trim(),
description: String(item.description || '').trim(),
size: String(item.size || '').trim(),
uploadUserName: String(item.uploadUserName || '').trim(),
@@ -2641,22 +2734,51 @@ export default {
if (mb >= 1) return `${mb.toFixed(2)} MB`;
return `${(byteSize / 1024).toFixed(2)} KB`;
},
handleQualificationUploadSuccess(file, row) {
row.name = file.name || row.name || '客商材料';
row.size = this.formatAttachmentSize(file.size || row.size);
row.uploadUserName = this.userInfo.realName || this.userInfo.userName || '';
row.uploadTime = this.$dayjs().format('YYYY-MM-DD HH:mm:ss');
row.url = file.url || row.url || '';
row.files = [file];
handleQualificationUploadSuccess(file) {
const originalName = file.originalName || file.name || '客商材料';
this.qualificationFiles.push({
type: this.resolveQualificationType(originalName),
originalName,
name: originalName,
description: '',
size: this.formatAttachmentSize(file.size),
uploadUserName: this.userInfo.realName || this.userInfo.userName || '',
uploadTime: this.$dayjs().format('YYYY-MM-DD HH:mm:ss'),
url: file.url || file.link || '',
files: [file],
});
},
resolveQualificationType(fileName) {
const name = String(fileName || '').toLocaleLowerCase();
return (
[...this.qualificationTypeOptions]
.filter(item => item?.label || item?.value)
.sort(
(a, b) =>
String(b.label || b.value || '').length - String(a.label || a.value || '').length
)
.find(item => {
const typeText = String(item.label || item.value || '').toLocaleLowerCase();
return typeText && name.includes(typeText);
})?.value || ''
);
},
downloadAttachments() {
const files = this.qualificationFiles.filter(item => item.url);
const source = this.selectedQualificationFiles.length
? this.selectedQualificationFiles
: this.qualificationFiles;
const files = source.filter(item => item.url);
if (!files.length) {
this.$message.warning('暂无可下载附件');
this.$message.warning(
this.selectedQualificationFiles.length ? '所选附件暂无可下载地址' : '暂无可下载附件'
);
return;
}
files.forEach(item => window.open(item.url, '_blank'));
},
handleQualificationSelectionChange(rows) {
this.selectedQualificationFiles = rows || [];
},
normalizeDetail(detail) {
const businessScope = this.splitValue(detail.businessScope);
const registeredDetailAddress =
@@ -2723,10 +2845,9 @@ export default {
const time = this.$dayjs(value).valueOf();
return Number.isFinite(time) ? time : 0;
},
getLatestCreditScore(scores = []) {
sortScoresByLatest(scores = []) {
return (scores || [])
.map((score, index) => ({ score, index }))
.filter(item => String(item.score.creditLevel || '').trim())
.sort((a, b) => {
const scoreDateDiff =
this.getScoreTimeValue(b.score.scoreDate) - this.getScoreTimeValue(a.score.scoreDate);
@@ -2738,7 +2859,12 @@ export default {
this.getScoreTimeValue(b.score.createTime) - this.getScoreTimeValue(a.score.createTime);
if (createTimeDiff) return createTimeDiff;
return b.index - a.index;
})[0]?.score;
});
},
getLatestCreditScore(scores = []) {
return this.sortScoresByLatest(scores)
.filter(item => String(item.score.creditLevel || '').trim())
[0]?.score;
},
applyArchiveCreditFromScores(archive) {
const latestScore = this.getLatestCreditScore(archive.scores || []);
@@ -2754,27 +2880,35 @@ export default {
this.readonly = readonly;
this.activeTab = 'scores';
this.resetDetailPagination();
this.resetChangeRecordPage();
if (row && row.id) {
getDetail(row.id).then(res => {
this.archiveForm = this.normalizeDetail(res.data.data);
this.qualificationFiles = this.parseAttachments(
this.archiveForm.qualificationAttachments
);
this.qualificationUploadFiles = [];
this.archiveBox = true;
this.loadChangeRecords();
});
return;
}
this.archiveForm = this.emptyArchive();
this.qualificationFiles = [];
this.qualificationUploadFiles = [];
this.selectedQualificationFiles = [];
this.archiveBox = true;
},
resetArchive() {
this.readonly = false;
this.archiveForm = this.emptyArchive();
this.qualificationFiles = [];
this.qualificationUploadFiles = [];
this.selectedQualificationFiles = [];
this.scoreBox = false;
this.resetScoreDialog();
this.resetDetailPagination();
this.resetChangeRecordPage();
this.contactBox = false;
this.contactIndex = -1;
this.contactForm = this.emptyContact();
@@ -3056,13 +3190,9 @@ export default {
this.calculateScore(this.currentScore);
},
handleScoreDetailScoreInput(detail, prop, value) {
const normalized = String(value || '')
.replace(/[^\d.]/g, '')
.replace(/^\./, '')
.replace(/(\..*)\./g, '$1')
.replace(/^(\d+)(\.\d{0,2})?.*$/, '$1$2');
const normalized = String(value || '').replace(/\D/g, '');
if (prop === 'reviewScore' && normalized !== '') {
const maxScore = this.getScoreItemFullScore(detail);
const maxScore = Math.floor(this.getScoreItemFullScore(detail));
if (Number(normalized) > maxScore) {
detail[prop] = String(maxScore);
this.$message.warning(
@@ -3112,7 +3242,7 @@ export default {
},
getSignedScore(detail, prop) {
const score = Number(detail[prop] || 0);
return this.isMinusScoreDetail(detail) ? -score : score;
return this.isMinusScoreDetail(detail) && score > 0 ? -score : score;
},
getScoreItemFullScore(detail = {}) {
const itemScore = Number(detail.score);
@@ -3220,7 +3350,7 @@ export default {
this.archiveForm.scores.splice(this.scoreRecordIndex, 1, score);
} else {
this.archiveForm.scores.push(score);
this.handleScoreCurrentChange(this.scorePageCount);
this.handleScoreCurrentChange(1);
}
this.syncArchiveCreditFromScores();
this.activeTab = 'scores';
@@ -3538,6 +3668,24 @@ business-term-field,
margin-bottom: 12px;
}
.qualification-upload-bar {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
margin-top: 12px;
:deep(.vehicle-attachment-upload) {
width: auto;
}
&__tip {
grid-column: 2;
color: #909399;
font-size: 13px;
text-align: center;
}
}
.archive-tabs {
margin-top: 18px;
}