1、车船模块fix bug
2、运力模块fix bug 3、新增设备台账 4、其他bug 修复 5、调整组织、人员模块
This commit is contained in:
@@ -61,6 +61,13 @@ export const getUser = id => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getCustomerOptions = () => {
|
||||||
|
return request({
|
||||||
|
url: '/blade-system/user/customer-options',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const getUserPlatform = id => {
|
export const getUserPlatform = id => {
|
||||||
return request({
|
return request({
|
||||||
url: '/blade-system/user/platform-detail',
|
url: '/blade-system/user/platform-detail',
|
||||||
|
|||||||
@@ -51,6 +51,14 @@ export const changeStatus = (id, status) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const auditCertification = (id, certificationStatus, rejectReason) => {
|
||||||
|
return request({
|
||||||
|
url: '/blade-transport/transport-vehicle/audit-certification',
|
||||||
|
method: 'post',
|
||||||
|
params: { id, certificationStatus, rejectReason },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const getExpiryStat = params => {
|
export const getExpiryStat = params => {
|
||||||
return request({
|
return request({
|
||||||
url: '/blade-transport/transport-vehicle/expiry-stat',
|
url: '/blade-transport/transport-vehicle/expiry-stat',
|
||||||
|
|||||||
23
src/api/vehicle/equipment-ledger.js
Normal file
23
src/api/vehicle/equipment-ledger.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import request from '@/axios';
|
||||||
|
|
||||||
|
export const getList = (current, size, params) =>
|
||||||
|
request({
|
||||||
|
url: '/blade-transport/equipment-ledger/list',
|
||||||
|
method: 'get',
|
||||||
|
params: { ...params, current, size },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getDetail = id =>
|
||||||
|
request({ url: '/blade-transport/equipment-ledger/detail', method: 'get', params: { id } });
|
||||||
|
|
||||||
|
export const getNextEquipmentCode = () =>
|
||||||
|
request({ url: '/blade-transport/equipment-ledger/next-equipment-code', method: 'get' });
|
||||||
|
|
||||||
|
export const add = row =>
|
||||||
|
request({ url: '/blade-transport/equipment-ledger/submit', method: 'post', data: row });
|
||||||
|
|
||||||
|
export const update = row =>
|
||||||
|
request({ url: '/blade-transport/equipment-ledger/submit', method: 'post', data: row });
|
||||||
|
|
||||||
|
export const remove = ids =>
|
||||||
|
request({ url: '/blade-transport/equipment-ledger/remove', method: 'post', params: { ids } });
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import website from '@/config/website';
|
|
||||||
import { getDeptLazyTree } from '@/api/system/dept';
|
import { getDeptLazyTree } from '@/api/system/dept';
|
||||||
|
|
||||||
export const userOption = safe => {
|
export const userOption = safe => {
|
||||||
@@ -25,42 +24,41 @@ export const userOption = safe => {
|
|||||||
searchShow: true,
|
searchShow: true,
|
||||||
searchMenuSpan: 24,
|
searchMenuSpan: 24,
|
||||||
searchIcon: true,
|
searchIcon: true,
|
||||||
searchIndex: 8,
|
searchIndex: 4,
|
||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
addBtn: false,
|
addBtn: false,
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
dialogType: 'drawer',
|
dialogType: 'dialog',
|
||||||
dialogWidth: 1000,
|
dialogWidth: '90%',
|
||||||
|
labelPosition: 'right',
|
||||||
|
labelWidth: 120,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
label: '登录账号',
|
label: '账号名',
|
||||||
prop: 'account',
|
prop: 'account',
|
||||||
search: true,
|
search: true,
|
||||||
|
searchOrder: 2,
|
||||||
display: false,
|
display: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '所属租户',
|
label: '姓名',
|
||||||
prop: 'tenantName',
|
|
||||||
slot: true,
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '用户姓名',
|
|
||||||
prop: 'realName',
|
prop: 'realName',
|
||||||
search: true,
|
search: true,
|
||||||
|
searchOrder: 4,
|
||||||
display: false,
|
display: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '所属角色',
|
label: '手机号',
|
||||||
prop: 'roleName',
|
prop: 'phone',
|
||||||
slot: true,
|
search: true,
|
||||||
overHidden: true,
|
searchOrder: 3,
|
||||||
display: false,
|
display: false,
|
||||||
},
|
},
|
||||||
|
{ label: '工号', prop: 'code', display: false },
|
||||||
{
|
{
|
||||||
label: '所属部门',
|
label: '所属部门',
|
||||||
prop: 'deptName',
|
prop: 'deptName',
|
||||||
@@ -68,33 +66,22 @@ export const userOption = safe => {
|
|||||||
overHidden: true,
|
overHidden: true,
|
||||||
display: false,
|
display: false,
|
||||||
},
|
},
|
||||||
|
{ label: '岗位', prop: 'postName', overHidden: true, display: false },
|
||||||
|
{ label: '性别', prop: 'sexName', width: 80, display: false },
|
||||||
|
{ label: 'OA人员id', prop: 'oaPersonId', minWidth: 120, overHidden: true, display: false },
|
||||||
|
{ label: '备注', prop: 'remark', minWidth: 160, overHidden: true, display: false },
|
||||||
{
|
{
|
||||||
label: '用户平台',
|
label: '状态',
|
||||||
prop: 'userTypeName',
|
prop: 'status',
|
||||||
width: 100,
|
|
||||||
slot: true,
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '用户平台',
|
|
||||||
type: 'select',
|
type: 'select',
|
||||||
dicUrl: '/blade-system/dict/dictionary?code=user_type',
|
dicData: [
|
||||||
props: {
|
{ label: '启用', value: 1 },
|
||||||
label: 'dictValue',
|
{ label: '禁用', value: 0 },
|
||||||
value: 'dictKey',
|
],
|
||||||
},
|
|
||||||
dataType: 'number',
|
dataType: 'number',
|
||||||
search: true,
|
search: true,
|
||||||
hide: true,
|
searchOrder: 1,
|
||||||
display: false,
|
display: false,
|
||||||
prop: 'userType',
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请选择用户平台',
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
group: [
|
group: [
|
||||||
@@ -104,53 +91,13 @@ export const userOption = safe => {
|
|||||||
icon: 'el-icon-user-solid',
|
icon: 'el-icon-user-solid',
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
label: '所属租户',
|
label: '账号名',
|
||||||
prop: 'tenantId',
|
|
||||||
type: 'tree',
|
|
||||||
dicUrl: '/blade-system/tenant/select',
|
|
||||||
props: {
|
|
||||||
label: 'tenantName',
|
|
||||||
value: 'tenantId',
|
|
||||||
},
|
|
||||||
hide: !website.tenantMode,
|
|
||||||
addDisplay: website.tenantMode,
|
|
||||||
editDisplay: website.tenantMode,
|
|
||||||
viewDisplay: website.tenantMode,
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入所属租户',
|
|
||||||
trigger: 'click',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
span: 24,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '登录账号',
|
|
||||||
prop: 'account',
|
prop: 'account',
|
||||||
|
span: 6,
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入登录账号',
|
message: '请输入账号名',
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '用户平台',
|
|
||||||
type: 'select',
|
|
||||||
dicUrl: '/blade-system/dict/dictionary?code=user_type',
|
|
||||||
props: {
|
|
||||||
label: 'dictValue',
|
|
||||||
value: 'dictKey',
|
|
||||||
},
|
|
||||||
dataType: 'number',
|
|
||||||
slot: true,
|
|
||||||
prop: 'userType',
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请选择用户平台',
|
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -161,6 +108,7 @@ export const userOption = safe => {
|
|||||||
hide: true,
|
hide: true,
|
||||||
editDisplay: false,
|
editDisplay: false,
|
||||||
viewDisplay: false,
|
viewDisplay: false,
|
||||||
|
addDisplay: false,
|
||||||
rules: [{ required: true, validator: validatePass, trigger: 'blur' }],
|
rules: [{ required: true, validator: validatePass, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -169,6 +117,7 @@ export const userOption = safe => {
|
|||||||
hide: true,
|
hide: true,
|
||||||
editDisplay: false,
|
editDisplay: false,
|
||||||
viewDisplay: false,
|
viewDisplay: false,
|
||||||
|
addDisplay: false,
|
||||||
rules: [{ required: true, validator: validatePass2, trigger: 'blur' }],
|
rules: [{ required: true, validator: validatePass2, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -191,12 +140,13 @@ export const userOption = safe => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '用户姓名',
|
label: '姓名',
|
||||||
prop: 'realName',
|
prop: 'realName',
|
||||||
|
span: 6,
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入用户姓名',
|
message: '请输入姓名',
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -209,12 +159,14 @@ export const userOption = safe => {
|
|||||||
{
|
{
|
||||||
label: '手机号码',
|
label: '手机号码',
|
||||||
prop: 'phone',
|
prop: 'phone',
|
||||||
|
span: 6,
|
||||||
|
rules: [{ required: true, message: '请输入手机号码', trigger: 'blur' }],
|
||||||
overHidden: true,
|
overHidden: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '电子邮箱',
|
label: '电子邮箱',
|
||||||
prop: 'email',
|
prop: 'email',
|
||||||
hide: true,
|
span: 6,
|
||||||
overHidden: true,
|
overHidden: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -235,7 +187,7 @@ export const userOption = safe => {
|
|||||||
value: 3,
|
value: 3,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
hide: true,
|
span: 6,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '用户生日',
|
label: '用户生日',
|
||||||
@@ -261,6 +213,8 @@ export const userOption = safe => {
|
|||||||
{
|
{
|
||||||
label: '用户编号',
|
label: '用户编号',
|
||||||
prop: 'code',
|
prop: 'code',
|
||||||
|
label: '工号',
|
||||||
|
span: 6,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '所属角色',
|
label: '所属角色',
|
||||||
@@ -273,13 +227,7 @@ export const userOption = safe => {
|
|||||||
},
|
},
|
||||||
checkStrictly: true,
|
checkStrictly: true,
|
||||||
slot: true,
|
slot: true,
|
||||||
rules: [
|
display: false,
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请选择所属角色',
|
|
||||||
trigger: 'click',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '所属部门',
|
label: '所属部门',
|
||||||
@@ -292,6 +240,7 @@ export const userOption = safe => {
|
|||||||
},
|
},
|
||||||
checkStrictly: true,
|
checkStrictly: true,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
span: 6,
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
@@ -304,7 +253,7 @@ export const userOption = safe => {
|
|||||||
label: '所属岗位',
|
label: '所属岗位',
|
||||||
prop: 'postId',
|
prop: 'postId',
|
||||||
type: 'tree',
|
type: 'tree',
|
||||||
multiple: true,
|
multiple: false,
|
||||||
dicData: [],
|
dicData: [],
|
||||||
props: {
|
props: {
|
||||||
label: 'postName',
|
label: 'postName',
|
||||||
@@ -317,6 +266,7 @@ export const userOption = safe => {
|
|||||||
trigger: 'click',
|
trigger: 'click',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
span: 6,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '直属主管',
|
label: '直属主管',
|
||||||
@@ -330,6 +280,7 @@ export const userOption = safe => {
|
|||||||
value: 'id',
|
value: 'id',
|
||||||
},
|
},
|
||||||
clearable: true,
|
clearable: true,
|
||||||
|
display: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '是否主管',
|
label: '是否主管',
|
||||||
@@ -346,6 +297,49 @@ export const userOption = safe => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
value: 0,
|
value: 0,
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '人员类别',
|
||||||
|
prop: 'personCategory',
|
||||||
|
type: 'select',
|
||||||
|
span: 6,
|
||||||
|
value: 1,
|
||||||
|
dicData: [
|
||||||
|
{ label: '内部员工', value: 1 },
|
||||||
|
{ label: '承运商', value: 2 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '数据权限范围',
|
||||||
|
prop: 'dataScopeRange',
|
||||||
|
type: 'radio',
|
||||||
|
span: 24,
|
||||||
|
value: 1,
|
||||||
|
dicData: [
|
||||||
|
{ label: '仅所属组织', value: 1 },
|
||||||
|
{ label: '全部组织', value: 2 },
|
||||||
|
{ label: '自定义', value: 3 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '数据层级范围',
|
||||||
|
prop: 'dataLevelRange',
|
||||||
|
type: 'radio',
|
||||||
|
span: 24,
|
||||||
|
value: 1,
|
||||||
|
dicData: [
|
||||||
|
{ label: '包含下级', value: 1 },
|
||||||
|
{ label: '仅本级', value: 2 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '备注',
|
||||||
|
prop: 'remark',
|
||||||
|
type: 'textarea',
|
||||||
|
span: 24,
|
||||||
|
maxlength: 200,
|
||||||
|
showWordLimit: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,58 +20,63 @@ export const option = {
|
|||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
label: '姓名',
|
label: '姓名身份证号',
|
||||||
prop: 'driverName',
|
prop: 'driverName',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 7,
|
searchOrder: 7,
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 120,
|
minWidth: 220,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '手机号',
|
label: '手机号码',
|
||||||
prop: 'mobile',
|
prop: 'mobile',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 6,
|
searchOrder: 6,
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '准驾车型',
|
label: '性别',
|
||||||
prop: 'drivingType',
|
prop: 'gender',
|
||||||
|
width: 80,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '司机类型',
|
||||||
|
prop: 'driverType',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 5,
|
searchOrder: 3,
|
||||||
hide: true,
|
|
||||||
type: 'select',
|
type: 'select',
|
||||||
dicData: [
|
dicData: [
|
||||||
{
|
{
|
||||||
label: 'A1',
|
label: '自有员工',
|
||||||
value: 'A1',
|
value: '自有',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'A2',
|
label: '外协',
|
||||||
value: 'A2',
|
value: '外协',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'A3',
|
label: '承运管理员',
|
||||||
value: 'A3',
|
value: '承运管理员',
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'B1',
|
|
||||||
value: 'B1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'B2',
|
|
||||||
value: 'B2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'C1',
|
|
||||||
value: 'C1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'C2',
|
|
||||||
value: 'C2',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '岗位',
|
||||||
|
prop: 'posts',
|
||||||
|
minWidth: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '所属组织',
|
||||||
|
prop: 'organizationName',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 1,
|
||||||
|
type: 'select',
|
||||||
|
filterable: true,
|
||||||
|
dicData: [],
|
||||||
|
minWidth: 160,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '状态',
|
label: '状态',
|
||||||
@@ -94,65 +99,52 @@ export const option = {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '司机类型',
|
label: '驾驶认证(日期)',
|
||||||
prop: 'driverType',
|
|
||||||
search: true,
|
|
||||||
searchOrder: 3,
|
|
||||||
type: 'select',
|
|
||||||
dicData: [
|
|
||||||
{
|
|
||||||
label: '自有员工',
|
|
||||||
value: '自有',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '外协',
|
|
||||||
value: '外协',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
minWidth: 110,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '身份证号',
|
|
||||||
prop: 'idCardNo',
|
|
||||||
search: true,
|
|
||||||
searchOrder: 2,
|
|
||||||
minWidth: 190,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '所属组织',
|
|
||||||
prop: 'organizationName',
|
|
||||||
search: true,
|
|
||||||
searchOrder: 1,
|
|
||||||
type: 'select',
|
|
||||||
filterable: true,
|
|
||||||
dicData: [],
|
|
||||||
minWidth: 160,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '性别',
|
|
||||||
prop: 'gender',
|
|
||||||
width: 80,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '岗位',
|
|
||||||
prop: 'posts',
|
|
||||||
minWidth: 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '驾驶认证',
|
|
||||||
prop: 'drivingLicenseEndDate',
|
prop: 'drivingLicenseEndDate',
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '从业资格认证',
|
label: '从业资格认证(日期)',
|
||||||
prop: 'qualificationEndDate',
|
prop: 'qualificationEndDate',
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 150,
|
minWidth: 160,
|
||||||
align: 'center',
|
},
|
||||||
|
{
|
||||||
|
label: '身份证号',
|
||||||
|
prop: 'idCardNo',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 2,
|
||||||
|
hide: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '准驾车型',
|
||||||
|
prop: 'drivingType',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 5,
|
||||||
|
hide: true,
|
||||||
|
type: 'select',
|
||||||
|
dicData: [
|
||||||
|
{ label: 'A1', value: 'A1' },
|
||||||
|
{ label: 'A2', value: 'A2' },
|
||||||
|
{ label: 'A3', value: 'A3' },
|
||||||
|
{ label: 'B1', value: 'B1' },
|
||||||
|
{ label: 'B2', value: 'B2' },
|
||||||
|
{ label: 'C1', value: 'C1' },
|
||||||
|
{ label: 'C2', value: 'C2' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '',
|
||||||
|
prop: 'expireStatus',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 0,
|
||||||
|
searchSpan: 6,
|
||||||
|
hide: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const option = {
|
|||||||
editBtn: false,
|
editBtn: false,
|
||||||
delBtn: false,
|
delBtn: false,
|
||||||
viewBtn: false,
|
viewBtn: false,
|
||||||
menuWidth: 220,
|
menuWidth: 320,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
@@ -32,6 +32,16 @@ export const option = {
|
|||||||
searchOrder: 4,
|
searchOrder: 4,
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '所属组织',
|
||||||
|
prop: 'organizationName',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 1,
|
||||||
|
type: 'select',
|
||||||
|
filterable: true,
|
||||||
|
dicData: [],
|
||||||
|
minWidth: 160,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '船检登记号',
|
label: '船检登记号',
|
||||||
prop: 'shipInspectionNo',
|
prop: 'shipInspectionNo',
|
||||||
@@ -54,28 +64,6 @@ export const option = {
|
|||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '所属组织',
|
|
||||||
prop: 'organizationName',
|
|
||||||
search: true,
|
|
||||||
searchOrder: 1,
|
|
||||||
type: 'select',
|
|
||||||
filterable: true,
|
|
||||||
dicData: [],
|
|
||||||
minWidth: 160,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '状态',
|
|
||||||
prop: 'status',
|
|
||||||
type: 'select',
|
|
||||||
slot: true,
|
|
||||||
dicData: [
|
|
||||||
{ label: '启用', value: 1 },
|
|
||||||
{ label: '停用', value: 2 },
|
|
||||||
],
|
|
||||||
minWidth: 90,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '国籍证有效期至',
|
label: '国籍证有效期至',
|
||||||
prop: 'nationalityCertEndDate',
|
prop: 'nationalityCertEndDate',
|
||||||
@@ -104,5 +92,16 @@ export const option = {
|
|||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '',
|
||||||
|
prop: 'expireStatus',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 0,
|
||||||
|
searchSpan: 6,
|
||||||
|
hide: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,22 +9,38 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
selection: true,
|
selection: false,
|
||||||
addBtn: false,
|
addBtn: false,
|
||||||
editBtn: false,
|
editBtn: false,
|
||||||
delBtn: false,
|
delBtn: false,
|
||||||
viewBtn: false,
|
viewBtn: false,
|
||||||
menuWidth: 220,
|
menuWidth: 320,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
label: '车牌号',
|
label: '车牌号',
|
||||||
prop: 'plateNo',
|
prop: 'plateNo',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 5,
|
searchOrder: 6,
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '业务关系',
|
||||||
|
prop: 'businessRelation',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 5,
|
||||||
|
searchValue: '',
|
||||||
|
type: 'select',
|
||||||
|
dicData: [
|
||||||
|
{ label: '全部', value: '' },
|
||||||
|
{ label: '自有', value: '自有' },
|
||||||
|
{ label: '管理挂靠', value: '管理挂靠' },
|
||||||
|
{ label: '业务合作', value: '业务合作' },
|
||||||
|
],
|
||||||
|
minWidth: 120,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '所属组织',
|
label: '所属组织',
|
||||||
prop: 'organizationName',
|
prop: 'organizationName',
|
||||||
@@ -35,26 +51,11 @@ export const option = {
|
|||||||
dicData: [],
|
dicData: [],
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '业务关系',
|
|
||||||
prop: 'businessRelation',
|
|
||||||
search: true,
|
|
||||||
searchOrder: 4,
|
|
||||||
type: 'select',
|
|
||||||
dicData: [
|
|
||||||
{ label: '全部', value: '' },
|
|
||||||
{ label: '自有', value: '自有' },
|
|
||||||
{ label: '管理挂靠', value: '管理挂靠' },
|
|
||||||
{ label: '业务合作', value: '业务合作' },
|
|
||||||
],
|
|
||||||
minWidth: 120,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '车辆类型',
|
label: '车辆类型',
|
||||||
prop: 'vehicleType',
|
prop: 'vehicleType',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 3,
|
searchOrder: 4,
|
||||||
type: 'select',
|
type: 'select',
|
||||||
dicData: [
|
dicData: [
|
||||||
{ label: '全部', value: '' },
|
{ label: '全部', value: '' },
|
||||||
@@ -74,11 +75,41 @@ export const option = {
|
|||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '绑定司机',
|
||||||
|
prop: 'boundDriver',
|
||||||
|
slot: true,
|
||||||
|
minWidth: 120,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '车辆类型',
|
||||||
|
prop: 'vehicleType',
|
||||||
|
minWidth: 110,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '认证状态',
|
||||||
|
prop: 'certificationStatus',
|
||||||
|
slot: true,
|
||||||
|
search: true,
|
||||||
|
searchOrder: 2,
|
||||||
|
searchValue: '',
|
||||||
|
type: 'select',
|
||||||
|
dicData: [
|
||||||
|
{ label: '全部', value: '' },
|
||||||
|
{ label: '认证中', value: 0 },
|
||||||
|
{ label: '已认证', value: 1 },
|
||||||
|
{ label: '已驳回', value: 2 },
|
||||||
|
],
|
||||||
|
minWidth: 110,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '车辆状态',
|
label: '车辆状态',
|
||||||
prop: 'status',
|
prop: 'status',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 2,
|
searchOrder: 3,
|
||||||
type: 'select',
|
type: 'select',
|
||||||
slot: true,
|
slot: true,
|
||||||
dicData: [
|
dicData: [
|
||||||
@@ -89,25 +120,41 @@ export const option = {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '行驶证有效期',
|
label: '道路运输证号',
|
||||||
|
prop: 'roadTransportCertNo',
|
||||||
|
minWidth: 160,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '行驶证认证',
|
||||||
prop: 'drivingLicenseEndDate',
|
prop: 'drivingLicenseEndDate',
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '道路运输证有效期',
|
label: '道路运输证认证',
|
||||||
prop: 'roadTransportCertEndDate',
|
prop: 'roadTransportCertEndDate',
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 160,
|
minWidth: 160,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '年审有效期',
|
label: '道路运输证年审',
|
||||||
prop: 'annualReviewEndDate',
|
prop: 'annualReviewEndDate',
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '',
|
||||||
|
prop: 'expireStatus',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 0,
|
||||||
|
searchSpan: 6,
|
||||||
|
hide: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -124,9 +125,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '直接经济损失',
|
label: '直接经济损失',
|
||||||
prop: 'directEconomicLoss',
|
prop: 'directEconomicLoss',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
@@ -135,9 +135,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '保险理赔金额',
|
label: '保险理赔金额',
|
||||||
prop: 'insuranceClaimAmount',
|
prop: 'insuranceClaimAmount',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -140,9 +141,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '费用',
|
label: '费用',
|
||||||
prop: 'fee',
|
prop: 'fee',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
@@ -155,6 +155,7 @@ export const option = {
|
|||||||
label: '评定(复核)单位',
|
label: '评定(复核)单位',
|
||||||
prop: 'assessmentUnit',
|
prop: 'assessmentUnit',
|
||||||
minWidth: 160,
|
minWidth: 160,
|
||||||
|
overHidden: true,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: [{ max: 50, message: '最多 50 个字符', trigger: 'blur' }],
|
rules: [{ max: 50, message: '最多 50 个字符', trigger: 'blur' }],
|
||||||
|
|||||||
226
src/option/vehicle/equipment-ledger.js
Normal file
226
src/option/vehicle/equipment-ledger.js
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
import { formatUpdateUserName } from '@/utils/audit';
|
||||||
|
|
||||||
|
export const vehicleTypeDic = [
|
||||||
|
{ label: '车辆', value: '车辆' },
|
||||||
|
{ label: '船舶', value: '船舶' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const onlineStatusDic = [
|
||||||
|
{ label: '否', value: 0 },
|
||||||
|
{ label: '是', value: 1 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const option = {
|
||||||
|
height: 'auto',
|
||||||
|
calcHeight: 32,
|
||||||
|
dialogWidth: 960,
|
||||||
|
labelPosition: 'right',
|
||||||
|
labelWidth: 'auto',
|
||||||
|
searchLabelWidth: 160,
|
||||||
|
tip: false,
|
||||||
|
searchBtnText: '查询',
|
||||||
|
emptyBtnText: '重置',
|
||||||
|
saveBtnText: '提交',
|
||||||
|
updateBtnText: '提交',
|
||||||
|
searchShow: true,
|
||||||
|
searchMenuSpan: 24,
|
||||||
|
searchIcon: true,
|
||||||
|
searchIndex: 4,
|
||||||
|
searchMenuPosition: 'right',
|
||||||
|
border: true,
|
||||||
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
|
viewBtn: true,
|
||||||
|
selection: true,
|
||||||
|
dialogClickModal: false,
|
||||||
|
menuWidth: 160,
|
||||||
|
menuFixed: 'right',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
label: '车船类型',
|
||||||
|
prop: 'vehicleType',
|
||||||
|
type: 'radio',
|
||||||
|
dicData: vehicleTypeDic,
|
||||||
|
value: '车辆',
|
||||||
|
search: true,
|
||||||
|
searchOrder: 3,
|
||||||
|
span: 24,
|
||||||
|
order: 1,
|
||||||
|
minWidth: 110,
|
||||||
|
rules: [{ required: true, message: '请选择车船类型', trigger: 'change' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '车牌号/船号',
|
||||||
|
prop: 'vehicleNo',
|
||||||
|
slot: true,
|
||||||
|
formslot: true,
|
||||||
|
search: true,
|
||||||
|
searchOrder: 4,
|
||||||
|
span: 12,
|
||||||
|
order: 2,
|
||||||
|
minWidth: 140,
|
||||||
|
rules: [{ required: true, message: '请输入车牌号/船号', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '设备号',
|
||||||
|
prop: 'equipmentCode',
|
||||||
|
formslot: true,
|
||||||
|
search: true,
|
||||||
|
searchOrder: 2,
|
||||||
|
span: 12,
|
||||||
|
order: 3,
|
||||||
|
minWidth: 150,
|
||||||
|
rules: [{ required: true, message: '设备编号由系统生成', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '设备名称',
|
||||||
|
prop: 'equipmentName',
|
||||||
|
span: 12,
|
||||||
|
order: 4,
|
||||||
|
minWidth: 150,
|
||||||
|
rules: [
|
||||||
|
{ required: true, message: '请输入设备名称', trigger: 'blur' },
|
||||||
|
{ max: 100, message: '最多 100 个字符', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '出厂日期',
|
||||||
|
prop: 'factoryDate',
|
||||||
|
type: 'date',
|
||||||
|
format: 'YYYY-MM-DD',
|
||||||
|
valueFormat: 'YYYY-MM-DD',
|
||||||
|
span: 12,
|
||||||
|
order: 8,
|
||||||
|
minWidth: 130,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '设备品牌',
|
||||||
|
prop: 'equipmentBrand',
|
||||||
|
span: 12,
|
||||||
|
order: 5,
|
||||||
|
minWidth: 130,
|
||||||
|
rules: [{ max: 50, message: '最多 50 个字符', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '设备类型',
|
||||||
|
prop: 'equipmentType',
|
||||||
|
type: 'select',
|
||||||
|
dicData: [],
|
||||||
|
span: 12,
|
||||||
|
order: 6,
|
||||||
|
minWidth: 130,
|
||||||
|
rules: [{ max: 50, message: '最多 50 个字符', trigger: 'change' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '规格型号',
|
||||||
|
prop: 'specificationModel',
|
||||||
|
span: 12,
|
||||||
|
order: 7,
|
||||||
|
minWidth: 150,
|
||||||
|
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '备注',
|
||||||
|
prop: 'remark',
|
||||||
|
type: 'textarea',
|
||||||
|
minRows: 3,
|
||||||
|
span: 24,
|
||||||
|
order: 10,
|
||||||
|
minWidth: 180,
|
||||||
|
overHidden: true,
|
||||||
|
rules: [{ max: 200, message: '最多 200 个字符', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '更新时间',
|
||||||
|
prop: 'updateTime',
|
||||||
|
type: 'datetime',
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
|
minWidth: 170,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '创建时间',
|
||||||
|
prop: 'createTime',
|
||||||
|
type: 'datetime',
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
|
minWidth: 170,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '是否在线',
|
||||||
|
prop: 'onlineStatus',
|
||||||
|
type: 'select',
|
||||||
|
dicData: onlineStatusDic,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
|
minWidth: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '原厂设备号',
|
||||||
|
prop: 'originalEquipmentNo',
|
||||||
|
span: 12,
|
||||||
|
order: 9,
|
||||||
|
hide: true,
|
||||||
|
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '附件',
|
||||||
|
prop: 'attachments',
|
||||||
|
slot: true,
|
||||||
|
formslot: true,
|
||||||
|
span: 24,
|
||||||
|
order: 11,
|
||||||
|
hide: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '组织',
|
||||||
|
prop: 'createDept',
|
||||||
|
type: 'tree',
|
||||||
|
dicData: [],
|
||||||
|
props: { label: 'title', value: 'id' },
|
||||||
|
checkStrictly: true,
|
||||||
|
search: true,
|
||||||
|
searchOrder: 1,
|
||||||
|
hide: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '更新人',
|
||||||
|
prop: 'updateUserName',
|
||||||
|
formatter: formatUpdateUserName,
|
||||||
|
display: false,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const excelOption = {
|
||||||
|
labelPosition: 'right',
|
||||||
|
submitBtn: false,
|
||||||
|
emptyBtn: false,
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
label: '模板上传',
|
||||||
|
prop: 'excelFile',
|
||||||
|
type: 'upload',
|
||||||
|
drag: true,
|
||||||
|
loadText: '模板上传中,请稍等',
|
||||||
|
span: 24,
|
||||||
|
propsHttp: { res: 'data' },
|
||||||
|
tip: '请上传 .xls,.xlsx 标准格式文件',
|
||||||
|
action: '/blade-transport/equipment-ledger/import-equipment-ledger',
|
||||||
|
},
|
||||||
|
{ label: '模板下载', prop: 'excelTemplate', formslot: true, span: 24 },
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -38,6 +38,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -103,9 +104,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '交易金额',
|
label: '交易金额',
|
||||||
prop: 'transactionAmount',
|
prop: 'transactionAmount',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -128,8 +129,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '保额',
|
label: '保额',
|
||||||
prop: 'insuredAmount',
|
prop: 'insuredAmount',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
append: '元',
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
@@ -137,8 +138,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '保费',
|
label: '保费',
|
||||||
prop: 'premium',
|
prop: 'premium',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
append: '元',
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
rules: [
|
rules: [
|
||||||
@@ -181,19 +182,6 @@ export const option = {
|
|||||||
display: false,
|
display: false,
|
||||||
minWidth: 170,
|
minWidth: 170,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '创建时间',
|
|
||||||
prop: 'createTimeRange',
|
|
||||||
type: 'date',
|
|
||||||
format: 'YYYY-MM-DD',
|
|
||||||
valueFormat: 'YYYY-MM-DD',
|
|
||||||
searchRange: true,
|
|
||||||
search: true,
|
|
||||||
hide: true,
|
|
||||||
addDisplay: false,
|
|
||||||
editDisplay: false,
|
|
||||||
viewDisplay: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '组织',
|
label: '组织',
|
||||||
prop: 'createDept',
|
prop: 'createDept',
|
||||||
@@ -210,6 +198,19 @@ export const option = {
|
|||||||
editDisplay: false,
|
editDisplay: false,
|
||||||
viewDisplay: false,
|
viewDisplay: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '创建时间',
|
||||||
|
prop: 'createTimeRange',
|
||||||
|
type: 'date',
|
||||||
|
format: 'YYYY-MM-DD',
|
||||||
|
valueFormat: 'YYYY-MM-DD',
|
||||||
|
searchRange: true,
|
||||||
|
search: true,
|
||||||
|
hide: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
viewDisplay: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '更新人',
|
label: '更新人',
|
||||||
prop: 'updateUserName',
|
prop: 'updateUserName',
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -67,9 +68,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '上月统计里程数',
|
label: '上月统计里程数',
|
||||||
prop: 'previousMonthMileage',
|
prop: 'previousMonthMileage',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '公里',
|
|
||||||
minWidth: 210,
|
minWidth: 210,
|
||||||
slot: true,
|
slot: true,
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
@@ -77,9 +77,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '本月统计里程数',
|
label: '本月统计里程数',
|
||||||
prop: 'currentMonthMileage',
|
prop: 'currentMonthMileage',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '公里',
|
|
||||||
minWidth: 210,
|
minWidth: 210,
|
||||||
slot: true,
|
slot: true,
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
@@ -87,9 +86,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '本月行驶里程数',
|
label: '本月行驶里程数',
|
||||||
prop: 'monthlyMileage',
|
prop: 'monthlyMileage',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '公里',
|
|
||||||
minWidth: 170,
|
minWidth: 170,
|
||||||
slot: true,
|
slot: true,
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
@@ -97,9 +95,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '累计行驶里程数',
|
label: '累计行驶里程数',
|
||||||
prop: 'totalMileage',
|
prop: 'totalMileage',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '公里',
|
|
||||||
minWidth: 170,
|
minWidth: 170,
|
||||||
slot: true,
|
slot: true,
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -111,25 +112,24 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '数量',
|
label: '数量',
|
||||||
prop: 'quantity',
|
prop: 'quantity',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '单价',
|
label: '单价',
|
||||||
prop: 'unitPrice',
|
prop: 'unitPrice',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
append: '元/升',
|
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '交易金额',
|
label: '交易金额',
|
||||||
prop: 'transactionAmount',
|
prop: 'transactionAmount',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
rules: [
|
rules: [
|
||||||
{ required: true, message: '请输入交易金额', trigger: 'blur' },
|
{ required: true, message: '请输入交易金额', trigger: 'blur' },
|
||||||
@@ -139,8 +139,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '余额',
|
label: '余额',
|
||||||
prop: 'balance',
|
prop: 'balance',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -102,9 +103,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '金额',
|
label: '金额',
|
||||||
prop: 'amount',
|
prop: 'amount',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -88,8 +89,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '换胎数量',
|
label: '换胎数量',
|
||||||
prop: 'tireQuantity',
|
prop: 'tireQuantity',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 0,
|
formslot: true,
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
@@ -98,9 +99,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '换胎费用',
|
label: '换胎费用',
|
||||||
prop: 'replacementCost',
|
prop: 'replacementCost',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
|
|||||||
@@ -25,14 +25,6 @@ export const vehicleTypeDic = [
|
|||||||
{ label: '船舶', value: '船舶' },
|
{ label: '船舶', value: '船舶' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const violationTypeDic = [
|
|
||||||
{ label: '闯红灯', value: '闯红灯' },
|
|
||||||
{ label: '超速', value: '超速' },
|
|
||||||
{ label: '违停', value: '违停' },
|
|
||||||
{ label: '压线', value: '压线' },
|
|
||||||
{ label: '其他', value: '其他' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export const processStatusDic = [
|
export const processStatusDic = [
|
||||||
{ label: '未处理', value: '未处理' },
|
{ label: '未处理', value: '未处理' },
|
||||||
{ label: '已处理', value: '已处理' },
|
{ label: '已处理', value: '已处理' },
|
||||||
@@ -57,6 +49,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -104,11 +97,11 @@ export const option = {
|
|||||||
label: '类型',
|
label: '类型',
|
||||||
prop: 'violationType',
|
prop: 'violationType',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
dicData: violationTypeDic,
|
dicData: [],
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请选择',
|
placeholder: '请选择',
|
||||||
rules: [{ required: true, message: '请选择类型', trigger: 'change' }],
|
rules: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '事项',
|
label: '事项',
|
||||||
@@ -118,10 +111,7 @@ export const option = {
|
|||||||
display: false,
|
display: false,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: [
|
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
||||||
{ required: true, message: '请输入事项', trigger: 'blur' },
|
|
||||||
{ max: 100, message: '最多 100 个字符', trigger: 'blur' },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '日期',
|
label: '日期',
|
||||||
@@ -149,8 +139,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '罚款',
|
label: '罚款',
|
||||||
prop: 'fineAmount',
|
prop: 'fineAmount',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
formslot: true,
|
||||||
append: '元',
|
append: '元',
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
span: 12,
|
span: 12,
|
||||||
@@ -160,8 +150,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '被扣分数',
|
label: '被扣分数',
|
||||||
prop: 'deductPoints',
|
prop: 'deductPoints',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 0,
|
formslot: true,
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
|
|||||||
@@ -40,23 +40,121 @@
|
|||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
<template #deptCategory="{ row }">
|
<template #deptCategory="{ row }">
|
||||||
<el-tag>{{ row.deptCategoryName }}</el-tag>
|
<el-tag>{{ getDeptCategoryLabel(row.deptCategory) }}</el-tag>
|
||||||
|
</template>
|
||||||
|
<template #leaderId="{ row }">
|
||||||
|
{{ getLeaderValue(row.leaderId, 'realName') }}
|
||||||
|
</template>
|
||||||
|
<template #leaderPhone="{ row }">
|
||||||
|
{{ getLeaderValue(row.leaderId, 'phone') }}
|
||||||
|
</template>
|
||||||
|
<template #status="{ row }">
|
||||||
|
<el-tag :type="Number(row.status) === 1 ? 'success' : 'info'">
|
||||||
|
{{ Number(row.status) === 1 ? '启用' : '停用' }}
|
||||||
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
|
<el-dialog v-model="carrierDialogVisible" title="选择承运商" width="1100px" append-to-body>
|
||||||
|
<el-form :inline="true" :model="carrierQuery" class="carrier-search-form">
|
||||||
|
<el-form-item label="名称">
|
||||||
|
<el-input v-model="carrierQuery.fullName" placeholder="请输入承运商名称" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="准入标准">
|
||||||
|
<el-select v-model="carrierQuery.accessType" placeholder="全部" clearable>
|
||||||
|
<el-option label="临时" value="temporary" />
|
||||||
|
<el-option label="正式" value="formal" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="审批状态">
|
||||||
|
<el-select v-model="carrierQuery.approvalStatus" placeholder="全部" clearable>
|
||||||
|
<el-option label="草稿" value="draft" />
|
||||||
|
<el-option label="审核中" value="reviewing" />
|
||||||
|
<el-option label="审核通过" value="approved" />
|
||||||
|
<el-option label="审核不通过" value="rejected" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-select v-model="carrierQuery.status" placeholder="全部" clearable>
|
||||||
|
<el-option label="启用" :value="1" />
|
||||||
|
<el-option label="停用" :value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="searchCarrier">搜索</el-button>
|
||||||
|
<el-button @click="resetCarrierQuery">清空</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-table :data="carrierData" border stripe height="420" @row-dblclick="selectCarrier">
|
||||||
|
<el-table-column prop="customerCode" label="客商编号" min-width="130" />
|
||||||
|
<el-table-column prop="shortName" label="客商简称" min-width="140" />
|
||||||
|
<el-table-column prop="fullName" label="客商名称" min-width="200" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="customerType" label="客户类型" min-width="120" />
|
||||||
|
<el-table-column prop="customerNature" label="客户性质" min-width="120" />
|
||||||
|
<el-table-column prop="unifiedCreditCode" label="统一信用代码" min-width="180" />
|
||||||
|
<el-table-column prop="deptName" label="所属组织" min-width="150" />
|
||||||
|
<el-table-column prop="accessType" label="准入标准" min-width="110">
|
||||||
|
<template #default="{ row }">{{ formatAccessType(row.accessType) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="approvalStatus" label="审批状态" min-width="120">
|
||||||
|
<template #default="{ row }">{{ formatApprovalStatus(row.approvalStatus) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="currentNode" label="当前节点" min-width="130" />
|
||||||
|
<el-table-column prop="currentProcessor" label="当前处理人" min-width="130" />
|
||||||
|
<el-table-column prop="approvedTime" label="审核通过时间" min-width="170" />
|
||||||
|
<el-table-column prop="status" label="状态" width="90">
|
||||||
|
<template #default="{ row }">{{ Number(row.status) === 1 ? '启用' : '停用' }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="90" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-link type="primary" @click="selectCarrier(row)">选择</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="carrier-pagination">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="carrierPage.current"
|
||||||
|
v-model:page-size="carrierPage.size"
|
||||||
|
:total="carrierPage.total"
|
||||||
|
:page-sizes="[10, 20, 50]"
|
||||||
|
layout="total, sizes, prev, pager, next"
|
||||||
|
@current-change="loadCarrierList"
|
||||||
|
@size-change="handleCarrierSizeChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</basic-container>
|
</basic-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getLazyList, remove, update, add, getDept, getDeptTree } from '@/api/system/dept';
|
import { getLazyList, remove, update, add, getDept, getDeptTree } from '@/api/system/dept';
|
||||||
import { getLeaderList } from '@/api/system/user';
|
import { getLeaderList } from '@/api/system/user';
|
||||||
|
import { getList as getCustomerArchiveList } from '@/api/vehicle/customer-archive';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import website from '@/config/website';
|
import website from '@/config/website';
|
||||||
import func from '@/utils/func';
|
import func from '@/utils/func';
|
||||||
|
|
||||||
|
const escapeRegExp = value => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
leaderOptions: [],
|
||||||
|
parentDeptCode: '',
|
||||||
|
parentDept: null,
|
||||||
|
carrierDialogVisible: false,
|
||||||
|
carrierData: [],
|
||||||
|
carrierQuery: {
|
||||||
|
fullName: '',
|
||||||
|
accessType: '',
|
||||||
|
approvalStatus: '',
|
||||||
|
status: undefined,
|
||||||
|
},
|
||||||
|
carrierPage: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
total: 0,
|
||||||
|
},
|
||||||
selectionList: [],
|
selectionList: [],
|
||||||
query: {},
|
query: {},
|
||||||
loading: true,
|
loading: true,
|
||||||
@@ -73,29 +171,170 @@ export default {
|
|||||||
searchShow: true,
|
searchShow: true,
|
||||||
searchMenuSpan: 24,
|
searchMenuSpan: 24,
|
||||||
searchIcon: true,
|
searchIcon: true,
|
||||||
searchIndex: 8,
|
searchIndex: 4,
|
||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
tree: true,
|
tree: true,
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
menuWidth: 160,
|
menuWidth: 320,
|
||||||
dialogWidth: 800,
|
dialogWidth: 800,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
|
labelPosition: 'right',
|
||||||
|
labelWidth: 'auto',
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
label: '机构名称',
|
label: '组织名称',
|
||||||
prop: 'deptName',
|
prop: 'deptName',
|
||||||
|
minWidth: 160,
|
||||||
|
order: 80,
|
||||||
search: true,
|
search: true,
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入机构名称',
|
message: '请输入组织名称',
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '组织编码',
|
||||||
|
prop: 'deptCode',
|
||||||
|
minWidth: 140,
|
||||||
|
order: 70,
|
||||||
|
maxlength: 30,
|
||||||
|
showWordLimit: true,
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入组织编码',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
const deptCode = String(value || '').trim();
|
||||||
|
if (deptCode.length > 30) {
|
||||||
|
callback(new Error('组织编码不能超过30个字符'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.parentDeptCode) {
|
||||||
|
callback(new Error('请先选择上级组织'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const pattern = new RegExp(`^${escapeRegExp(this.parentDeptCode)}-\\d+$`);
|
||||||
|
if (!pattern.test(deptCode)) {
|
||||||
|
callback(new Error(`组织编码格式应为:${this.parentDeptCode}-分段数字`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '组织简称',
|
||||||
|
prop: 'shortName',
|
||||||
|
minWidth: 140,
|
||||||
|
order: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '组织类型',
|
||||||
|
type: 'select',
|
||||||
|
dicData: [
|
||||||
|
{ label: '一级集团', value: 1 },
|
||||||
|
{ label: '二级事业部', value: 2 },
|
||||||
|
{ label: '部门', value: 3 },
|
||||||
|
{ label: '三级分公司', value: 4 },
|
||||||
|
{ label: '物流园区', value: 5 },
|
||||||
|
{ label: '承运商', value: 6 },
|
||||||
|
],
|
||||||
|
dataType: 'number',
|
||||||
|
minWidth: 120,
|
||||||
|
order: 90,
|
||||||
|
prop: 'deptCategory',
|
||||||
|
slot: true,
|
||||||
|
change: ({ value }) => this.handleDeptCategoryChange(value),
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择组织类型',
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '负责人',
|
||||||
|
prop: 'leaderId',
|
||||||
|
minWidth: 120,
|
||||||
|
slot: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '联系电话',
|
||||||
|
prop: 'leaderPhone',
|
||||||
|
minWidth: 140,
|
||||||
|
slot: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '助记码',
|
||||||
|
prop: 'mnemonicCode',
|
||||||
|
minWidth: 120,
|
||||||
|
order: 40,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '拼音助记码',
|
||||||
|
prop: 'pinyinMnemonic',
|
||||||
|
minWidth: 140,
|
||||||
|
order: 50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '排序',
|
||||||
|
prop: 'sort',
|
||||||
|
type: 'number',
|
||||||
|
align: 'right',
|
||||||
|
width: 80,
|
||||||
|
order: 30,
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入排序',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '状态',
|
||||||
|
prop: 'status',
|
||||||
|
width: 100,
|
||||||
|
slot: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '上级组织',
|
||||||
|
prop: 'parentId',
|
||||||
|
dicData: [],
|
||||||
|
type: 'tree',
|
||||||
|
hide: true,
|
||||||
|
addDisabled: false,
|
||||||
|
order: 100,
|
||||||
|
change: ({ value }) => this.handleParentChange(value),
|
||||||
|
props: {
|
||||||
|
label: 'title',
|
||||||
|
},
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择上级组织',
|
||||||
|
trigger: 'click',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '所属租户',
|
label: '所属租户',
|
||||||
prop: 'tenantId',
|
prop: 'tenantId',
|
||||||
@@ -104,112 +343,37 @@ export default {
|
|||||||
addDisplay: false,
|
addDisplay: false,
|
||||||
editDisplay: false,
|
editDisplay: false,
|
||||||
viewDisplay: website.tenantMode,
|
viewDisplay: website.tenantMode,
|
||||||
span: 24,
|
|
||||||
props: {
|
props: {
|
||||||
label: 'tenantName',
|
label: 'tenantName',
|
||||||
value: 'tenantId',
|
value: 'tenantId',
|
||||||
},
|
},
|
||||||
hide: !website.tenantMode,
|
hide: true,
|
||||||
search: website.tenantMode,
|
search: website.tenantMode,
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入所属租户',
|
|
||||||
trigger: 'click',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '机构全称',
|
label: '机构全称',
|
||||||
prop: 'fullName',
|
prop: 'fullName',
|
||||||
search: true,
|
search: true,
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入机构全称',
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '上级机构',
|
|
||||||
prop: 'parentId',
|
|
||||||
dicData: [],
|
|
||||||
type: 'tree',
|
|
||||||
hide: true,
|
hide: true,
|
||||||
addDisabled: false,
|
addDisplay: false,
|
||||||
props: {
|
editDisplay: false,
|
||||||
label: 'title',
|
|
||||||
},
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: false,
|
|
||||||
message: '请选择上级机构',
|
|
||||||
trigger: 'click',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '直属主管',
|
|
||||||
prop: 'leaderId',
|
|
||||||
type: 'tree',
|
|
||||||
multiple: true,
|
|
||||||
filterable: true,
|
|
||||||
dicData: [],
|
|
||||||
props: {
|
|
||||||
label: 'realName',
|
|
||||||
value: 'id',
|
|
||||||
},
|
|
||||||
clearable: true,
|
|
||||||
hide: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '机构类型',
|
|
||||||
type: 'select',
|
|
||||||
dicUrl: '/blade-system/dict/dictionary?code=org_category',
|
|
||||||
props: {
|
|
||||||
label: 'dictValue',
|
|
||||||
value: 'dictKey',
|
|
||||||
},
|
|
||||||
dataType: 'number',
|
|
||||||
width: 120,
|
|
||||||
prop: 'deptCategory',
|
|
||||||
slot: true,
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入机构类型',
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '排序',
|
|
||||||
prop: 'sort',
|
|
||||||
type: 'number',
|
|
||||||
align: 'right',
|
|
||||||
width: 80,
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入排序',
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '备注',
|
label: '备注',
|
||||||
prop: 'remark',
|
prop: 'remark',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
span: 24,
|
|
||||||
minRows: 2,
|
|
||||||
hide: true,
|
hide: true,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
data: [],
|
data: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.loadLeaderOptions();
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['userInfo', 'permission']),
|
...mapGetters(['userInfo', 'permission']),
|
||||||
permissionList() {
|
permissionList() {
|
||||||
@@ -234,13 +398,130 @@ export default {
|
|||||||
const column = this.findColumn(this.option.column, 'parentId');
|
const column = this.findColumn(this.option.column, 'parentId');
|
||||||
column.dicData = res.data.data;
|
column.dicData = res.data.data;
|
||||||
});
|
});
|
||||||
getLeaderList(tenantId).then(res => {
|
},
|
||||||
const column = this.findColumn(this.option.column, 'leaderId');
|
handleParentChange(parentId) {
|
||||||
column.dicData = res.data.data;
|
this.loadParentDeptCode(parentId);
|
||||||
|
},
|
||||||
|
loadParentDeptCode(parentId) {
|
||||||
|
this.parentDeptCode = '';
|
||||||
|
this.parentDept = null;
|
||||||
|
if (!parentId || String(parentId) === '0') return;
|
||||||
|
getDept(parentId).then(res => {
|
||||||
|
this.parentDept = res.data.data || null;
|
||||||
|
this.parentDeptCode = this.parentDept?.deptCode || '';
|
||||||
|
this.updateDeptCategoryOptions();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updateDeptCategoryOptions() {
|
||||||
|
const categoryColumn = this.findColumn(this.option.column, 'deptCategory');
|
||||||
|
const parent = this.parentDept;
|
||||||
|
if (!parent) return;
|
||||||
|
let dicData = [];
|
||||||
|
if (this.isRootDept(parent)) {
|
||||||
|
dicData =
|
||||||
|
parent.deptName === '外部组织'
|
||||||
|
? [{ label: '承运商', value: 6 }]
|
||||||
|
: [{ label: '集团', value: 1 }];
|
||||||
|
} else if (Number(parent.deptCategory) === 1) {
|
||||||
|
dicData = [
|
||||||
|
{ label: '事业部', value: 2 },
|
||||||
|
{ label: '部门', value: 3 },
|
||||||
|
];
|
||||||
|
} else if ([2, 3].includes(Number(parent.deptCategory))) {
|
||||||
|
dicData = [
|
||||||
|
{ label: '分公司', value: 4 },
|
||||||
|
{ label: '物流园区', value: 5 },
|
||||||
|
{ label: '承运商', value: 6 },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
categoryColumn.dicData = dicData;
|
||||||
|
if (!dicData.some(item => item.value === Number(this.form.deptCategory))) {
|
||||||
|
this.form.deptCategory = dicData[0]?.value;
|
||||||
|
}
|
||||||
|
if (Number(this.form.deptCategory) === 6) {
|
||||||
|
this.openCarrierDialog();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleDeptCategoryChange(value) {
|
||||||
|
if (Number(value) === 6) {
|
||||||
|
this.openCarrierDialog();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openCarrierDialog() {
|
||||||
|
this.carrierDialogVisible = true;
|
||||||
|
this.loadCarrierList();
|
||||||
|
},
|
||||||
|
loadCarrierList() {
|
||||||
|
getCustomerArchiveList(this.carrierPage.current, this.carrierPage.size, {
|
||||||
|
...this.carrierQuery,
|
||||||
|
customerType: '承运商',
|
||||||
|
}).then(res => {
|
||||||
|
const page = res.data.data || {};
|
||||||
|
this.carrierData = page.records || [];
|
||||||
|
this.carrierPage.total = page.total || 0;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
searchCarrier() {
|
||||||
|
this.carrierPage.current = 1;
|
||||||
|
this.loadCarrierList();
|
||||||
|
},
|
||||||
|
resetCarrierQuery() {
|
||||||
|
this.carrierQuery = { fullName: '', accessType: '', approvalStatus: '', status: undefined };
|
||||||
|
this.searchCarrier();
|
||||||
|
},
|
||||||
|
handleCarrierSizeChange(size) {
|
||||||
|
this.carrierPage.size = size;
|
||||||
|
this.carrierPage.current = 1;
|
||||||
|
this.loadCarrierList();
|
||||||
|
},
|
||||||
|
selectCarrier(row) {
|
||||||
|
this.form.carrierCustomerId = row.id;
|
||||||
|
this.form.deptName = row.fullName;
|
||||||
|
this.form.shortName = row.shortName;
|
||||||
|
this.form.mnemonicCode = row.mnemonicCode;
|
||||||
|
this.carrierDialogVisible = false;
|
||||||
|
},
|
||||||
|
formatAccessType(value) {
|
||||||
|
return value === 'formal' ? '正式' : value === 'temporary' ? '临时' : '-';
|
||||||
|
},
|
||||||
|
formatApprovalStatus(value) {
|
||||||
|
const statusMap = {
|
||||||
|
draft: '草稿',
|
||||||
|
reviewing: '审核中',
|
||||||
|
approved: '审核通过',
|
||||||
|
rejected: '审核不通过',
|
||||||
|
};
|
||||||
|
return statusMap[value] || '-';
|
||||||
|
},
|
||||||
|
loadLeaderOptions(tenantId) {
|
||||||
|
getLeaderList(tenantId).then(res => {
|
||||||
|
this.leaderOptions = res.data.data || [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getDeptCategoryLabel(deptCategory) {
|
||||||
|
const categoryMap = {
|
||||||
|
1: '集团',
|
||||||
|
2: '事业部',
|
||||||
|
3: '部门',
|
||||||
|
4: '分公司',
|
||||||
|
5: '物流园区',
|
||||||
|
6: '承运商',
|
||||||
|
};
|
||||||
|
return categoryMap[Number(deptCategory)] || '-';
|
||||||
|
},
|
||||||
|
getLeaderValue(leaderId, field) {
|
||||||
|
const values = func.split(leaderId);
|
||||||
|
const result = values
|
||||||
|
.map(id => this.leaderOptions.find(item => String(item.id) === String(id))?.[field])
|
||||||
|
.filter(Boolean);
|
||||||
|
return result.length ? result.join('、') : '-';
|
||||||
|
},
|
||||||
|
isRootDept(row) {
|
||||||
|
return row && (row.parentId === 0 || String(row.parentId) === '0');
|
||||||
|
},
|
||||||
handleAdd(row) {
|
handleAdd(row) {
|
||||||
this.parentId = row.id;
|
this.parentId = row.id;
|
||||||
|
this.loadParentDeptCode(row.id);
|
||||||
const column = this.findColumn(this.option.column, 'parentId');
|
const column = this.findColumn(this.option.column, 'parentId');
|
||||||
column.value = row.id;
|
column.value = row.id;
|
||||||
column.addDisabled = true;
|
column.addDisabled = true;
|
||||||
@@ -248,7 +529,13 @@ export default {
|
|||||||
},
|
},
|
||||||
rowSave(row, done, loading) {
|
rowSave(row, done, loading) {
|
||||||
row.tenantId = row.tenantId || this.userInfo.tenantId || website.tenantId;
|
row.tenantId = row.tenantId || this.userInfo.tenantId || website.tenantId;
|
||||||
|
row.deptCode = String(row.deptCode || '').trim();
|
||||||
row.leaderId = func.join(row.leaderId);
|
row.leaderId = func.join(row.leaderId);
|
||||||
|
if (Number(row.deptCategory) === 6 && !row.carrierCustomerId) {
|
||||||
|
this.$message.warning('请选择承运商');
|
||||||
|
loading();
|
||||||
|
return;
|
||||||
|
}
|
||||||
add(row).then(
|
add(row).then(
|
||||||
res => {
|
res => {
|
||||||
// 获取新增数据的相关字段
|
// 获取新增数据的相关字段
|
||||||
@@ -271,7 +558,13 @@ export default {
|
|||||||
},
|
},
|
||||||
rowUpdate(row, index, done, loading) {
|
rowUpdate(row, index, done, loading) {
|
||||||
row.tenantId = row.tenantId || this.userInfo.tenantId || website.tenantId;
|
row.tenantId = row.tenantId || this.userInfo.tenantId || website.tenantId;
|
||||||
|
row.deptCode = String(row.deptCode || '').trim();
|
||||||
row.leaderId = func.join(row.leaderId);
|
row.leaderId = func.join(row.leaderId);
|
||||||
|
if (Number(row.deptCategory) === 6 && !row.carrierCustomerId) {
|
||||||
|
this.$message.warning('请选择承运商');
|
||||||
|
loading();
|
||||||
|
return;
|
||||||
|
}
|
||||||
update(row).then(
|
update(row).then(
|
||||||
() => {
|
() => {
|
||||||
this.$message({
|
this.$message({
|
||||||
@@ -288,6 +581,10 @@ export default {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
rowDel(row, index, done) {
|
rowDel(row, index, done) {
|
||||||
|
if (this.isRootDept(row)) {
|
||||||
|
this.$message.warning('根节点不能删除');
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$confirm('确定将选择数据删除?', {
|
this.$confirm('确定将选择数据删除?', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@@ -310,13 +607,22 @@ export default {
|
|||||||
this.$message.warning('请选择至少一条数据');
|
this.$message.warning('请选择至少一条数据');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const deletableRows = this.selectionList.filter(row => !this.isRootDept(row));
|
||||||
|
if (deletableRows.length === 0) {
|
||||||
|
this.$message.warning('根节点不能删除');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (deletableRows.length !== this.selectionList.length) {
|
||||||
|
this.$message.warning('根节点不能删除,已忽略根节点');
|
||||||
|
}
|
||||||
|
const deletableIds = deletableRows.map(row => row.id).join(',');
|
||||||
this.$confirm('确定将选择数据删除?', {
|
this.$confirm('确定将选择数据删除?', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return remove(this.ids);
|
return remove(deletableIds);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// 刷新表格数据并重载
|
// 刷新表格数据并重载
|
||||||
@@ -355,6 +661,7 @@ export default {
|
|||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
this.form.tenantId = this.form.tenantId || this.userInfo.tenantId || website.tenantId;
|
this.form.tenantId = this.form.tenantId || this.userInfo.tenantId || website.tenantId;
|
||||||
this.initData(this.form.tenantId);
|
this.initData(this.form.tenantId);
|
||||||
|
this.loadParentDeptCode(this.form.parentId);
|
||||||
}
|
}
|
||||||
if (type === 'edit') {
|
if (type === 'edit') {
|
||||||
this.initData(this.form.tenantId || this.userInfo.tenantId || website.tenantId);
|
this.initData(this.form.tenantId || this.userInfo.tenantId || website.tenantId);
|
||||||
@@ -367,6 +674,7 @@ export default {
|
|||||||
if (this.form.parentId === '0') {
|
if (this.form.parentId === '0') {
|
||||||
this.form.parentId = '';
|
this.form.parentId = '';
|
||||||
}
|
}
|
||||||
|
this.loadParentDeptCode(this.form.parentId);
|
||||||
if (this.form.hasOwnProperty('leaderId')) {
|
if (this.form.hasOwnProperty('leaderId')) {
|
||||||
this.form.leaderId = func.split(this.form.leaderId);
|
this.form.leaderId = func.split(this.form.leaderId);
|
||||||
}
|
}
|
||||||
@@ -376,6 +684,8 @@ export default {
|
|||||||
},
|
},
|
||||||
beforeClose(done) {
|
beforeClose(done) {
|
||||||
this.parentId = '';
|
this.parentId = '';
|
||||||
|
this.parentDeptCode = '';
|
||||||
|
this.parentDept = null;
|
||||||
const column = this.findColumn(this.option.column, 'parentId');
|
const column = this.findColumn(this.option.column, 'parentId');
|
||||||
column.value = '';
|
column.value = '';
|
||||||
column.addDisabled = false;
|
column.addDisabled = false;
|
||||||
@@ -408,4 +718,15 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style></style>
|
<style scoped>
|
||||||
|
.carrier-search-form {
|
||||||
|
padding: 12px 12px 4px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carrier-pagination {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
v-if="permission.user_add && !auditMode"
|
v-if="permission.user_add && !auditMode"
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
@click="$refs.crud.rowAdd()"
|
@click="openUserDialog('add')"
|
||||||
>新 增
|
>新 增
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
<el-link
|
<el-link
|
||||||
type="primary"
|
type="primary"
|
||||||
v-if="this.permission.user_edit"
|
v-if="this.permission.user_edit"
|
||||||
@click.stop="$refs.crud.rowEdit(row, index)"
|
@click.stop="openUserDialog('edit', row)"
|
||||||
>编辑
|
>编辑
|
||||||
</el-link>
|
</el-link>
|
||||||
<el-dropdown @command="command => handleDropdownCommand(command, row, index)">
|
<el-dropdown @command="command => handleDropdownCommand(command, row, index)">
|
||||||
@@ -147,12 +147,6 @@
|
|||||||
<el-dropdown-item command="grantRole" v-if="permission.user_role">
|
<el-dropdown-item command="grantRole" v-if="permission.user_role">
|
||||||
角色配置
|
角色配置
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
|
||||||
command="platformConfig"
|
|
||||||
v-if="userInfo.authority.includes('admin')"
|
|
||||||
>
|
|
||||||
平台配置
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="authLog" v-if="userInfo.authority.includes('admin')">
|
<el-dropdown-item command="authLog" v-if="userInfo.authority.includes('admin')">
|
||||||
认证日志
|
认证日志
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
@@ -172,20 +166,62 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
<template #tenantName="{ row }">
|
|
||||||
<el-tag>{{ row.tenantName }}</el-tag>
|
|
||||||
</template>
|
|
||||||
<template #roleName="{ row }">
|
<template #roleName="{ row }">
|
||||||
<el-tag>{{ row.roleName }}</el-tag>
|
<el-tag>{{ row.roleName }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #deptName="{ row }">
|
<template #deptName="{ row }">
|
||||||
<el-tag>{{ row.deptName }}</el-tag>
|
<el-tag>{{ row.deptName }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #userTypeName="{ row }">
|
|
||||||
<el-tag>{{ row.userTypeName }}</el-tag>
|
|
||||||
</template>
|
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="userDialog"
|
||||||
|
:title="userDialogMode === 'add' ? '新增用户' : '编辑用户'"
|
||||||
|
width="90%"
|
||||||
|
top="5vh"
|
||||||
|
append-to-body
|
||||||
|
destroy-on-close
|
||||||
|
class="user-edit-dialog"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<span class="dialog-title">{{ userDialogMode === 'add' ? '新增用户' : '编辑用户' }}</span>
|
||||||
|
</template>
|
||||||
|
<el-form ref="userFormRef" :model="form" :rules="userRules" label-position="right" label-width="120px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6"><el-form-item label="账号名" prop="account"><el-input v-model="form.account" /></el-form-item></el-col>
|
||||||
|
<el-col :span="6"><el-form-item label="姓名" prop="realName"><el-input v-model="form.realName" /></el-form-item></el-col>
|
||||||
|
<el-col :span="6"><el-form-item label="手机号" prop="phone"><el-input v-model="form.phone" /></el-form-item></el-col>
|
||||||
|
<el-col :span="6"><el-form-item label="邮箱"><el-input v-model="form.email" /></el-form-item></el-col>
|
||||||
|
<el-col :span="6"><el-form-item label="性别"><el-select v-model="form.sex" class="full-width"><el-option label="男" :value="1" /><el-option label="女" :value="2" /><el-option label="未知" :value="3" /></el-select></el-form-item></el-col>
|
||||||
|
<el-col :span="6"><el-form-item label="岗位" prop="postId"><el-tree-select v-model="form.postId" :data="postList" :props="{ label: 'postName', value: 'id' }" check-strictly class="full-width" /></el-form-item></el-col>
|
||||||
|
<el-col :span="6"><el-form-item label="所属组织" prop="deptId"><el-tree-select v-model="form.deptId" :data="permissionDeptTree" :props="{ label: 'title', value: 'id' }" multiple check-strictly show-checkbox class="full-width" /></el-form-item></el-col>
|
||||||
|
<el-col :span="6"><el-form-item label="工号"><el-input v-model="form.code" /></el-form-item></el-col>
|
||||||
|
<el-col :span="6"><el-form-item label="人员类别"><el-select v-model="form.personCategory" class="full-width"><el-option label="内部员工" :value="1" /><el-option label="承运商" :value="2" /></el-select></el-form-item></el-col>
|
||||||
|
<el-col :span="18"><el-form-item label="数据权限范围"><el-radio-group v-model="form.dataScopeRange"><el-radio :value="1">仅所属组织</el-radio><el-radio :value="2">全部组织</el-radio><el-radio :value="3">自定义</el-radio></el-radio-group></el-form-item></el-col>
|
||||||
|
<el-col :span="18" :offset="6"><el-form-item label="数据层级范围"><el-radio-group v-model="form.dataLevelRange"><el-radio :value="1">包含下级</el-radio><el-radio :value="2">仅本级</el-radio></el-radio-group></el-form-item></el-col>
|
||||||
|
<el-col :span="24"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="200" show-word-limit /></el-form-item></el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<el-tabs class="user-permission-tabs">
|
||||||
|
<el-tab-pane label="已拥有角色">
|
||||||
|
<el-table :data="formRoleList" border>
|
||||||
|
<el-table-column type="index" label="序号" width="70" />
|
||||||
|
<el-table-column prop="id" label="角色编号" />
|
||||||
|
<el-table-column prop="title" label="角色名称" />
|
||||||
|
<el-table-column label="操作" width="90"><template #default="{ row }"><el-link type="danger" @click="removeFormRole(row.id)">删除</el-link></template></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane v-if="form.dataScopeRange === 3" label="数据权限">
|
||||||
|
<el-tree :data="permissionDeptTree" show-checkbox node-key="id" :default-checked-keys="form.dataScopeDeptIds || []" :props="{ label: 'title', children: 'children' }" @check="handleDataScopeCheck" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="客商权限">
|
||||||
|
<div class="permission-toolbar customer-toolbar"><el-checkbox v-model="form.includeNewCustomer" :true-value="1" :false-value="0">包含新增的客商</el-checkbox></div>
|
||||||
|
<el-table ref="customerTable" :data="customerList" border @selection-change="handleCustomerSelection"><el-table-column type="selection" width="55" /><el-table-column prop="customerCode" label="客商编码" /><el-table-column prop="fullName" label="客商名称" /></el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<template #footer><span class="dialog-footer"><el-button type="primary" @click="submitUserForm">保存</el-button><el-button @click="userDialog = false">返回</el-button><el-button v-if="userDialogMode === 'edit'" @click="resetDialogPassword">重置密码</el-button><el-button @click="handleAddRole">添加角色</el-button></span></template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 用户角色配置 -->
|
<!-- 用户角色配置 -->
|
||||||
<el-dialog title="用户角色配置" append-to-body v-model="roleBox" width="345px">
|
<el-dialog title="用户角色配置" append-to-body v-model="roleBox" width="345px">
|
||||||
<el-row
|
<el-row
|
||||||
@@ -200,8 +236,13 @@
|
|||||||
size="small"
|
size="small"
|
||||||
@change="handleLinkedChange('treeRole')"
|
@change="handleLinkedChange('treeRole')"
|
||||||
/>
|
/>
|
||||||
<el-tooltip content="开启后勾选父节点会自动勾选所有子节点,关闭则可独立勾选任意节点" placement="top">
|
<el-tooltip
|
||||||
<el-icon style="margin-left: 4px; color: #909399; cursor: pointer"><el-icon-question-filled /></el-icon>
|
content="开启后勾选父节点会自动勾选所有子节点,关闭则可独立勾选任意节点"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<el-icon style="margin-left: 4px; color: #909399; cursor: pointer"
|
||||||
|
><el-icon-question-filled
|
||||||
|
/></el-icon>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<el-button-group>
|
<el-button-group>
|
||||||
@@ -246,17 +287,6 @@
|
|||||||
</avue-form>
|
</avue-form>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 用户平台配置(行级别) -->
|
|
||||||
<el-dialog title="用户平台配置" append-to-body v-model="platformBox" width="600px">
|
|
||||||
<avue-form ref="platformFormRef" :option="platformFormOption" v-model="platformForm" />
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="platformBox = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="submitPlatformConfig">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 管理员修改密码 -->
|
<!-- 管理员修改密码 -->
|
||||||
<el-dialog title="修改密码" append-to-body v-model="passwordBox" width="460px">
|
<el-dialog title="修改密码" append-to-body v-model="passwordBox" width="460px">
|
||||||
<el-form
|
<el-form
|
||||||
@@ -265,7 +295,7 @@
|
|||||||
:rules="passwordRules"
|
:rules="passwordRules"
|
||||||
label-width="auto"
|
label-width="auto"
|
||||||
>
|
>
|
||||||
<el-form-item label="登录账号">
|
<el-form-item label="账号名">
|
||||||
<el-input v-model="passwordForm.account" disabled />
|
<el-input v-model="passwordForm.account" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="新密码" prop="password">
|
<el-form-item label="新密码" prop="password">
|
||||||
@@ -296,10 +326,8 @@
|
|||||||
import {
|
import {
|
||||||
getList,
|
getList,
|
||||||
getUser,
|
getUser,
|
||||||
getUserPlatform,
|
|
||||||
remove,
|
remove,
|
||||||
update,
|
update,
|
||||||
updatePlatform,
|
|
||||||
add,
|
add,
|
||||||
grant,
|
grant,
|
||||||
resetPassword,
|
resetPassword,
|
||||||
@@ -308,6 +336,7 @@ import {
|
|||||||
auditRefuse,
|
auditRefuse,
|
||||||
setLeader,
|
setLeader,
|
||||||
getLeaderList,
|
getLeaderList,
|
||||||
|
getCustomerOptions,
|
||||||
} from '@/api/system/user';
|
} from '@/api/system/user';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
@@ -315,14 +344,13 @@ import { getRoleTree } from '@/api/system/role';
|
|||||||
import { getPostList } from '@/api/system/post';
|
import { getPostList } from '@/api/system/post';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
import website from '@/config/website';
|
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
import func from '@/utils/func';
|
import func from '@/utils/func';
|
||||||
import { sensitive } from '@/utils/sensitive';
|
import { sensitive } from '@/utils/sensitive';
|
||||||
import { excelOption, platformFormOption, treeOption, userOption } from '@/option/system/user';
|
import { excelOption, treeOption, userOption } from '@/option/system/user';
|
||||||
import AuthLog from './authlog.vue';
|
import AuthLog from './authlog.vue';
|
||||||
import AuthLock from './authlock.vue';
|
import AuthLock from './authlock.vue';
|
||||||
|
|
||||||
@@ -331,13 +359,15 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
userDialog: false,
|
||||||
|
userDialogMode: 'add',
|
||||||
search: {},
|
search: {},
|
||||||
sensitiveManager: null,
|
sensitiveManager: null,
|
||||||
roleBox: false,
|
roleBox: false,
|
||||||
roleLinked: false,
|
roleLinked: false,
|
||||||
|
roleFormMode: false,
|
||||||
grantUserId: '',
|
grantUserId: '',
|
||||||
excelBox: false,
|
excelBox: false,
|
||||||
platformBox: false,
|
|
||||||
passwordBox: false,
|
passwordBox: false,
|
||||||
initFlag: true,
|
initFlag: true,
|
||||||
auditMode: false,
|
auditMode: false,
|
||||||
@@ -357,11 +387,12 @@ export default {
|
|||||||
roleTreeObj: [],
|
roleTreeObj: [],
|
||||||
treeDeptId: '',
|
treeDeptId: '',
|
||||||
treeData: [],
|
treeData: [],
|
||||||
|
permissionDeptTree: [],
|
||||||
|
postList: [],
|
||||||
|
customerList: [],
|
||||||
treeOption: treeOption,
|
treeOption: treeOption,
|
||||||
userOption: userOption(this),
|
userOption: userOption(this),
|
||||||
platformFormOption: platformFormOption,
|
|
||||||
data: [],
|
data: [],
|
||||||
platformForm: {},
|
|
||||||
passwordForm: {},
|
passwordForm: {},
|
||||||
passwordRules: {
|
passwordRules: {
|
||||||
password: [
|
password: [
|
||||||
@@ -373,16 +404,17 @@ export default {
|
|||||||
{ validator: this.validatePassword2, trigger: 'blur' },
|
{ validator: this.validatePassword2, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
userRules: {
|
||||||
|
account: [{ required: true, message: '请输入账号名', trigger: 'blur' }],
|
||||||
|
realName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||||
|
phone: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
|
||||||
|
deptId: [{ required: true, message: '请选择所属组织', trigger: 'change' }],
|
||||||
|
},
|
||||||
excelForm: {},
|
excelForm: {},
|
||||||
excelOption: excelOption,
|
excelOption: excelOption,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'form.tenantId'() {
|
|
||||||
if (this.form.tenantId !== '' && this.initFlag) {
|
|
||||||
this.initData(this.form.tenantId);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'excelForm.isCovered'() {
|
'excelForm.isCovered'() {
|
||||||
if (this.excelForm.isCovered !== '') {
|
if (this.excelForm.isCovered !== '') {
|
||||||
const column = this.findColumn(this.excelOption.column, 'excelFile');
|
const column = this.findColumn(this.excelOption.column, 'excelFile');
|
||||||
@@ -407,14 +439,20 @@ export default {
|
|||||||
});
|
});
|
||||||
return ids.join(',');
|
return ids.join(',');
|
||||||
},
|
},
|
||||||
|
formRoleList() {
|
||||||
|
const selected = new Set(func.split(this.form.roleId || '').map(String));
|
||||||
|
const roles = [];
|
||||||
|
const walk = nodes =>
|
||||||
|
(nodes || []).forEach(node => {
|
||||||
|
if (selected.has(String(node.id))) roles.push(node);
|
||||||
|
walk(node.children);
|
||||||
|
});
|
||||||
|
walk(this.roleGrantList);
|
||||||
|
return roles;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// 非租户模式默认加载管理组数据
|
this.initData(this.userInfo.tenantId || this.website.tenantId);
|
||||||
if (!website.tenantMode) {
|
|
||||||
this.initData(website.tenantId);
|
|
||||||
} else {
|
|
||||||
this.initData();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 创建脱敏工具实例
|
// 创建脱敏工具实例
|
||||||
@@ -437,8 +475,6 @@ export default {
|
|||||||
this.$refs.authLog.openUserAuthLog(row.id, row.name);
|
this.$refs.authLog.openUserAuthLog(row.id, row.name);
|
||||||
} else if (command === 'lockUser') {
|
} else if (command === 'lockUser') {
|
||||||
this.$refs.authLock.openLockUser(row.id, row.account);
|
this.$refs.authLock.openLockUser(row.id, row.account);
|
||||||
} else if (command === 'platformConfig') {
|
|
||||||
this.handlePlatformForRow(row);
|
|
||||||
} else if (command === 'resetPassword') {
|
} else if (command === 'resetPassword') {
|
||||||
this.handleResetForRow(row);
|
this.handleResetForRow(row);
|
||||||
} else if (command === 'setPassword') {
|
} else if (command === 'setPassword') {
|
||||||
@@ -488,14 +524,17 @@ export default {
|
|||||||
},
|
},
|
||||||
initData(tenantId) {
|
initData(tenantId) {
|
||||||
getRoleTree(tenantId).then(res => {
|
getRoleTree(tenantId).then(res => {
|
||||||
|
this.roleGrantList = res.data.data;
|
||||||
const column = this.findColumn(this.userOption.group, 'roleId');
|
const column = this.findColumn(this.userOption.group, 'roleId');
|
||||||
column.dicData = res.data.data;
|
column.dicData = res.data.data;
|
||||||
});
|
});
|
||||||
getDeptTree(tenantId).then(res => {
|
getDeptTree(tenantId).then(res => {
|
||||||
|
this.permissionDeptTree = res.data.data;
|
||||||
const column = this.findColumn(this.userOption.group, 'deptId');
|
const column = this.findColumn(this.userOption.group, 'deptId');
|
||||||
column.dicData = res.data.data;
|
column.dicData = res.data.data;
|
||||||
});
|
});
|
||||||
getPostList(tenantId).then(res => {
|
getPostList(tenantId).then(res => {
|
||||||
|
this.postList = res.data.data;
|
||||||
const column = this.findColumn(this.userOption.group, 'postId');
|
const column = this.findColumn(this.userOption.group, 'postId');
|
||||||
column.dicData = res.data.data;
|
column.dicData = res.data.data;
|
||||||
});
|
});
|
||||||
@@ -503,9 +542,18 @@ export default {
|
|||||||
const column = this.findColumn(this.userOption.group, 'leaderId');
|
const column = this.findColumn(this.userOption.group, 'leaderId');
|
||||||
column.dicData = res.data.data;
|
column.dicData = res.data.data;
|
||||||
});
|
});
|
||||||
|
getCustomerOptions().then(res => {
|
||||||
|
this.customerList = res.data.data || [];
|
||||||
|
});
|
||||||
},
|
},
|
||||||
submitRole() {
|
submitRole() {
|
||||||
const roleList = this.$refs.treeRole.getCheckedKeys().join(',');
|
const roleList = this.$refs.treeRole.getCheckedKeys().join(',');
|
||||||
|
if (this.roleFormMode) {
|
||||||
|
this.form.roleId = roleList;
|
||||||
|
this.roleBox = false;
|
||||||
|
this.roleFormMode = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
grant(this.grantUserId, roleList).then(() => {
|
grant(this.grantUserId, roleList).then(() => {
|
||||||
this.roleBox = false;
|
this.roleBox = false;
|
||||||
this.$message({
|
this.$message({
|
||||||
@@ -515,6 +563,98 @@ export default {
|
|||||||
this.onLoad(this.page);
|
this.onLoad(this.page);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleAddRole() {
|
||||||
|
this.roleFormMode = true;
|
||||||
|
this.roleTreeObj = func.split(this.form.roleId || '');
|
||||||
|
this.roleLinked = false;
|
||||||
|
getRoleTree(this.userInfo.tenantId).then(res => {
|
||||||
|
this.roleGrantList = res.data.data;
|
||||||
|
this.roleBox = true;
|
||||||
|
this.$nextTick(() => this.applyCheckedKeys('treeRole', this.roleTreeObj));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeFormRole(roleId) {
|
||||||
|
this.form.roleId = func
|
||||||
|
.split(this.form.roleId || '')
|
||||||
|
.filter(id => String(id) !== String(roleId));
|
||||||
|
},
|
||||||
|
handleDataScopeCheck(_, checked) {
|
||||||
|
this.form.dataScopeDeptIds = checked.checkedKeys;
|
||||||
|
},
|
||||||
|
handleCustomerSelection(rows) {
|
||||||
|
this.form.customerIds = rows.map(row => row.id);
|
||||||
|
},
|
||||||
|
openUserDialog(mode, row = {}) {
|
||||||
|
this.userDialogMode = mode;
|
||||||
|
if (mode === 'add') {
|
||||||
|
this.form = {
|
||||||
|
account: '',
|
||||||
|
realName: '',
|
||||||
|
phone: '',
|
||||||
|
email: '',
|
||||||
|
sex: 3,
|
||||||
|
postId: '',
|
||||||
|
deptId: [],
|
||||||
|
code: '',
|
||||||
|
personCategory: 1,
|
||||||
|
dataScopeRange: 1,
|
||||||
|
dataLevelRange: 1,
|
||||||
|
remark: '',
|
||||||
|
roleId: '',
|
||||||
|
dataScopeDeptIds: [],
|
||||||
|
customerIds: [],
|
||||||
|
includeNewCustomer: 0,
|
||||||
|
};
|
||||||
|
this.userDialog = true;
|
||||||
|
this.$nextTick(() => this.$refs.userFormRef && this.$refs.userFormRef.clearValidate());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getUser(row.id).then(res => {
|
||||||
|
const user = res.data.data;
|
||||||
|
this.form = {
|
||||||
|
...user,
|
||||||
|
deptId: func.split(user.deptId || ''),
|
||||||
|
postId: func.split(user.postId || '')[0] || '',
|
||||||
|
roleId: func.join(user.roleId || ''),
|
||||||
|
dataScopeDeptIds: user.dataScopeDeptIds || [],
|
||||||
|
customerIds: user.customerIds || [],
|
||||||
|
includeNewCustomer: user.includeNewCustomer || 0,
|
||||||
|
personCategory: user.personCategory || 1,
|
||||||
|
dataScopeRange: user.dataScopeRange || 1,
|
||||||
|
dataLevelRange: user.dataLevelRange || 1,
|
||||||
|
};
|
||||||
|
this.sensitiveManager.saveInitialData(this.form);
|
||||||
|
this.userDialog = true;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.userFormRef && this.$refs.userFormRef.clearValidate();
|
||||||
|
(this.form.customerIds || []).forEach(id => {
|
||||||
|
const customer = this.customerList.find(item => String(item.id) === String(id));
|
||||||
|
if (customer) this.$refs.customerTable && this.$refs.customerTable.toggleRowSelection(customer, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submitUserForm() {
|
||||||
|
this.$refs.userFormRef.validate(valid => {
|
||||||
|
if (!valid) return;
|
||||||
|
const row = {
|
||||||
|
...this.form,
|
||||||
|
deptId: func.join(this.form.deptId),
|
||||||
|
postId: func.join(this.form.postId),
|
||||||
|
roleId: func.join(this.form.roleId),
|
||||||
|
leaderId: func.join(this.form.leaderId),
|
||||||
|
};
|
||||||
|
const request = this.userDialogMode === 'add' ? add(row) : update(this.sensitiveManager.getSubmitData(row));
|
||||||
|
request.then(() => {
|
||||||
|
this.userDialog = false;
|
||||||
|
this.onLoad(this.page);
|
||||||
|
this.$message.success('操作成功!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetDialogPassword() {
|
||||||
|
this.handleResetForRow(this.form);
|
||||||
|
},
|
||||||
rowSave(row, done, loading) {
|
rowSave(row, done, loading) {
|
||||||
row.deptId = func.join(row.deptId);
|
row.deptId = func.join(row.deptId);
|
||||||
row.roleId = func.join(row.roleId);
|
row.roleId = func.join(row.roleId);
|
||||||
@@ -779,23 +919,6 @@ export default {
|
|||||||
if (!tree) return;
|
if (!tree) return;
|
||||||
tree.setCheckedKeys(keys);
|
tree.setCheckedKeys(keys);
|
||||||
},
|
},
|
||||||
// ========== 平台配置(行级别) ==========
|
|
||||||
handlePlatformForRow(row) {
|
|
||||||
getUserPlatform(row.id).then(res => {
|
|
||||||
this.platformForm = { ...res.data.data, account: row.account };
|
|
||||||
this.platformBox = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submitPlatformConfig() {
|
|
||||||
updatePlatform(
|
|
||||||
this.platformForm.id,
|
|
||||||
this.platformForm.userType,
|
|
||||||
this.platformForm.userExt
|
|
||||||
).then(() => {
|
|
||||||
this.platformBox = false;
|
|
||||||
this.$message({ type: 'success', message: '操作成功!' });
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handlePasswordForRow(row) {
|
handlePasswordForRow(row) {
|
||||||
this.passwordForm = {
|
this.passwordForm = {
|
||||||
userId: row.id,
|
userId: row.id,
|
||||||
@@ -902,12 +1025,11 @@ export default {
|
|||||||
},
|
},
|
||||||
onLoad(page, params = {}) {
|
onLoad(page, params = {}) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getList(
|
const queryParams = { ...this.query, ...params };
|
||||||
page.currentPage,
|
if (this.auditMode) {
|
||||||
page.pageSize,
|
queryParams.status = 0;
|
||||||
Object.assign(params, this.query, { status: this.auditMode ? 0 : 1 }),
|
}
|
||||||
this.treeDeptId
|
getList(page.currentPage, page.pageSize, queryParams, this.treeDeptId).then(res => {
|
||||||
).then(res => {
|
|
||||||
const data = res.data.data;
|
const data = res.data.data;
|
||||||
this.page.total = data.total;
|
this.page.total = data.total;
|
||||||
this.data = data.records;
|
this.data = data.records;
|
||||||
@@ -931,4 +1053,62 @@ export default {
|
|||||||
.box .el-scrollbar__wrap {
|
.box .el-scrollbar__wrap {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-permission-tabs {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-edit-dialog .dialog-title {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-edit-dialog .dialog-title::before {
|
||||||
|
width: 4px;
|
||||||
|
height: 18px;
|
||||||
|
margin-right: 8px;
|
||||||
|
background: #409eff;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-edit-dialog .el-form-item {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-edit-dialog .el-form-item__label {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-edit-dialog .el-radio-group {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-permission-tabs .el-tabs__header {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-toolbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customer-toolbar {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avue-dialog .el-form-item__label {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avue-dialog .el-radio-group {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
90
src/views/transportCapacity/components/ship-ledger.vue
Normal file
90
src/views/transportCapacity/components/ship-ledger.vue
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :model-value="modelValue" title="船舶综合台账" width="96%" top="3vh" append-to-body destroy-on-close @update:model-value="$emit('update:modelValue', $event)">
|
||||||
|
<div v-loading="detailLoading" class="ship-ledger">
|
||||||
|
<section v-for="section in sections" :key="section.title" class="ship-ledger__section">
|
||||||
|
<div class="dialog-section-title">{{ section.title }}</div>
|
||||||
|
<el-descriptions :column="3" border>
|
||||||
|
<el-descriptions-item v-for="item in section.items" :key="item.label" :label="item.label">
|
||||||
|
{{ display(item) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</section>
|
||||||
|
<section class="ship-ledger__section">
|
||||||
|
<div class="dialog-section-title">证书附件</div>
|
||||||
|
<div class="ship-ledger__images">
|
||||||
|
<div v-for="item in imageFields" :key="item.prop" class="ship-ledger__image-item">
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
<el-image v-if="shipDetail[item.prop]" :src="shipDetail[item.prop]" :preview-src-list="imageUrls" preview-teleported fit="cover" />
|
||||||
|
<el-empty v-else :image-size="36" description="暂无附件" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<el-tabs v-model="activeTab" @tab-change="loadRecords">
|
||||||
|
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.label" :name="tab.name" />
|
||||||
|
</el-tabs>
|
||||||
|
<el-table v-loading="tableLoading" :data="records" border stripe>
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||||
|
<el-table-column v-for="column in activeColumns" :key="column.prop" :prop="column.prop" :label="column.label" :min-width="column.width || 140" show-overflow-tooltip />
|
||||||
|
</el-table>
|
||||||
|
<div class="ship-ledger__pagination"><el-pagination v-model:current-page="page.current" v-model:page-size="page.size" :page-sizes="[10, 20, 50]" :total="page.total" layout="total, sizes, prev, pager, next" @size-change="handlePageChange" @current-change="loadRecords" /></div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getDetail } from '@/api/transportCapacity/transport-ship';
|
||||||
|
import { getList as insurance } from '@/api/vehicle/insurance-record';
|
||||||
|
import { getList as violation } from '@/api/vehicle/violation-record';
|
||||||
|
import { getList as maintenance } from '@/api/vehicle/maintenance-record';
|
||||||
|
import { getList as maintenancePlan } from '@/api/vehicle/maintenance-plan';
|
||||||
|
import { getList as accident } from '@/api/vehicle/accident-record';
|
||||||
|
import { getList as annualInspection } from '@/api/vehicle/annual-inspection-record';
|
||||||
|
import { getList as change } from '@/api/vehicle/transport-change-record';
|
||||||
|
import { getList as oilElectric } from '@/api/vehicle/oil-electric-record';
|
||||||
|
import { getList as otherExpense } from '@/api/vehicle/other-expense-record';
|
||||||
|
|
||||||
|
const columns = (...items) => items.map(([label, prop]) => ({ label, prop }));
|
||||||
|
const tabConfigs = [
|
||||||
|
['insurance', '保险记录', insurance, columns(['船号', 'vehicleNo'], ['保险类型', 'insuranceType'], ['开始日期', 'startDate'], ['结束日期', 'endDate'], ['保费', 'premium'], ['保单号', 'policyNo'])],
|
||||||
|
['violation', '违章记录', violation, columns(['船号', 'vehicleNo'], ['驾驶人/船长', 'driverName'], ['类型', 'violationType'], ['事项', 'violationItem'], ['违章时间', 'violationTime'], ['罚款金额', 'fineAmount'])],
|
||||||
|
['maintenance', '维修记录', maintenance, columns(['船号', 'vehicleNo'], ['维修人', 'maintainer'], ['维修时间', 'maintenanceTime'], ['维修位置', 'location'], ['费用', 'cost'])],
|
||||||
|
['maintenancePlan', '保养记录', maintenancePlan, columns(['船号', 'vehicleNo'], ['保养人', 'maintainer'], ['保养时间', 'maintenanceTime'], ['保养项目', 'maintenanceItem'], ['费用', 'cost'])],
|
||||||
|
['accident', '事故记录', accident, columns(['船号', 'vehicleNo'], ['事故时间', 'accidentTime'], ['事故地点', 'accidentLocation'], ['事故类型', 'accidentType'], ['损失金额', 'lossAmount'])],
|
||||||
|
['annualInspection', '年检记录', annualInspection, columns(['船号', 'vehicleNo'], ['年检日期', 'inspectionDate'], ['年检有效期至', 'inspectionEndDate'], ['年检机构', 'inspectionOrganization'], ['费用', 'cost'])],
|
||||||
|
['change', '变更记录', change, columns(['船号', 'vehicleNo'], ['变更类型', 'changeType'], ['变更时间', 'changeTime'], ['变更前内容', 'beforeChange'], ['变更后内容', 'afterChange'])],
|
||||||
|
['equipment', '设备台账', null, columns(['设备编码', 'equipmentCode'], ['设备名称', 'equipmentName'], ['设备类型', 'equipmentType'], ['安装日期', 'installDate'], ['状态', 'status'])],
|
||||||
|
['oilElectric', '油电台账', oilElectric, columns(['船号', 'vehicleNo'], ['加油/充电日期', 'recordDate'], ['类型', 'energyType'], ['数量', 'quantity'], ['金额', 'amount'])],
|
||||||
|
['otherExpense', '其他费用记录', otherExpense, columns(['船号', 'vehicleNo'], ['费用日期', 'expenseDate'], ['费用类型', 'expenseType'], ['金额', 'amount'], ['备注', 'remark'])],
|
||||||
|
].map(([name, label, request, cols]) => ({ name, label, request, columns: cols }));
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: { modelValue: Boolean, ship: { type: Object, default: () => ({}) } }, emits: ['update:modelValue'],
|
||||||
|
data() { return { detailLoading: false, tableLoading: false, shipDetail: {}, activeTab: 'insurance', records: [], page: { current: 1, size: 10, total: 0 } }; },
|
||||||
|
computed: {
|
||||||
|
tabs() { return tabConfigs; }, activeConfig() { return tabConfigs.find(item => item.name === this.activeTab) || tabConfigs[0]; }, activeColumns() { return this.activeConfig.columns; },
|
||||||
|
imageFields() { return [['船舶所有权证书', 'ownershipCertImage'], ['内河船舶安全与环保证书', 'safetyCertImage'], ['船舶国籍证书', 'nationalityCertImage'], ['最低安全配员证书', 'safeManningCertImage'], ['船舶营业运输证', 'businessTransportCertImage'], ['光船租赁登记证书', 'leaseContractImage']].map(([label, prop]) => ({ label, prop })); },
|
||||||
|
imageUrls() { return this.imageFields.map(item => this.shipDetail[item.prop]).filter(Boolean); },
|
||||||
|
sections() { const s = this.shipDetail; return [
|
||||||
|
{ title: '船舶基本信息', items: [['船舶所属组织', 'organizationName'], ['船名', 'shipName'], ['安放龙骨日期/建造完工日期', 'constructionDate'], ['总长(m)', 'totalLength'], ['船宽(m)', 'shipWidth'], ['型深(m)', 'moldedDepth'], ['最大船高(m)', 'maxShipHeight'], ['空载吃水(t)', 'lightDraft'], ['满载吃水(t)', 'fullLoadDraft'], ['航区', 'navigationArea']] },
|
||||||
|
{ title: '船舶证书信息', items: [['登记号码', 'ownershipRegistrationNo'], ['初次登记号码', 'initialRegistrationNo'], ['船舶所有人', 'shipOwner'], ['取得所有权日期', 'ownershipAcquisitionDate'], ['船舶识别号', 'shipIdentifierNo'], ['总吨', 'grossTonnage'], ['净吨', 'netTonnage'], ['船检登记号', 'shipInspectionNo'], ['船舶类型', 'shipType'], ['国籍证书有效期', 'nationalityCertDate'], ['最低安全配员证书有效期', 'safeManningCertDate'], ['起租日期', 'leaseStartDate'], ['终止日期', 'leaseEndDate'], ['船舶承租人', 'shipLessee'], ['营业运输证证书编号', 'businessTransportCertNo'], ['营业运输证发证日期', 'businessTransportCertIssueDate'], ['营业运输证有效期至', 'businessTransportCertEndDate'], ['船舶经营人', 'shipOperator']] },
|
||||||
|
].map(section => ({ ...section, items: section.items.map(([label, prop]) => ({ label, prop, value: prop === 'constructionDate' ? `${s.keelLayingDate || '-'} / ${s.buildCompletionDate || '-'}` : prop === 'nationalityCertDate' ? `${s.nationalityCertStartDate || '-'} 至 ${s.nationalityCertEndDate || '-'}` : prop === 'safeManningCertDate' ? `${s.safeManningCertStartDate || '-'} 至 ${s.safeManningCertEndDate || '-'}` : s[prop] })) })); },
|
||||||
|
},
|
||||||
|
watch: { modelValue(value) { if (value) this.initialize(); } },
|
||||||
|
methods: {
|
||||||
|
display(item) { return item.value === null || item.value === undefined || item.value === '' ? '-' : item.value; },
|
||||||
|
async initialize() { this.activeTab = 'insurance'; this.page.current = 1; this.shipDetail = { ...this.ship }; if (this.ship.id) { this.detailLoading = true; try { const res = await getDetail(this.ship.id); this.shipDetail = { ...this.ship, ...(res.data.data || {}) }; } finally { this.detailLoading = false; } } this.loadRecords(); },
|
||||||
|
async loadRecords() { const { request } = this.activeConfig; if (!request) { this.records = []; this.page.total = 0; return; } this.tableLoading = true; try { const res = await request(this.page.current, this.page.size, { vehicleNo: this.shipDetail.shipName || this.ship.shipName, vehicleType: '船舶' }); const data = res.data.data || {}; this.records = data.records || []; this.page.total = data.total || 0; } finally { this.tableLoading = false; } },
|
||||||
|
handlePageChange() { this.page.current = 1; this.loadRecords(); },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.ship-ledger__section { margin-bottom: 16px; }
|
||||||
|
.ship-ledger__images { display: flex; gap: 16px; overflow-x: auto; padding: 12px 0; }
|
||||||
|
.ship-ledger__image-item { width: 150px; flex: 0 0 150px; text-align: center; color: #606266; }
|
||||||
|
.ship-ledger__image-item > span { display: block; margin-bottom: 8px; }
|
||||||
|
.ship-ledger__image-item :deep(.el-image) { width: 150px; height: 110px; border: 1px solid #eff1f7; }
|
||||||
|
.ship-ledger__image-item :deep(.el-empty) { height: 110px; border: 1px solid #eff1f7; }
|
||||||
|
.ship-ledger__pagination { display: flex; justify-content: flex-end; margin-top: 16px; }
|
||||||
|
</style>
|
||||||
141
src/views/transportCapacity/components/vehicle-ledger.vue
Normal file
141
src/views/transportCapacity/components/vehicle-ledger.vue
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:model-value="modelValue"
|
||||||
|
title="车辆综合台账"
|
||||||
|
width="96%"
|
||||||
|
top="3vh"
|
||||||
|
append-to-body
|
||||||
|
destroy-on-close
|
||||||
|
@update:model-value="$emit('update:modelValue', $event)"
|
||||||
|
>
|
||||||
|
<div v-loading="detailLoading" class="vehicle-ledger">
|
||||||
|
<section class="vehicle-ledger__overview">
|
||||||
|
<div class="vehicle-ledger__title">
|
||||||
|
<span>{{ vehicleDetail.plateNo || vehicle.plateNo }}</span>
|
||||||
|
<el-tag :type="plateColorType">{{ vehicleDetail.plateColor || '-' }}</el-tag>
|
||||||
|
<el-tag type="primary">{{ vehicleDetail.businessRelation || '-' }}</el-tag>
|
||||||
|
</div>
|
||||||
|
<el-descriptions :column="4" border>
|
||||||
|
<el-descriptions-item label="所属组织">{{ vehicleDetail.organizationName || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="车辆类型">{{ vehicleDetail.vehicleType || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="能源类型">{{ vehicleDetail.energyType || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="外廓尺寸(mm)">{{ dimensions }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="核定载质量(KG)">{{ vehicleDetail.approvedLoadKg ?? '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="准牵引总质量(KG)">{{ vehicleDetail.tractionMassKg ?? '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="行驶证档案编号">{{ vehicleDetail.drivingLicenseNo || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="道路运输证号">{{ vehicleDetail.roadTransportCertNo || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="行驶证有效期">{{ vehicleDetail.drivingLicenseEndDate || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="道路运输证有效期">{{ vehicleDetail.roadTransportCertEndDate || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="道路运输证年审有效期">{{ vehicleDetail.annualReviewEndDate || '-' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<div class="vehicle-ledger__images">
|
||||||
|
<div v-for="item in imageFields" :key="item.prop" class="vehicle-ledger__image-item">
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
<el-image
|
||||||
|
v-if="vehicleDetail[item.prop]"
|
||||||
|
:src="vehicleDetail[item.prop]"
|
||||||
|
:preview-src-list="imageUrls"
|
||||||
|
preview-teleported
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
<el-empty v-else :image-size="36" description="暂无图片" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<el-tabs v-model="activeTab" class="vehicle-ledger__tabs" @tab-change="loadRecords">
|
||||||
|
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.label" :name="tab.name" />
|
||||||
|
</el-tabs>
|
||||||
|
<el-table v-loading="tableLoading" :data="records" border stripe>
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||||
|
<el-table-column
|
||||||
|
v-for="column in activeColumns"
|
||||||
|
:key="column.prop"
|
||||||
|
:prop="column.prop"
|
||||||
|
:label="column.label"
|
||||||
|
:min-width="column.width || 140"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
<div class="vehicle-ledger__pagination">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="page.current"
|
||||||
|
v-model:page-size="page.size"
|
||||||
|
:page-sizes="[10, 20, 50]"
|
||||||
|
:total="page.total"
|
||||||
|
layout="total, sizes, prev, pager, next"
|
||||||
|
@size-change="handlePageChange"
|
||||||
|
@current-change="loadRecords"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getDetail } from '@/api/transportCapacity/transport-vehicle';
|
||||||
|
import { getList as getInsuranceList } from '@/api/vehicle/insurance-record';
|
||||||
|
import { getList as getViolationList } from '@/api/vehicle/violation-record';
|
||||||
|
import { getList as getMaintenanceList } from '@/api/vehicle/maintenance-record';
|
||||||
|
import { getList as getMaintenancePlanList } from '@/api/vehicle/maintenance-plan';
|
||||||
|
import { getList as getTireList } from '@/api/vehicle/tire-replacement-record';
|
||||||
|
import { getList as getAccidentList } from '@/api/vehicle/accident-record';
|
||||||
|
import { getList as getAnnualInspectionList } from '@/api/vehicle/annual-inspection-record';
|
||||||
|
import { getList as getMileageList } from '@/api/vehicle/mileage-record';
|
||||||
|
import { getList as getChangeList } from '@/api/vehicle/transport-change-record';
|
||||||
|
import { getList as getOilElectricList } from '@/api/vehicle/oil-electric-record';
|
||||||
|
import { getList as getEtcList } from '@/api/vehicle/etc-record';
|
||||||
|
import { getList as getOtherExpenseList } from '@/api/vehicle/other-expense-record';
|
||||||
|
|
||||||
|
const cols = (...items) => items.map(([label, prop, width]) => ({ label, prop, width }));
|
||||||
|
const tabConfigs = [
|
||||||
|
['insurance', '保险记录', getInsuranceList, cols(['车牌号', 'vehicleNo'], ['保险类型', 'insuranceType'], ['开始日期', 'startDate'], ['结束日期', 'endDate'], ['保费', 'premium'], ['保单号', 'policyNo'])],
|
||||||
|
['violation', '违章记录', getViolationList, cols(['车牌号', 'vehicleNo'], ['驾驶人', 'driverName'], ['类型', 'violationType'], ['事项', 'violationItem'], ['违章时间', 'violationTime'], ['罚款金额', 'fineAmount'])],
|
||||||
|
['maintenance', '维修记录', getMaintenanceList, cols(['车牌号', 'vehicleNo'], ['维修人', 'maintainer'], ['维修时间', 'maintenanceTime'], ['维修位置', 'location'], ['费用', 'cost'], ['维修单位', 'company'])],
|
||||||
|
['maintenancePlan', '保养记录', getMaintenancePlanList, cols(['车牌号', 'vehicleNo'], ['保养人', 'maintainer'], ['保养时间', 'maintenanceTime'], ['保养项目', 'maintenanceItem'], ['费用', 'cost'], ['下次保养时间', 'nextMaintenanceTime'])],
|
||||||
|
['tire', '换胎记录', getTireList, cols(['车牌号', 'vehicleNo'], ['更换时间', 'replacementTime'], ['轮胎品牌', 'tireBrand'], ['轮胎规格', 'tireSpec'], ['费用', 'cost'])],
|
||||||
|
['accident', '事故记录', getAccidentList, cols(['车牌号', 'vehicleNo'], ['事故时间', 'accidentTime'], ['事故地点', 'accidentLocation'], ['事故类型', 'accidentType'], ['损失金额', 'lossAmount'])],
|
||||||
|
['annualInspection', '年检记录', getAnnualInspectionList, cols(['车牌号', 'vehicleNo'], ['年检日期', 'inspectionDate'], ['年检有效期至', 'inspectionEndDate'], ['年检机构', 'inspectionOrganization'], ['费用', 'cost'])],
|
||||||
|
['mileage', '里程记录', getMileageList, cols(['车牌号', 'vehicleNo'], ['记录时间', 'recordTime'], ['里程数', 'mileage'], ['里程单位', 'mileageUnit'], ['备注', 'remark'])],
|
||||||
|
['change', '变更记录', getChangeList, cols(['车牌号', 'vehicleNo'], ['变更类型', 'changeType'], ['变更时间', 'changeTime'], ['变更前内容', 'beforeChange'], ['变更后内容', 'afterChange'])],
|
||||||
|
['equipment', '设备台账', null, cols(['设备编码', 'equipmentCode'], ['设备名称', 'equipmentName'], ['设备类型', 'equipmentType'], ['安装日期', 'installDate'], ['状态', 'status'])],
|
||||||
|
['oilElectric', '油电台账', getOilElectricList, cols(['车牌号', 'vehicleNo'], ['加油/充电日期', 'recordDate'], ['类型', 'energyType'], ['数量', 'quantity'], ['金额', 'amount'])],
|
||||||
|
['etc', 'ETC记录', getEtcList, cols(['车牌号', 'vehicleNo'], ['交易日期', 'transactionDate'], ['交易金额', 'amount'], ['交易地点', 'location'], ['ETC卡号', 'etcCardNo'])],
|
||||||
|
['otherExpense', '其他费用记录', getOtherExpenseList, cols(['车牌号', 'vehicleNo'], ['费用日期', 'expenseDate'], ['费用类型', 'expenseType'], ['金额', 'amount'], ['备注', 'remark'])],
|
||||||
|
].map(([name, label, request, columns]) => ({ name, label, request, columns }));
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: { modelValue: Boolean, vehicle: { type: Object, default: () => ({}) } },
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
data() {
|
||||||
|
return { detailLoading: false, tableLoading: false, vehicleDetail: {}, activeTab: 'insurance', records: [], page: { current: 1, size: 10, total: 0 } };
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tabs() { return tabConfigs; },
|
||||||
|
activeConfig() { return tabConfigs.find(item => item.name === this.activeTab) || tabConfigs[0]; },
|
||||||
|
activeColumns() { return this.activeConfig.columns; },
|
||||||
|
dimensions() { const v = this.vehicleDetail; return [v.outerLength, v.outerWidth, v.outerHeight].filter(item => item !== null && item !== undefined && item !== '').join('×') || '-'; },
|
||||||
|
plateColorType() { return { 黄牌: 'warning', 蓝牌: 'primary', 绿牌: 'success' }[this.vehicleDetail.plateColor] || 'info'; },
|
||||||
|
imageFields() { return [['行驶证主页面', 'drivingLicenseImage'], ['行驶证主页反页', 'drivingLicenseMainBack'], ['行驶证副页正页', 'drivingLicenseViceFront'], ['行驶证副页反页', 'drivingLicenseViceBack'], ['道路运输证', 'roadTransportCertImage']].map(([label, prop]) => ({ label, prop })); },
|
||||||
|
imageUrls() { return this.imageFields.map(item => this.vehicleDetail[item.prop]).filter(Boolean); },
|
||||||
|
},
|
||||||
|
watch: { modelValue(value) { if (value) this.initialize(); } },
|
||||||
|
methods: {
|
||||||
|
async initialize() { this.activeTab = 'insurance'; this.page.current = 1; this.vehicleDetail = { ...this.vehicle }; if (this.vehicle.id) { this.detailLoading = true; try { const res = await getDetail(this.vehicle.id); this.vehicleDetail = { ...this.vehicle, ...(res.data.data || {}) }; } finally { this.detailLoading = false; } } this.loadRecords(); },
|
||||||
|
async loadRecords() { const { request } = this.activeConfig; if (!request) { this.records = []; this.page.total = 0; return; } this.tableLoading = true; try { const res = await request(this.page.current, this.page.size, { vehicleNo: this.vehicleDetail.plateNo || this.vehicle.plateNo, vehicleType: '车辆' }); const data = res.data.data || {}; this.records = data.records || []; this.page.total = data.total || 0; } finally { this.tableLoading = false; } },
|
||||||
|
handlePageChange() { this.page.current = 1; this.loadRecords(); },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.vehicle-ledger__overview { padding: 16px; border: 1px solid #eff1f7; }
|
||||||
|
.vehicle-ledger__title { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; font-size: 26px; font-weight: 600; }
|
||||||
|
.vehicle-ledger__images { display: flex; gap: 16px; margin-top: 16px; overflow-x: auto; }
|
||||||
|
.vehicle-ledger__image-item { width: 150px; flex: 0 0 150px; color: #606266; text-align: center; }
|
||||||
|
.vehicle-ledger__image-item > span { display: block; margin-bottom: 8px; }
|
||||||
|
.vehicle-ledger__image-item :deep(.el-image) { width: 150px; height: 110px; border: 1px solid #eff1f7; }
|
||||||
|
.vehicle-ledger__image-item :deep(.el-empty) { height: 110px; border: 1px solid #eff1f7; }
|
||||||
|
.vehicle-ledger__tabs { margin-top: 16px; }
|
||||||
|
.vehicle-ledger__pagination { display: flex; justify-content: flex-end; margin-top: 16px; }
|
||||||
|
</style>
|
||||||
@@ -41,23 +41,23 @@
|
|||||||
>批量删除
|
>批量删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #menu-right>
|
<template #expireStatus-search>
|
||||||
<el-radio-group
|
<div class="driver-page__expiry-tags">
|
||||||
v-model="query.expireStatus"
|
<el-check-tag
|
||||||
class="driver-stat"
|
v-for="item in expiryTagOptions"
|
||||||
@change="handleExpireChange"
|
:key="item.value"
|
||||||
>
|
:checked="query.expireStatus === item.value"
|
||||||
<el-radio-button label="">全部({{ expiryStat.total }})</el-radio-button>
|
@change="handleExpireChange(item.value)"
|
||||||
<el-radio-button label="within30"
|
|
||||||
>30天内到期({{ expiryStat.within30 }})</el-radio-button
|
|
||||||
>
|
>
|
||||||
<el-radio-button label="expired">已到期({{ expiryStat.expired }})</el-radio-button>
|
{{ item.label }}({{ expiryStat[item.statKey] || 0 }})
|
||||||
</el-radio-group>
|
</el-check-tag>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #driverName="{ row }">
|
<template #driverName="{ row }">
|
||||||
<el-button type="primary" link @click="openDriver(row, true)">
|
<div class="driver-page__identity">
|
||||||
{{ row.driverName }}
|
<el-link type="primary" @click="openDriver(row, true)">{{ row.driverName }}</el-link>
|
||||||
</el-button>
|
<span>{{ row.idCardNo || '-' }}</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #status="{ row }">
|
<template #status="{ row }">
|
||||||
<el-tag :type="row.status === 1 ? 'primary' : 'info'">
|
<el-tag :type="row.status === 1 ? 'primary' : 'info'">
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
<el-row :gutter="18">
|
<el-row :gutter="18">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="司机姓名" prop="driverName">
|
<el-form-item label="司机姓名" prop="driverName">
|
||||||
<el-input v-model="driverForm.driverName" maxlength="20" show-word-limit />
|
<el-input v-model="driverForm.driverName" maxlength="10" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
@@ -345,8 +345,6 @@
|
|||||||
v-model="driverForm.qualificationType"
|
v-model="driverForm.qualificationType"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
allow-create
|
|
||||||
default-first-option
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in qualificationTypeOptions"
|
v-for="item in qualificationTypeOptions"
|
||||||
@@ -418,32 +416,35 @@
|
|||||||
|
|
||||||
<section-card title="司机联系信息">
|
<section-card title="司机联系信息">
|
||||||
<el-row :gutter="18">
|
<el-row :gutter="18">
|
||||||
<el-col :span="8">
|
<el-col :span="6">
|
||||||
<el-form-item label="司机类型" prop="driverType">
|
<el-form-item label="司机类型" prop="driverType">
|
||||||
<el-select v-model="driverForm.driverType" filterable>
|
<el-select v-model="driverForm.driverType" filterable>
|
||||||
<el-option label="自有" value="自有" />
|
<el-option label="自有" value="自有" />
|
||||||
<el-option label="外协" value="外协" />
|
<el-option label="外协" value="外协" />
|
||||||
|
<el-option label="承运管理员" value="承运管理员" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="6">
|
||||||
<el-form-item label="手机号" prop="mobile">
|
<el-form-item label="手机号" prop="mobile">
|
||||||
<el-input v-model="driverForm.mobile" maxlength="20" />
|
<el-input v-model="driverForm.mobile" maxlength="20" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="6">
|
||||||
<el-form-item label="紧急联系人姓名" prop="emergencyContactName">
|
<el-form-item label="紧急联系人姓名" prop="emergencyContactName">
|
||||||
<el-input v-model="driverForm.emergencyContactName" maxlength="20" />
|
<el-input
|
||||||
|
v-model="driverForm.emergencyContactName"
|
||||||
|
maxlength="20"
|
||||||
|
@input="driverForm.emergencyContactName = removeDigits($event)"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
<el-col :span="6">
|
||||||
<el-row :gutter="18">
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="紧急联系人手机号" prop="emergencyContactMobile">
|
<el-form-item label="紧急联系人手机号" prop="emergencyContactMobile">
|
||||||
<el-input v-model="driverForm.emergencyContactMobile" maxlength="20" />
|
<el-input v-model="driverForm.emergencyContactMobile" maxlength="20" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="6">
|
||||||
<el-form-item label="与联系人关系" prop="contactRelation">
|
<el-form-item label="与联系人关系" prop="contactRelation">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="driverForm.contactRelation"
|
v-model="driverForm.contactRelation"
|
||||||
@@ -461,7 +462,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="6">
|
||||||
<el-form-item label="所属组织" prop="organizationName">
|
<el-form-item label="所属组织" prop="organizationName">
|
||||||
<el-select v-model="driverForm.organizationName" clearable filterable>
|
<el-select v-model="driverForm.organizationName" clearable filterable>
|
||||||
<el-option
|
<el-option
|
||||||
@@ -502,6 +503,7 @@ import {
|
|||||||
recognitionTransportCertificates,
|
recognitionTransportCertificates,
|
||||||
} from '@/api/transportCapacity/driver';
|
} from '@/api/transportCapacity/driver';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { getLazyTree } from '@/api/base/region';
|
import { getLazyTree } from '@/api/base/region';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
@@ -639,18 +641,8 @@ export default {
|
|||||||
],
|
],
|
||||||
educationOptions: ['初中', '高中', '中专', '大专', '本科', '硕士及以上'],
|
educationOptions: ['初中', '高中', '中专', '大专', '本科', '硕士及以上'],
|
||||||
drivingTypeOptions: ['A1', 'A2', 'A3', 'B1', 'B2', 'C1', 'C2'],
|
drivingTypeOptions: ['A1', 'A2', 'A3', 'B1', 'B2', 'C1', 'C2'],
|
||||||
qualificationTypeOptions: [
|
qualificationTypeOptions: [],
|
||||||
'放射品押运员',
|
relationOptions: ['父母', '配偶', '子女', '兄弟姐妹', '朋友', '同事', '其他'],
|
||||||
'道路运输从业资格证',
|
|
||||||
'危险货物运输从业资格证',
|
|
||||||
'A1',
|
|
||||||
'A2',
|
|
||||||
'B1',
|
|
||||||
'B2',
|
|
||||||
'C1',
|
|
||||||
'C2',
|
|
||||||
],
|
|
||||||
relationOptions: ['父母', '配偶', '子女', '兄弟姐妹', '朋友', '同事'],
|
|
||||||
organizationOptions: [],
|
organizationOptions: [],
|
||||||
regionOptions: [],
|
regionOptions: [],
|
||||||
formRules: {
|
formRules: {
|
||||||
@@ -686,6 +678,7 @@ export default {
|
|||||||
mobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
|
mobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
|
||||||
emergencyContactName: [
|
emergencyContactName: [
|
||||||
{ required: true, message: '请输入紧急联系人姓名', trigger: 'blur' },
|
{ required: true, message: '请输入紧急联系人姓名', trigger: 'blur' },
|
||||||
|
{ validator: this.validateEmergencyContactName, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
emergencyContactMobile: [
|
emergencyContactMobile: [
|
||||||
{ required: true, message: '请输入紧急联系人手机号', trigger: 'blur' },
|
{ required: true, message: '请输入紧急联系人手机号', trigger: 'blur' },
|
||||||
@@ -726,10 +719,18 @@ export default {
|
|||||||
emitPath: true,
|
emitPath: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
expiryTagOptions() {
|
||||||
|
return [
|
||||||
|
{ label: '全部', value: '', statKey: 'total' },
|
||||||
|
{ label: '30天内到期', value: 'within30', statKey: 'within30' },
|
||||||
|
{ label: '已到期', value: 'expired', statKey: 'expired' },
|
||||||
|
];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
this.initRegionOptions();
|
this.initRegionOptions();
|
||||||
|
this.initQualificationTypeOptions();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
hasPermission(code) {
|
hasPermission(code) {
|
||||||
@@ -740,6 +741,16 @@ export default {
|
|||||||
this.organizationOptions = this.formatDeptOptions(res.data.data || []);
|
this.organizationOptions = this.formatDeptOptions(res.data.data || []);
|
||||||
const column = this.findColumn(this.option.column, 'organizationName');
|
const column = this.findColumn(this.option.column, 'organizationName');
|
||||||
column.dicData = this.organizationOptions;
|
column.dicData = this.organizationOptions;
|
||||||
|
if (this.driverBox && !this.driverForm.id && !this.driverForm.organizationName) {
|
||||||
|
this.driverForm.organizationName = this.getCurrentOrganizationName();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
initQualificationTypeOptions() {
|
||||||
|
getDictionary({ code: 'type_of_cert' }).then(res => {
|
||||||
|
this.qualificationTypeOptions = (res.data.data || [])
|
||||||
|
.map(item => item.dictValue)
|
||||||
|
.filter(Boolean);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
formatDeptOptions(tree = [], level = 0) {
|
formatDeptOptions(tree = [], level = 0) {
|
||||||
@@ -749,6 +760,8 @@ export default {
|
|||||||
result.push({
|
result.push({
|
||||||
label: `${' '.repeat(level)}${label}`,
|
label: `${' '.repeat(level)}${label}`,
|
||||||
value: label,
|
value: label,
|
||||||
|
rawLabel: label,
|
||||||
|
id: item.id || item.value,
|
||||||
});
|
});
|
||||||
if (item.children && item.children.length) {
|
if (item.children && item.children.length) {
|
||||||
result.push(...this.formatDeptOptions(item.children, level + 1));
|
result.push(...this.formatDeptOptions(item.children, level + 1));
|
||||||
@@ -756,6 +769,13 @@ export default {
|
|||||||
});
|
});
|
||||||
return result;
|
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 || '';
|
||||||
|
},
|
||||||
initRegionOptions() {
|
initRegionOptions() {
|
||||||
getLazyTree().then(res => {
|
getLazyTree().then(res => {
|
||||||
const regions = this.buildRegionTree(res.data.data || []);
|
const regions = this.buildRegionTree(res.data.data || []);
|
||||||
@@ -885,10 +905,21 @@ export default {
|
|||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
},
|
},
|
||||||
|
validateEmergencyContactName(rule, value, callback) {
|
||||||
|
if (/\d/.test(value || '')) {
|
||||||
|
callback(new Error('紧急联系人姓名不能包含数字'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
removeDigits(value = '') {
|
||||||
|
return String(value).replace(/\d/g, '');
|
||||||
|
},
|
||||||
openDriver(row, readonly = false) {
|
openDriver(row, readonly = false) {
|
||||||
this.readonly = readonly;
|
this.readonly = readonly;
|
||||||
if (!row?.id) {
|
if (!row?.id) {
|
||||||
this.driverForm = emptyForm();
|
this.driverForm = emptyForm();
|
||||||
|
this.driverForm.organizationName = this.getCurrentOrganizationName();
|
||||||
this.driverBox = true;
|
this.driverBox = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -921,9 +952,9 @@ export default {
|
|||||||
this.setImage(prop, url);
|
this.setImage(prop, url);
|
||||||
this.recognizeIdCard(url);
|
this.recognizeIdCard(url);
|
||||||
},
|
},
|
||||||
handleDrivingLicenseUploadSuccess(prop, url, file = {}) {
|
handleDrivingLicenseUploadSuccess(prop, url) {
|
||||||
this.setImage(prop, url);
|
this.setImage(prop, url);
|
||||||
this.drivingLicenseUploads[prop] = this.getUploadRecognitionKey(file, url);
|
this.drivingLicenseUploads[prop] = url;
|
||||||
this.recognizeDrivingLicense();
|
this.recognizeDrivingLicense();
|
||||||
},
|
},
|
||||||
recognizeIdCard(url = '') {
|
recognizeIdCard(url = '') {
|
||||||
@@ -976,10 +1007,10 @@ export default {
|
|||||||
buildDrivingLicenseRecognitionCertificates() {
|
buildDrivingLicenseRecognitionCertificates() {
|
||||||
return ['drivingLicenseFront', 'drivingLicenseBack']
|
return ['drivingLicenseFront', 'drivingLicenseBack']
|
||||||
.map(prop => {
|
.map(prop => {
|
||||||
const objectKey = this.drivingLicenseUploads[prop] || this.driverForm[prop];
|
const url = this.drivingLicenseUploads[prop] || this.driverForm[prop];
|
||||||
if (!objectKey) return null;
|
if (!url) return null;
|
||||||
return {
|
return {
|
||||||
driverLicenseUrl: objectKey,
|
driverLicenseUrl: url,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
@@ -1046,19 +1077,6 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getUploadRecognitionKey(file = {}, url = '') {
|
|
||||||
return (
|
|
||||||
file.objectKey ||
|
|
||||||
file.key ||
|
|
||||||
file.fileName ||
|
|
||||||
file.name ||
|
|
||||||
file.link ||
|
|
||||||
file.url ||
|
|
||||||
file.domain ||
|
|
||||||
url ||
|
|
||||||
''
|
|
||||||
);
|
|
||||||
},
|
|
||||||
applyIdCardRecognition(data = {}) {
|
applyIdCardRecognition(data = {}) {
|
||||||
const driverName = data.name || data.driverName || this.getOcrValue(data, ['name', '姓名']);
|
const driverName = data.name || data.driverName || this.getOcrValue(data, ['name', '姓名']);
|
||||||
const idCardNo = String(
|
const idCardNo = String(
|
||||||
@@ -1206,7 +1224,8 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleExpireChange() {
|
handleExpireChange(expireStatus) {
|
||||||
|
this.query.expireStatus = expireStatus;
|
||||||
this.page.currentPage = 1;
|
this.page.currentPage = 1;
|
||||||
this.onLoad(this.page);
|
this.onLoad(this.page);
|
||||||
},
|
},
|
||||||
@@ -1322,8 +1341,24 @@ export default {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.driver-page {
|
.driver-page {
|
||||||
.driver-stat {
|
&__identity {
|
||||||
flex-shrink: 0;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__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),
|
:deep(.el-table th .cell),
|
||||||
@@ -1409,9 +1444,8 @@ export default {
|
|||||||
|
|
||||||
@media (max-width: 1200px) {
|
@media (max-width: 1200px) {
|
||||||
.driver-page {
|
.driver-page {
|
||||||
.driver-stat {
|
&__expiry-tags {
|
||||||
display: flex;
|
flex: 1;
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,14 +44,17 @@
|
|||||||
批量删除
|
批量删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #menu-right>
|
<template #expireStatus-search>
|
||||||
<el-radio-group v-model="query.expireStatus" class="ship-stat" @change="handleExpireChange">
|
<div class="transport-ship-page__expiry-tags">
|
||||||
<el-radio-button label="">全部({{ expiryStat.total }})</el-radio-button>
|
<el-check-tag
|
||||||
<el-radio-button label="within30"
|
v-for="item in expiryTagOptions"
|
||||||
>30天内到期({{ expiryStat.within30 }})</el-radio-button
|
:key="item.value"
|
||||||
|
:checked="query.expireStatus === item.value"
|
||||||
|
@change="handleExpireChange(item.value)"
|
||||||
>
|
>
|
||||||
<el-radio-button label="expired">已到期({{ expiryStat.expired }})</el-radio-button>
|
{{ item.label }}({{ expiryStat[item.statKey] || 0 }})
|
||||||
</el-radio-group>
|
</el-check-tag>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #shipName="{ row }">
|
<template #shipName="{ row }">
|
||||||
<el-button type="primary" link @click="openShip(row, true)">
|
<el-button type="primary" link @click="openShip(row, true)">
|
||||||
@@ -69,14 +72,22 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #safeManningCertEndDate="{ row }">
|
<template #safeManningCertEndDate="{ row }">
|
||||||
<span :class="getDateClass(row, 'safeManningCertEndDate', 'safeManningCertLongTerm')">
|
<span
|
||||||
|
:class="
|
||||||
|
getCertificateExpiryClass(row, 'safeManningCertEndDate', 'safeManningCertLongTerm')
|
||||||
|
"
|
||||||
|
>
|
||||||
{{ formatEndDate(row.safeManningCertEndDate, row.safeManningCertLongTerm) }}
|
{{ formatEndDate(row.safeManningCertEndDate, row.safeManningCertLongTerm) }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #businessTransportCertEndDate="{ row }">
|
<template #businessTransportCertEndDate="{ row }">
|
||||||
<span
|
<span
|
||||||
:class="
|
:class="
|
||||||
getDateClass(row, 'businessTransportCertEndDate', 'businessTransportCertLongTerm')
|
getCertificateExpiryClass(
|
||||||
|
row,
|
||||||
|
'businessTransportCertEndDate',
|
||||||
|
'businessTransportCertLongTerm'
|
||||||
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ formatEndDate(row.businessTransportCertEndDate, row.businessTransportCertLongTerm) }}
|
{{ formatEndDate(row.businessTransportCertEndDate, row.businessTransportCertLongTerm) }}
|
||||||
@@ -94,7 +105,7 @@
|
|||||||
<el-link
|
<el-link
|
||||||
type="primary"
|
type="primary"
|
||||||
v-if="hasPermission('transport_ship_view')"
|
v-if="hasPermission('transport_ship_view')"
|
||||||
@click="openShip(row, true)"
|
@click="openShipLedger(row)"
|
||||||
>
|
>
|
||||||
综合台账
|
综合台账
|
||||||
</el-link>
|
</el-link>
|
||||||
@@ -108,6 +119,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
|
|
||||||
|
<ship-ledger v-model="shipLedgerBox" :ship="ledgerShip" />
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="dialogTitle"
|
:title="dialogTitle"
|
||||||
append-to-body
|
append-to-body
|
||||||
@@ -146,7 +159,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="船名" prop="shipName">
|
<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-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
@@ -172,64 +185,64 @@
|
|||||||
<el-row :gutter="18">
|
<el-row :gutter="18">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="总长" prop="totalLength">
|
<el-form-item label="总长" prop="totalLength">
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="shipForm.totalLength"
|
v-model="shipForm.totalLength"
|
||||||
:min="0"
|
@input="normalizeNonNegativeDecimal('totalLength')"
|
||||||
:precision="2"
|
>
|
||||||
:controls="false"
|
<template #suffix>m</template>
|
||||||
/>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="船宽" prop="shipWidth">
|
<el-form-item label="船宽" prop="shipWidth">
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="shipForm.shipWidth"
|
v-model="shipForm.shipWidth"
|
||||||
:min="0"
|
@input="normalizeNonNegativeDecimal('shipWidth')"
|
||||||
:precision="2"
|
>
|
||||||
:controls="false"
|
<template #suffix>m</template>
|
||||||
/>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="型深" prop="moldedDepth">
|
<el-form-item label="型深" prop="moldedDepth">
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="shipForm.moldedDepth"
|
v-model="shipForm.moldedDepth"
|
||||||
:min="0"
|
@input="normalizeNonNegativeDecimal('moldedDepth')"
|
||||||
:precision="2"
|
>
|
||||||
:controls="false"
|
<template #suffix>m</template>
|
||||||
/>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="18">
|
<el-row :gutter="18">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="最大船高" prop="maxShipHeight">
|
<el-form-item label="最大船高" prop="maxShipHeight">
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="shipForm.maxShipHeight"
|
v-model="shipForm.maxShipHeight"
|
||||||
:min="0"
|
@input="normalizeNonNegativeDecimal('maxShipHeight')"
|
||||||
:precision="2"
|
>
|
||||||
:controls="false"
|
<template #suffix>m</template>
|
||||||
/>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="空载吃水" prop="lightDraft">
|
<el-form-item label="空载吃水" prop="lightDraft">
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="shipForm.lightDraft"
|
v-model="shipForm.lightDraft"
|
||||||
:min="0"
|
@input="normalizeNonNegativeDecimal('lightDraft')"
|
||||||
:precision="2"
|
>
|
||||||
:controls="false"
|
<template #suffix>t</template>
|
||||||
/>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="满载吃水" prop="fullLoadDraft">
|
<el-form-item label="满载吃水" prop="fullLoadDraft">
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="shipForm.fullLoadDraft"
|
v-model="shipForm.fullLoadDraft"
|
||||||
:min="0"
|
@input="normalizeNonNegativeDecimal('fullLoadDraft')"
|
||||||
:precision="2"
|
>
|
||||||
:controls="false"
|
<template #suffix>t</template>
|
||||||
/>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -349,7 +362,12 @@
|
|||||||
<el-row :gutter="18">
|
<el-row :gutter="18">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="船舶类型" prop="shipType">
|
<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-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -577,6 +595,7 @@ import { getToken } from '@/utils/auth';
|
|||||||
import { getUploadHeaders } from '@/utils/upload';
|
import { getUploadHeaders } from '@/utils/upload';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import ImageUploadField from '@/components/image-upload-field/main.vue';
|
import ImageUploadField from '@/components/image-upload-field/main.vue';
|
||||||
|
import ShipLedger from './components/ship-ledger.vue';
|
||||||
|
|
||||||
const emptyForm = () => ({
|
const emptyForm = () => ({
|
||||||
id: '',
|
id: '',
|
||||||
@@ -626,7 +645,7 @@ const emptyForm = () => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ImageUploadField, InfoFilled },
|
components: { ImageUploadField, InfoFilled, ShipLedger },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
option,
|
option,
|
||||||
@@ -641,13 +660,18 @@ export default {
|
|||||||
page: { pageSize: 10, currentPage: 1, total: 0 },
|
page: { pageSize: 10, currentPage: 1, total: 0 },
|
||||||
expiryStat: { total: 0, within30: 0, expired: 0 },
|
expiryStat: { total: 0, within30: 0, expired: 0 },
|
||||||
shipBox: false,
|
shipBox: false,
|
||||||
|
shipLedgerBox: false,
|
||||||
|
ledgerShip: {},
|
||||||
readonly: false,
|
readonly: false,
|
||||||
shipForm: emptyForm(),
|
shipForm: emptyForm(),
|
||||||
uploadHeaders: getUploadHeaders(),
|
uploadHeaders: getUploadHeaders(),
|
||||||
organizationOptions: [],
|
organizationOptions: [],
|
||||||
formRules: {
|
formRules: {
|
||||||
organizationName: [{ required: true, message: '请选择船舶所属组织', trigger: 'change' }],
|
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' }],
|
keelLayingDate: [{ validator: this.validateKeelCompletionDate, trigger: 'change' }],
|
||||||
shipIdentifierNo: [{ required: true, message: '请输入船舶识别号', trigger: 'blur' }],
|
shipIdentifierNo: [{ required: true, message: '请输入船舶识别号', trigger: 'blur' }],
|
||||||
totalLength: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
|
totalLength: [{ validator: this.validateNonNegativeField, trigger: 'change' }],
|
||||||
@@ -663,7 +687,7 @@ export default {
|
|||||||
grossTonnage: [{ required: true, message: '请输入总吨', trigger: 'change' }],
|
grossTonnage: [{ required: true, message: '请输入总吨', trigger: 'change' }],
|
||||||
netTonnage: [{ required: true, message: '请输入净吨', trigger: 'change' }],
|
netTonnage: [{ required: true, message: '请输入净吨', trigger: 'change' }],
|
||||||
shipInspectionNo: [{ required: true, message: '请输入船检登记号', trigger: 'blur' }],
|
shipInspectionNo: [{ required: true, message: '请输入船检登记号', trigger: 'blur' }],
|
||||||
shipType: [{ required: true, message: '请输入船舶类型', trigger: 'blur' }],
|
shipType: [{ required: true, message: '请选择船舶类型', trigger: 'change' }],
|
||||||
nationalityCertStartDate: [
|
nationalityCertStartDate: [
|
||||||
{ validator: this.validateNationalityCertDate, trigger: 'change' },
|
{ validator: this.validateNationalityCertDate, trigger: 'change' },
|
||||||
],
|
],
|
||||||
@@ -704,6 +728,13 @@ export default {
|
|||||||
if (this.readonly) return '船舶综合台账';
|
if (this.readonly) return '船舶综合台账';
|
||||||
return this.shipForm.id ? '修改船舶' : '新增船舶';
|
return this.shipForm.id ? '修改船舶' : '新增船舶';
|
||||||
},
|
},
|
||||||
|
expiryTagOptions() {
|
||||||
|
return [
|
||||||
|
{ label: '全部', value: '', statKey: 'total' },
|
||||||
|
{ label: '30天内到期', value: 'within30', statKey: 'within30' },
|
||||||
|
{ label: '已到期', value: 'expired', statKey: 'expired' },
|
||||||
|
];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
@@ -717,6 +748,9 @@ export default {
|
|||||||
this.organizationOptions = this.flattenDeptOptions(res.data.data || []);
|
this.organizationOptions = this.flattenDeptOptions(res.data.data || []);
|
||||||
const column = this.findColumn(this.option.column, 'organizationName');
|
const column = this.findColumn(this.option.column, 'organizationName');
|
||||||
column.dicData = this.organizationOptions;
|
column.dicData = this.organizationOptions;
|
||||||
|
if (this.shipBox && !this.shipForm.id && !this.shipForm.organizationName) {
|
||||||
|
this.shipForm.organizationName = this.getCurrentOrganizationName();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
flattenDeptOptions(tree = [], level = 0) {
|
flattenDeptOptions(tree = [], level = 0) {
|
||||||
@@ -726,6 +760,8 @@ export default {
|
|||||||
result.push({
|
result.push({
|
||||||
label: `${' '.repeat(level)}${label}`,
|
label: `${' '.repeat(level)}${label}`,
|
||||||
value: label,
|
value: label,
|
||||||
|
rawLabel: label,
|
||||||
|
id: item.id || item.value,
|
||||||
});
|
});
|
||||||
if (item.children && item.children.length) {
|
if (item.children && item.children.length) {
|
||||||
result.push(...this.flattenDeptOptions(item.children, level + 1));
|
result.push(...this.flattenDeptOptions(item.children, level + 1));
|
||||||
@@ -733,9 +769,22 @@ export default {
|
|||||||
});
|
});
|
||||||
return result;
|
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) {
|
validateField(prop) {
|
||||||
this.$refs.shipForm?.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) {
|
validateNonNegativeField(rule, value, callback) {
|
||||||
if (value !== undefined && value !== null && value < 0) {
|
if (value !== undefined && value !== null && value < 0) {
|
||||||
callback(new Error('数值不能小于0'));
|
callback(new Error('数值不能小于0'));
|
||||||
@@ -818,6 +867,7 @@ export default {
|
|||||||
this.readonly = readonly;
|
this.readonly = readonly;
|
||||||
if (!row?.id) {
|
if (!row?.id) {
|
||||||
this.shipForm = emptyForm();
|
this.shipForm = emptyForm();
|
||||||
|
this.shipForm.organizationName = this.getCurrentOrganizationName();
|
||||||
this.shipBox = true;
|
this.shipBox = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -826,6 +876,10 @@ export default {
|
|||||||
this.shipBox = true;
|
this.shipBox = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
openShipLedger(row) {
|
||||||
|
this.ledgerShip = { ...row };
|
||||||
|
this.shipLedgerBox = true;
|
||||||
|
},
|
||||||
resetShip() {
|
resetShip() {
|
||||||
this.shipForm = emptyForm();
|
this.shipForm = emptyForm();
|
||||||
this.readonly = false;
|
this.readonly = false;
|
||||||
@@ -881,7 +935,8 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleExpireChange() {
|
handleExpireChange(expireStatus) {
|
||||||
|
this.query.expireStatus = expireStatus;
|
||||||
this.page.currentPage = 1;
|
this.page.currentPage = 1;
|
||||||
this.onLoad(this.page);
|
this.onLoad(this.page);
|
||||||
},
|
},
|
||||||
@@ -977,14 +1032,28 @@ export default {
|
|||||||
if (endDate.diff(today, 'day') <= 30) return 'date-warning';
|
if (endDate.diff(today, 'day') <= 30) return 'date-warning';
|
||||||
return '';
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.transport-ship-page {
|
.transport-ship-page {
|
||||||
.ship-stat {
|
&__expiry-tags {
|
||||||
flex-shrink: 0;
|
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),
|
:deep(.el-table th .cell),
|
||||||
|
|||||||
@@ -41,18 +41,17 @@
|
|||||||
>批量删除
|
>批量删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #menu-right>
|
<template #expireStatus-search>
|
||||||
<el-radio-group
|
<div class="transport-vehicle-page__expiry-tags">
|
||||||
v-model="query.expireStatus"
|
<el-check-tag
|
||||||
class="vehicle-stat"
|
v-for="item in expiryTagOptions"
|
||||||
@change="handleExpireChange"
|
:key="item.value"
|
||||||
>
|
:checked="query.expireStatus === item.value"
|
||||||
<el-radio-button label="">全部({{ expiryStat.total }})</el-radio-button>
|
@change="handleExpireChange(item.value)"
|
||||||
<el-radio-button label="within30"
|
|
||||||
>30天内到期({{ expiryStat.within30 }})</el-radio-button
|
|
||||||
>
|
>
|
||||||
<el-radio-button label="expired">已到期({{ expiryStat.expired }})</el-radio-button>
|
{{ item.label }}({{ expiryStat[item.statKey] || 0 }})
|
||||||
</el-radio-group>
|
</el-check-tag>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #plateNo="{ row }">
|
<template #plateNo="{ row }">
|
||||||
<el-button type="primary" link @click="openVehicle(row, true)">
|
<el-button type="primary" link @click="openVehicle(row, true)">
|
||||||
@@ -64,6 +63,14 @@
|
|||||||
{{ row.status === 1 ? '启用' : '停用' }}
|
{{ row.status === 1 ? '启用' : '停用' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
|
<template #boundDriver>
|
||||||
|
<span>-</span>
|
||||||
|
</template>
|
||||||
|
<template #certificationStatus="{ row }">
|
||||||
|
<el-tag :type="getCertificationStatus(row).type">
|
||||||
|
{{ getCertificationStatus(row).label }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
<template #drivingLicenseEndDate="{ row }">
|
<template #drivingLicenseEndDate="{ row }">
|
||||||
<span :class="getDateClass(row, 'drivingLicenseEndDate', 'drivingLicenseLongTerm')">
|
<span :class="getDateClass(row, 'drivingLicenseEndDate', 'drivingLicenseLongTerm')">
|
||||||
{{ formatEndDate(row.drivingLicenseEndDate, row.drivingLicenseLongTerm) }}
|
{{ formatEndDate(row.drivingLicenseEndDate, row.drivingLicenseLongTerm) }}
|
||||||
@@ -94,6 +101,10 @@
|
|||||||
>
|
>
|
||||||
修改
|
修改
|
||||||
</el-link>
|
</el-link>
|
||||||
|
<el-link type="primary" @click="openVehicleLedger(row)">综合台账</el-link>
|
||||||
|
<el-link type="primary" v-if="row.certificationStatus === 0" @click="openCertificationAudit(row)">
|
||||||
|
审核
|
||||||
|
</el-link>
|
||||||
<el-link
|
<el-link
|
||||||
type="primary"
|
type="primary"
|
||||||
v-if="hasPermission('transport_vehicle_status')"
|
v-if="hasPermission('transport_vehicle_status')"
|
||||||
@@ -104,6 +115,26 @@
|
|||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
|
|
||||||
|
<vehicle-ledger v-model="vehicleLedgerBox" :vehicle="ledgerVehicle" />
|
||||||
|
|
||||||
|
<el-dialog v-model="certificationAuditBox" title="车辆认证审核" width="92%" top="4vh">
|
||||||
|
<el-descriptions :column="3" border>
|
||||||
|
<el-descriptions-item v-for="item in auditDetailItems" :key="item.label" :label="item.label">
|
||||||
|
{{ formatAuditValue(item) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<el-form v-if="showRejectReason" class="certification-audit__reason" label-position="right" label-width="auto">
|
||||||
|
<el-form-item label="驳回原因" required>
|
||||||
|
<el-input v-model="certificationRejectReason" type="textarea" maxlength="200" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="certificationAuditBox = false">取消</el-button>
|
||||||
|
<el-button type="danger" @click="handleCertificationReject">认证驳回</el-button>
|
||||||
|
<el-button type="primary" @click="handleCertificationApprove">认证通过</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="dialogTitle"
|
:title="dialogTitle"
|
||||||
append-to-body
|
append-to-body
|
||||||
@@ -201,29 +232,26 @@
|
|||||||
<div class="dimension-group">
|
<div class="dimension-group">
|
||||||
<div class="dimension-group__item">
|
<div class="dimension-group__item">
|
||||||
<span class="dimension-group__label">长</span>
|
<span class="dimension-group__label">长</span>
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="vehicleForm.outerLength"
|
v-model="vehicleForm.outerLength"
|
||||||
:min="0"
|
inputmode="numeric"
|
||||||
:precision="0"
|
@input="vehicleForm.outerLength = digitsOnly($event)"
|
||||||
controls-position="right"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="dimension-group__item">
|
<div class="dimension-group__item">
|
||||||
<span class="dimension-group__label">宽</span>
|
<span class="dimension-group__label">宽</span>
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="vehicleForm.outerWidth"
|
v-model="vehicleForm.outerWidth"
|
||||||
:min="0"
|
inputmode="numeric"
|
||||||
:precision="0"
|
@input="vehicleForm.outerWidth = digitsOnly($event)"
|
||||||
controls-position="right"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="dimension-group__item">
|
<div class="dimension-group__item">
|
||||||
<span class="dimension-group__label">高</span>
|
<span class="dimension-group__label">高</span>
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="vehicleForm.outerHeight"
|
v-model="vehicleForm.outerHeight"
|
||||||
:min="0"
|
inputmode="numeric"
|
||||||
:precision="0"
|
@input="vehicleForm.outerHeight = digitsOnly($event)"
|
||||||
controls-position="right"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -233,21 +261,19 @@
|
|||||||
<el-row :gutter="18">
|
<el-row :gutter="18">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="核定载质量(KG)" prop="approvedLoadKg">
|
<el-form-item label="核定载质量(KG)" prop="approvedLoadKg">
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="vehicleForm.approvedLoadKg"
|
v-model="vehicleForm.approvedLoadKg"
|
||||||
:min="0"
|
inputmode="numeric"
|
||||||
:precision="0"
|
@input="vehicleForm.approvedLoadKg = digitsOnly($event)"
|
||||||
controls-position="right"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="准牵引总质量(KG)" prop="tractionMassKg">
|
<el-form-item label="准牵引总质量(KG)" prop="tractionMassKg">
|
||||||
<el-input-number
|
<el-input
|
||||||
v-model="vehicleForm.tractionMassKg"
|
v-model="vehicleForm.tractionMassKg"
|
||||||
:min="0"
|
inputmode="numeric"
|
||||||
:precision="0"
|
@input="vehicleForm.tractionMassKg = digitsOnly($event)"
|
||||||
controls-position="right"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -509,6 +535,7 @@ import {
|
|||||||
submit,
|
submit,
|
||||||
remove,
|
remove,
|
||||||
changeStatus,
|
changeStatus,
|
||||||
|
auditCertification,
|
||||||
getExpiryStat,
|
getExpiryStat,
|
||||||
recognitionTransportCertificates,
|
recognitionTransportCertificates,
|
||||||
} from '@/api/transportCapacity/transport-vehicle';
|
} from '@/api/transportCapacity/transport-vehicle';
|
||||||
@@ -518,6 +545,7 @@ import { getToken } from '@/utils/auth';
|
|||||||
import { getUploadHeaders } from '@/utils/upload';
|
import { getUploadHeaders } from '@/utils/upload';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import ImageUploadField from '@/components/image-upload-field/main.vue';
|
import ImageUploadField from '@/components/image-upload-field/main.vue';
|
||||||
|
import VehicleLedger from './components/vehicle-ledger.vue';
|
||||||
|
|
||||||
const emptyForm = () => ({
|
const emptyForm = () => ({
|
||||||
id: '',
|
id: '',
|
||||||
@@ -599,6 +627,7 @@ const plateColorOptions = ['黄牌', '蓝牌', '绿牌'].map(item => ({ label: i
|
|||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ImageUploadField,
|
ImageUploadField,
|
||||||
|
VehicleLedger,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -607,7 +636,9 @@ export default {
|
|||||||
query: {
|
query: {
|
||||||
expireStatus: '',
|
expireStatus: '',
|
||||||
},
|
},
|
||||||
searchForm: {},
|
searchForm: {
|
||||||
|
businessRelation: '',
|
||||||
|
},
|
||||||
loading: true,
|
loading: true,
|
||||||
submitLoading: false,
|
submitLoading: false,
|
||||||
data: [],
|
data: [],
|
||||||
@@ -624,6 +655,12 @@ export default {
|
|||||||
expired: 0,
|
expired: 0,
|
||||||
},
|
},
|
||||||
vehicleBox: false,
|
vehicleBox: false,
|
||||||
|
vehicleLedgerBox: false,
|
||||||
|
ledgerVehicle: {},
|
||||||
|
certificationAuditBox: false,
|
||||||
|
certificationAuditForm: {},
|
||||||
|
certificationRejectReason: '',
|
||||||
|
showRejectReason: false,
|
||||||
readonly: false,
|
readonly: false,
|
||||||
vehicleForm: emptyForm(),
|
vehicleForm: emptyForm(),
|
||||||
vehicleCertificateUploads: {},
|
vehicleCertificateUploads: {},
|
||||||
@@ -643,7 +680,10 @@ export default {
|
|||||||
energyTypeOptions: ['柴油', '汽油', '新能源', '天然气'],
|
energyTypeOptions: ['柴油', '汽油', '新能源', '天然气'],
|
||||||
formRules: {
|
formRules: {
|
||||||
organizationName: [{ required: true, message: '请选择所属组织', trigger: 'change' }],
|
organizationName: [{ required: true, message: '请选择所属组织', trigger: 'change' }],
|
||||||
plateNo: [{ validator: this.validatePlateNo, trigger: 'change' }],
|
plateNo: [
|
||||||
|
{ required: true, message: '请输入车牌号', trigger: 'change' },
|
||||||
|
{ validator: this.validatePlateNo, trigger: 'change' },
|
||||||
|
],
|
||||||
vehicleType: [{ required: true, message: '请选择车辆类型', trigger: 'change' }],
|
vehicleType: [{ required: true, message: '请选择车辆类型', trigger: 'change' }],
|
||||||
approvedLoadKg: [{ required: true, message: '请输入核定载质量', trigger: 'blur' }],
|
approvedLoadKg: [{ required: true, message: '请输入核定载质量', trigger: 'blur' }],
|
||||||
businessRelation: [{ required: true, message: '请选择业务关系', trigger: 'change' }],
|
businessRelation: [{ required: true, message: '请选择业务关系', trigger: 'change' }],
|
||||||
@@ -681,6 +721,25 @@ export default {
|
|||||||
}
|
}
|
||||||
return this.vehicleForm.id ? '修改车辆' : '新增车辆';
|
return this.vehicleForm.id ? '修改车辆' : '新增车辆';
|
||||||
},
|
},
|
||||||
|
auditDetailItems() {
|
||||||
|
return [
|
||||||
|
['所属组织', 'organizationName'], ['车牌号', 'plateNo'], ['车牌颜色', 'plateColor'],
|
||||||
|
['车辆类型', 'vehicleType'], ['外廓长度(mm)', 'outerLength'], ['外廓宽度(mm)', 'outerWidth'],
|
||||||
|
['外廓高度(mm)', 'outerHeight'], ['核定载质量(KG)', 'approvedLoadKg'], ['准牵引总质量(KG)', 'tractionMassKg'],
|
||||||
|
['业务关系', 'businessRelation'], ['能源类型', 'energyType'], ['强制报废日期', 'compulsoryScrapDate'],
|
||||||
|
['海关备案号', 'customsRecordNo'], ['行驶证档案编号', 'drivingLicenseNo'], ['行驶证有效期起', 'drivingLicenseStartDate'],
|
||||||
|
['行驶证有效期止', 'drivingLicenseEndDate'], ['道路运输证号', 'roadTransportCertNo'], ['道路运输证有效期起', 'roadTransportCertStartDate'],
|
||||||
|
['道路运输证有效期止', 'roadTransportCertEndDate'], ['道路运输年审有效期', 'annualReviewEndDate'],
|
||||||
|
['机动车登记编号', 'registrationNo'], ['机动车登记日期', 'registrationDate'], ['备注', 'remark'],
|
||||||
|
].map(([label, prop]) => ({ label, prop }));
|
||||||
|
},
|
||||||
|
expiryTagOptions() {
|
||||||
|
return [
|
||||||
|
{ label: '全部', value: '', statKey: 'total' },
|
||||||
|
{ label: '30天内到期', value: 'within30', statKey: 'within30' },
|
||||||
|
{ label: '已到期', value: 'expired', statKey: 'expired' },
|
||||||
|
];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
@@ -694,6 +753,9 @@ export default {
|
|||||||
this.organizationOptions = this.flattenDeptOptions(res.data.data || []);
|
this.organizationOptions = this.flattenDeptOptions(res.data.data || []);
|
||||||
const column = this.findColumn(this.option.column, 'organizationName');
|
const column = this.findColumn(this.option.column, 'organizationName');
|
||||||
column.dicData = this.organizationOptions;
|
column.dicData = this.organizationOptions;
|
||||||
|
if (this.vehicleBox && !this.vehicleForm.id && !this.vehicleForm.organizationName) {
|
||||||
|
this.vehicleForm.organizationName = this.getCurrentOrganizationName();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
flattenDeptOptions(tree = [], level = 0) {
|
flattenDeptOptions(tree = [], level = 0) {
|
||||||
@@ -703,6 +765,8 @@ export default {
|
|||||||
result.push({
|
result.push({
|
||||||
label: `${' '.repeat(level)}${label}`,
|
label: `${' '.repeat(level)}${label}`,
|
||||||
value: label,
|
value: label,
|
||||||
|
rawLabel: label,
|
||||||
|
id: item.id || item.value,
|
||||||
});
|
});
|
||||||
if (item.children && item.children.length) {
|
if (item.children && item.children.length) {
|
||||||
result.push(...this.flattenDeptOptions(item.children, level + 1));
|
result.push(...this.flattenDeptOptions(item.children, level + 1));
|
||||||
@@ -710,6 +774,16 @@ export default {
|
|||||||
});
|
});
|
||||||
return result;
|
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 || '';
|
||||||
|
},
|
||||||
|
digitsOnly(value = '') {
|
||||||
|
return String(value).replace(/\D/g, '');
|
||||||
|
},
|
||||||
validatePlateNo(rule, value, callback) {
|
validatePlateNo(rule, value, callback) {
|
||||||
const plateProvince = String(this.vehicleForm.plateProvince || '').trim();
|
const plateProvince = String(this.vehicleForm.plateProvince || '').trim();
|
||||||
const plateNoBody = String(this.vehicleForm.plateNoBody || '')
|
const plateNoBody = String(this.vehicleForm.plateNoBody || '')
|
||||||
@@ -737,6 +811,7 @@ export default {
|
|||||||
this.readonly = readonly;
|
this.readonly = readonly;
|
||||||
if (!row?.id) {
|
if (!row?.id) {
|
||||||
this.vehicleForm = emptyForm();
|
this.vehicleForm = emptyForm();
|
||||||
|
this.vehicleForm.organizationName = this.getCurrentOrganizationName();
|
||||||
this.syncPlateNo(false);
|
this.syncPlateNo(false);
|
||||||
this.vehicleBox = true;
|
this.vehicleBox = true;
|
||||||
return;
|
return;
|
||||||
@@ -751,6 +826,38 @@ export default {
|
|||||||
this.vehicleBox = true;
|
this.vehicleBox = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
openVehicleLedger(row) {
|
||||||
|
this.ledgerVehicle = { ...row };
|
||||||
|
this.vehicleLedgerBox = true;
|
||||||
|
},
|
||||||
|
openCertificationAudit(row) {
|
||||||
|
getDetail(row.id).then(res => {
|
||||||
|
this.certificationAuditForm = { ...(res.data.data || {}) };
|
||||||
|
this.certificationRejectReason = '';
|
||||||
|
this.showRejectReason = false;
|
||||||
|
this.certificationAuditBox = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formatAuditValue(item) {
|
||||||
|
const value = this.certificationAuditForm[item.prop];
|
||||||
|
return value === undefined || value === null || value === '' ? '-' : value;
|
||||||
|
},
|
||||||
|
handleCertificationApprove() {
|
||||||
|
auditCertification(this.certificationAuditForm.id, 1).then(() => {
|
||||||
|
this.$message.success('认证已通过');
|
||||||
|
this.certificationAuditBox = false;
|
||||||
|
this.onLoad(this.page);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleCertificationReject() {
|
||||||
|
if (!this.showRejectReason) { this.showRejectReason = true; return; }
|
||||||
|
if (!this.certificationRejectReason.trim()) { this.$message.warning('请输入认证驳回原因'); return; }
|
||||||
|
auditCertification(this.certificationAuditForm.id, 2, this.certificationRejectReason).then(() => {
|
||||||
|
this.$message.success('认证已驳回');
|
||||||
|
this.certificationAuditBox = false;
|
||||||
|
this.onLoad(this.page);
|
||||||
|
});
|
||||||
|
},
|
||||||
resetVehicle() {
|
resetVehicle() {
|
||||||
this.vehicleForm = emptyForm();
|
this.vehicleForm = emptyForm();
|
||||||
this.vehicleCertificateUploads = {};
|
this.vehicleCertificateUploads = {};
|
||||||
@@ -762,9 +869,9 @@ export default {
|
|||||||
this.vehicleForm[prop] = url;
|
this.vehicleForm[prop] = url;
|
||||||
this.$refs.vehicleForm?.validateField(prop);
|
this.$refs.vehicleForm?.validateField(prop);
|
||||||
},
|
},
|
||||||
handleVehicleCertificateUploadSuccess(prop, url, file = {}) {
|
handleVehicleCertificateUploadSuccess(prop, url) {
|
||||||
this.setImage(prop, url);
|
this.setImage(prop, url);
|
||||||
this.vehicleCertificateUploads[prop] = this.getUploadRecognitionKey(file, url);
|
this.vehicleCertificateUploads[prop] = url;
|
||||||
this.recognizeVehicleCertificates();
|
this.recognizeVehicleCertificates();
|
||||||
},
|
},
|
||||||
recognizeVehicleCertificates() {
|
recognizeVehicleCertificates() {
|
||||||
@@ -845,19 +952,6 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getUploadRecognitionKey(file = {}, url = '') {
|
|
||||||
return (
|
|
||||||
file.objectKey ||
|
|
||||||
file.key ||
|
|
||||||
file.fileName ||
|
|
||||||
file.name ||
|
|
||||||
file.link ||
|
|
||||||
file.url ||
|
|
||||||
file.domain ||
|
|
||||||
url ||
|
|
||||||
''
|
|
||||||
);
|
|
||||||
},
|
|
||||||
normalizeDate(value = '') {
|
normalizeDate(value = '') {
|
||||||
const dateValue = String(value || '').trim();
|
const dateValue = String(value || '').trim();
|
||||||
const match = dateValue.match(/^(\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})日?$/);
|
const match = dateValue.match(/^(\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})日?$/);
|
||||||
@@ -948,7 +1042,8 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleExpireChange() {
|
handleExpireChange(expireStatus) {
|
||||||
|
this.query.expireStatus = expireStatus;
|
||||||
this.page.currentPage = 1;
|
this.page.currentPage = 1;
|
||||||
this.onLoad(this.page);
|
this.onLoad(this.page);
|
||||||
},
|
},
|
||||||
@@ -962,7 +1057,9 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
searchReset() {
|
searchReset() {
|
||||||
this.searchForm = {};
|
this.searchForm = {
|
||||||
|
businessRelation: '',
|
||||||
|
};
|
||||||
this.query = {
|
this.query = {
|
||||||
expireStatus: this.query.expireStatus,
|
expireStatus: this.query.expireStatus,
|
||||||
};
|
};
|
||||||
@@ -1063,14 +1160,44 @@ export default {
|
|||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
getCertificationStatus(row) {
|
||||||
|
if (row.certificationStatus === 0) return { label: '认证中', type: 'warning' };
|
||||||
|
if (row.certificationStatus === 1) return { label: '已认证', type: 'success' };
|
||||||
|
if (row.certificationStatus === 2) return { label: '已驳回', type: 'danger' };
|
||||||
|
const today = this.$dayjs().startOf('day');
|
||||||
|
const certificateDates = [
|
||||||
|
[row.drivingLicenseEndDate, row.drivingLicenseLongTerm],
|
||||||
|
[row.roadTransportCertEndDate, row.roadTransportCertLongTerm],
|
||||||
|
];
|
||||||
|
if (certificateDates.some(([date, longTerm]) => longTerm !== 1 && !date)) {
|
||||||
|
return { label: '未认证', type: 'info' };
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
certificateDates.some(
|
||||||
|
([date, longTerm]) => longTerm !== 1 && this.$dayjs(date).isBefore(today, 'day')
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return { label: '已过期', type: 'danger' };
|
||||||
|
}
|
||||||
|
return { label: '已认证', type: 'success' };
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.transport-vehicle-page {
|
.transport-vehicle-page {
|
||||||
.vehicle-stat {
|
&__expiry-tags {
|
||||||
flex-shrink: 0;
|
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),
|
:deep(.el-table th .cell),
|
||||||
@@ -1193,7 +1320,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.date-warning {
|
.date-warning {
|
||||||
color: #f56c6c;
|
color: #d40000;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,28 @@
|
|||||||
class="accident-record-page__input"
|
class="accident-record-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #directEconomicLossForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.directEconomicLoss"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('directEconomicLoss', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #insuranceClaimAmountForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.insuranceClaimAmount"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('insuranceClaimAmount', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #attachments="{ row }">
|
<template #attachments="{ row }">
|
||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -256,6 +278,13 @@ export default {
|
|||||||
if (!value || typeof value === 'string') return value;
|
if (!value || typeof value === 'string') return value;
|
||||||
return JSON.stringify(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;
|
||||||
|
},
|
||||||
normalizeRow(row) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.vehicleType = values.vehicleType || '车辆';
|
values.vehicleType = values.vehicleType || '车辆';
|
||||||
|
|||||||
@@ -70,6 +70,17 @@
|
|||||||
class="annual-inspection-record-page__input"
|
class="annual-inspection-record-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #feeForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.fee"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('fee', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #attachments="{ row }">
|
<template #attachments="{ row }">
|
||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -256,6 +267,13 @@ export default {
|
|||||||
if (!value || typeof value === 'string') return value;
|
if (!value || typeof value === 'string') return value;
|
||||||
return JSON.stringify(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;
|
||||||
|
},
|
||||||
normalizeRow(row) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.vehicleType = values.vehicleType || '车辆';
|
values.vehicleType = values.vehicleType || '车辆';
|
||||||
|
|||||||
343
src/views/vehicle/equipment-ledger.vue
Normal file
343
src/views/vehicle/equipment-ledger.vue
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
<template>
|
||||||
|
<basic-container class="equipment-ledger-page">
|
||||||
|
<avue-crud
|
||||||
|
ref="crud"
|
||||||
|
v-model="form"
|
||||||
|
v-model:page="page"
|
||||||
|
:option="option"
|
||||||
|
:data="data"
|
||||||
|
:permission="permissionList"
|
||||||
|
:table-loading="loading"
|
||||||
|
:before-open="beforeOpen"
|
||||||
|
@row-save="rowSave"
|
||||||
|
@row-update="rowUpdate"
|
||||||
|
@row-del="rowDel"
|
||||||
|
@search-change="searchChange"
|
||||||
|
@search-reset="searchReset"
|
||||||
|
@selection-change="selectionChange"
|
||||||
|
@current-change="currentChange"
|
||||||
|
@size-change="sizeChange"
|
||||||
|
@refresh-change="refreshChange"
|
||||||
|
@on-load="onLoad"
|
||||||
|
>
|
||||||
|
<template #menu-left>
|
||||||
|
<el-button
|
||||||
|
v-if="hasPermission('equipment_ledger_import')"
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="handleImport"
|
||||||
|
>
|
||||||
|
批量导入
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="hasPermission('equipment_ledger_template')"
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="handleTemplate"
|
||||||
|
>
|
||||||
|
下载模板
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="hasPermission('equipment_ledger_export')"
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
>
|
||||||
|
批量导出
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<template #vehicleNo="{ row, index }">
|
||||||
|
<el-link type="primary" @click="$refs.crud.rowView(row, index)">{{
|
||||||
|
row.vehicleNo
|
||||||
|
}}</el-link>
|
||||||
|
</template>
|
||||||
|
<template #vehicleNoForm>
|
||||||
|
<el-autocomplete
|
||||||
|
v-model="form.vehicleNo"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
:fetch-suggestions="fetchVehicleOptions"
|
||||||
|
:placeholder="vehicleNoPlaceholder"
|
||||||
|
clearable
|
||||||
|
value-key="value"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #equipmentCodeForm>
|
||||||
|
<el-input v-model="form.equipmentCode" disabled />
|
||||||
|
</template>
|
||||||
|
<template #attachments="{ row }">
|
||||||
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
|
</template>
|
||||||
|
<template #attachmentsForm>
|
||||||
|
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
|
</template>
|
||||||
|
<template #attachments-form>
|
||||||
|
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
|
</template>
|
||||||
|
</avue-crud>
|
||||||
|
<empty-pagination
|
||||||
|
:page="page"
|
||||||
|
@size-change="sizeChange"
|
||||||
|
@current-change="currentChange"
|
||||||
|
@load="onLoad(page, query)"
|
||||||
|
/>
|
||||||
|
<el-dialog title="设备台账数据导入" append-to-body v-model="excelBox" width="555px">
|
||||||
|
<avue-form :option="excelOption" v-model="excelForm">
|
||||||
|
<template #excelTemplate>
|
||||||
|
<el-button type="primary" @click="handleTemplate">点击下载</el-button>
|
||||||
|
</template>
|
||||||
|
</avue-form>
|
||||||
|
</el-dialog>
|
||||||
|
</basic-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
add,
|
||||||
|
getDetail,
|
||||||
|
getList,
|
||||||
|
getNextEquipmentCode,
|
||||||
|
remove,
|
||||||
|
update,
|
||||||
|
} from '@/api/vehicle/equipment-ledger';
|
||||||
|
import { getList as getVehicleList } from '@/api/transportCapacity/transport-vehicle';
|
||||||
|
import { getList as getShipList } from '@/api/transportCapacity/transport-ship';
|
||||||
|
import { exportBlob } from '@/api/common';
|
||||||
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
|
import { getToken } from '@/utils/auth';
|
||||||
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
|
import { downloadXls } from '@/utils/util';
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
import { excelOption, option } from '@/option/vehicle/equipment-ledger';
|
||||||
|
import NProgress from 'nprogress';
|
||||||
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {},
|
||||||
|
query: {},
|
||||||
|
loading: true,
|
||||||
|
excelBox: false,
|
||||||
|
excelForm: {},
|
||||||
|
boxType: '',
|
||||||
|
option,
|
||||||
|
excelOption,
|
||||||
|
data: [],
|
||||||
|
selectionList: [],
|
||||||
|
page: { pageSize: 10, pageSizes: [10, 20, 50, 100], currentPage: 1, total: 0 },
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['permission', 'userInfo']),
|
||||||
|
isAdmin() {
|
||||||
|
return (this.userInfo.authority || '').includes('admin');
|
||||||
|
},
|
||||||
|
permissionList() {
|
||||||
|
return {
|
||||||
|
addBtn: this.hasPermission('equipment_ledger_add'),
|
||||||
|
viewBtn: this.hasPermission('equipment_ledger_view'),
|
||||||
|
editBtn: this.hasPermission('equipment_ledger_edit'),
|
||||||
|
delBtn: this.hasPermission('equipment_ledger_delete'),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
vehicleNoPlaceholder() {
|
||||||
|
return this.form.vehicleType === '船舶' ? '输入船号模糊查询选择' : '输入车牌号模糊查询选择';
|
||||||
|
},
|
||||||
|
ids() {
|
||||||
|
return this.selectionList.map(item => item.id).join(',');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initDeptTree();
|
||||||
|
this.initEquipmentTypeOptions();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
hasPermission(code) {
|
||||||
|
return this.isAdmin || this.validData(this.permission[code], false);
|
||||||
|
},
|
||||||
|
initDeptTree() {
|
||||||
|
getDeptTree(this.userInfo.tenantId).then(res => {
|
||||||
|
this.findColumn(this.option.column, 'createDept').dicData = res.data.data || [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
initEquipmentTypeOptions() {
|
||||||
|
getDictionary({ code: 'equip_type' }).then(res => {
|
||||||
|
this.findColumn(this.option.column, 'equipmentType').dicData = (res.data.data || []).map(
|
||||||
|
item => ({
|
||||||
|
label: item.dictValue,
|
||||||
|
value: item.dictValue,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fetchVehicleOptions(queryString, callback) {
|
||||||
|
const isShip = this.form.vehicleType === '船舶';
|
||||||
|
const request = isShip ? getShipList : getVehicleList;
|
||||||
|
const params = isShip ? { shipIdentifierNo: queryString } : { plateNo: queryString };
|
||||||
|
request(1, 20, params)
|
||||||
|
.then(res => {
|
||||||
|
callback(
|
||||||
|
(res.data.data.records || []).map(item => ({
|
||||||
|
value: isShip ? item.shipIdentifierNo || item.shipName : item.plateNo,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(() => callback([]));
|
||||||
|
},
|
||||||
|
formatAttachments(value) {
|
||||||
|
if (!value) return '';
|
||||||
|
if (Array.isArray(value)) return `${value.length} 个`;
|
||||||
|
try {
|
||||||
|
const attachments = JSON.parse(value);
|
||||||
|
return Array.isArray(attachments) ? `${attachments.length} 个` : '1 个';
|
||||||
|
} catch (error) {
|
||||||
|
return `${value.split(',').filter(Boolean).length} 个`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseAttachments(value) {
|
||||||
|
if (!value || Array.isArray(value)) return value;
|
||||||
|
try {
|
||||||
|
const attachments = JSON.parse(value);
|
||||||
|
return Array.isArray(attachments) ? attachments : [];
|
||||||
|
} catch (error) {
|
||||||
|
return value
|
||||||
|
.split(',')
|
||||||
|
.filter(Boolean)
|
||||||
|
.map(url => ({ name: url, url }));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
normalizeRow(row) {
|
||||||
|
const values = { ...row };
|
||||||
|
values.vehicleType = values.vehicleType || '车辆';
|
||||||
|
values.vehicleNo = (values.vehicleNo || '').trim();
|
||||||
|
if (values.vehicleType === '车辆') values.vehicleNo = values.vehicleNo.toUpperCase();
|
||||||
|
values.attachments = Array.isArray(values.attachments)
|
||||||
|
? JSON.stringify(values.attachments)
|
||||||
|
: values.attachments;
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
rowSave(row, done, loading) {
|
||||||
|
add(this.normalizeRow(row)).then(
|
||||||
|
() => {
|
||||||
|
this.onLoad(this.page);
|
||||||
|
this.$message.success('操作成功');
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
() => loading()
|
||||||
|
);
|
||||||
|
},
|
||||||
|
rowUpdate(row, index, done, loading) {
|
||||||
|
update(this.normalizeRow(row)).then(
|
||||||
|
() => {
|
||||||
|
this.onLoad(this.page);
|
||||||
|
this.$message.success('操作成功');
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
() => loading()
|
||||||
|
);
|
||||||
|
},
|
||||||
|
rowDel(row) {
|
||||||
|
this.$confirm('确认删除该条数据?删除后将不可恢复!', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
.then(() => remove(row.id))
|
||||||
|
.then(() => {
|
||||||
|
this.onLoad(this.page);
|
||||||
|
this.$message.success('操作成功');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
beforeOpen(done, type) {
|
||||||
|
this.boxType = type;
|
||||||
|
if (type === 'add') {
|
||||||
|
getNextEquipmentCode().then(res => {
|
||||||
|
this.form = { vehicleType: '车辆', equipmentCode: res.data.data };
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (['edit', 'view'].includes(type)) {
|
||||||
|
getDetail(this.form.id).then(res => {
|
||||||
|
this.form = {
|
||||||
|
...res.data.data,
|
||||||
|
attachments: this.parseAttachments(res.data.data.attachments),
|
||||||
|
};
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
searchChange(params, done) {
|
||||||
|
this.query = params;
|
||||||
|
this.page.currentPage = 1;
|
||||||
|
this.onLoad(this.page, params);
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
searchReset() {
|
||||||
|
this.query = {};
|
||||||
|
this.onLoad(this.page);
|
||||||
|
},
|
||||||
|
selectionChange(list) {
|
||||||
|
this.selectionList = list;
|
||||||
|
},
|
||||||
|
currentChange(currentPage) {
|
||||||
|
this.page.currentPage = currentPage;
|
||||||
|
},
|
||||||
|
sizeChange(pageSize) {
|
||||||
|
this.page.pageSize = pageSize;
|
||||||
|
},
|
||||||
|
refreshChange() {
|
||||||
|
this.onLoad(this.page, this.query);
|
||||||
|
},
|
||||||
|
onLoad(page, params = {}) {
|
||||||
|
this.loading = true;
|
||||||
|
getList(page.currentPage, page.pageSize, { ...this.query, ...params })
|
||||||
|
.then(res => {
|
||||||
|
const result = res.data.data;
|
||||||
|
this.page.total = result.total;
|
||||||
|
this.data = result.records;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleImport() {
|
||||||
|
openImportDialog(this, '设备台账');
|
||||||
|
},
|
||||||
|
handleExport() {
|
||||||
|
this.$confirm('是否导出设备台账数据?', '提示', { type: 'warning' }).then(() => {
|
||||||
|
NProgress.start();
|
||||||
|
exportBlob(
|
||||||
|
'/blade-transport/equipment-ledger/export-equipment-ledger',
|
||||||
|
{ ...this.query, ids: this.ids, [this.website.tokenHeader]: getToken() },
|
||||||
|
{ feedback: true }
|
||||||
|
)
|
||||||
|
.then(res =>
|
||||||
|
downloadXls(res.data, `设备台账${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`)
|
||||||
|
)
|
||||||
|
.finally(() => NProgress.done());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleTemplate() {
|
||||||
|
exportBlob(
|
||||||
|
`/blade-transport/equipment-ledger/export-template?${
|
||||||
|
this.website.tokenHeader
|
||||||
|
}=${getToken()}`,
|
||||||
|
{ feedback: true }
|
||||||
|
).then(res => downloadXls(res.data, '设备台账模板.xlsx'));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.equipment-ledger-page {
|
||||||
|
:deep(.el-table th .cell),
|
||||||
|
:deep(.el-table td .cell) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -70,6 +70,17 @@
|
|||||||
class="etc-record-page__input"
|
class="etc-record-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #transactionAmountForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.transactionAmount"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('transactionAmount', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #attachments="{ row }">
|
<template #attachments="{ row }">
|
||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -209,6 +220,13 @@ export default {
|
|||||||
isEmpty(value) {
|
isEmpty(value) {
|
||||||
return value === undefined || value === null || 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) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.dataSource = values.dataSource || '手工录入';
|
values.dataSource = values.dataSource || '手工录入';
|
||||||
@@ -379,11 +397,9 @@ export default {
|
|||||||
type: 'warning',
|
type: 'warning',
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
exportBlob(
|
exportBlob('/blade-transport/etc-record/export-etc-record', this.buildExportParams(), {
|
||||||
'/blade-transport/etc-record/export-etc-record',
|
feedback: true,
|
||||||
this.buildExportParams(),
|
})
|
||||||
{ feedback: true }
|
|
||||||
)
|
|
||||||
.then(res => {
|
.then(res => {
|
||||||
downloadXls(res.data, `ETC记录${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`);
|
downloadXls(res.data, `ETC记录${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -69,6 +69,28 @@
|
|||||||
class="insurance-record-page__vehicle-input"
|
class="insurance-record-page__vehicle-input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #insuredAmountForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.insuredAmount"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('insuredAmount', value)"
|
||||||
|
>
|
||||||
|
<template #append>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #premiumForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.premium"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('premium', value)"
|
||||||
|
>
|
||||||
|
<template #append>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #policyFileForm>
|
<template #policyFileForm>
|
||||||
<div class="insurance-record-page__upload">
|
<div class="insurance-record-page__upload">
|
||||||
<div class="insurance-record-page__upload-info">
|
<div class="insurance-record-page__upload-info">
|
||||||
@@ -177,6 +199,7 @@ export default {
|
|||||||
excelBox: false,
|
excelBox: false,
|
||||||
excelForm: {},
|
excelForm: {},
|
||||||
isDetailLoading: false,
|
isDetailLoading: false,
|
||||||
|
boxType: '',
|
||||||
option,
|
option,
|
||||||
excelOption,
|
excelOption,
|
||||||
page: {
|
page: {
|
||||||
@@ -285,6 +308,13 @@ export default {
|
|||||||
}
|
}
|
||||||
return values;
|
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 = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
||||||
},
|
},
|
||||||
@@ -369,6 +399,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
beforeOpen(done, type) {
|
beforeOpen(done, type) {
|
||||||
|
this.boxType = type;
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
this.form.vehicleType = '车辆';
|
this.form.vehicleType = '车辆';
|
||||||
this.form.ocrTemplate = '紫金-机动车交强险';
|
this.form.ocrTemplate = '紫金-机动车交强险';
|
||||||
|
|||||||
@@ -70,6 +70,39 @@
|
|||||||
class="maintenance-plan-page__input"
|
class="maintenance-plan-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #mileageForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.mileage"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('mileage', value)"
|
||||||
|
>
|
||||||
|
<template #append>{{ form.mileageUnit || '公里' }}</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #costForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.cost"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('cost', value)"
|
||||||
|
>
|
||||||
|
<template #append>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #nextMaintenanceMileageForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.nextMaintenanceMileage"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('nextMaintenanceMileage', value)"
|
||||||
|
>
|
||||||
|
<template #append>{{ form.mileageUnit || '公里' }}</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #mileage="{ row }">
|
<template #mileage="{ row }">
|
||||||
<span>{{ formatMileage(row.mileage, row.mileageUnit) }}</span>
|
<span>{{ formatMileage(row.mileage, row.mileageUnit) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -169,6 +202,7 @@ export default {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -223,12 +257,10 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '里程/航程数',
|
label: '里程/航程数',
|
||||||
prop: 'mileage',
|
prop: 'mileage',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
slot: true,
|
slot: true,
|
||||||
span: 12,
|
span: 12,
|
||||||
append: '公里',
|
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
@@ -255,9 +287,8 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '费用',
|
label: '费用',
|
||||||
prop: 'cost',
|
prop: 'cost',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
slot: true,
|
||||||
append: '元',
|
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: [
|
rules: [
|
||||||
@@ -302,12 +333,10 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '下次保养里程/航程',
|
label: '下次保养里程/航程',
|
||||||
prop: 'nextMaintenanceMileage',
|
prop: 'nextMaintenanceMileage',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
|
||||||
minWidth: 170,
|
minWidth: 170,
|
||||||
slot: true,
|
slot: true,
|
||||||
span: 12,
|
span: 12,
|
||||||
append: '公里',
|
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
@@ -531,6 +560,13 @@ export default {
|
|||||||
if (!value || typeof value === 'string') return value;
|
if (!value || typeof value === 'string') return value;
|
||||||
return JSON.stringify(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() {
|
initDeptTree() {
|
||||||
getDeptTree(this.userInfo.tenantId).then(res => {
|
getDeptTree(this.userInfo.tenantId).then(res => {
|
||||||
const column = this.findColumn(this.option.column, 'createDept');
|
const column = this.findColumn(this.option.column, 'createDept');
|
||||||
|
|||||||
@@ -70,6 +70,28 @@
|
|||||||
class="maintenance-record-page__input"
|
class="maintenance-record-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #costForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.cost"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('cost', value)"
|
||||||
|
>
|
||||||
|
<template #append>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #mileageForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.mileage"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('mileage', value)"
|
||||||
|
>
|
||||||
|
<template #append>{{ form.mileageUnit || '公里' }}</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #mileage="{ row }">
|
<template #mileage="{ row }">
|
||||||
<span>{{ formatMileage(row.mileage, row.mileageUnit) }}</span>
|
<span>{{ formatMileage(row.mileage, row.mileageUnit) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -167,6 +189,7 @@ export default {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
|
indexLabel: '序号',
|
||||||
viewBtn: true,
|
viewBtn: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -239,9 +262,8 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '费用',
|
label: '费用',
|
||||||
prop: 'cost',
|
prop: 'cost',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
slot: true,
|
||||||
append: '元',
|
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
rules: [
|
rules: [
|
||||||
@@ -287,10 +309,8 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '里程/航程数',
|
label: '里程/航程数',
|
||||||
prop: 'mileage',
|
prop: 'mileage',
|
||||||
type: 'number',
|
type: 'input',
|
||||||
precision: 2,
|
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
append: '公里',
|
|
||||||
slot: true,
|
slot: true,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请输入',
|
||||||
@@ -526,6 +546,13 @@ export default {
|
|||||||
if (!value || typeof value === 'string') return value;
|
if (!value || typeof value === 'string') return value;
|
||||||
return JSON.stringify(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() {
|
initDeptTree() {
|
||||||
getDeptTree(this.userInfo.tenantId).then(res => {
|
getDeptTree(this.userInfo.tenantId).then(res => {
|
||||||
const column = this.findColumn(this.option.column, 'createDept');
|
const column = this.findColumn(this.option.column, 'createDept');
|
||||||
|
|||||||
@@ -82,6 +82,50 @@
|
|||||||
class="mileage-record-page__input"
|
class="mileage-record-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #previousMonthMileageForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.previousMonthMileage"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="numeric"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeIntegerInput('previousMonthMileage', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>km</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #currentMonthMileageForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.currentMonthMileage"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="numeric"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeIntegerInput('currentMonthMileage', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>km</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #monthlyMileageForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.monthlyMileage"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="numeric"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeIntegerInput('monthlyMileage', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>km</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #totalMileageForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.totalMileage"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="numeric"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeIntegerInput('totalMileage', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>km</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #totalMileageStart-search="{ row }">
|
<template #totalMileageStart-search="{ row }">
|
||||||
<div class="mileage-record-page__range">
|
<div class="mileage-record-page__range">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -224,7 +268,6 @@ export default {
|
|||||||
Object.keys(labelMap).forEach(prop => {
|
Object.keys(labelMap).forEach(prop => {
|
||||||
const column = this.findColumn(this.option.column, prop);
|
const column = this.findColumn(this.option.column, prop);
|
||||||
column.label = labelMap[prop];
|
column.label = labelMap[prop];
|
||||||
column.append = unit;
|
|
||||||
});
|
});
|
||||||
vehicleTypeColumn.disabled = Boolean(this.form.id);
|
vehicleTypeColumn.disabled = Boolean(this.form.id);
|
||||||
const unitColumn = this.findColumn(this.option.column, 'mileageUnit');
|
const unitColumn = this.findColumn(this.option.column, 'mileageUnit');
|
||||||
@@ -304,6 +347,9 @@ export default {
|
|||||||
toMoney(value) {
|
toMoney(value) {
|
||||||
return Math.round(Number(value) * 100) / 100;
|
return Math.round(Number(value) * 100) / 100;
|
||||||
},
|
},
|
||||||
|
normalizeIntegerInput(prop, value) {
|
||||||
|
this.form[prop] = String(value ?? '').replace(/\D/g, '');
|
||||||
|
},
|
||||||
normalizeRow(row) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.vehicleType = values.vehicleType || '车辆';
|
values.vehicleType = values.vehicleType || '车辆';
|
||||||
|
|||||||
@@ -70,6 +70,48 @@
|
|||||||
class="oil-electric-record-page__input"
|
class="oil-electric-record-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #quantityForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.quantity"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('quantity', value)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #unitPriceForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.unitPrice"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('unitPrice', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #transactionAmountForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.transactionAmount"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('transactionAmount', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #balanceForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.balance"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('balance', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #attachments="{ row }">
|
<template #attachments="{ row }">
|
||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -190,9 +232,7 @@ export default {
|
|||||||
},
|
},
|
||||||
updateFeeType(feeType) {
|
updateFeeType(feeType) {
|
||||||
const oilProductColumn = this.findColumn(this.option.column, 'oilProduct');
|
const oilProductColumn = this.findColumn(this.option.column, 'oilProduct');
|
||||||
const unitPriceColumn = this.findColumn(this.option.column, 'unitPrice');
|
|
||||||
oilProductColumn.display = feeType !== '充电';
|
oilProductColumn.display = feeType !== '充电';
|
||||||
unitPriceColumn.append = feeType === '充电' ? '元/度' : '元/升';
|
|
||||||
if (feeType === '充电') {
|
if (feeType === '充电') {
|
||||||
this.form.oilProduct = undefined;
|
this.form.oilProduct = undefined;
|
||||||
}
|
}
|
||||||
@@ -249,6 +289,13 @@ export default {
|
|||||||
isEmpty(value) {
|
isEmpty(value) {
|
||||||
return value === undefined || value === null || 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) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.vehicleType = values.vehicleType || '车辆';
|
values.vehicleType = values.vehicleType || '车辆';
|
||||||
|
|||||||
@@ -70,6 +70,17 @@
|
|||||||
class="other-expense-record-page__input"
|
class="other-expense-record-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #amountForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.amount"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('amount', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #attachments="{ row }">
|
<template #attachments="{ row }">
|
||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -234,6 +245,13 @@ export default {
|
|||||||
isEmpty(value) {
|
isEmpty(value) {
|
||||||
return value === undefined || value === null || 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) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.vehicleType = values.vehicleType || '车辆';
|
values.vehicleType = values.vehicleType || '车辆';
|
||||||
|
|||||||
@@ -70,6 +70,26 @@
|
|||||||
class="tire-replacement-record-page__input"
|
class="tire-replacement-record-page__input"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #tireQuantityForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.tireQuantity"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="numeric"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeIntegerInput('tireQuantity', value)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #replacementCostForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.replacementCost"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('replacementCost', value)"
|
||||||
|
>
|
||||||
|
<template #suffix>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
<template #attachments="{ row }">
|
<template #attachments="{ row }">
|
||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -225,6 +245,16 @@ export default {
|
|||||||
if (!value || typeof value === 'string') return value;
|
if (!value || typeof value === 'string') return value;
|
||||||
return JSON.stringify(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) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
if (values.vehicleNo) {
|
if (values.vehicleNo) {
|
||||||
|
|||||||
@@ -90,6 +90,26 @@
|
|||||||
placeholder="请输入船长"
|
placeholder="请输入船长"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #fineAmountForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.fineAmount"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="decimal"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeDecimalInput('fineAmount', value)"
|
||||||
|
>
|
||||||
|
<template #append>元</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<template #deductPointsForm>
|
||||||
|
<el-input
|
||||||
|
v-model="form.deductPoints"
|
||||||
|
:disabled="boxType === 'view'"
|
||||||
|
inputmode="numeric"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => normalizeIntegerInput('deductPoints', value)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<template #processStatus="{ row }">
|
<template #processStatus="{ row }">
|
||||||
<span :class="row.processStatus === '未处理' ? 'violation-record-page__danger' : ''">
|
<span :class="row.processStatus === '未处理' ? 'violation-record-page__danger' : ''">
|
||||||
{{ row.processStatus }}
|
{{ 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 getShipList } from '@/api/transportCapacity/transport-ship';
|
||||||
import { getList as getDriverList } from '@/api/transportCapacity/driver';
|
import { getList as getDriverList } from '@/api/transportCapacity/driver';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
@@ -179,6 +200,7 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
|
this.initViolationTypeOptions();
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['permission', 'userInfo']),
|
...mapGetters(['permission', 'userInfo']),
|
||||||
@@ -229,6 +251,15 @@ export default {
|
|||||||
column.dicData = res.data.data;
|
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) {
|
updateVehicleTypeDisplays(vehicleType, oldValue) {
|
||||||
const vehicleTypeColumn = this.findColumn(this.option.column, 'vehicleType');
|
const vehicleTypeColumn = this.findColumn(this.option.column, 'vehicleType');
|
||||||
const vehicleNoColumn = this.findColumn(this.option.column, 'vehicleNo');
|
const vehicleNoColumn = this.findColumn(this.option.column, 'vehicleNo');
|
||||||
@@ -240,6 +271,17 @@ export default {
|
|||||||
driverColumn.label = vehicleType === '船舶' ? '船长' : '驾驶人';
|
driverColumn.label = vehicleType === '船舶' ? '船长' : '驾驶人';
|
||||||
typeColumn.display = vehicleType !== '船舶';
|
typeColumn.display = vehicleType !== '船舶';
|
||||||
itemColumn.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);
|
vehicleTypeColumn.disabled = Boolean(this.form.id);
|
||||||
if (!this.isDetailLoading && oldValue && vehicleType !== oldValue) {
|
if (!this.isDetailLoading && oldValue && vehicleType !== oldValue) {
|
||||||
this.form.vehicleNo = '';
|
this.form.vehicleNo = '';
|
||||||
@@ -315,6 +357,16 @@ export default {
|
|||||||
if (!value || typeof value === 'string') return value;
|
if (!value || typeof value === 'string') return value;
|
||||||
return JSON.stringify(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) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.vehicleType = values.vehicleType || '车辆';
|
values.vehicleType = values.vehicleType || '车辆';
|
||||||
@@ -337,6 +389,14 @@ export default {
|
|||||||
return values;
|
return values;
|
||||||
},
|
},
|
||||||
validateRow(row) {
|
validateRow(row) {
|
||||||
|
if (row.vehicleType === '船舶' && !row.violationItem) {
|
||||||
|
this.$message.warning('请输入事项');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (row.vehicleType !== '船舶' && !row.violationType) {
|
||||||
|
this.$message.warning('请选择类型');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
row.violationTime &&
|
row.violationTime &&
|
||||||
new Date(row.violationTime.replace(/-/g, '/')).getTime() > Date.now()
|
new Date(row.violationTime.replace(/-/g, '/')).getTime() > Date.now()
|
||||||
|
|||||||
Reference in New Issue
Block a user