@@ -177,6 +199,7 @@ export default {
excelBox: false,
excelForm: {},
isDetailLoading: false,
+ boxType: '',
option,
excelOption,
page: {
@@ -285,6 +308,13 @@ export default {
}
return values;
},
+ normalizeDecimalInput(prop, value) {
+ const sanitized = String(value ?? '').replace(/[^\d.]/g, '');
+ const [integerPart, ...decimalParts] = sanitized.split('.');
+ this.form[prop] = decimalParts.length
+ ? `${integerPart || '0'}.${decimalParts.join('').slice(0, 2)}`
+ : integerPart;
+ },
buildQuery(params = {}) {
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
},
@@ -369,6 +399,7 @@ export default {
});
},
beforeOpen(done, type) {
+ this.boxType = type;
if (type === 'add') {
this.form.vehicleType = '车辆';
this.form.ocrTemplate = '紫金-机动车交强险';
diff --git a/src/views/vehicle/maintenance-plan.vue b/src/views/vehicle/maintenance-plan.vue
index e862bb1..bc57a56 100644
--- a/src/views/vehicle/maintenance-plan.vue
+++ b/src/views/vehicle/maintenance-plan.vue
@@ -70,6 +70,39 @@
class="maintenance-plan-page__input"
/>
+
+ normalizeDecimalInput('mileage', value)"
+ >
+ {{ form.mileageUnit || '公里' }}
+
+
+
+ normalizeDecimalInput('cost', value)"
+ >
+ 元
+
+
+
+ normalizeDecimalInput('nextMaintenanceMileage', value)"
+ >
+ {{ form.mileageUnit || '公里' }}
+
+
{{ formatMileage(row.mileage, row.mileageUnit) }}
@@ -169,6 +202,7 @@ export default {
searchMenuPosition: 'right',
border: true,
index: true,
+ indexLabel: '序号',
viewBtn: true,
selection: true,
dialogClickModal: false,
@@ -223,12 +257,10 @@ export default {
{
label: '里程/航程数',
prop: 'mileage',
- type: 'number',
- precision: 2,
+ type: 'input',
minWidth: 130,
slot: true,
span: 12,
- append: '公里',
placeholder: '请输入',
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
},
@@ -255,9 +287,8 @@ export default {
{
label: '费用',
prop: 'cost',
- type: 'number',
- precision: 2,
- append: '元',
+ type: 'input',
+ slot: true,
span: 12,
placeholder: '请输入',
rules: [
@@ -302,12 +333,10 @@ export default {
{
label: '下次保养里程/航程',
prop: 'nextMaintenanceMileage',
- type: 'number',
- precision: 2,
+ type: 'input',
minWidth: 170,
slot: true,
span: 12,
- append: '公里',
placeholder: '请输入',
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
},
@@ -531,6 +560,13 @@ export default {
if (!value || typeof value === 'string') return value;
return JSON.stringify(value);
},
+ normalizeDecimalInput(prop, value) {
+ const sanitized = String(value ?? '').replace(/[^\d.]/g, '');
+ const [integerPart, ...decimalParts] = sanitized.split('.');
+ this.form[prop] = decimalParts.length
+ ? `${integerPart || '0'}.${decimalParts.join('').slice(0, 2)}`
+ : integerPart;
+ },
initDeptTree() {
getDeptTree(this.userInfo.tenantId).then(res => {
const column = this.findColumn(this.option.column, 'createDept');
diff --git a/src/views/vehicle/maintenance-record.vue b/src/views/vehicle/maintenance-record.vue
index f2f3381..9d624b2 100644
--- a/src/views/vehicle/maintenance-record.vue
+++ b/src/views/vehicle/maintenance-record.vue
@@ -70,6 +70,28 @@
class="maintenance-record-page__input"
/>
+
+ normalizeDecimalInput('cost', value)"
+ >
+ 元
+
+
+
+ normalizeDecimalInput('mileage', value)"
+ >
+ {{ form.mileageUnit || '公里' }}
+
+
{{ formatMileage(row.mileage, row.mileageUnit) }}
@@ -167,6 +189,7 @@ export default {
searchMenuPosition: 'right',
border: true,
index: true,
+ indexLabel: '序号',
viewBtn: true,
selection: true,
dialogClickModal: false,
@@ -239,9 +262,8 @@ export default {
{
label: '费用',
prop: 'cost',
- type: 'number',
- precision: 2,
- append: '元',
+ type: 'input',
+ slot: true,
span: 12,
placeholder: '请输入',
rules: [
@@ -287,10 +309,8 @@ export default {
{
label: '里程/航程数',
prop: 'mileage',
- type: 'number',
- precision: 2,
+ type: 'input',
minWidth: 130,
- append: '公里',
slot: true,
span: 12,
placeholder: '请输入',
@@ -526,6 +546,13 @@ export default {
if (!value || typeof value === 'string') return value;
return JSON.stringify(value);
},
+ normalizeDecimalInput(prop, value) {
+ const sanitized = String(value ?? '').replace(/[^\d.]/g, '');
+ const [integerPart, ...decimalParts] = sanitized.split('.');
+ this.form[prop] = decimalParts.length
+ ? `${integerPart || '0'}.${decimalParts.join('').slice(0, 2)}`
+ : integerPart;
+ },
initDeptTree() {
getDeptTree(this.userInfo.tenantId).then(res => {
const column = this.findColumn(this.option.column, 'createDept');
diff --git a/src/views/vehicle/mileage-record.vue b/src/views/vehicle/mileage-record.vue
index 7c5b875..ec42494 100644
--- a/src/views/vehicle/mileage-record.vue
+++ b/src/views/vehicle/mileage-record.vue
@@ -82,6 +82,50 @@
class="mileage-record-page__input"
/>
+
+ normalizeIntegerInput('previousMonthMileage', value)"
+ >
+ km
+
+
+
+ normalizeIntegerInput('currentMonthMileage', value)"
+ >
+ km
+
+
+
+ normalizeIntegerInput('monthlyMileage', value)"
+ >
+ km
+
+
+
+ normalizeIntegerInput('totalMileage', value)"
+ >
+ km
+
+
{
const column = this.findColumn(this.option.column, prop);
column.label = labelMap[prop];
- column.append = unit;
});
vehicleTypeColumn.disabled = Boolean(this.form.id);
const unitColumn = this.findColumn(this.option.column, 'mileageUnit');
@@ -304,6 +347,9 @@ export default {
toMoney(value) {
return Math.round(Number(value) * 100) / 100;
},
+ normalizeIntegerInput(prop, value) {
+ this.form[prop] = String(value ?? '').replace(/\D/g, '');
+ },
normalizeRow(row) {
const values = { ...row };
values.vehicleType = values.vehicleType || '车辆';
diff --git a/src/views/vehicle/oil-electric-record.vue b/src/views/vehicle/oil-electric-record.vue
index aa9f49e..7c29579 100644
--- a/src/views/vehicle/oil-electric-record.vue
+++ b/src/views/vehicle/oil-electric-record.vue
@@ -70,6 +70,48 @@
class="oil-electric-record-page__input"
/>
+
+ normalizeDecimalInput('quantity', value)"
+ />
+
+
+ normalizeDecimalInput('unitPrice', value)"
+ >
+ 元
+
+
+
+ normalizeDecimalInput('transactionAmount', value)"
+ >
+ 元
+
+
+
+ normalizeDecimalInput('balance', value)"
+ >
+ 元
+
+
{{ formatAttachments(row.attachments) }}
@@ -190,9 +232,7 @@ export default {
},
updateFeeType(feeType) {
const oilProductColumn = this.findColumn(this.option.column, 'oilProduct');
- const unitPriceColumn = this.findColumn(this.option.column, 'unitPrice');
oilProductColumn.display = feeType !== '充电';
- unitPriceColumn.append = feeType === '充电' ? '元/度' : '元/升';
if (feeType === '充电') {
this.form.oilProduct = undefined;
}
@@ -249,6 +289,13 @@ export default {
isEmpty(value) {
return value === undefined || value === null || value === '';
},
+ normalizeDecimalInput(prop, value) {
+ const sanitized = String(value ?? '').replace(/[^\d.]/g, '');
+ const [integerPart, ...decimalParts] = sanitized.split('.');
+ this.form[prop] = decimalParts.length
+ ? `${integerPart || '0'}.${decimalParts.join('').slice(0, 2)}`
+ : integerPart;
+ },
normalizeRow(row) {
const values = { ...row };
values.vehicleType = values.vehicleType || '车辆';
diff --git a/src/views/vehicle/other-expense-record.vue b/src/views/vehicle/other-expense-record.vue
index 848d71a..cd5812e 100644
--- a/src/views/vehicle/other-expense-record.vue
+++ b/src/views/vehicle/other-expense-record.vue
@@ -70,6 +70,17 @@
class="other-expense-record-page__input"
/>
+
+ normalizeDecimalInput('amount', value)"
+ >
+ 元
+
+
{{ formatAttachments(row.attachments) }}
@@ -234,6 +245,13 @@ export default {
isEmpty(value) {
return value === undefined || value === null || value === '';
},
+ normalizeDecimalInput(prop, value) {
+ const sanitized = String(value ?? '').replace(/[^\d.]/g, '');
+ const [integerPart, ...decimalParts] = sanitized.split('.');
+ this.form[prop] = decimalParts.length
+ ? `${integerPart || '0'}.${decimalParts.join('').slice(0, 2)}`
+ : integerPart;
+ },
normalizeRow(row) {
const values = { ...row };
values.vehicleType = values.vehicleType || '车辆';
diff --git a/src/views/vehicle/tire-replacement-record.vue b/src/views/vehicle/tire-replacement-record.vue
index 6f2d6c4..e282262 100644
--- a/src/views/vehicle/tire-replacement-record.vue
+++ b/src/views/vehicle/tire-replacement-record.vue
@@ -70,6 +70,26 @@
class="tire-replacement-record-page__input"
/>
+
+ normalizeIntegerInput('tireQuantity', value)"
+ />
+
+
+ normalizeDecimalInput('replacementCost', value)"
+ >
+ 元
+
+
{{ formatAttachments(row.attachments) }}
@@ -225,6 +245,16 @@ export default {
if (!value || typeof value === 'string') return value;
return JSON.stringify(value);
},
+ normalizeDecimalInput(prop, value) {
+ const sanitized = String(value ?? '').replace(/[^\d.]/g, '');
+ const [integerPart, ...decimalParts] = sanitized.split('.');
+ this.form[prop] = decimalParts.length
+ ? `${integerPart || '0'}.${decimalParts.join('').slice(0, 2)}`
+ : integerPart;
+ },
+ normalizeIntegerInput(prop, value) {
+ this.form[prop] = String(value ?? '').replace(/\D/g, '');
+ },
normalizeRow(row) {
const values = { ...row };
if (values.vehicleNo) {
diff --git a/src/views/vehicle/violation-record.vue b/src/views/vehicle/violation-record.vue
index 74c483f..b6df5ca 100644
--- a/src/views/vehicle/violation-record.vue
+++ b/src/views/vehicle/violation-record.vue
@@ -90,6 +90,26 @@
placeholder="请输入船长"
/>
+
+ normalizeDecimalInput('fineAmount', value)"
+ >
+ 元
+
+
+
+ normalizeIntegerInput('deductPoints', value)"
+ />
+
{{ row.processStatus }}
@@ -141,6 +161,7 @@ import { getList as getVehicleList } from '@/api/transportCapacity/transport-veh
import { getList as getShipList } from '@/api/transportCapacity/transport-ship';
import { getList as getDriverList } from '@/api/transportCapacity/driver';
import { getDeptTree } from '@/api/system/dept';
+import { getDictionary } from '@/api/system/dictbiz';
import { exportBlob } from '@/api/common';
import { downloadXls } from '@/utils/util';
import { openImportDialog } from '@/utils/import-excel';
@@ -179,6 +200,7 @@ export default {
},
created() {
this.initDeptTree();
+ this.initViolationTypeOptions();
},
computed: {
...mapGetters(['permission', 'userInfo']),
@@ -229,6 +251,15 @@ export default {
column.dicData = res.data.data;
});
},
+ initViolationTypeOptions() {
+ getDictionary({ code: 'type_of_traffic_violation' }).then(res => {
+ const column = this.findColumn(this.option.column, 'violationType');
+ column.dicData = (res.data.data || []).map(item => ({
+ label: item.dictValue,
+ value: item.dictValue,
+ }));
+ });
+ },
updateVehicleTypeDisplays(vehicleType, oldValue) {
const vehicleTypeColumn = this.findColumn(this.option.column, 'vehicleType');
const vehicleNoColumn = this.findColumn(this.option.column, 'vehicleNo');
@@ -240,6 +271,17 @@ export default {
driverColumn.label = vehicleType === '船舶' ? '船长' : '驾驶人';
typeColumn.display = vehicleType !== '船舶';
itemColumn.display = vehicleType === '船舶';
+ typeColumn.rules =
+ vehicleType === '船舶'
+ ? []
+ : [{ required: true, message: '请选择类型', trigger: 'change' }];
+ itemColumn.rules =
+ vehicleType === '船舶'
+ ? [
+ { required: true, message: '请输入事项', trigger: 'blur' },
+ { max: 100, message: '最多 100 个字符', trigger: 'blur' },
+ ]
+ : [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }];
vehicleTypeColumn.disabled = Boolean(this.form.id);
if (!this.isDetailLoading && oldValue && vehicleType !== oldValue) {
this.form.vehicleNo = '';
@@ -315,6 +357,16 @@ export default {
if (!value || typeof value === 'string') return value;
return JSON.stringify(value);
},
+ normalizeDecimalInput(prop, value) {
+ const sanitized = String(value ?? '').replace(/[^\d.]/g, '');
+ const [integerPart, ...decimalParts] = sanitized.split('.');
+ this.form[prop] = decimalParts.length
+ ? `${integerPart || '0'}.${decimalParts.join('').slice(0, 2)}`
+ : integerPart;
+ },
+ normalizeIntegerInput(prop, value) {
+ this.form[prop] = String(value ?? '').replace(/\D/g, '');
+ },
normalizeRow(row) {
const values = { ...row };
values.vehicleType = values.vehicleType || '车辆';
@@ -337,6 +389,14 @@ export default {
return values;
},
validateRow(row) {
+ if (row.vehicleType === '船舶' && !row.violationItem) {
+ this.$message.warning('请输入事项');
+ return false;
+ }
+ if (row.vehicleType !== '船舶' && !row.violationType) {
+ this.$message.warning('请选择类型');
+ return false;
+ }
if (
row.violationTime &&
new Date(row.violationTime.replace(/-/g, '/')).getTime() > Date.now()