调整基础数据、车船务、项目、合同
This commit is contained in:
@@ -1,56 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>合同弹窗调试</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module">
|
|
||||||
import { createApp, nextTick, onMounted, ref } from 'vue/dist/vue.esm-bundler.js';
|
|
||||||
import ElementPlus from 'element-plus';
|
|
||||||
import 'element-plus/dist/index.css';
|
|
||||||
import './src/styles/common.scss';
|
|
||||||
import ReceivablePayableDetail from './src/views/settlement/receivable-payable-detail.vue';
|
|
||||||
import { setupTableColumnDrag } from './src/utils/table-column-drag.js';
|
|
||||||
|
|
||||||
const fields = [
|
|
||||||
'contractNo',
|
|
||||||
'contractName',
|
|
||||||
'projectName',
|
|
||||||
'organizationName',
|
|
||||||
'contractCategory',
|
|
||||||
'signType',
|
|
||||||
'partyA',
|
|
||||||
'partyB',
|
|
||||||
'startDate',
|
|
||||||
'endDate',
|
|
||||||
'temporaryStartDate',
|
|
||||||
'temporaryEndDate',
|
|
||||||
];
|
|
||||||
const row = Object.fromEntries(fields.map(field => [field, `${field}数据`]));
|
|
||||||
const TestComponent = { ...ReceivablePayableDetail, mounted() {} };
|
|
||||||
const app = createApp({
|
|
||||||
components: { TestComponent },
|
|
||||||
setup() {
|
|
||||||
const target = ref();
|
|
||||||
onMounted(async () => {
|
|
||||||
await nextTick();
|
|
||||||
target.value.generateContractDialog.rows = Array.from({ length: 10 }, () => ({ ...row }));
|
|
||||||
target.value.generateContractDialog.page.total = 10;
|
|
||||||
target.value.generateContractDialog.visible = true;
|
|
||||||
});
|
|
||||||
return { target };
|
|
||||||
},
|
|
||||||
template: '<test-component ref="target" settlement-type="payable" />',
|
|
||||||
});
|
|
||||||
app.component('basic-container', { template: '<div><slot /></div>' });
|
|
||||||
app.config.globalProperties.$route = { fullPath: '/debug', query: {} };
|
|
||||||
app.config.globalProperties.$store = { getters: { permission: {}, userInfo: {} } };
|
|
||||||
app.use(ElementPlus, { table: { showOverflowTooltip: true } });
|
|
||||||
setupTableColumnDrag(app);
|
|
||||||
app.mount('#app');
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -59,14 +59,14 @@ export const withdraw = id =>
|
|||||||
params: { id },
|
params: { id },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const startChange = (id, reason) =>
|
export const startChange = (id, changeContent, changeReason = changeContent) =>
|
||||||
request({
|
request({
|
||||||
url: `${baseUrl}/start-change`,
|
url: `${baseUrl}/start-change`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
params: {
|
params: {
|
||||||
id,
|
id,
|
||||||
changeContent: reason,
|
changeContent: changeContent || '',
|
||||||
changeReason: reason,
|
changeReason,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import VuePdfEmbed from 'vue-pdf-embed';
|
import { defineAsyncComponent } from 'vue';
|
||||||
import 'vue-pdf-embed/dist/styles/annotationLayer.css';
|
import 'vue-pdf-embed/dist/styles/annotationLayer.css';
|
||||||
import 'vue-pdf-embed/dist/styles/textLayer.css';
|
import 'vue-pdf-embed/dist/styles/textLayer.css';
|
||||||
|
|
||||||
|
const VuePdfEmbed = defineAsyncComponent(() => import('vue-pdf-embed'));
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PdfPreview',
|
name: 'PdfPreview',
|
||||||
components: { VuePdfEmbed },
|
components: { VuePdfEmbed },
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ export const getCargoTypeOption = ctx => ({
|
|||||||
height: 'auto',
|
height: 'auto',
|
||||||
calcHeight: 22,
|
calcHeight: 22,
|
||||||
dialogWidth: 760,
|
dialogWidth: 760,
|
||||||
|
// 货物类型弹窗单独使用样式,避免全局 Avue footer 上移遮挡底部备注字段
|
||||||
|
dialogCustomClass: 'cargo-type-dialog',
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
labelWidth: 'auto',
|
labelWidth: 'auto',
|
||||||
tip: false,
|
tip: false,
|
||||||
@@ -172,6 +174,7 @@ export const getCargoTypeOption = ctx => ({
|
|||||||
label: '备注',
|
label: '备注',
|
||||||
prop: 'remark',
|
prop: 'remark',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
|
formslot: true,
|
||||||
minRows: 2,
|
minRows: 2,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import {
|
|||||||
auditColumns,
|
auditColumns,
|
||||||
createCrudOption,
|
createCrudOption,
|
||||||
packageOptions,
|
packageOptions,
|
||||||
priceUnitOptions,
|
|
||||||
textRule,
|
textRule,
|
||||||
} from './common';
|
} from './common';
|
||||||
|
|
||||||
@@ -25,10 +24,42 @@ export const config = {
|
|||||||
enableAllDept: false,
|
enableAllDept: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 单价统一按两位小数展示;格式非法时保留原值,交由表单校验提示。
|
||||||
|
export const formatCargoValue = value => {
|
||||||
|
if (value === undefined || value === null) return '';
|
||||||
|
const raw = String(value).trim();
|
||||||
|
if (!raw || raw === '-1') return '';
|
||||||
|
if (!/^\d+(?:\.\d+)?$/.test(raw)) return raw;
|
||||||
|
const number = Number(raw);
|
||||||
|
return Number.isFinite(number) ? number.toFixed(2) : raw;
|
||||||
|
};
|
||||||
|
|
||||||
export const option = createCrudOption([
|
export const option = createCrudOption([
|
||||||
|
{
|
||||||
|
label: '一级货物类型',
|
||||||
|
prop: 'firstCargoTypeName',
|
||||||
|
formslot: true,
|
||||||
|
order: 60,
|
||||||
|
span: 12,
|
||||||
|
minWidth: 150,
|
||||||
|
editDisabled: true,
|
||||||
|
rules: [{ required: true, message: '请选择一级货物类型', trigger: 'change' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '二级货物类型',
|
||||||
|
prop: 'secondCargoTypeName',
|
||||||
|
formslot: true,
|
||||||
|
order: 59,
|
||||||
|
span: 12,
|
||||||
|
minWidth: 150,
|
||||||
|
editDisabled: true,
|
||||||
|
rules: [{ required: true, message: '请选择二级货物类型', trigger: 'change' }],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '货物名称',
|
label: '货物名称',
|
||||||
prop: 'cargoName',
|
prop: 'cargoName',
|
||||||
|
order: 50,
|
||||||
|
span: 12,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: textRule('货物名称', 100, true),
|
rules: textRule('货物名称', 100, true),
|
||||||
@@ -37,6 +68,8 @@ export const option = createCrudOption([
|
|||||||
label: '货物编号',
|
label: '货物编号',
|
||||||
prop: 'cargoCode',
|
prop: 'cargoCode',
|
||||||
formslot: true,
|
formslot: true,
|
||||||
|
order: 49,
|
||||||
|
span: 12,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
maxlength: 20,
|
maxlength: 20,
|
||||||
showWordLimit: true,
|
showWordLimit: true,
|
||||||
@@ -45,14 +78,6 @@ export const option = createCrudOption([
|
|||||||
{ max: 20, message: '货物编号不能超过20个字符', trigger: 'blur' },
|
{ max: 20, message: '货物编号不能超过20个字符', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '一级货物类型',
|
|
||||||
prop: 'firstCargoTypeName',
|
|
||||||
formslot: true,
|
|
||||||
minWidth: 150,
|
|
||||||
editDisabled: true,
|
|
||||||
rules: [{ required: true, message: '请选择一级货物类型', trigger: 'change' }],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '一级货物类型编码',
|
label: '一级货物类型编码',
|
||||||
prop: 'firstCargoTypeCode',
|
prop: 'firstCargoTypeCode',
|
||||||
@@ -61,14 +86,6 @@ export const option = createCrudOption([
|
|||||||
addDisplay: false,
|
addDisplay: false,
|
||||||
editDisabled: true,
|
editDisabled: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '二级货物类型',
|
|
||||||
prop: 'secondCargoTypeName',
|
|
||||||
formslot: true,
|
|
||||||
minWidth: 150,
|
|
||||||
editDisabled: true,
|
|
||||||
rules: [{ required: true, message: '请选择二级货物类型', trigger: 'change' }],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '二级货物类型编码',
|
label: '二级货物类型编码',
|
||||||
prop: 'secondCargoTypeCode',
|
prop: 'secondCargoTypeCode',
|
||||||
@@ -174,12 +191,16 @@ export const option = createCrudOption([
|
|||||||
prop: 'packageType',
|
prop: 'packageType',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
dicData: packageOptions,
|
dicData: packageOptions,
|
||||||
|
order: 39,
|
||||||
|
span: 12,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '品牌',
|
label: '品牌',
|
||||||
prop: 'brand',
|
prop: 'brand',
|
||||||
search: false,
|
search: false,
|
||||||
|
order: 40,
|
||||||
|
span: 12,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: textRule('品牌', 50),
|
rules: textRule('品牌', 50),
|
||||||
@@ -187,22 +208,18 @@ export const option = createCrudOption([
|
|||||||
{
|
{
|
||||||
label: '规格',
|
label: '规格',
|
||||||
prop: 'specification',
|
prop: 'specification',
|
||||||
|
order: 29,
|
||||||
|
span: 12,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: textRule('规格', 50),
|
rules: textRule('规格', 50),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '型号',
|
label: '货值',
|
||||||
prop: 'model',
|
|
||||||
minWidth: 120,
|
|
||||||
placeholder: '请输入',
|
|
||||||
rules: textRule('型号', 50),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '单价',
|
|
||||||
prop: 'cargoValue',
|
prop: 'cargoValue',
|
||||||
formslot: true,
|
formslot: true,
|
||||||
formatter: row => (String(row.cargoValue) === '-1' ? '' : row.cargoValue),
|
order: 30,
|
||||||
|
formatter: row => formatCargoValue(row.cargoValue),
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
@@ -225,10 +242,19 @@ export const option = createCrudOption([
|
|||||||
label: '计价单位',
|
label: '计价单位',
|
||||||
prop: 'priceUnit',
|
prop: 'priceUnit',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
dicData: priceUnitOptions,
|
dicData: [],
|
||||||
display: false,
|
display: false,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '型号',
|
||||||
|
prop: 'model',
|
||||||
|
order: 19,
|
||||||
|
span: 12,
|
||||||
|
minWidth: 120,
|
||||||
|
placeholder: '请输入',
|
||||||
|
rules: textRule('型号', 50, true),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '尺寸',
|
label: '尺寸',
|
||||||
prop: 'sizeText',
|
prop: 'sizeText',
|
||||||
@@ -238,23 +264,19 @@ export const option = createCrudOption([
|
|||||||
rules: textRule('尺寸', 100),
|
rules: textRule('尺寸', 100),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '其他说明1',
|
label: '说明',
|
||||||
prop: 'descriptionOne',
|
prop: 'descriptionOne',
|
||||||
|
order: 20,
|
||||||
|
span: 12,
|
||||||
minWidth: 160,
|
minWidth: 160,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: textRule('其他说明1', 100),
|
rules: textRule('说明', 100),
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '其他说明2',
|
|
||||||
prop: 'descriptionTwo',
|
|
||||||
minWidth: 160,
|
|
||||||
placeholder: '请输入',
|
|
||||||
rules: textRule('其他说明2', 100),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '备注',
|
label: '备注',
|
||||||
prop: 'remark',
|
prop: 'remark',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
|
order: 10,
|
||||||
minRows: 2,
|
minRows: 2,
|
||||||
span: 24,
|
span: 24,
|
||||||
maxlength: 200,
|
maxlength: 200,
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ export const option = {
|
|||||||
searchPlaceholder: '请选择',
|
searchPlaceholder: '请选择',
|
||||||
dicData: processStatusOptions,
|
dicData: processStatusOptions,
|
||||||
slot: true,
|
slot: true,
|
||||||
hide: true,
|
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
addDisplay: false,
|
addDisplay: false,
|
||||||
|
|||||||
@@ -268,6 +268,19 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'accidentDate', label: '事故发生日期' },
|
||||||
|
{ prop: 'accidentLocation', label: '事故发生地点' },
|
||||||
|
{ prop: 'accidentNature', label: '事故性质' },
|
||||||
|
{ prop: 'accidentResponsibility', label: '事故责任' },
|
||||||
|
{ prop: 'directEconomicLoss', label: '直接经济损失' },
|
||||||
|
{ prop: 'insuranceClaimAmount', label: '保险理赔金额' },
|
||||||
|
{ prop: 'accidentReasonDamage', label: '事故原因及损坏情况' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -278,6 +278,20 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'inspectionAssessmentDate', label: '检测评定日期' },
|
||||||
|
{ prop: 'validUntilDate', label: '有效期截止日' },
|
||||||
|
{ prop: 'vehicleTechnicalLevel', label: '车辆技术等级' },
|
||||||
|
{ prop: 'shipInspectionType', label: '船舶检验类型' },
|
||||||
|
{ prop: 'passengerTypeLevel', label: '客车类型及等级' },
|
||||||
|
{ prop: 'inspectionUnit', label: '检测评定单位' },
|
||||||
|
{ prop: 'fee', label: '费用(元)' },
|
||||||
|
{ prop: 'assessmentUnit', label: '评定(复核)单位' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -211,6 +211,19 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'equipmentCode', label: '设备号' },
|
||||||
|
{ prop: 'equipmentName', label: '设备名称' },
|
||||||
|
{ prop: 'factoryDate', label: '出厂日期' },
|
||||||
|
{ prop: 'equipmentBrand', label: '设备品牌' },
|
||||||
|
{ prop: 'equipmentType', label: '设备类型' },
|
||||||
|
{ prop: 'specificationModel', label: '规格型号' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
{ prop: 'originalEquipmentNo', label: '原厂设备号' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -206,6 +206,18 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号' },
|
||||||
|
{ prop: 'entryTime', label: '入口时间' },
|
||||||
|
{ prop: 'etcCardNo', label: 'ETC卡号' },
|
||||||
|
{ prop: 'exitTime', label: '出口时间' },
|
||||||
|
{ prop: 'entryStation', label: '入口站' },
|
||||||
|
{ prop: 'transactionAmount', label: '交易金额' },
|
||||||
|
{ prop: 'exitStation', label: '出口站' },
|
||||||
|
{ prop: 'dataSource', label: '数据来源' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -240,6 +240,20 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'insuranceType', label: '保险类型' },
|
||||||
|
{ prop: 'policyNo', label: '保单号' },
|
||||||
|
{ prop: 'startDate', label: '开始日期' },
|
||||||
|
{ prop: 'endDate', label: '结束日期' },
|
||||||
|
{ prop: 'insuredAmount', label: '保额' },
|
||||||
|
{ prop: 'premium', label: '保费' },
|
||||||
|
{ prop: 'invoiceNo', label: '发票号' },
|
||||||
|
{ prop: 'invoiceDate', label: '开票日期' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -199,6 +199,15 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号' },
|
||||||
|
{ prop: 'previousMonthMileage', label: '上月统计里程数' },
|
||||||
|
{ prop: 'currentMonthMileage', label: '本月统计里程数' },
|
||||||
|
{ prop: 'monthlyMileage', label: '本月行驶里程数' },
|
||||||
|
{ prop: 'totalMileage', label: '累计行驶里程数' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -287,6 +287,23 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'cardNo', label: '卡号' },
|
||||||
|
{ prop: 'transactionTime', label: '交易时间' },
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'feeType', label: '费用类型' },
|
||||||
|
{ prop: 'oilProduct', label: '油品' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'cardHolder', label: '持卡人' },
|
||||||
|
{ prop: 'dataSource', label: '数据来源' },
|
||||||
|
{ prop: 'quantity', label: '数量' },
|
||||||
|
{ prop: 'unitPrice', label: '单价' },
|
||||||
|
{ prop: 'transactionAmount', label: '交易金额' },
|
||||||
|
{ prop: 'balance', label: '余额' },
|
||||||
|
{ prop: 'station', label: '站点' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -209,6 +209,16 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'expenseDate', label: '费用日期' },
|
||||||
|
{ prop: 'expenseType', label: '费用类型' },
|
||||||
|
{ prop: 'amount', label: '金额' },
|
||||||
|
{ prop: 'dataSource', label: '数据来源' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -206,6 +206,17 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号' },
|
||||||
|
{ prop: 'handler', label: '处理人' },
|
||||||
|
{ prop: 'replacementTime', label: '换胎时间' },
|
||||||
|
{ prop: 'tireBrand', label: '轮胎品牌' },
|
||||||
|
{ prop: 'tireQuantity', label: '换胎数量' },
|
||||||
|
{ prop: 'replacementCost', label: '换胎费用' },
|
||||||
|
{ prop: 'replacementDescription', label: '换胎说明' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -161,6 +161,14 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'changeItem', label: '变更事项' },
|
||||||
|
{ prop: 'changeContent', label: '变更内容' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ export const option = {
|
|||||||
prop: 'processStatus',
|
prop: 'processStatus',
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
dicData: processStatusDic,
|
dicData: processStatusDic,
|
||||||
value: '未处理',
|
value: '已处理',
|
||||||
search: true,
|
search: true,
|
||||||
clearable: true,
|
clearable: true,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
@@ -278,6 +278,22 @@ export const option = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'driverName', label: '驾驶人' },
|
||||||
|
{ prop: 'violationType', label: '类型' },
|
||||||
|
{ prop: 'violationItem', label: '事项' },
|
||||||
|
{ prop: 'violationTime', label: '日期' },
|
||||||
|
{ prop: 'location', label: '地点' },
|
||||||
|
{ prop: 'fineAmount', label: '罚款' },
|
||||||
|
{ prop: 'deductPoints', label: '被扣分数' },
|
||||||
|
{ prop: 'penaltyUnit', label: '被罚单位' },
|
||||||
|
{ prop: 'processStatus', label: '状态' },
|
||||||
|
{ prop: 'processDescription', label: '过程描述' },
|
||||||
|
{ prop: 'processResult', label: '处理结果' },
|
||||||
|
];
|
||||||
|
|
||||||
export const excelOption = {
|
export const excelOption = {
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
|||||||
@@ -55,6 +55,19 @@
|
|||||||
{{ row.createUserName || row.createUser || '' }}
|
{{ row.createUserName || row.createUser || '' }}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #remark-form>
|
||||||
|
<el-input
|
||||||
|
v-model="form.remark"
|
||||||
|
class="remark-input"
|
||||||
|
type="textarea"
|
||||||
|
:rows="2"
|
||||||
|
:disabled="dialogType === 'view'"
|
||||||
|
maxlength="200"
|
||||||
|
show-word-limit
|
||||||
|
placeholder="请输入"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #parentId-form>
|
<template #parentId-form>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.parentId"
|
v-model="form.parentId"
|
||||||
@@ -644,3 +657,18 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/* 货物类型新增/编辑弹窗:footer 不上移,避免覆盖备注文本域底部内容 */
|
||||||
|
.cargo-type-dialog.avue-dialog.avue-crud__dialog .avue-dialog__footer {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cargo-type-dialog.avue-dialog.avue-crud__dialog .el-dialog__body {
|
||||||
|
padding-bottom: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cargo-type-dialog .remark-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -50,6 +50,19 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
<template #taxRate="{ row }">{{ formatTaxRate(row.taxRate) }}</template>
|
||||||
|
<template #taxRate-form>
|
||||||
|
<el-input
|
||||||
|
v-model="form.taxRate"
|
||||||
|
inputmode="decimal"
|
||||||
|
maxlength="6"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入税率"
|
||||||
|
@input="handleTaxRateInput"
|
||||||
|
>
|
||||||
|
<template #append>%</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #englishName-form>
|
<template #englishName-form>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.englishName"
|
v-model="form.englishName"
|
||||||
@@ -156,6 +169,30 @@ export default {
|
|||||||
maxlength: 100,
|
maxlength: 100,
|
||||||
rules: [{ required: true, message: '请输入费用项代码', trigger: 'blur' }],
|
rules: [{ required: true, message: '请输入费用项代码', trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '税率',
|
||||||
|
prop: 'taxRate',
|
||||||
|
type: 'input',
|
||||||
|
formslot: true,
|
||||||
|
slot: true,
|
||||||
|
minWidth: 100,
|
||||||
|
span: 12,
|
||||||
|
rules: [
|
||||||
|
{ required: true, message: '请输入税率', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
const text = String(value ?? '').trim();
|
||||||
|
const rate = Number(text);
|
||||||
|
if (!/^\d+(\.\d{1,2})?$/.test(text) || rate < 0 || rate > 100) {
|
||||||
|
callback(new Error('税率必须是0到100之间且最多保留2位小数的数字'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '费用项',
|
label: '费用项',
|
||||||
prop: 'name',
|
prop: 'name',
|
||||||
@@ -326,6 +363,9 @@ export default {
|
|||||||
);
|
);
|
||||||
return option ? `${option.dictValue}/${option.dictKey}` : feeCategory;
|
return option ? `${option.dictValue}/${option.dictKey}` : feeCategory;
|
||||||
},
|
},
|
||||||
|
formatTaxRate(value) {
|
||||||
|
return value === undefined || value === null || value === '' ? '' : `${value}%`;
|
||||||
|
},
|
||||||
getFeeItemCodeSuffix(code, feeCategory) {
|
getFeeItemCodeSuffix(code, feeCategory) {
|
||||||
const value = String(code || '').trim();
|
const value = String(code || '').trim();
|
||||||
const prefix = this.getFeeCategoryPrefix(feeCategory);
|
const prefix = this.getFeeCategoryPrefix(feeCategory);
|
||||||
@@ -347,6 +387,7 @@ export default {
|
|||||||
const code = this.getFeeItemCodeSuffix(values.englishName, values.feeCategory);
|
const code = this.getFeeItemCodeSuffix(values.englishName, values.feeCategory);
|
||||||
values.feeCategory = String(values.feeCategory || '').trim();
|
values.feeCategory = String(values.feeCategory || '').trim();
|
||||||
values.name = String(values.name || '').trim();
|
values.name = String(values.name || '').trim();
|
||||||
|
values.taxRate = Number(values.taxRate);
|
||||||
values.englishName = prefix ? `${prefix}${code}` : code;
|
values.englishName = prefix ? `${prefix}${code}` : code;
|
||||||
values.remark = String(values.remark || '').trim() || undefined;
|
values.remark = String(values.remark || '').trim() || undefined;
|
||||||
if (!values.status) values.status = 1;
|
if (!values.status) values.status = 1;
|
||||||
@@ -455,6 +496,15 @@ export default {
|
|||||||
this.form.englishName = '';
|
this.form.englishName = '';
|
||||||
done();
|
done();
|
||||||
},
|
},
|
||||||
|
handleTaxRateInput(value) {
|
||||||
|
let normalized = String(value || '').replace(/[^\d.]/g, '');
|
||||||
|
normalized = normalized.replace(/(\..*)\./g, '$1');
|
||||||
|
if (normalized.startsWith('.')) normalized = `0${normalized}`;
|
||||||
|
const [integerPart, decimalPart] = normalized.split('.');
|
||||||
|
normalized =
|
||||||
|
decimalPart === undefined ? integerPart : `${integerPart}.${decimalPart.slice(0, 2)}`;
|
||||||
|
this.form.taxRate = normalized;
|
||||||
|
},
|
||||||
searchReset() {
|
searchReset() {
|
||||||
this.query = {};
|
this.query = {};
|
||||||
this.onLoad(this.page);
|
this.onLoad(this.page);
|
||||||
|
|||||||
@@ -113,7 +113,7 @@
|
|||||||
:maxlength="getCargoCodeMaxLength()"
|
:maxlength="getCargoCodeMaxLength()"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
:disabled="dialogReadonly || dialogType === 'edit'"
|
:disabled="dialogReadonly"
|
||||||
@input="handleCargoCodeInput"
|
@input="handleCargoCodeInput"
|
||||||
>
|
>
|
||||||
<template v-if="getCargoCodePrefix()" #prepend>
|
<template v-if="getCargoCodePrefix()" #prepend>
|
||||||
@@ -130,11 +130,13 @@
|
|||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
:disabled="dialogReadonly"
|
:disabled="dialogReadonly"
|
||||||
@input="handleCargoValueInput"
|
@input="handleCargoValueInput"
|
||||||
|
@blur="handleCargoValueBlur"
|
||||||
/>
|
/>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.priceUnit"
|
v-model="form.priceUnit"
|
||||||
clearable
|
clearable
|
||||||
:disabled="dialogReadonly"
|
:disabled="dialogReadonly"
|
||||||
|
:loading="priceUnitLoading"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
@@ -147,6 +149,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #cargoValue="{ row }">
|
||||||
|
{{ formatCargoValue(row.cargoValue) }}
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #menu="{ row, index }">
|
<template #menu="{ row, index }">
|
||||||
<el-link
|
<el-link
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -196,8 +202,8 @@ import * as api from '@/api/business/common-cargo';
|
|||||||
import { getList as getCargoTypeList } from '@/api/base/cargo-type';
|
import { getList as getCargoTypeList } from '@/api/base/cargo-type';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
import { config, excelOption, option } from '@/option/business/common-cargo';
|
import { config, excelOption, formatCargoValue, option } from '@/option/business/common-cargo';
|
||||||
import { priceUnitOptions } from '@/option/business/common';
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
@@ -211,7 +217,8 @@ export default {
|
|||||||
api,
|
api,
|
||||||
config,
|
config,
|
||||||
option,
|
option,
|
||||||
priceUnitOptions,
|
priceUnitOptions: [],
|
||||||
|
priceUnitLoading: false,
|
||||||
form: {},
|
form: {},
|
||||||
query: {},
|
query: {},
|
||||||
loading: true,
|
loading: true,
|
||||||
@@ -254,8 +261,10 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
|
this.loadPriceUnitOptions();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
formatCargoValue,
|
||||||
hasPermission(code) {
|
hasPermission(code) {
|
||||||
return this.isAdmin || this.validData(this.permission && this.permission[code], false);
|
return this.isAdmin || this.validData(this.permission && this.permission[code], false);
|
||||||
},
|
},
|
||||||
@@ -273,6 +282,28 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
loadPriceUnitOptions() {
|
||||||
|
this.priceUnitLoading = true;
|
||||||
|
getDictionary({ code: 'unit_fee' })
|
||||||
|
.then(res => {
|
||||||
|
const payload = res?.data?.data || res?.data || [];
|
||||||
|
const list = Array.isArray(payload) ? payload : payload.records || payload.data || [];
|
||||||
|
this.priceUnitOptions = list
|
||||||
|
.map(item => ({
|
||||||
|
label: item.dictValue || item.label || item.name || item.dictKey || item.value,
|
||||||
|
value: item.dictKey || item.value || item.dictValue || item.name,
|
||||||
|
}))
|
||||||
|
.filter(item => item.label && item.value);
|
||||||
|
if (this.dialogType === 'add' && !this.form.priceUnit && this.priceUnitOptions.length) {
|
||||||
|
this.form.priceUnit = this.priceUnitOptions[0].value;
|
||||||
|
}
|
||||||
|
const priceUnitColumn = this.findColumn(this.option.column, 'priceUnit');
|
||||||
|
if (priceUnitColumn) priceUnitColumn.dicData = this.priceUnitOptions;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.priceUnitLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
flattenDept(tree, level = 0) {
|
flattenDept(tree, level = 0) {
|
||||||
const result = [];
|
const result = [];
|
||||||
tree.forEach(item => {
|
tree.forEach(item => {
|
||||||
@@ -389,6 +420,9 @@ export default {
|
|||||||
const decimal = parts.slice(1).join('').slice(0, 2);
|
const decimal = parts.slice(1).join('').slice(0, 2);
|
||||||
this.form.cargoValue = parts.length > 1 ? `${integer}.${decimal}` : integer;
|
this.form.cargoValue = parts.length > 1 ? `${integer}.${decimal}` : integer;
|
||||||
},
|
},
|
||||||
|
handleCargoValueBlur() {
|
||||||
|
this.form.cargoValue = formatCargoValue(this.form.cargoValue);
|
||||||
|
},
|
||||||
normalizeRow(row) {
|
normalizeRow(row) {
|
||||||
const submitRow = { ...row };
|
const submitRow = { ...row };
|
||||||
Object.keys(submitRow).forEach(key => {
|
Object.keys(submitRow).forEach(key => {
|
||||||
@@ -399,14 +433,23 @@ export default {
|
|||||||
if (submitRow.cargoValue !== undefined && submitRow.cargoValue !== null) {
|
if (submitRow.cargoValue !== undefined && submitRow.cargoValue !== null) {
|
||||||
submitRow.cargoValue = String(submitRow.cargoValue).trim();
|
submitRow.cargoValue = String(submitRow.cargoValue).trim();
|
||||||
}
|
}
|
||||||
if (!submitRow.cargoValue || String(submitRow.cargoValue) === '-1') {
|
const cargoValue = submitRow.cargoValue;
|
||||||
|
if (
|
||||||
|
cargoValue === undefined ||
|
||||||
|
cargoValue === null ||
|
||||||
|
String(cargoValue).trim() === '' ||
|
||||||
|
String(cargoValue) === '-1'
|
||||||
|
) {
|
||||||
submitRow.cargoValue = null;
|
submitRow.cargoValue = null;
|
||||||
|
} else {
|
||||||
|
submitRow.cargoValue = formatCargoValue(submitRow.cargoValue);
|
||||||
}
|
}
|
||||||
return submitRow;
|
return submitRow;
|
||||||
},
|
},
|
||||||
normalizeCargoValue(row) {
|
normalizeCargoValue(row) {
|
||||||
if (row && String(row.cargoValue) === '-1') {
|
if (row && Object.prototype.hasOwnProperty.call(row, 'cargoValue')) {
|
||||||
row.cargoValue = null;
|
const formatted = formatCargoValue(row.cargoValue);
|
||||||
|
row.cargoValue = formatted || null;
|
||||||
}
|
}
|
||||||
return row;
|
return row;
|
||||||
},
|
},
|
||||||
@@ -445,6 +488,14 @@ export default {
|
|||||||
this.$message.warning('货值只能输入数字,最多保留2位小数');
|
this.$message.warning('货值只能输入数字,最多保留2位小数');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!row.model) {
|
||||||
|
this.$message.warning('请输入型号');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (row.model.length > 50) {
|
||||||
|
this.$message.warning('型号不能超过50个字符');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (row.remark && row.remark.length > 200) {
|
if (row.remark && row.remark.length > 200) {
|
||||||
this.$message.warning('备注不能超过200个字符');
|
this.$message.warning('备注不能超过200个字符');
|
||||||
return false;
|
return false;
|
||||||
@@ -539,8 +590,8 @@ export default {
|
|||||||
this.dialogType = type || 'add';
|
this.dialogType = type || 'add';
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
this.form = {
|
this.form = {
|
||||||
priceUnit: '元/吨',
|
|
||||||
...this.form,
|
...this.form,
|
||||||
|
priceUnit: this.priceUnitOptions[0]?.value || this.form.priceUnit || '',
|
||||||
};
|
};
|
||||||
this.loadFirstCargoTypeOptions();
|
this.loadFirstCargoTypeOptions();
|
||||||
done();
|
done();
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
:value="item.value" /></el-select></el-form-item
|
:value="item.value" /></el-select></el-form-item
|
||||||
></el-col>
|
></el-col>
|
||||||
<el-col :span="8"
|
<el-col :span="8"
|
||||||
><el-form-item label="默认方案"
|
><el-form-item
|
||||||
><el-checkbox v-model="draft.defaultPlan" :disabled="readonly">默认方案</el-checkbox
|
><el-checkbox v-model="draft.defaultPlan" :disabled="readonly">默认方案</el-checkbox
|
||||||
><el-tooltip content="同一运输方式仅支持配置一个默认计费方案" placement="top">
|
><el-tooltip content="同一运输方式仅支持配置一个默认计费方案" placement="top">
|
||||||
<el-icon class="billing-plan-editor__default-tip"
|
<el-icon class="billing-plan-editor__default-tip"
|
||||||
@@ -103,12 +103,28 @@
|
|||||||
filterable
|
filterable
|
||||||
:disabled="!row.feeType"
|
:disabled="!row.feeType"
|
||||||
:loading="feeItemLoadingMap[feeTypeKey(row)]"
|
:loading="feeItemLoadingMap[feeTypeKey(row)]"
|
||||||
|
@change="value => handleFeeItemChange(row, value)"
|
||||||
><el-option
|
><el-option
|
||||||
v-for="item in feeItemOptions(row)"
|
v-for="item in feeItemOptions(row)"
|
||||||
:key="item.id || item.name || item.englishName"
|
:key="item.id || item.name || item.englishName"
|
||||||
:label="item.name || item.englishName"
|
:label="item.name || item.englishName"
|
||||||
:value="item.name || item.englishName" /></el-select></template
|
:value="item.name || item.englishName" /></el-select></template
|
||||||
></el-table-column>
|
></el-table-column>
|
||||||
|
<el-table-column label="税率" width="180"
|
||||||
|
><template #default="{ row }"
|
||||||
|
><span v-if="readonly">{{ formatTaxRate(row.taxRate) }}</span
|
||||||
|
><el-input
|
||||||
|
v-else
|
||||||
|
v-model="row.taxRate"
|
||||||
|
inputmode="decimal"
|
||||||
|
maxlength="6"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => taxRateInput(row, value)"
|
||||||
|
><template #append>%</template></el-input
|
||||||
|
></template
|
||||||
|
></el-table-column
|
||||||
|
>
|
||||||
<el-table-column label="计费要素" width="170"
|
<el-table-column label="计费要素" width="170"
|
||||||
><template #default="{ row }"
|
><template #default="{ row }"
|
||||||
><span v-if="readonly">{{ displayValue(row.billingElement) }}</span
|
><span v-if="readonly">{{ displayValue(row.billingElement) }}</span
|
||||||
@@ -372,6 +388,7 @@ const clone = value => JSON.parse(JSON.stringify(value));
|
|||||||
const defaultRule = () => ({
|
const defaultRule = () => ({
|
||||||
feeType: '',
|
feeType: '',
|
||||||
feeItem: '',
|
feeItem: '',
|
||||||
|
taxRate: '',
|
||||||
billingElement: '',
|
billingElement: '',
|
||||||
billingType: '',
|
billingType: '',
|
||||||
billingUnit: '',
|
billingUnit: '',
|
||||||
@@ -467,7 +484,6 @@ export default {
|
|||||||
label: 'cargoName',
|
label: 'cargoName',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
children: 'children',
|
children: 'children',
|
||||||
disabled: (data, node) => node.level === 1,
|
|
||||||
leaf: 'leaf',
|
leaf: 'leaf',
|
||||||
checkStrictly: true,
|
checkStrictly: true,
|
||||||
emitPath: true,
|
emitPath: true,
|
||||||
@@ -622,27 +638,64 @@ export default {
|
|||||||
feeItemOptions(row) {
|
feeItemOptions(row) {
|
||||||
return this.feeItems[this.feeTypeKey(row)] || [];
|
return this.feeItems[this.feeTypeKey(row)] || [];
|
||||||
},
|
},
|
||||||
|
formatTaxRate(value) {
|
||||||
|
return value === undefined || value === null || value === '' ? '-' : `${value}%`;
|
||||||
|
},
|
||||||
loadRuleItems() {
|
loadRuleItems() {
|
||||||
(this.draft.rules || []).forEach(row => this.loadFeeItems(row.feeType));
|
(this.draft.rules || []).forEach(row => this.loadFeeItems(row.feeType));
|
||||||
},
|
},
|
||||||
loadFeeItems(value) {
|
loadFeeItems(value) {
|
||||||
const key = this.feeTypeKey({ feeType: value });
|
const key = this.feeTypeKey({ feeType: value });
|
||||||
if (!key || this.feeItems[key]) return;
|
if (!key) return;
|
||||||
|
if (this.feeItems[key]) {
|
||||||
|
this.fillLoadedRuleTaxRates(key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.feeItemLoadingMap[key] = true;
|
this.feeItemLoadingMap[key] = true;
|
||||||
getFeeItemList(1, 9999, { feeCategory: key })
|
getFeeItemList(1, 9999, { feeCategory: key })
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const data = res?.data?.data || res?.data || {};
|
const data = res?.data?.data || res?.data || {};
|
||||||
this.feeItems[key] = Array.isArray(data) ? data : data.records || [];
|
this.feeItems[key] = Array.isArray(data) ? data : data.records || [];
|
||||||
|
this.fillLoadedRuleTaxRates(key);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.feeItemLoadingMap[key] = false;
|
this.feeItemLoadingMap[key] = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
fillLoadedRuleTaxRates(key) {
|
||||||
|
(this.draft.rules || [])
|
||||||
|
.filter(row => this.feeTypeKey(row) === key)
|
||||||
|
.forEach(row => this.fillRuleTaxRate(row));
|
||||||
|
},
|
||||||
handleFeeTypeChange(row, value) {
|
handleFeeTypeChange(row, value) {
|
||||||
row.feeType = this.feeTypeKey({ feeType: value });
|
row.feeType = this.feeTypeKey({ feeType: value });
|
||||||
row.feeItem = '';
|
row.feeItem = '';
|
||||||
|
row.taxRate = '';
|
||||||
this.loadFeeItems(row.feeType);
|
this.loadFeeItems(row.feeType);
|
||||||
},
|
},
|
||||||
|
handleFeeItemChange(row, value) {
|
||||||
|
row.feeItem = value;
|
||||||
|
const feeItem = this.feeItemOptions(row).find(
|
||||||
|
item => String(item.name || item.englishName || '') === String(value || '')
|
||||||
|
);
|
||||||
|
row.taxRate = this.hasTaxRate(feeItem?.taxRate) ? String(feeItem.taxRate) : '';
|
||||||
|
},
|
||||||
|
fillRuleTaxRate(row) {
|
||||||
|
if (this.hasTaxRate(row.taxRate) || !row.feeItem) return;
|
||||||
|
const feeItem = this.feeItemOptions(row).find(
|
||||||
|
item => String(item.name || item.englishName || '') === String(row.feeItem)
|
||||||
|
);
|
||||||
|
if (this.hasTaxRate(feeItem?.taxRate)) row.taxRate = String(feeItem.taxRate);
|
||||||
|
},
|
||||||
|
hasTaxRate(value) {
|
||||||
|
return value !== undefined && value !== null && String(value).trim() !== '';
|
||||||
|
},
|
||||||
|
taxRateInput(row, value) {
|
||||||
|
const text = String(value || '').replace(/[^\d.]/g, '');
|
||||||
|
const parts = text.split('.');
|
||||||
|
row.taxRate =
|
||||||
|
parts.length > 1 ? `${parts[0]}.${parts.slice(1).join('').slice(0, 2)}` : parts[0];
|
||||||
|
},
|
||||||
billingTypes(row) {
|
billingTypes(row) {
|
||||||
return this.typeMap[row.billingElement] || [];
|
return this.typeMap[row.billingElement] || [];
|
||||||
},
|
},
|
||||||
@@ -771,6 +824,7 @@ export default {
|
|||||||
const required = [
|
const required = [
|
||||||
['feeType', '费用类型'],
|
['feeType', '费用类型'],
|
||||||
['feeItem', '费用项'],
|
['feeItem', '费用项'],
|
||||||
|
['taxRate', '税率'],
|
||||||
['billingElement', '计费要素'],
|
['billingElement', '计费要素'],
|
||||||
['billingType', '计费类型'],
|
['billingType', '计费类型'],
|
||||||
['billingUnit', '计费单位'],
|
['billingUnit', '计费单位'],
|
||||||
@@ -789,6 +843,13 @@ export default {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
feeItemSet.add(feeItem);
|
feeItemSet.add(feeItem);
|
||||||
|
if (this.hasTaxRate(row.taxRate)) {
|
||||||
|
const taxRate = Number(row.taxRate);
|
||||||
|
if (!/^\d+(\.\d{1,2})?$/.test(String(row.taxRate)) || taxRate < 0 || taxRate > 100) {
|
||||||
|
this.$message.warning(`第${i + 1}行税率必须在0到100之间且最多保留2位小数`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
!this.usesRangeUnitPrice(row) &&
|
!this.usesRangeUnitPrice(row) &&
|
||||||
(row.unitPrice === undefined ||
|
(row.unitPrice === undefined ||
|
||||||
@@ -803,8 +864,9 @@ export default {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!this.canEditLimit(row)) continue;
|
if (!this.canEditLimit(row)) continue;
|
||||||
const key = row.billingElement;
|
const billingElement = String(row.billingElement).trim();
|
||||||
groups[key] = groups[key] || [];
|
const key = JSON.stringify([feeItem, billingElement]);
|
||||||
|
groups[key] = groups[key] || { feeItem, billingElement, ranges: [] };
|
||||||
for (const range of this.getRanges(row)) {
|
for (const range of this.getRanges(row)) {
|
||||||
const lower = Number(range.lowerLimit);
|
const lower = Number(range.lowerLimit);
|
||||||
const upper = Number(range.upperLimit);
|
const upper = Number(range.upperLimit);
|
||||||
@@ -830,22 +892,24 @@ export default {
|
|||||||
this.$message.warning('计费要素下限不能大于上限');
|
this.$message.warning('计费要素下限不能大于上限');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
groups[key].push({ lower, upper });
|
groups[key].ranges.push({ lower, upper });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.validateRangeGroups(groups);
|
return this.validateRangeGroups(groups);
|
||||||
},
|
},
|
||||||
validateRangeGroups(groups) {
|
validateRangeGroups(groups) {
|
||||||
const precision = 0.000001;
|
const precision = 0.000001;
|
||||||
for (const [element, ranges] of Object.entries(groups)) {
|
for (const { feeItem, billingElement, ranges } of Object.values(groups)) {
|
||||||
const sorted = [...ranges].sort((a, b) => a.lower - b.lower || a.upper - b.upper);
|
const sorted = [...ranges].sort((a, b) => a.lower - b.lower || a.upper - b.upper);
|
||||||
for (let i = 1; i < sorted.length; i += 1) {
|
for (let i = 1; i < sorted.length; i += 1) {
|
||||||
if (sorted[i].lower < sorted[i - 1].upper - precision) {
|
if (sorted[i].lower < sorted[i - 1].upper - precision) {
|
||||||
this.$message.warning(`${element}的计费要素区间不能重叠`);
|
this.$message.warning(`费用项“${feeItem}”${billingElement}的计费要素区间不能重叠`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (sorted[i].lower > sorted[i - 1].upper + precision) {
|
if (sorted[i].lower > sorted[i - 1].upper + precision) {
|
||||||
this.$message.warning(`${element}的计费要素区间必须连续,不能存在间隙`);
|
this.$message.warning(
|
||||||
|
`费用项“${feeItem}”${billingElement}的计费要素区间必须连续,不能存在间隙`
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1078,25 +1142,27 @@ export default {
|
|||||||
},
|
},
|
||||||
matchCargoChange(value) {
|
matchCargoChange(value) {
|
||||||
const path =
|
const path =
|
||||||
Array.isArray(value) && value.length >= 2
|
Array.isArray(value) && value.length
|
||||||
? value.slice(0, 2).map(item => String(item))
|
? value.slice(0, 2).map(item => String(item))
|
||||||
: [];
|
: [];
|
||||||
const item = this.cargoFlatOptions.find(
|
const item = this.cargoFlatOptions.find(
|
||||||
option => String(option.id) === String(path[1]) && option.path?.length >= 2
|
option =>
|
||||||
|
option.path?.length === path.length &&
|
||||||
|
option.path.every((itemValue, index) => String(itemValue) === path[index])
|
||||||
);
|
);
|
||||||
this.matchForm.cargoTypePath = path;
|
this.matchForm.cargoTypePath = path;
|
||||||
this.matchForm.cargoType = item ? this.cargoLabels(path).join('/') : '';
|
this.matchForm.cargoType = item ? this.cargoLabels(path).join('/') : '';
|
||||||
this.matchForm.cargoTypeCode = item ? item.cargoCode || item.code || item.id : '';
|
this.matchForm.cargoTypeCode = item ? item.cargoCode || item.code || item.id : '';
|
||||||
},
|
},
|
||||||
resolveCargoPath(condition) {
|
resolveCargoPath(condition) {
|
||||||
if (Array.isArray(condition.cargoTypePath) && condition.cargoTypePath.length >= 2)
|
if (Array.isArray(condition.cargoTypePath) && condition.cargoTypePath.length)
|
||||||
return condition.cargoTypePath;
|
return condition.cargoTypePath.slice(0, 2).map(item => String(item));
|
||||||
const item = this.cargoFlatOptions.find(
|
const item = this.cargoFlatOptions.find(
|
||||||
option =>
|
option =>
|
||||||
option.path?.length >= 2 &&
|
|
||||||
(String(option.cargoCode || option.code || option.id) ===
|
(String(option.cargoCode || option.code || option.id) ===
|
||||||
String(condition.cargoTypeCode) ||
|
String(condition.cargoTypeCode) ||
|
||||||
option.cargoName === condition.cargoType)
|
option.cargoName === condition.cargoType ||
|
||||||
|
this.cargoLabels(option.path).join('/') === condition.cargoType)
|
||||||
);
|
);
|
||||||
return item?.path || [];
|
return item?.path || [];
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1089,7 +1089,7 @@
|
|||||||
class="business-crud-page__freight-form business-crud-page__freight-form--road"
|
class="business-crud-page__freight-form business-crud-page__freight-form--road"
|
||||||
>
|
>
|
||||||
<template v-for="(cargo, index) in transportCargoRows" :key="index">
|
<template v-for="(cargo, index) in transportCargoRows" :key="index">
|
||||||
<el-form-item :label="`单价${index + 1}`">
|
<el-form-item label="单价">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="cargo.unitPrice"
|
v-model="cargo.unitPrice"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
@@ -1115,7 +1115,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`数量合计${index + 1}`">
|
<el-form-item label="数量合计">
|
||||||
<el-input :model-value="taskFullFreightQuantity(index)" disabled>
|
<el-input :model-value="taskFullFreightQuantity(index)" disabled>
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-select
|
<el-select
|
||||||
@@ -1132,7 +1132,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`运费${index + 1}`">
|
<el-form-item label="运费">
|
||||||
<el-input
|
<el-input
|
||||||
:model-value="taskFullFreightAmount(cargo)"
|
:model-value="taskFullFreightAmount(cargo)"
|
||||||
placeholder="请输入运费"
|
placeholder="请输入运费"
|
||||||
@@ -1674,7 +1674,7 @@
|
|||||||
class="business-crud-page__freight-form business-crud-page__freight-form--road"
|
class="business-crud-page__freight-form business-crud-page__freight-form--road"
|
||||||
>
|
>
|
||||||
<template v-for="(row, index) in shippingTemplateFreight.freightItems" :key="index">
|
<template v-for="(row, index) in shippingTemplateFreight.freightItems" :key="index">
|
||||||
<el-form-item :label="`单价${index + 1}`">
|
<el-form-item label="单价">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="row.unitPrice"
|
v-model="row.unitPrice"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
@@ -1701,7 +1701,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`数量合计${index + 1}`">
|
<el-form-item label="数量合计">
|
||||||
<el-input :model-value="shippingTemplateRoadFreightQuantity(index)" disabled>
|
<el-input :model-value="shippingTemplateRoadFreightQuantity(index)" disabled>
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-select
|
<el-select
|
||||||
@@ -1718,7 +1718,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`运费${index + 1}`">
|
<el-form-item label="运费">
|
||||||
<el-input :model-value="shippingTemplateRoadFreightAmount(row, index)" disabled>
|
<el-input :model-value="shippingTemplateRoadFreightAmount(row, index)" disabled>
|
||||||
<template #suffix>{{ shippingTemplateCurrencyLabel }}</template>
|
<template #suffix>{{ shippingTemplateCurrencyLabel }}</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
@@ -3799,7 +3799,7 @@
|
|||||||
class="business-crud-page__dispatch-item-grid business-crud-page__dispatch-item-grid--full"
|
class="business-crud-page__dispatch-item-grid business-crud-page__dispatch-item-grid--full"
|
||||||
>
|
>
|
||||||
<template v-for="(cargo, index) in dispatchItemCargoRows" :key="cargo._key || index">
|
<template v-for="(cargo, index) in dispatchItemCargoRows" :key="cargo._key || index">
|
||||||
<el-form-item :label="`单价${index + 1}`">
|
<el-form-item label="单价">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="cargo.unitPrice"
|
v-model="cargo.unitPrice"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
@@ -3819,12 +3819,12 @@
|
|||||||
></template>
|
></template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`数量合计${index + 1}`"
|
<el-form-item label="数量合计"
|
||||||
><el-input :model-value="formatDispatchQuantity(cargo.quantity)" disabled
|
><el-input :model-value="formatDispatchQuantity(cargo.quantity)" disabled
|
||||||
><template #append>{{ cargo.quantityUnit || '吨' }}</template></el-input
|
><template #append>{{ cargo.quantityUnit || '吨' }}</template></el-input
|
||||||
></el-form-item
|
></el-form-item
|
||||||
>
|
>
|
||||||
<el-form-item :label="`运费${index + 1}`"
|
<el-form-item label="运费"
|
||||||
><el-input :model-value="dispatchCargoFreightAmount(cargo)" disabled
|
><el-input :model-value="dispatchCargoFreightAmount(cargo)" disabled
|
||||||
><template #suffix>{{ dispatchItemFreightCurrencyLabel }}</template></el-input
|
><template #suffix>{{ dispatchItemFreightCurrencyLabel }}</template></el-input
|
||||||
></el-form-item
|
></el-form-item
|
||||||
|
|||||||
@@ -112,21 +112,21 @@
|
|||||||
<el-form :model="route" label-position="right" label-width="auto" class="dispatch-form freight-form">
|
<el-form :model="route" label-position="right" label-width="auto" class="dispatch-form freight-form">
|
||||||
<el-row v-for="(group, index) in freightGroups(route)" :key="group.key" :gutter="16">
|
<el-row v-for="(group, index) in freightGroups(route)" :key="group.key" :gutter="16">
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item :label="`单价${index + 1}`">
|
<el-form-item label="单价">
|
||||||
<el-input :model-value="freightGroupUnitPrice(group)" inputmode="decimal" placeholder="请输入" @input="value => handleFreightGroupUnitPriceInput(group, value)" @clear="() => handleFreightGroupUnitPriceInput(group, '')">
|
<el-input :model-value="freightGroupUnitPrice(group)" inputmode="decimal" placeholder="请输入" @input="value => handleFreightGroupUnitPriceInput(group, value)" @clear="() => handleFreightGroupUnitPriceInput(group, '')">
|
||||||
<template #append><el-select :model-value="freightGroupPriceUnit(group)" class="freight-unit-select" @change="value => handleFreightGroupPriceUnitChange(group, value)"><el-option label="元/吨" value="元/吨" /><el-option label="元/件" value="元/件" /><el-option label="元/方" value="元/方" /></el-select></template>
|
<template #append><el-select :model-value="freightGroupPriceUnit(group)" class="freight-unit-select" @change="value => handleFreightGroupPriceUnitChange(group, value)"><el-option label="元/吨" value="元/吨" /><el-option label="元/件" value="元/件" /><el-option label="元/方" value="元/方" /></el-select></template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item :label="`数量${index + 1}`">
|
<el-form-item label="数量">
|
||||||
<el-input :model-value="formatQuantity(freightGroupQuantity(group))" readonly>
|
<el-input :model-value="formatQuantity(freightGroupQuantity(group))" readonly>
|
||||||
<template #append><el-select :model-value="group.quantityUnit" class="freight-unit-select" @change="value => handleFreightGroupQuantityUnitChange(route, group, value)"><el-option v-for="unit in quantityUnitOptions" :key="unit" :label="unit" :value="unit" /></el-select></template>
|
<template #append><el-select :model-value="group.quantityUnit" class="freight-unit-select" @change="value => handleFreightGroupQuantityUnitChange(route, group, value)"><el-option v-for="unit in quantityUnitOptions" :key="unit" :label="unit" :value="unit" /></el-select></template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item :label="`运费${index + 1}`">
|
<el-form-item label="运费">
|
||||||
<el-input :model-value="formatAmount(freightGroupAmount(group))" readonly><template #suffix>{{ currencyLabel(route.currency) }}</template></el-input>
|
<el-input :model-value="formatAmount(freightGroupAmount(group))" readonly><template #suffix>{{ currencyLabel(route.currency) }}</template></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|||||||
@@ -366,7 +366,7 @@
|
|||||||
v-for="(item, index) in shippingTemplateFreight.freightItems"
|
v-for="(item, index) in shippingTemplateFreight.freightItems"
|
||||||
:key="item.quantityUnit || `empty-${index}`"
|
:key="item.quantityUnit || `empty-${index}`"
|
||||||
>
|
>
|
||||||
<el-form-item :label="`单价${index + 1}`">
|
<el-form-item label="单价">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="item.unitPrice"
|
v-model="item.unitPrice"
|
||||||
:disabled="dialogReadonly"
|
:disabled="dialogReadonly"
|
||||||
@@ -387,7 +387,7 @@
|
|||||||
></template>
|
></template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`运费${index + 1}`"
|
<el-form-item label="运费"
|
||||||
><el-input
|
><el-input
|
||||||
:model-value="freightAmount(item)"
|
:model-value="freightAmount(item)"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
@@ -643,12 +643,12 @@
|
|||||||
>
|
>
|
||||||
<template v-if="detailTransportMode === 'road'">
|
<template v-if="detailTransportMode === 'road'">
|
||||||
<template v-for="(item, index) in detailFreightItems" :key="item.quantityUnit || index">
|
<template v-for="(item, index) in detailFreightItems" :key="item.quantityUnit || index">
|
||||||
<el-form-item :label="`单价${index + 1}`">
|
<el-form-item label="单价">
|
||||||
<el-input :model-value="item.unitPrice || '-'" disabled>
|
<el-input :model-value="item.unitPrice || '-'" disabled>
|
||||||
<template #append>{{ item.priceUnit || '-' }}</template>
|
<template #append>{{ item.priceUnit || '-' }}</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`运费${index + 1}`">
|
<el-form-item label="运费">
|
||||||
<el-input :model-value="item.freightAmount || '-'" disabled>
|
<el-input :model-value="item.freightAmount || '-'" disabled>
|
||||||
<template #append>{{ detailFreight.currency || '-' }}</template>
|
<template #append>{{ detailFreight.currency || '-' }}</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
|||||||
@@ -1544,15 +1544,10 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="transport-plan-page__dispatch-mode-switch">
|
||||||
class="dialog-section-title dialog-section-title--action"
|
|
||||||
style="display: flex; width: 100%; justify-content: space-between"
|
|
||||||
>
|
|
||||||
<span class="transport-plan-page__dispatch-task-title">任务信息</span>
|
|
||||||
<el-segmented
|
<el-segmented
|
||||||
v-model="dispatchItemForm.taskEntryMode"
|
v-model="dispatchItemForm.taskEntryMode"
|
||||||
:options="dispatchTaskEntryModeOptions"
|
:options="dispatchTaskEntryModeOptions"
|
||||||
class="transport-plan-page__dispatch-entry-mode"
|
|
||||||
@change="handleDispatchTaskEntryModeChange"
|
@change="handleDispatchTaskEntryModeChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1709,7 +1704,7 @@
|
|||||||
class="transport-plan-page__dispatch-item-grid transport-plan-page__dispatch-item-grid--full"
|
class="transport-plan-page__dispatch-item-grid transport-plan-page__dispatch-item-grid--full"
|
||||||
>
|
>
|
||||||
<template v-for="(group, index) in dispatchItemFreightGroups" :key="group.key">
|
<template v-for="(group, index) in dispatchItemFreightGroups" :key="group.key">
|
||||||
<el-form-item :label="`单价${index + 1}`">
|
<el-form-item label="单价">
|
||||||
<el-input
|
<el-input
|
||||||
:model-value="dispatchFreightGroupUnitPrice(group)"
|
:model-value="dispatchFreightGroupUnitPrice(group)"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
@@ -1731,12 +1726,12 @@
|
|||||||
></template>
|
></template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`数量合计${index + 1}`"
|
<el-form-item label="数量合计"
|
||||||
><el-input :model-value="dispatchFreightGroupQuantity(group)" disabled
|
><el-input :model-value="dispatchFreightGroupQuantity(group)" disabled
|
||||||
><template #append>{{ group.quantityUnit || '吨' }}</template></el-input
|
><template #append>{{ group.quantityUnit || '吨' }}</template></el-input
|
||||||
></el-form-item
|
></el-form-item
|
||||||
>
|
>
|
||||||
<el-form-item :label="`运费${index + 1}`"
|
<el-form-item label="运费"
|
||||||
><el-input :model-value="dispatchFreightGroupAmount(group)" disabled
|
><el-input :model-value="dispatchFreightGroupAmount(group)" disabled
|
||||||
><template #suffix>{{ dispatchItemFreightCurrencyLabel }}</template></el-input
|
><template #suffix>{{ dispatchItemFreightCurrencyLabel }}</template></el-input
|
||||||
></el-form-item
|
></el-form-item
|
||||||
@@ -1758,6 +1753,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
<div class="dialog-section-title transport-plan-page__dispatch-task-content-title">
|
||||||
|
任务信息
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="transport-plan-page__dispatch-item-grid transport-plan-page__dispatch-item-grid--compact"
|
class="transport-plan-page__dispatch-item-grid transport-plan-page__dispatch-item-grid--compact"
|
||||||
>
|
>
|
||||||
@@ -1982,10 +1980,9 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="dispatchItemForm.taskEntryMode === 'full'"
|
v-if="dispatchItemForm.taskEntryMode === 'full'"
|
||||||
class="dialog-section-title transport-plan-page__dispatch-carrier-title"
|
class="dialog-section-title transport-plan-page__dispatch-task-content-title"
|
||||||
style="display: flex; width: 100%; margin-top: 16px"
|
|
||||||
>
|
>
|
||||||
承运信息
|
任务信息
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="dispatchItemForm.taskEntryMode === 'full'"
|
v-if="dispatchItemForm.taskEntryMode === 'full'"
|
||||||
@@ -8224,15 +8221,13 @@ export default {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
&__dispatch-carrier-title {
|
&__dispatch-mode-switch {
|
||||||
flex-basis: 100%;
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
width: 100%;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__dispatch-task-title {
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__route-label {
|
&__route-label {
|
||||||
color: #606266;
|
color: #606266;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|||||||
@@ -153,6 +153,15 @@
|
|||||||
|
|
||||||
<template v-if="config.enableProjectSelect" #projectName-label>项目</template>
|
<template v-if="config.enableProjectSelect" #projectName-label>项目</template>
|
||||||
|
|
||||||
|
<template #relationNo-label>
|
||||||
|
<span class="waybill-manage-page__label-with-info">
|
||||||
|
<span>关联单号</span>
|
||||||
|
<el-tooltip content="仅做关联标记,用于业务中子母单情况" placement="top">
|
||||||
|
<el-icon class="waybill-manage-page__info-icon"><InfoFilled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #projectName-form>
|
<template #projectName-form>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="selectedProjectId"
|
v-model="selectedProjectId"
|
||||||
@@ -353,10 +362,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #taskInfoTitle-form>
|
<template #taskInfoTitle-form>
|
||||||
<div
|
<div class="waybill-manage-page__task-mode-switch">
|
||||||
class="dialog-section-title dialog-section-title--action waybill-manage-page__task-title"
|
|
||||||
>
|
|
||||||
<span>任务信息</span>
|
|
||||||
<el-segmented
|
<el-segmented
|
||||||
v-model="form.taskEntryMode"
|
v-model="form.taskEntryMode"
|
||||||
:options="taskEntryModeOptions"
|
:options="taskEntryModeOptions"
|
||||||
@@ -561,6 +567,7 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="dialog-section-title waybill-manage-page__task-content-title">任务信息</div>
|
||||||
<el-form
|
<el-form
|
||||||
:model="form"
|
:model="form"
|
||||||
label-position="right"
|
label-position="right"
|
||||||
@@ -1033,7 +1040,12 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<div class="waybill-manage-page__subsection">
|
<div class="waybill-manage-page__subsection">
|
||||||
<div class="waybill-manage-page__subsection-head">
|
<div class="waybill-manage-page__subsection-head">
|
||||||
<span>运费信息</span>
|
<span class="waybill-manage-page__label-with-info">
|
||||||
|
<span>运费信息</span>
|
||||||
|
<el-tooltip content="可选填写,仅做记录,不影响应付结算" placement="top">
|
||||||
|
<el-icon class="waybill-manage-page__info-icon"><InfoFilled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<el-form
|
<el-form
|
||||||
:model="form"
|
:model="form"
|
||||||
@@ -1042,7 +1054,7 @@
|
|||||||
class="waybill-manage-page__freight-form waybill-manage-page__freight-form--road"
|
class="waybill-manage-page__freight-form waybill-manage-page__freight-form--road"
|
||||||
>
|
>
|
||||||
<template v-for="(group, index) in taskFreightGroups" :key="group.key">
|
<template v-for="(group, index) in taskFreightGroups" :key="group.key">
|
||||||
<el-form-item :label="`单价${index + 1}`">
|
<el-form-item label="单价">
|
||||||
<el-input
|
<el-input
|
||||||
:model-value="taskFullFreightGroupUnitPrice(group)"
|
:model-value="taskFullFreightGroupUnitPrice(group)"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
@@ -1072,7 +1084,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`数量合计${index + 1}`">
|
<el-form-item label="数量合计">
|
||||||
<el-input :model-value="taskFullFreightGroupQuantity(group)" disabled>
|
<el-input :model-value="taskFullFreightGroupQuantity(group)" disabled>
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-select
|
<el-select
|
||||||
@@ -1089,7 +1101,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="`运费${index + 1}`">
|
<el-form-item label="运费">
|
||||||
<el-input
|
<el-input
|
||||||
:model-value="taskFullFreightGroupAmount(group)"
|
:model-value="taskFullFreightGroupAmount(group)"
|
||||||
placeholder="请输入运费"
|
placeholder="请输入运费"
|
||||||
@@ -1120,8 +1132,14 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="!isTaskFullMode"
|
||||||
|
class="dialog-section-title waybill-manage-page__task-content-title"
|
||||||
|
>
|
||||||
|
任务信息
|
||||||
|
</div>
|
||||||
<el-form
|
<el-form
|
||||||
v-else
|
v-if="!isTaskFullMode"
|
||||||
:model="form"
|
:model="form"
|
||||||
label-position="right"
|
label-position="right"
|
||||||
label-width="auto"
|
label-width="auto"
|
||||||
@@ -2781,7 +2799,7 @@ import { openImportDialog } from '@/utils/import-excel';
|
|||||||
import { applyTableMenuWidth } from '@/utils/table-menu';
|
import { applyTableMenuWidth } from '@/utils/table-menu';
|
||||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||||
import { isMobile } from '@/utils/validate';
|
import { isMobile } from '@/utils/validate';
|
||||||
import { Location, OfficeBuilding, Rank, Search } from '@element-plus/icons-vue';
|
import { InfoFilled, Location, OfficeBuilding, Rank, Search } from '@element-plus/icons-vue';
|
||||||
import { ElImageViewer } from 'element-plus';
|
import { ElImageViewer } from 'element-plus';
|
||||||
import { OpenFileViewer } from '@open-file-viewer/vue';
|
import { OpenFileViewer } from '@open-file-viewer/vue';
|
||||||
import {
|
import {
|
||||||
@@ -2943,6 +2961,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
WaybillImportDialog,
|
WaybillImportDialog,
|
||||||
PageAvueForm,
|
PageAvueForm,
|
||||||
|
InfoFilled,
|
||||||
Rank,
|
Rank,
|
||||||
ElImageViewer,
|
ElImageViewer,
|
||||||
OpenFileViewer,
|
OpenFileViewer,
|
||||||
@@ -7808,8 +7827,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__shipping-title,
|
&__shipping-title,
|
||||||
&__goods-title,
|
&__goods-title {
|
||||||
&__task-title {
|
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7833,6 +7851,20 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__task-mode-switch {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__task-content-title {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__task-full &__task-content-title {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
&__task-form {
|
&__task-form {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
@@ -7870,7 +7902,6 @@ export default {
|
|||||||
|
|
||||||
&__task-form--full {
|
&__task-form--full {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__task-row {
|
&__task-row {
|
||||||
@@ -7909,6 +7940,18 @@ export default {
|
|||||||
grid-column: span 1;
|
grid-column: span 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__label-with-info {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 4px;
|
||||||
|
align-items: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info-icon {
|
||||||
|
color: #909399;
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
&__task-carrier-type {
|
&__task-carrier-type {
|
||||||
:deep(.el-form-item__content) {
|
:deep(.el-form-item__content) {
|
||||||
flex: 0 1 260px;
|
flex: 0 1 260px;
|
||||||
@@ -7949,16 +7992,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 运单独立表单的任务信息:标题靠左,短字段保持与里程输入框一致的宽度。
|
|
||||||
:global(.waybill-manage-page--form-page .waybill-manage-page__task-title) {
|
|
||||||
justify-content: flex-start !important;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.waybill-manage-page--form-page .waybill-manage-page__task-title > .el-segmented) {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(
|
:global(
|
||||||
.waybill-manage-page--form-page
|
.waybill-manage-page--form-page
|
||||||
.waybill-manage-page__task-form
|
.waybill-manage-page__task-form
|
||||||
|
|||||||
@@ -82,7 +82,20 @@
|
|||||||
<el-upload action="#" :auto-upload="false" multiple :show-file-list="false" @change="handleAttachment"><el-button plain>上传附件</el-button></el-upload>
|
<el-upload action="#" :auto-upload="false" multiple :show-file-list="false" @change="handleAttachment"><el-button plain>上传附件</el-button></el-upload>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="change-section change-reason-section"><div class="dialog-section-title">变更原因</div><el-form-item prop="changeReason"><el-input v-model="form.changeReason" type="textarea" :rows="2" maxlength="2000" show-word-limit placeholder="请输入变更原因" /></el-form-item><div class="dialog-section-title">变更材料</div><el-upload action="#" :auto-upload="false" multiple :show-file-list="false" @change="handleChangeMaterial"><el-button plain>上传变更材料</el-button></el-upload></section>
|
<section class="change-section change-reason-section">
|
||||||
|
<div class="dialog-section-title">变更内容</div>
|
||||||
|
<el-form-item prop="changeContent"><el-input v-model="form.changeContent" type="textarea" :rows="3" maxlength="2000" show-word-limit placeholder="请输入变更内容" /></el-form-item>
|
||||||
|
<div class="dialog-section-title">变更原因</div>
|
||||||
|
<el-form-item prop="changeReason"><el-input v-model="form.changeReason" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入变更原因" /></el-form-item>
|
||||||
|
<div class="dialog-section-title">变更材料</div>
|
||||||
|
<el-table :data="changeMaterials" border class="change-table">
|
||||||
|
<el-table-column type="index" label="序号" width="70" />
|
||||||
|
<el-table-column label="文件名" min-width="240"><template #default="{ row }">{{ row.originalName || row.name }}</template></el-table-column>
|
||||||
|
<el-table-column label="文件大小" width="120"><template #default="{ row }">{{ formatFileSize(row.size) }}</template></el-table-column>
|
||||||
|
<el-table-column label="操作" width="100"><template #default="{ $index }"><el-link type="danger" @click="changeMaterials.splice($index, 1)">删除</el-link></template></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="attachment-upload"><vehicle-attachment-upload v-model="changeMaterials" :readonly="false" :file-types="attachmentFileTypes" :max-size="500" :show-file-list="false" button-text="上传变更材料" /></div>
|
||||||
|
</section>
|
||||||
<div class="page-footer">
|
<div class="page-footer">
|
||||||
<el-button @click="$router.back()">取消</el-button>
|
<el-button @click="$router.back()">取消</el-button>
|
||||||
<el-button type="primary" @click="submit">提交</el-button>
|
<el-button type="primary" @click="submit">提交</el-button>
|
||||||
@@ -125,7 +138,7 @@ export default {
|
|||||||
mounted() { this.load(); },
|
mounted() { this.load(); },
|
||||||
watch: { settlementConfigTab(tab, oldTab) { if (tab === oldTab) return; if (oldTab === 'pre') this.preSettlementConfig = { ...this.settlementRule }; else this.formalSettlementConfig = { ...this.settlementRule }; this.settlementRule = { ...(tab === 'pre' ? this.preSettlementConfig : this.formalSettlementConfig) }; } },
|
watch: { settlementConfigTab(tab, oldTab) { if (tab === oldTab) return; if (oldTab === 'pre') this.preSettlementConfig = { ...this.settlementRule }; else this.formalSettlementConfig = { ...this.settlementRule }; this.settlementRule = { ...(tab === 'pre' ? this.preSettlementConfig : this.formalSettlementConfig) }; } },
|
||||||
methods: {
|
methods: {
|
||||||
async load() { const id = this.$route.query.id; if (!id) return; const res = await api.getDetail(id); const data = res.data?.data || res.data || {}; this.form = { ...data, copyCount: normalizeOptionalPositiveInteger(data.copyCount), paymentDays: normalizeOptionalPositiveInteger(data.paymentDays), changeType: '合同信息变更' }; this.period = data.startDate && data.endDate ? [data.startDate, data.endDate] : []; this.plans = this.parse(data.billingPlanJson); this.attachments = this.parse(data.attachmentsJson); this.contractFileRows = this.parse(data.contractFileJson); const rules = this.parseObject(data.settlementRuleJson); const pre = this.parseObject(data.preSettlementConfigJson); const formal = this.parseObject(data.formalSettlementConfigJson); const legacy = Object.keys(rules).some(key => !['preSettlementConfig', 'formalSettlementConfig'].includes(key)) ? rules : {}; this.preSettlementConfig = rules.preSettlementConfig || (Object.keys(pre).length ? pre : legacy); this.formalSettlementConfig = rules.formalSettlementConfig || (Object.keys(formal).length ? formal : legacy); this.settlementRule = { ...this.preSettlementConfig }; this.feeGenerationMode = data.feeGenerationMode || (Number(data.billingEnabled) === 0 ? 'manual' : 'system'); this.paymentRatioRows = this.parse(data.paymentRatioJson); },
|
async load() { const id = this.$route.query.id; if (!id) return; const res = await api.getDetail(id); const data = res.data?.data || res.data || {}; this.form = { ...data, changeContent: '', changeReason: '', changeAttachmentsJson: '', copyCount: normalizeOptionalPositiveInteger(data.copyCount), paymentDays: normalizeOptionalPositiveInteger(data.paymentDays), changeType: '合同信息变更' }; this.changeMaterials = []; this.period = data.startDate && data.endDate ? [data.startDate, data.endDate] : []; this.plans = this.parse(data.billingPlanJson); this.attachments = this.parse(data.attachmentsJson); this.contractFileRows = this.parse(data.contractFileJson); const rules = this.parseObject(data.settlementRuleJson); const pre = this.parseObject(data.preSettlementConfigJson); const formal = this.parseObject(data.formalSettlementConfigJson); const legacy = Object.keys(rules).some(key => !['preSettlementConfig', 'formalSettlementConfig'].includes(key)) ? rules : {}; this.preSettlementConfig = rules.preSettlementConfig || (Object.keys(pre).length ? pre : legacy); this.formalSettlementConfig = rules.formalSettlementConfig || (Object.keys(formal).length ? formal : legacy); this.settlementRule = { ...this.preSettlementConfig }; this.feeGenerationMode = data.feeGenerationMode || (Number(data.billingEnabled) === 0 ? 'manual' : 'system'); this.paymentRatioRows = this.parse(data.paymentRatioJson); },
|
||||||
parse(value) { try { const result = JSON.parse(value || '[]'); return Array.isArray(result) ? result : []; } catch { return []; } },
|
parse(value) { try { const result = JSON.parse(value || '[]'); return Array.isArray(result) ? result : []; } catch { return []; } },
|
||||||
parseObject(value) { try { return { autoGenerate: 1, settlementType: '月结', billCycleType: '固定截单日', billCutoffDay: 25, cycleDays: 15, ...(JSON.parse(value || '{}') || {}) }; } catch { return { autoGenerate: 1, settlementType: '月结', billCycleType: '固定截单日', billCutoffDay: 25, cycleDays: 15 }; } },
|
parseObject(value) { try { return { autoGenerate: 1, settlementType: '月结', billCycleType: '固定截单日', billCutoffDay: 25, cycleDays: 15, ...(JSON.parse(value || '{}') || {}) }; } catch { return { autoGenerate: 1, settlementType: '月结', billCycleType: '固定截单日', billCutoffDay: 25, cycleDays: 15 }; } },
|
||||||
positiveIntegerInput(prop, value) { this.form[prop] = String(value ?? '').replace(/\D/g, '').replace(/^0+/, ''); },
|
positiveIntegerInput(prop, value) { this.form[prop] = String(value ?? '').replace(/\D/g, '').replace(/^0+/, ''); },
|
||||||
@@ -147,9 +160,8 @@ export default {
|
|||||||
removeContractFile(index) { this.contractFileRows.splice(index, 1); },
|
removeContractFile(index) { this.contractFileRows.splice(index, 1); },
|
||||||
handleContractFileBatchDownload() { (this.selectedContractFiles.length ? this.selectedContractFiles : this.contractFileRows).forEach(row => { if (row.url) window.open(row.url, '_blank'); }); },
|
handleContractFileBatchDownload() { (this.selectedContractFiles.length ? this.selectedContractFiles : this.contractFileRows).forEach(row => { if (row.url) window.open(row.url, '_blank'); }); },
|
||||||
formatFileSize(value) { const size = Number(value || 0); return size > 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(2)}MB` : `${Math.max(1, Math.ceil(size / 1024))}KB`; },
|
formatFileSize(value) { const size = Number(value || 0); return size > 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(2)}MB` : `${Math.max(1, Math.ceil(size / 1024))}KB`; },
|
||||||
handleChangeMaterial(event) { if (event.raw) this.changeMaterials.push(event.raw); },
|
|
||||||
addPaymentRatioRow() { this.paymentRatioRows.push({ paymentTerm: `第${this.paymentRatioRows.length + 1}笔`, ratioLimit: '', remark: '' }); },
|
addPaymentRatioRow() { this.paymentRatioRows.push({ paymentTerm: `第${this.paymentRatioRows.length + 1}笔`, ratioLimit: '', remark: '' }); },
|
||||||
async submit() { await this.$refs.formRef.validate(); const total = this.paymentRatioRows.reduce((sum, row) => sum + Number(row.ratioLimit || 0), 0); if (this.paymentRatioRows.length && Math.abs(total - 100) > 0.0001) { this.$message.warning('付款比例上限合计必须等于100%'); return; } const settlementRule = { preSettlementConfig: this.preSettlementConfig, formalSettlementConfig: this.formalSettlementConfig }; await api.submitChange({ ...this.form, copyCount: normalizeOptionalPositiveInteger(this.form.copyCount), paymentDays: normalizeOptionalPositiveInteger(this.form.paymentDays), startDate: this.period[0], endDate: this.period[1], feeGenerationMode: this.feeGenerationMode, billingEnabled: this.feeGenerationMode === 'system' ? 1 : 0, billingPlanJson: JSON.stringify(this.plans), settlementRuleJson: JSON.stringify(settlementRule), preSettlementConfigJson: JSON.stringify(this.preSettlementConfig), formalSettlementConfigJson: JSON.stringify(this.formalSettlementConfig), paymentRatioJson: JSON.stringify(this.paymentRatioRows), contractFileJson: JSON.stringify(this.contractFileRows), attachmentsJson: JSON.stringify(this.attachments), changeContent: this.form.changeReason, changeReason: this.form.changeReason }); this.$message.success('变更已提交'); this.$router.back(); },
|
async submit() { await this.$refs.formRef.validate(); const total = this.paymentRatioRows.reduce((sum, row) => sum + Number(row.ratioLimit || 0), 0); if (this.paymentRatioRows.length && Math.abs(total - 100) > 0.0001) { this.$message.warning('付款比例上限合计必须等于100%'); return; } const settlementRule = { preSettlementConfig: this.preSettlementConfig, formalSettlementConfig: this.formalSettlementConfig }; await api.submitChange({ ...this.form, copyCount: normalizeOptionalPositiveInteger(this.form.copyCount), paymentDays: normalizeOptionalPositiveInteger(this.form.paymentDays), startDate: this.period[0], endDate: this.period[1], feeGenerationMode: this.feeGenerationMode, billingEnabled: this.feeGenerationMode === 'system' ? 1 : 0, billingPlanJson: JSON.stringify(this.plans), settlementRuleJson: JSON.stringify(settlementRule), preSettlementConfigJson: JSON.stringify(this.preSettlementConfig), formalSettlementConfigJson: JSON.stringify(this.formalSettlementConfig), paymentRatioJson: JSON.stringify(this.paymentRatioRows), contractFileJson: JSON.stringify(this.contractFileRows), attachmentsJson: JSON.stringify(this.attachments), changeContent: this.form.changeContent, changeReason: this.form.changeReason, changeAttachmentsJson: JSON.stringify(this.changeMaterials) }); this.$message.success('变更已提交'); this.$router.back(); },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -769,7 +769,7 @@
|
|||||||
<el-table-column prop="statusName" label="状态" min-width="140" align="center" />
|
<el-table-column prop="statusName" label="状态" min-width="140" align="center" />
|
||||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||||
<template #default="{ row }"
|
<template #default="{ row }"
|
||||||
><el-link type="primary" @click="openFlow(row)">流程</el-link></template
|
><el-link type="primary" @click="openDetailChangeRecord(row)">查看详情</el-link></template
|
||||||
>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -780,6 +780,46 @@
|
|||||||
>
|
>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="detailChangeRecordVisible"
|
||||||
|
title="变更记录详情"
|
||||||
|
append-to-body
|
||||||
|
destroy-on-close
|
||||||
|
width="1100px"
|
||||||
|
top="10px"
|
||||||
|
class="contract-change-record-detail-dialog"
|
||||||
|
>
|
||||||
|
<div v-if="detailChangeRecord" class="contract-change-record-detail-meta">
|
||||||
|
<span>变更日期:{{ detailChangeRecord.changeDate || '-' }}</span>
|
||||||
|
<span>经办人:{{ detailChangeRecord.handlerUserName || '-' }}</span>
|
||||||
|
<span>变更类型:{{ detailChangeRecord.changeType || '-' }}</span>
|
||||||
|
<span>状态:{{ detailChangeRecord.statusName || detailChangeRecord.status || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<el-table :data="detailChangeRecordDetailRows" border :show-overflow-tooltip="false">
|
||||||
|
<el-table-column prop="field" label="变更字段" min-width="180" />
|
||||||
|
<el-table-column
|
||||||
|
prop="before"
|
||||||
|
label="变更前"
|
||||||
|
min-width="360"
|
||||||
|
class-name="contract-change-record-detail-value"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
prop="after"
|
||||||
|
label="变更后"
|
||||||
|
min-width="500"
|
||||||
|
class-name="contract-change-record-detail-value"
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
<el-empty
|
||||||
|
v-if="!detailChangeRecordDetailRows.length"
|
||||||
|
description="暂无变更内容"
|
||||||
|
:image-size="60"
|
||||||
|
/>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary" @click="detailChangeRecordVisible = false">关闭</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<billing-plan-editor
|
<billing-plan-editor
|
||||||
v-model="detailBillingPlanBox"
|
v-model="detailBillingPlanBox"
|
||||||
:value="detailBillingPlanForm"
|
:value="detailBillingPlanForm"
|
||||||
@@ -1220,6 +1260,9 @@ export default {
|
|||||||
detailFormalSettlementRuleForm: defaultSettlementRule(),
|
detailFormalSettlementRuleForm: defaultSettlementRule(),
|
||||||
detailPaymentRatioRows: [],
|
detailPaymentRatioRows: [],
|
||||||
detailChangeRecordRows: [],
|
detailChangeRecordRows: [],
|
||||||
|
detailChangeRecordVisible: false,
|
||||||
|
detailChangeRecord: null,
|
||||||
|
detailChangeRecordDetailRows: [],
|
||||||
flowBox: false,
|
flowBox: false,
|
||||||
flowUrl: '',
|
flowUrl: '',
|
||||||
processInstanceId: '',
|
processInstanceId: '',
|
||||||
@@ -1655,7 +1698,7 @@ export default {
|
|||||||
this.submitAction = action;
|
this.submitAction = action;
|
||||||
const submit = {
|
const submit = {
|
||||||
...this.normalizeSubmit(),
|
...this.normalizeSubmit(),
|
||||||
contractStage: action === 'draft' ? 'draft' : 'temporary',
|
contractStage: action === 'formal' ? 'temporary' : 'draft',
|
||||||
approvalStatus: 'draft',
|
approvalStatus: 'draft',
|
||||||
};
|
};
|
||||||
this.api
|
this.api
|
||||||
@@ -1663,9 +1706,11 @@ export default {
|
|||||||
.then(res => {
|
.then(res => {
|
||||||
const saved = res.data?.data || {};
|
const saved = res.data?.data || {};
|
||||||
const id = saved.id || this.form.id;
|
const id = saved.id || this.form.id;
|
||||||
if (action === 'formal') {
|
if (action === 'temporary' || action === 'formal') {
|
||||||
if (!id) throw new Error('合同保存成功但未返回主键,无法提交正式合同');
|
if (!id) throw new Error('合同保存成功但未返回主键,无法提交合同');
|
||||||
return this.api.submitFormal(id);
|
return action === 'temporary'
|
||||||
|
? this.api.toTemporary(id)
|
||||||
|
: this.api.submitFormal(id);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
@@ -2104,6 +2149,116 @@ export default {
|
|||||||
this.detailBillingPlanIndex = index;
|
this.detailBillingPlanIndex = index;
|
||||||
this.detailBillingPlanBox = true;
|
this.detailBillingPlanBox = true;
|
||||||
},
|
},
|
||||||
|
parseChangeRecordData(value) {
|
||||||
|
if (!value) return {};
|
||||||
|
if (typeof value === 'object') return value;
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(value);
|
||||||
|
return data && typeof data === 'object' && !Array.isArray(data) ? data : {};
|
||||||
|
} catch (error) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
normalizeChangeRecordValue(value) {
|
||||||
|
if (typeof value !== 'string') return value;
|
||||||
|
const text = value.trim();
|
||||||
|
if (!text || (!text.startsWith('[') && !text.startsWith('{') && text !== 'null')) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch (error) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isEmptyChangeRecordValue(value) {
|
||||||
|
const normalized = this.normalizeChangeRecordValue(value);
|
||||||
|
if (normalized === undefined || normalized === null || normalized === '') return true;
|
||||||
|
if (Array.isArray(normalized)) return normalized.length === 0;
|
||||||
|
if (typeof normalized === 'object') return Object.keys(normalized).length === 0;
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
getContractChangeFieldLabel(field) {
|
||||||
|
const labels = {
|
||||||
|
contractName: '合同名称',
|
||||||
|
partyB: '乙方',
|
||||||
|
startDate: '开始日期',
|
||||||
|
endDate: '结束日期',
|
||||||
|
contractFormat: '合同格式',
|
||||||
|
settlementMode: '结算方式',
|
||||||
|
legalSealFlag: '是否需要加盖法人章',
|
||||||
|
copyCount: '一式(份)',
|
||||||
|
settlementCurrency: '结算币种',
|
||||||
|
invoiceCycle: '开票周期',
|
||||||
|
paymentDays: '回款账期',
|
||||||
|
remark: '备注',
|
||||||
|
feeGenerationMode: '费用生成模式',
|
||||||
|
billingPlanJson: '计费方案',
|
||||||
|
settlementRuleJson: '结算单规则',
|
||||||
|
preSettlementConfigJson: '预结算配置',
|
||||||
|
formalSettlementConfigJson: '正式结算配置',
|
||||||
|
paymentRatioJson: '付款比例设置',
|
||||||
|
contractFileJson: '合同文件',
|
||||||
|
attachmentsJson: '其它附件',
|
||||||
|
changeAttachmentsJson: '变更材料',
|
||||||
|
};
|
||||||
|
return labels[field] || field;
|
||||||
|
},
|
||||||
|
formatChangeRecordAttachments(value) {
|
||||||
|
const attachments = Array.isArray(value)
|
||||||
|
? value
|
||||||
|
: parseArray(typeof value === 'string' ? value : JSON.stringify(value || []));
|
||||||
|
const names = attachments
|
||||||
|
.map(item =>
|
||||||
|
typeof item === 'string'
|
||||||
|
? item
|
||||||
|
: item?.originalName || item?.name || item?.fileName || item?.url || item?.link || ''
|
||||||
|
)
|
||||||
|
.filter(Boolean);
|
||||||
|
return names.length ? names.join('、') : '空';
|
||||||
|
},
|
||||||
|
formatContractChangeValue(field, value) {
|
||||||
|
const normalized = this.normalizeChangeRecordValue(value);
|
||||||
|
if (this.isEmptyChangeRecordValue(normalized)) return '空';
|
||||||
|
if (['contractFileJson', 'attachmentsJson', 'changeAttachmentsJson'].includes(field)) {
|
||||||
|
return this.formatChangeRecordAttachments(normalized);
|
||||||
|
}
|
||||||
|
if (field === 'legalSealFlag') return Number(normalized) === 1 ? '是' : '否';
|
||||||
|
if (field === 'feeGenerationMode') return normalized === 'manual' ? '手动生成' : '系统生成';
|
||||||
|
if (field === 'invoiceCycle' || field === 'paymentDays') return `${normalized}天`;
|
||||||
|
if (Array.isArray(normalized) || typeof normalized === 'object') {
|
||||||
|
return JSON.stringify(normalized);
|
||||||
|
}
|
||||||
|
return String(normalized);
|
||||||
|
},
|
||||||
|
buildDetailChangeRecordRows(row = {}) {
|
||||||
|
const beforeData = this.parseChangeRecordData(row.beforeData);
|
||||||
|
const afterData = this.parseChangeRecordData(row.afterData);
|
||||||
|
const fields = [...new Set([...Object.keys(beforeData), ...Object.keys(afterData)])];
|
||||||
|
const rows = fields
|
||||||
|
.filter(
|
||||||
|
field =>
|
||||||
|
JSON.stringify(this.normalizeChangeRecordValue(beforeData[field])) !==
|
||||||
|
JSON.stringify(this.normalizeChangeRecordValue(afterData[field]))
|
||||||
|
)
|
||||||
|
.map(field => ({
|
||||||
|
field: this.getContractChangeFieldLabel(field),
|
||||||
|
before: this.formatContractChangeValue(field, beforeData[field]),
|
||||||
|
after: this.formatContractChangeValue(field, afterData[field]),
|
||||||
|
}));
|
||||||
|
if (row.changeContent) {
|
||||||
|
rows.unshift({ field: '变更内容', before: '空', after: row.changeContent });
|
||||||
|
}
|
||||||
|
if (row.changeReason) {
|
||||||
|
rows.push({ field: '变更原因', before: '空', after: row.changeReason });
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
},
|
||||||
|
openDetailChangeRecord(row) {
|
||||||
|
this.detailChangeRecord = row;
|
||||||
|
this.detailChangeRecordDetailRows = this.buildDetailChangeRecordRows(row);
|
||||||
|
this.detailChangeRecordVisible = true;
|
||||||
|
},
|
||||||
displayValue(value) {
|
displayValue(value) {
|
||||||
return value === undefined || value === null || value === '' ? '-' : value;
|
return value === undefined || value === null || value === '' ? '-' : value;
|
||||||
},
|
},
|
||||||
@@ -2310,6 +2465,23 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.contract-change-record-detail-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px 32px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.contract-change-record-detail-dialog .el-dialog__body) {
|
||||||
|
padding-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.contract-change-record-detail-dialog .contract-change-record-detail-value .cell) {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
:global(.avue--collapse .contract-manage-page__footer) {
|
:global(.avue--collapse .contract-manage-page__footer) {
|
||||||
left: 60px;
|
left: 60px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@
|
|||||||
:disabled="isBasicInfoReadonly"
|
:disabled="isBasicInfoReadonly"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="项目简称" prop="projectShortName">
|
<el-form-item label="项目简称" prop="projectShortName" required>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.projectShortName"
|
v-model="form.projectShortName"
|
||||||
placeholder="请填写项目简称"
|
placeholder="请填写项目简称"
|
||||||
@@ -512,6 +512,12 @@
|
|||||||
<div class="project-apply-form__material-card">
|
<div class="project-apply-form__material-card">
|
||||||
<div class="project-apply-form__material-head">
|
<div class="project-apply-form__material-head">
|
||||||
<div class="dialog-section-title project-apply-form__material-title">项目材料</div>
|
<div class="dialog-section-title project-apply-form__material-title">项目材料</div>
|
||||||
|
<span
|
||||||
|
v-if="!dialogReadonly && missingRequiredAttachmentTypes.length"
|
||||||
|
class="project-apply-form__material-warn"
|
||||||
|
>
|
||||||
|
未上传:{{ missingRequiredAttachmentTypes.join('、') }}
|
||||||
|
</span>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
:disabled="!attachmentRows.length"
|
:disabled="!attachmentRows.length"
|
||||||
@@ -569,8 +575,7 @@
|
|||||||
<el-table-column prop="uploadUserName" label="上传人" min-width="140" align="center" />
|
<el-table-column prop="uploadUserName" label="上传人" min-width="140" align="center" />
|
||||||
<el-table-column prop="uploadTime" label="上传时间" min-width="170" align="center" sortable/>
|
<el-table-column prop="uploadTime" label="上传时间" min-width="170" align="center" sortable/>
|
||||||
<el-table-column label="操作" width="110" align="center">
|
<el-table-column label="操作" width="110" align="center">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ $index }">
|
||||||
<el-link type="primary" @click="downloadAttachment(row)">下载</el-link>
|
|
||||||
<el-link v-if="!dialogReadonly" type="danger" @click="removeAttachment($index)"
|
<el-link v-if="!dialogReadonly" type="danger" @click="removeAttachment($index)"
|
||||||
>删除</el-link
|
>删除</el-link
|
||||||
>
|
>
|
||||||
@@ -590,11 +595,14 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!isChangeDialog" class="dialog-section-title project-apply-form__table-title">
|
<div
|
||||||
|
v-if="!isChangeDialog && !isNewProjectDialog"
|
||||||
|
class="dialog-section-title project-apply-form__table-title"
|
||||||
|
>
|
||||||
变更记录
|
变更记录
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
v-if="!isChangeDialog"
|
v-if="!isChangeDialog && !isNewProjectDialog"
|
||||||
:data="changeRows"
|
:data="changeRows"
|
||||||
border
|
border
|
||||||
class="project-apply-form__table"
|
class="project-apply-form__table"
|
||||||
@@ -1174,6 +1182,9 @@ export default {
|
|||||||
isChangeDialog() {
|
isChangeDialog() {
|
||||||
return this.dialogType === 'change';
|
return this.dialogType === 'change';
|
||||||
},
|
},
|
||||||
|
isNewProjectDialog() {
|
||||||
|
return ['add', 'majorSupplement'].includes(this.dialogType);
|
||||||
|
},
|
||||||
isProjectFormPage() {
|
isProjectFormPage() {
|
||||||
return this.$route.path === '/business/project-apply/form';
|
return this.$route.path === '/business/project-apply/form';
|
||||||
},
|
},
|
||||||
@@ -1693,6 +1704,10 @@ export default {
|
|||||||
if (!options.includeChangeType) {
|
if (!options.includeChangeType) {
|
||||||
delete submitRow.changeType;
|
delete submitRow.changeType;
|
||||||
}
|
}
|
||||||
|
if (this.isNewProjectDialog && !options.includeChangeType) {
|
||||||
|
delete submitRow.changeContent;
|
||||||
|
delete submitRow.changeReason;
|
||||||
|
}
|
||||||
['projectIntro', 'profitRemark', 'riskPoint', 'emergencyPlan'].forEach(
|
['projectIntro', 'profitRemark', 'riskPoint', 'emergencyPlan'].forEach(
|
||||||
key => delete submitRow[key]
|
key => delete submitRow[key]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ import { getToken } from '@/utils/auth';
|
|||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/accident-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/accident-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -475,6 +475,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -483,7 +484,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/accident-record/export-template?${this.website.tokenHeader}=${getToken()}`,
|
'/blade-transport/accident-record/export-template',
|
||||||
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '事故记录模板.xlsx');
|
downloadXls(res.data, '事故记录模板.xlsx');
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ import { openImportDialog } from '@/utils/import-excel';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/annual-inspection-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/annual-inspection-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -445,14 +445,14 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.query,
|
...this.query,
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/annual-inspection-record/export-template?${
|
'/blade-transport/annual-inspection-record/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '年检记录模板.xlsx');
|
downloadXls(res.data, '年检记录模板.xlsx');
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ import { openImportDialog } from '@/utils/import-excel';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/equipment-ledger';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/equipment-ledger';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -356,7 +356,12 @@ export default {
|
|||||||
NProgress.start();
|
NProgress.start();
|
||||||
exportBlob(
|
exportBlob(
|
||||||
'/blade-transport/equipment-ledger/export-equipment-ledger',
|
'/blade-transport/equipment-ledger/export-equipment-ledger',
|
||||||
{ ...this.query, ids: this.ids, [this.website.tokenHeader]: getToken() },
|
{
|
||||||
|
...this.query,
|
||||||
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
|
[this.website.tokenHeader]: getToken(),
|
||||||
|
},
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
)
|
)
|
||||||
.then(res =>
|
.then(res =>
|
||||||
@@ -367,9 +372,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/equipment-ledger/export-template?${
|
'/blade-transport/equipment-ledger/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => downloadXls(res.data, '设备台账模板.xlsx'));
|
).then(res => downloadXls(res.data, '设备台账模板.xlsx'));
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ import { openImportDialog } from '@/utils/import-excel';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/etc-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/etc-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -416,12 +416,14 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.query,
|
...this.query,
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/etc-record/export-template?${this.website.tokenHeader}=${getToken()}`,
|
'/blade-transport/etc-record/export-template',
|
||||||
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, 'ETC记录模板.xlsx');
|
downloadXls(res.data, 'ETC记录模板.xlsx');
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ import { getUploadHeaders } from '@/utils/upload';
|
|||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { ElLoading } from 'element-plus';
|
import { ElLoading } from 'element-plus';
|
||||||
import { excelOption, option } from '@/option/vehicle/insurance-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/insurance-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -506,14 +506,14 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/insurance-record/export-template?${
|
'/blade-transport/insurance-record/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '保险记录模板.xlsx');
|
downloadXls(res.data, '保险记录模板.xlsx');
|
||||||
|
|||||||
@@ -177,6 +177,22 @@ const createTimeRangeMap = {
|
|||||||
createTimeRange: ['createTimeStart', 'createTimeEnd'],
|
createTimeRange: ['createTimeStart', 'createTimeEnd'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'maintainer', label: '保养人' },
|
||||||
|
{ prop: 'maintenanceTime', label: '保养时间' },
|
||||||
|
{ prop: 'mileage', label: '里程/航程数' },
|
||||||
|
{ prop: 'maintenanceItem', label: '保养项目' },
|
||||||
|
{ prop: 'cost', label: '费用' },
|
||||||
|
{ prop: 'storeName', label: '店名' },
|
||||||
|
{ prop: 'contactPhone', label: '联系电话' },
|
||||||
|
{ prop: 'address', label: '地址' },
|
||||||
|
{ prop: 'nextMaintenanceTime', label: '下次保养时间' },
|
||||||
|
{ prop: 'nextMaintenanceMileage', label: '下次保养里程/航程' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
AddressMapPicker,
|
AddressMapPicker,
|
||||||
@@ -715,6 +731,12 @@ export default {
|
|||||||
detail.attachments = this.parseAttachments(detail.attachments);
|
detail.attachments = this.parseAttachments(detail.attachments);
|
||||||
detail.vehicleType = detail.vehicleType || '车辆';
|
detail.vehicleType = detail.vehicleType || '车辆';
|
||||||
detail.mileageUnit = detail.vehicleType === '船舶' ? '海里' : '公里';
|
detail.mileageUnit = detail.vehicleType === '船舶' ? '海里' : '公里';
|
||||||
|
if (type === 'edit') {
|
||||||
|
if (Number(detail.mileage) === -1) detail.mileage = '';
|
||||||
|
if (Number(detail.nextMaintenanceMileage) === -1) {
|
||||||
|
detail.nextMaintenanceMileage = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
this.form = detail;
|
this.form = detail;
|
||||||
this.updateVehicleType(detail.vehicleType);
|
this.updateVehicleType(detail.vehicleType);
|
||||||
});
|
});
|
||||||
@@ -787,6 +809,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -795,9 +818,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/maintenance-plan/export-template?${
|
'/blade-transport/maintenance-plan/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '保养记录模板.xlsx');
|
downloadXls(res.data, '保养记录模板.xlsx');
|
||||||
|
|||||||
@@ -150,6 +150,22 @@ const createTimeRangeMap = {
|
|||||||
createTimeRange: ['createTimeStart', 'createTimeEnd'],
|
createTimeRange: ['createTimeStart', 'createTimeEnd'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exportColumns = [
|
||||||
|
{ prop: 'vehicleType', label: '车船类型' },
|
||||||
|
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||||||
|
{ prop: 'maintainer', label: '维修人' },
|
||||||
|
{ prop: 'maintenanceTime', label: '维修时间' },
|
||||||
|
{ prop: 'location', label: '维修位置' },
|
||||||
|
{ prop: 'replacedPart', label: '更换零件' },
|
||||||
|
{ prop: 'cost', label: '费用' },
|
||||||
|
{ prop: 'company', label: '维修单位' },
|
||||||
|
{ prop: 'contact', label: '联系方式' },
|
||||||
|
{ prop: 'address', label: '地址' },
|
||||||
|
{ prop: 'factoryTime', label: '出厂时间' },
|
||||||
|
{ prop: 'mileage', label: '里程/航程数' },
|
||||||
|
{ prop: 'remark', label: '备注' },
|
||||||
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
AddressMapPicker,
|
AddressMapPicker,
|
||||||
@@ -321,6 +337,7 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '里程/航程数(公里)',
|
label: '里程/航程数(公里)',
|
||||||
prop: 'mileage',
|
prop: 'mileage',
|
||||||
|
renderHeader: () => '里程/航程数',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
slot: true,
|
slot: true,
|
||||||
@@ -749,6 +766,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -757,9 +775,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/maintenance-record/export-template?${
|
'/blade-transport/maintenance-record/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '维修记录模板.xlsx');
|
downloadXls(res.data, '维修记录模板.xlsx');
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ import { getToken } from '@/utils/auth';
|
|||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/mileage-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/mileage-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -531,6 +531,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -542,7 +543,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/mileage-record/export-template?${this.website.tokenHeader}=${getToken()}`,
|
'/blade-transport/mileage-record/export-template',
|
||||||
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '里程记录模板.xlsx');
|
downloadXls(res.data, '里程记录模板.xlsx');
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ import { openImportDialog } from '@/utils/import-excel';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/oil-electric-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/oil-electric-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -500,14 +500,14 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.query,
|
...this.query,
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/oil-electric-record/export-template?${
|
'/blade-transport/oil-electric-record/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '油电记录模板.xlsx');
|
downloadXls(res.data, '油电记录模板.xlsx');
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ import { openImportDialog } from '@/utils/import-excel';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/other-expense-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/other-expense-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -465,14 +465,14 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/other-expense-record/export-template?${
|
'/blade-transport/other-expense-record/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '其他费用记录模板.xlsx');
|
downloadXls(res.data, '其他费用记录模板.xlsx');
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ import { getToken } from '@/utils/auth';
|
|||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/tire-replacement-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/tire-replacement-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -416,6 +416,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -424,9 +425,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/tire-replacement-record/export-template?${
|
'/blade-transport/tire-replacement-record/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '换胎记录模板.xlsx');
|
downloadXls(res.data, '换胎记录模板.xlsx');
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ import { getToken } from '@/utils/auth';
|
|||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/transport-change-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/transport-change-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -416,6 +416,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -424,9 +425,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/transport-change-record/export-template?${
|
'/blade-transport/transport-change-record/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '变更记录模板.xlsx');
|
downloadXls(res.data, '变更记录模板.xlsx');
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ import { normalizeSearchRangeParams } from '@/utils/search-range';
|
|||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/violation-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/violation-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
@@ -508,11 +508,11 @@ export default {
|
|||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
this.form = {
|
this.form = {
|
||||||
vehicleType: '车辆',
|
vehicleType: '车辆',
|
||||||
processStatus: '未处理',
|
processStatus: '已处理',
|
||||||
attachments: [],
|
attachments: [],
|
||||||
};
|
};
|
||||||
this.updateVehicleTypeDisplays('车辆');
|
this.updateVehicleTypeDisplays('车辆');
|
||||||
this.updateProcessResultDisplay('未处理');
|
this.updateProcessResultDisplay('已处理');
|
||||||
}
|
}
|
||||||
if (['edit', 'view'].includes(type)) {
|
if (['edit', 'view'].includes(type)) {
|
||||||
this.isDetailLoading = true;
|
this.isDetailLoading = true;
|
||||||
@@ -598,6 +598,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.buildQuery(),
|
...this.buildQuery(),
|
||||||
ids: this.ids,
|
ids: this.ids,
|
||||||
|
exportColumns: JSON.stringify(exportColumns),
|
||||||
[this.website.tokenHeader]: getToken(),
|
[this.website.tokenHeader]: getToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -606,9 +607,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
`/blade-transport/violation-record/export-template?${
|
'/blade-transport/violation-record/export-template',
|
||||||
this.website.tokenHeader
|
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||||||
}=${getToken()}`,
|
|
||||||
{ feedback: true }
|
{ feedback: true }
|
||||||
).then(res => {
|
).then(res => {
|
||||||
downloadXls(res.data, '违章记录模板.xlsx');
|
downloadXls(res.data, '违章记录模板.xlsx');
|
||||||
|
|||||||
@@ -87,6 +87,10 @@ export default ({ mode, command }) => {
|
|||||||
plugins: createVitePlugins(env, command === 'build'),
|
plugins: createVitePlugins(env, command === 'build'),
|
||||||
build: buildConfig,
|
build: buildConfig,
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
|
// vue-pdf-embed is loaded on demand by the PDF preview component. Keeping
|
||||||
|
// it out of the shared dependency bundle avoids stale Vue chunk cycles
|
||||||
|
// when the development dependency cache is refreshed.
|
||||||
|
exclude: ['vue-pdf-embed'],
|
||||||
esbuildOptions: {
|
esbuildOptions: {
|
||||||
target: 'esnext',
|
target: 'esnext',
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user