1、车船模块fix bug
2、运力模块fix bug 3、新增设备台账 4、其他bug 修复 5、调整组织、人员模块
This commit is contained in:
@@ -44,14 +44,17 @@
|
||||
批量删除
|
||||
</el-button>
|
||||
</template>
|
||||
<template #menu-right>
|
||||
<el-radio-group v-model="query.expireStatus" class="ship-stat" @change="handleExpireChange">
|
||||
<el-radio-button label="">全部({{ expiryStat.total }})</el-radio-button>
|
||||
<el-radio-button label="within30"
|
||||
>30天内到期({{ expiryStat.within30 }})</el-radio-button
|
||||
<template #expireStatus-search>
|
||||
<div class="transport-ship-page__expiry-tags">
|
||||
<el-check-tag
|
||||
v-for="item in expiryTagOptions"
|
||||
:key="item.value"
|
||||
:checked="query.expireStatus === item.value"
|
||||
@change="handleExpireChange(item.value)"
|
||||
>
|
||||
<el-radio-button label="expired">已到期({{ expiryStat.expired }})</el-radio-button>
|
||||
</el-radio-group>
|
||||
{{ item.label }}({{ expiryStat[item.statKey] || 0 }})
|
||||
</el-check-tag>
|
||||
</div>
|
||||
</template>
|
||||
<template #shipName="{ row }">
|
||||
<el-button type="primary" link @click="openShip(row, true)">
|
||||
@@ -69,14 +72,22 @@
|
||||
</span>
|
||||
</template>
|
||||
<template #safeManningCertEndDate="{ row }">
|
||||
<span :class="getDateClass(row, 'safeManningCertEndDate', 'safeManningCertLongTerm')">
|
||||
<span
|
||||
:class="
|
||||
getCertificateExpiryClass(row, 'safeManningCertEndDate', 'safeManningCertLongTerm')
|
||||
"
|
||||
>
|
||||
{{ formatEndDate(row.safeManningCertEndDate, row.safeManningCertLongTerm) }}
|
||||
</span>
|
||||
</template>
|
||||
<template #businessTransportCertEndDate="{ row }">
|
||||
<span
|
||||
:class="
|
||||
getDateClass(row, 'businessTransportCertEndDate', 'businessTransportCertLongTerm')
|
||||
getCertificateExpiryClass(
|
||||
row,
|
||||
'businessTransportCertEndDate',
|
||||
'businessTransportCertLongTerm'
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ formatEndDate(row.businessTransportCertEndDate, row.businessTransportCertLongTerm) }}
|
||||
@@ -94,7 +105,7 @@
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="hasPermission('transport_ship_view')"
|
||||
@click="openShip(row, true)"
|
||||
@click="openShipLedger(row)"
|
||||
>
|
||||
综合台账
|
||||
</el-link>
|
||||
@@ -108,6 +119,8 @@
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<ship-ledger v-model="shipLedgerBox" :ship="ledgerShip" />
|
||||
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
append-to-body
|
||||
@@ -146,7 +159,7 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="船名" prop="shipName">
|
||||
<el-input v-model="shipForm.shipName" maxlength="50" show-word-limit />
|
||||
<el-input v-model="shipForm.shipName" maxlength="20" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -172,64 +185,64 @@
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="总长" prop="totalLength">
|
||||
<el-input-number
|
||||
<el-input
|
||||
v-model="shipForm.totalLength"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:controls="false"
|
||||
/>
|
||||
@input="normalizeNonNegativeDecimal('totalLength')"
|
||||
>
|
||||
<template #suffix>m</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="船宽" prop="shipWidth">
|
||||
<el-input-number
|
||||
<el-input
|
||||
v-model="shipForm.shipWidth"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:controls="false"
|
||||
/>
|
||||
@input="normalizeNonNegativeDecimal('shipWidth')"
|
||||
>
|
||||
<template #suffix>m</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="型深" prop="moldedDepth">
|
||||
<el-input-number
|
||||
<el-input
|
||||
v-model="shipForm.moldedDepth"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:controls="false"
|
||||
/>
|
||||
@input="normalizeNonNegativeDecimal('moldedDepth')"
|
||||
>
|
||||
<template #suffix>m</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="最大船高" prop="maxShipHeight">
|
||||
<el-input-number
|
||||
<el-input
|
||||
v-model="shipForm.maxShipHeight"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:controls="false"
|
||||
/>
|
||||
@input="normalizeNonNegativeDecimal('maxShipHeight')"
|
||||
>
|
||||
<template #suffix>m</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="空载吃水" prop="lightDraft">
|
||||
<el-input-number
|
||||
<el-input
|
||||
v-model="shipForm.lightDraft"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:controls="false"
|
||||
/>
|
||||
@input="normalizeNonNegativeDecimal('lightDraft')"
|
||||
>
|
||||
<template #suffix>t</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="满载吃水" prop="fullLoadDraft">
|
||||
<el-input-number
|
||||
<el-input
|
||||
v-model="shipForm.fullLoadDraft"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:controls="false"
|
||||
/>
|
||||
@input="normalizeNonNegativeDecimal('fullLoadDraft')"
|
||||
>
|
||||
<template #suffix>t</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -349,7 +362,12 @@
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="船舶类型" prop="shipType">
|
||||
<el-input v-model="shipForm.shipType" maxlength="50" />
|
||||
<el-select v-model="shipForm.shipType" placeholder="请选择船舶类型" clearable>
|
||||
<el-option label="散货船" value="散货船" />
|
||||
<el-option label="集装箱船" value="集装箱船" />
|
||||
<el-option label="杂货船" value="杂货船" />
|
||||
<el-option label="油船" value="油船" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -577,6 +595,7 @@ import { getToken } from '@/utils/auth';
|
||||
import { getUploadHeaders } from '@/utils/upload';
|
||||
import { downloadXls } from '@/utils/util';
|
||||
import ImageUploadField from '@/components/image-upload-field/main.vue';
|
||||
import ShipLedger from './components/ship-ledger.vue';
|
||||
|
||||
const emptyForm = () => ({
|
||||
id: '',
|
||||
@@ -626,7 +645,7 @@ const emptyForm = () => ({
|
||||
});
|
||||
|
||||
export default {
|
||||
components: { ImageUploadField, InfoFilled },
|
||||
components: { ImageUploadField, InfoFilled, ShipLedger },
|
||||
data() {
|
||||
return {
|
||||
option,
|
||||
@@ -641,13 +660,18 @@ export default {
|
||||
page: { pageSize: 10, currentPage: 1, total: 0 },
|
||||
expiryStat: { total: 0, within30: 0, expired: 0 },
|
||||
shipBox: false,
|
||||
shipLedgerBox: false,
|
||||
ledgerShip: {},
|
||||
readonly: false,
|
||||
shipForm: emptyForm(),
|
||||
uploadHeaders: getUploadHeaders(),
|
||||
organizationOptions: [],
|
||||
formRules: {
|
||||
organizationName: [{ required: true, message: '请选择船舶所属组织', trigger: 'change' }],
|
||||
shipName: [{ required: true, message: '请输入船名', trigger: 'blur' }],
|
||||
shipName: [
|
||||
{ required: true, message: '请输入船名', trigger: 'blur' },
|
||||
{ max: 20, message: '船名不能超过20个字符', trigger: 'blur' },
|
||||
],
|
||||
keelLayingDate: [{ validator: this.validateKeelCompletionDate, trigger: 'change' }],
|
||||
shipIdentifierNo: [{ required: true, message: '请输入船舶识别号', trigger: 'blur' }],
|
||||
totalLength: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
|
||||
@@ -663,7 +687,7 @@ export default {
|
||||
grossTonnage: [{ required: true, message: '请输入总吨', trigger: 'change' }],
|
||||
netTonnage: [{ required: true, message: '请输入净吨', trigger: 'change' }],
|
||||
shipInspectionNo: [{ required: true, message: '请输入船检登记号', trigger: 'blur' }],
|
||||
shipType: [{ required: true, message: '请输入船舶类型', trigger: 'blur' }],
|
||||
shipType: [{ required: true, message: '请选择船舶类型', trigger: 'change' }],
|
||||
nationalityCertStartDate: [
|
||||
{ validator: this.validateNationalityCertDate, trigger: 'change' },
|
||||
],
|
||||
@@ -704,6 +728,13 @@ export default {
|
||||
if (this.readonly) return '船舶综合台账';
|
||||
return this.shipForm.id ? '修改船舶' : '新增船舶';
|
||||
},
|
||||
expiryTagOptions() {
|
||||
return [
|
||||
{ label: '全部', value: '', statKey: 'total' },
|
||||
{ label: '30天内到期', value: 'within30', statKey: 'within30' },
|
||||
{ label: '已到期', value: 'expired', statKey: 'expired' },
|
||||
];
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initDeptTree();
|
||||
@@ -717,6 +748,9 @@ export default {
|
||||
this.organizationOptions = this.flattenDeptOptions(res.data.data || []);
|
||||
const column = this.findColumn(this.option.column, 'organizationName');
|
||||
column.dicData = this.organizationOptions;
|
||||
if (this.shipBox && !this.shipForm.id && !this.shipForm.organizationName) {
|
||||
this.shipForm.organizationName = this.getCurrentOrganizationName();
|
||||
}
|
||||
});
|
||||
},
|
||||
flattenDeptOptions(tree = [], level = 0) {
|
||||
@@ -726,6 +760,8 @@ export default {
|
||||
result.push({
|
||||
label: `${' '.repeat(level)}${label}`,
|
||||
value: label,
|
||||
rawLabel: label,
|
||||
id: item.id || item.value,
|
||||
});
|
||||
if (item.children && item.children.length) {
|
||||
result.push(...this.flattenDeptOptions(item.children, level + 1));
|
||||
@@ -733,9 +769,22 @@ export default {
|
||||
});
|
||||
return result;
|
||||
},
|
||||
getCurrentOrganizationName() {
|
||||
const currentDeptId = this.userInfo.deptId || this.userInfo.dept_id;
|
||||
const currentDept = this.organizationOptions.find(
|
||||
item => String(item.id) === String(currentDeptId)
|
||||
);
|
||||
return currentDept?.rawLabel || this.userInfo.deptName || this.userInfo.dept_name || '';
|
||||
},
|
||||
validateField(prop) {
|
||||
this.$refs.shipForm?.validateField(prop);
|
||||
},
|
||||
normalizeNonNegativeDecimal(prop) {
|
||||
const value = String(this.shipForm[prop] ?? '').replace(/[^\d.]/g, '');
|
||||
const [integerPart = '', ...decimalParts] = value.split('.');
|
||||
const decimalPart = decimalParts.join('').slice(0, 2);
|
||||
this.shipForm[prop] = decimalParts.length ? `${integerPart}.${decimalPart}` : integerPart;
|
||||
},
|
||||
validateNonNegativeField(rule, value, callback) {
|
||||
if (value !== undefined && value !== null && value < 0) {
|
||||
callback(new Error('数值不能小于0'));
|
||||
@@ -818,6 +867,7 @@ export default {
|
||||
this.readonly = readonly;
|
||||
if (!row?.id) {
|
||||
this.shipForm = emptyForm();
|
||||
this.shipForm.organizationName = this.getCurrentOrganizationName();
|
||||
this.shipBox = true;
|
||||
return;
|
||||
}
|
||||
@@ -826,6 +876,10 @@ export default {
|
||||
this.shipBox = true;
|
||||
});
|
||||
},
|
||||
openShipLedger(row) {
|
||||
this.ledgerShip = { ...row };
|
||||
this.shipLedgerBox = true;
|
||||
},
|
||||
resetShip() {
|
||||
this.shipForm = emptyForm();
|
||||
this.readonly = false;
|
||||
@@ -881,7 +935,8 @@ export default {
|
||||
});
|
||||
});
|
||||
},
|
||||
handleExpireChange() {
|
||||
handleExpireChange(expireStatus) {
|
||||
this.query.expireStatus = expireStatus;
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page);
|
||||
},
|
||||
@@ -977,14 +1032,28 @@ export default {
|
||||
if (endDate.diff(today, 'day') <= 30) return 'date-warning';
|
||||
return '';
|
||||
},
|
||||
getCertificateExpiryClass(row, dateProp, longTermProp) {
|
||||
if (row[longTermProp] === 1 || !row[dateProp]) return '';
|
||||
const endDate = this.$dayjs(row[dateProp]);
|
||||
return endDate.isValid() && endDate.diff(this.$dayjs(), 'day') <= 30 ? 'date-danger' : '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.transport-ship-page {
|
||||
.ship-stat {
|
||||
flex-shrink: 0;
|
||||
&__expiry-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
|
||||
:deep(.el-check-tag) {
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table th .cell),
|
||||
|
||||
Reference in New Issue
Block a user