This commit is contained in:
2026-08-25 16:13:58 +08:00
parent e309987199
commit 55583551b5
14 changed files with 953 additions and 286 deletions
+12 -6
View File
@@ -190,7 +190,9 @@ export default {
}
};
const validateIcaoCode = (rule, value, callback) => {
if (!/^[A-Z]{4}$/.test(String(value || '').toUpperCase())) {
if (!value) {
callback();
} else if (!/^[A-Z]{4}$/.test(String(value).toUpperCase())) {
callback(new Error('ICAO代码为4位大写字母'));
} else {
callback();
@@ -281,10 +283,7 @@ export default {
prop: 'icaoCode',
minWidth: 100,
maxlength: 4,
rules: [
{ required: true, message: '请输入ICAO代码', trigger: 'blur' },
{ validator: validateIcaoCode, trigger: 'blur' },
],
rules: [{ validator: validateIcaoCode, trigger: 'blur' }],
change: ({ value }) => this.handleIcaoChange(value),
blur: ({ value }) => this.handleIcaoChange(value),
},
@@ -376,7 +375,10 @@ export default {
overHidden: false,
maxlength: 255,
showWordLimit: true,
rules: [{ max: 255, message: '详细地址不能超过255字', trigger: 'blur' }],
rules: [
{ required: true, message: '请输入详细地址', trigger: 'blur' },
{ max: 255, message: '详细地址不能超过255字', trigger: 'blur' },
],
},
{
label: '经度',
@@ -674,6 +676,7 @@ export default {
row.districtCode = String(row.districtCode || '').trim();
row.districtName = String(row.districtName || '').trim();
row.detailAddress = String(row.detailAddress || '').trim();
row.icaoCode = String(row.icaoCode || '').trim() || undefined;
row.longitude = normalizeCoordinateInput(row.longitude);
row.latitude = normalizeCoordinateInput(row.latitude);
if (!row.dataSource) row.dataSource = '手动录入';
@@ -696,6 +699,9 @@ export default {
validateUnique(row) {
const rowId = String(row.id || '');
const hasDuplicate = (params, prop) => {
if (!row[prop]) {
return Promise.resolve(false);
}
return getList(1, 10, params).then(res => {
const records = res.data.data.records || [];
return records.some(item => item[prop] === row[prop] && String(item.id || '') !== rowId);
+2 -2
View File
@@ -213,9 +213,9 @@ export const decorateCargoTypeFailDetail = async workbook => {
}
}
reasonCell.value = decorated.join('');
// 仅操作 G 列:黑色字体、无背景填充,其余列保持后端原样
// 仅失败原因列使用红色字体,其余列保持普通字体
reasonCell.fill = { type: 'pattern', pattern: 'none' };
reasonCell.font = { color: { argb: 'FF000000' } };
reasonCell.font = { color: { argb: 'FFFF0000' } };
reasonCell.alignment = { wrapText: true, vertical: 'top' };
});
// 加宽各列,避免内容拥挤(仅改列宽,不改动单元格样式)
+14 -60
View File
@@ -21,12 +21,6 @@
@on-load="onLoad"
>
<template #menu-left>
<el-button type="primary" plain v-if="permission.fee_item_import" @click="handleImport">
<el-icon class="el-icon--left"><Upload /></el-icon>批量导入
</el-button>
<el-button type="primary" plain v-if="permission.fee_item_template" @click="handleTemplate">
<el-icon class="el-icon--left"><Download /></el-icon>下载模板
</el-button>
<el-button type="primary" plain v-if="permission.fee_item_export" @click="handleExport">
<el-icon class="el-icon--left"><Download /></el-icon>批量导出
</el-button>
@@ -80,16 +74,6 @@
</el-link>
</template>
</avue-crud>
<el-dialog title="费用项导入" append-to-body v-model="excelBox" width="555px">
<avue-form :option="excelOption" v-model="excelForm">
<template #excelTemplate>
<el-button type="primary" @click="handleTemplate">
点击下载<i class="el-icon-download el-icon--right"></i>
</el-button>
</template>
</avue-form>
</el-dialog>
</basic-container>
</template>
@@ -99,24 +83,20 @@ import { exportBlob } from '@/api/common';
import { getDictionary } from '@/api/system/dictbiz';
import { getDeptTree } from '@/api/system/dept';
import { downloadXls } from '@/utils/util';
import { openImportDialog } from '@/utils/import-excel';
import { getToken } from '@/utils/auth';
import { getUploadHeaders } from '@/utils/upload';
import { Upload, Download } from '@element-plus/icons-vue';
import { Download } from '@element-plus/icons-vue';
import { mapGetters } from 'vuex';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default {
components: { Upload, Download },
components: { Download },
data() {
return {
form: {},
query: {},
loading: true,
data: [],
excelBox: false,
excelForm: {},
dialogType: 'add',
feeCategoryOptions: [],
page: {
@@ -184,6 +164,17 @@ export default {
maxlength: 50,
rules: [{ required: true, message: '请输入费用项', trigger: 'blur' }],
},
{
label: '备注',
prop: 'remark',
type: 'textarea',
minRows: 2,
span: 24,
hide: true,
maxlength: 200,
showWordLimit: true,
rules: [{ max: 200, message: '备注不能超过200个字', trigger: 'blur' }],
},
{
label: '组织',
prop: 'createDeptName',
@@ -259,32 +250,6 @@ export default {
},
],
},
excelOption: {
submitBtn: false,
emptyBtn: false,
column: [
{
label: '模板上传',
prop: 'excelFile',
type: 'upload',
drag: true,
loadText: '模板上传中,请稍等',
span: 24,
propsHttp: {
res: 'data',
},
headers: getUploadHeaders(),
tip: '请上传 .xls,.xlsx 标准格式文件',
action: '/blade-system/fee-item/import-fee-item',
},
{
label: '模板下载',
prop: 'excelTemplate',
formslot: true,
span: 24,
},
],
},
};
},
created() {
@@ -364,6 +329,7 @@ export default {
values.feeCategory = String(values.feeCategory || '').trim();
values.name = String(values.name || '').trim();
values.englishName = prefix ? `${prefix}${code}` : code;
values.remark = String(values.remark || '').trim() || undefined;
if (!values.status) values.status = 1;
return values;
},
@@ -464,9 +430,6 @@ export default {
refreshChange() {
this.onLoad(this.page, this.query);
},
handleImport() {
openImportDialog(this, '费用项');
},
buildExportParams() {
return {
...this.query,
@@ -492,15 +455,6 @@ export default {
});
});
},
handleTemplate() {
exportBlob(
`/blade-system/fee-item/export-template?${this.website.tokenHeader}=${getToken()}`,
undefined,
{ feedback: true }
).then(res => {
downloadXls(res.data, '费用项模板.xlsx');
});
},
onLoad(page, params = {}) {
this.loading = true;
getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+16 -7
View File
@@ -393,7 +393,7 @@ export default {
dicData: [],
hide: true,
span: 12,
order: 100,
order: 101,
placeholder: '请选择',
rules: [{ required: false, message: '请选择上级港口', trigger: 'change' }],
change: ({ value }) => this.handleParentChange(value),
@@ -412,10 +412,11 @@ export default {
minWidth: 120,
slot: true,
span: 12,
order: 101,
disabled: true,
addDisplay: false,
editDisplay: false,
placeholder: '自动带出',
rules: [{ required: false, message: '请选择上级港口', trigger: 'change' }],
},
{
label: '国家',
@@ -537,7 +538,10 @@ export default {
placeholder: '请输入',
maxlength: 255,
showWordLimit: true,
rules: [{ max: 255, message: '详细地址不能超过255字', trigger: 'blur' }],
rules: [
{ required: true, message: '请输入详细地址', trigger: 'blur' },
{ max: 255, message: '详细地址不能超过255字', trigger: 'blur' },
],
},
{
label: '数据来源',
@@ -551,9 +555,9 @@ export default {
editDisplay: false,
dicData: [
{ label: '全部', value: '' },
{ label: '初始化入', value: '初始化入' },
{ label: '初始化入', value: '初始化入' },
{ label: '批量导入', value: '批量导入' },
{ label: '手工导入', value: '手工导入' },
{ label: '手动录入', value: '手动录入' },
],
},
{
@@ -761,6 +765,7 @@ export default {
parentColumn.rules[0].required = required;
}
this.setColumnDisplay('parentId', required);
this.setColumnDisplay('parentCode', required);
if (value === '港口') {
this.form.parentId = undefined;
this.form.parentCode = '';
@@ -992,7 +997,7 @@ export default {
submitRow.parentCode = undefined;
submitRow.parentName = undefined;
}
if (!submitRow.dataSource) submitRow.dataSource = '手工导入';
if (!submitRow.dataSource) submitRow.dataSource = '手动录入';
if (!submitRow.status) submitRow.status = 1;
delete submitRow.terminalCode;
delete submitRow.cityCode;
@@ -1021,6 +1026,10 @@ export default {
this.$message.warning('请选择区县');
return false;
}
if (isBlank(row.detailAddress)) {
this.$message.warning('请输入详细地址');
return false;
}
if (isBlank(row.longitude)) {
this.$message.warning('请输入经度');
return false;
@@ -1133,7 +1142,7 @@ export default {
beforeOpen(done, type) {
if (type === 'add') {
this.form.category = this.form.category || '港口';
this.form.dataSource = this.form.dataSource || '手工导入';
this.form.dataSource = this.form.dataSource || '手动录入';
this.form.status = this.form.status || 1;
}
this.handleCategoryChange(this.form.category || '港口');
+4 -1
View File
@@ -347,7 +347,10 @@ export default {
overHidden: false,
maxlength: 255,
showWordLimit: true,
rules: [{ max: 255, message: '详细地址不能超过255字', trigger: 'blur' }],
rules: [
{ required: true, message: '请输入详细地址', trigger: 'blur' },
{ max: 255, message: '详细地址不能超过255字', trigger: 'blur' },
],
},
{
label: '经度',