fix: 若干上传文件,表单bug

This commit is contained in:
louis 2024-03-08 10:38:53 +08:00
parent b2db3f82f1
commit fdc30067de
12 changed files with 369 additions and 183 deletions

View File

@ -1661,9 +1661,9 @@ declare namespace API {
/** 年度 */
year: number;
/** 外出使用的车辆Id */
vechicleId: number;
vehicleId: number;
/** 外出使用的车辆名称(字典) */
vechicle: DictItemEntity;
vehicle: DictItemEntity;
/** 申请人 */
applicant: string;
/** 出行司机 */
@ -1696,11 +1696,13 @@ declare namespace API {
/** 年度 */
year: number;
/** 外出使用的车辆名称(字典) */
vechicleId: number;
vehicleId: number;
/** 申请人 */
applicant: string;
/** 出行司机 */
driver: string;
/** 随行人员 */
partner: string;
/** 当前车辆里程数(KM) */
currentMileage: number;
/** 预计出行开始时间 */
@ -1723,7 +1725,6 @@ declare namespace API {
};
type VehicleUsageUpdateParams = {
id: number;
};
type VehicleUsageParams = {
page?: number;
@ -1739,7 +1740,7 @@ declare namespace API {
/** 年度 */
year?: number;
/** 外出使用的车辆名称(字典) */
vechicleId?: number;
vehicleId?: number;
/** 申请人 */
applicant?: string;
/** 出行司机 */

View File

@ -81,7 +81,7 @@ type ComponentSchema<T extends object = Recordable> =
/** 表单项 */
export type FormSchema<T extends object = Recordable> = ComponentSchema<T> & {
/** 字段名 */
field: GetFieldKeys<T>;
field?: GetFieldKeys<T>;
// Event name triggered by internal value change, default change
changeEvent?: string;
// Variable name bound to v-model Default value

View File

@ -1,4 +1,5 @@
export enum DictEnum {
ContractType = 'contract_type', // 合同类型
Unit = 'unit', // 单位
Unit = 'unit', // 单位,
Vehicle = 'vehicle', // 车辆
}

5
src/enums/vehicleEnum.ts Normal file
View File

@ -0,0 +1,5 @@
export enum VehicleUsageStatusEnum {
Pending = 0, // 待审核
Approved = 1, // 已通过
Rejected = 2, // 已拒绝
}

View File

@ -35,7 +35,7 @@
<LockOutlined @click="lockscreenStore.setLock(true)" />
</Tooltip>
<FullScreen />
<LocalePicker />
<!-- <LocalePicker /> -->
<Dropdown placement="bottomRight">
<Avatar :src="userInfo.avatar" :alt="userInfo.username">{{ userInfo.username }}</Avatar>
<template #overlay>

View File

@ -5,7 +5,8 @@ import { store } from '@/store';
import { DictEnum } from '@/enums/dictEnum';
const needCachedKey = [
DictEnum.ContractType,
DictEnum.Unit
DictEnum.Unit,
DictEnum.Vehicle
];
export const useDictStore = defineStore('dict', () => {

View File

@ -11,7 +11,7 @@ export function formatToDateTime(date?: dayjs.ConfigType, format = DATE_TIME_FOR
}
export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): string {
return dayjs(date).format(format);
return date ? dayjs(date).format(format) : '';
}
export const dateUtil = dayjs;

View File

@ -1,10 +1,10 @@
import type { FormSchema } from '@/components/core/schema-form/';
import { ContractStatusEnum } from '@/enums/contractEnum';
import { formatStatus } from './columns';
export const contractSchemas = (
contractTypes: API.DictItemEntity[],
): FormSchema<API.ContractEntity>[] => [
import { useDictStore } from '@/store/modules/dict';
import { DictEnum } from '@/enums/dictEnum';
const { getDictItemsByCode } = useDictStore();
export const formSchemas = (isEdit = false): FormSchema<API.ContractEntity>[] => [
{
field: 'contractNumber',
component: 'Input',
@ -47,7 +47,6 @@ export const contractSchemas = (
field: 'signingDate',
label: '签订时间',
component: 'DatePicker',
// defaultValue: new Date(),
colProps: { span: 12 },
componentProps: {},
},
@ -55,7 +54,6 @@ export const contractSchemas = (
field: 'deliveryDeadline',
label: '交付期限',
component: 'DatePicker',
// defaultValue: new Date(),
colProps: { span: 12 },
},
{
@ -67,7 +65,10 @@ export const contractSchemas = (
span: 12,
},
componentProps: {
options: contractTypes.map(({ label, id }) => ({ value: id, label })),
options: getDictItemsByCode(DictEnum.ContractType).map(({ label, id }) => ({
value: id,
label,
})),
},
},
{
@ -75,6 +76,7 @@ export const contractSchemas = (
label: '审核结果',
component: 'Select',
required: true,
vIf:isEdit,
defaultValue: 0,
colProps: {
span: 12,

View File

@ -28,7 +28,7 @@
import { baseColumns, type TableColumnItem, type TableListItem } from './columns';
import Api from '@/api/';
import { useFormModal, useModal } from '@/hooks/useModal';
import { contractSchemas } from './formSchemas';
import { formSchemas } from './formSchemas';
import { formatToDate } from '@/utils/dateUtil';
import { Button } from 'ant-design-vue';
import AttachmentManage from '@/components/business/attachment-manage/index.vue';
@ -40,10 +40,7 @@
const [DynamicTable, dynamicTableInstance] = useTable();
const [showModal] = useFormModal();
const [fnModal] = useModal();
const contractTypes = ref<API.DictItemEntity[]>([]);
const isUploadPopupVisiable = ref(false);
// contractList;
let columns = ref<TableColumnItem[]>();
onMounted(() => {
columns.value = [
@ -139,20 +136,20 @@
onFinish: async (values) => {
const params = {
...values,
signingDate: formatToDate(values.signingDate),
deliveryDeadline: formatToDate(values.deliveryDeadline),
signingDate: formatToDate(values.signingDate) || undefined,
deliveryDeadline: formatToDate(values.deliveryDeadline) || undefined,
};
if (record.id) {
await Api.contract.contractUpdate({ id: record.id }, params);
} else {
await Api.contract.contractCreate(params);
await Api.contract.contractCreate(params as API.ContractDto);
}
dynamicTableInstance?.reload();
},
},
formProps: {
labelWidth: 100,
schemas: contractSchemas(contractTypes.value),
schemas: formSchemas(!!record.id),
},
});

View File

@ -1,62 +1,172 @@
import Api from '@/api';
import type { TableColumn } from '@/components/core/dynamic-table';
import { VehicleUsageStatusEnum } from '@/enums/vehicleEnum';
import { formatToDate } from '@/utils/dateUtil';
import { Tag } from 'ant-design-vue';
import dayjs from 'dayjs';
export type TableListItem = API.VehicleUsageEntity;
export type TableColumnItem = TableColumn<TableListItem>;
export const baseColumns: TableColumnItem[] = [
{
title: '外出使用的车辆名称及车牌号',
dataIndex: 'vechicle',
title: '年度',
width: 80,
fixed: 'left',
dataIndex: 'year',
formItemProps: {
label: '年度',
component: 'Select',
componentProps: {
fieldNames: {
label: 'label',
value: 'value',
},
options: Array.from({ length: dayjs().year() - 2010 }).map((_, index) => ({
label: `${dayjs().year() - index}`,
value: dayjs().year() - index,
})),
},
colProps: {
span: 4,
},
},
},
{
title: '车辆名称及车牌号',
width: 150,
dataIndex: 'vehicle',
fixed: 'left',
formItemProps: {
labelWidth: 150,
label: '车辆名称及车牌号',
span: 12,
},
customRender: ({ record }) => {
return record?.vechicle?.label || '';
return record?.vehicle?.label || '';
},
},
{
title: '申请人',
dataIndex: 'applicant',
formItemProps: {
span: 10,
},
},
{
title: '出行司机',
hideInSearch: true,
dataIndex: 'driver',
},
// /** 外出使用的车辆Id */
// vechicleId: number;
// /** 外出使用的车辆名称(字典) */
// vechicle: DictItemEntity;
// /** 申请人 */
// applicant: string;
// /** 出行司机 */
// driver: string;
// /** 当前车辆里程数(KM) */
// currentMileage: number;
// /** 预计出行开始时间 */
// expectedStartDate: Date;
// /** 预计出行结束时间 */
// expectedEndDate: Date;
// /** 使用事由 */
// purpose: string;
// /** 实际回司时间 */
// actualReturnTime: Date;
// /** 回城车辆里程数(KM) */
// returnMileage: number;
// /** 审核人 */
// reviewer: string;
// /** 审核状态0待审核1同意2.不同意(字典) */
// status: number;
// /** 备注 */
// remark: string;
// {
// title: '所属公司',
// dataIndex: 'company',
// customRender: ({ record }) => {
// return record?.company?.name || '';
// },
// },
// {
// title: '单位',
// dataIndex: 'unit',
// customRender: ({ record }) => {
// return record?.unit?.label || '';
// },
// },
{
title: '随行人员',
hideInSearch: true,
dataIndex: 'partner',
},
{
title: '当前车辆里程数(KM)',
hideInSearch: true,
dataIndex: 'currentMileage',
},
{
title: '预计出行开始时间',
width: 130,
hideInSearch: true,
align: 'center',
dataIndex: 'expectedStartDate',
customRender: ({ record }) => {
return formatToDate(record.expectedStartDate);
},
},
{
title: '预计出行结束时间',
width: 130,
hideInSearch: true,
align: 'center',
dataIndex: 'expectedEndDate',
customRender: ({ record }) => {
return formatToDate(record.expectedEndDate);
},
},
{
title: '使用事由',
dataIndex: 'purpose',
hideInSearch: true,
},
{
title: '实际回司时间',
hideInSearch: true,
width: 130,
align: 'center',
dataIndex: 'actualReturnTime',
customRender: ({ record }) => {
return formatToDate(record.actualReturnTime);
},
},
{
title: '回城车辆里程数(KM)',
hideInSearch: true,
dataIndex: 'returnMileage',
},
{
title: '审核人',
hideInSearch: true,
dataIndex: 'reviewer',
},
{
title: '备注',
hideInSearch: true,
dataIndex: 'remark',
},
{
title: '审核状态',
width: 100,
align:'center',
fixed: 'right',
dataIndex: 'status',
formItemProps: {
component: 'Select',
componentProps: {
options: Object.values(VehicleUsageStatusEnum)
.filter((value) => typeof value === 'number')
.map((item) => formatStatus(item as VehicleUsageStatusEnum)),
},
},
customRender: ({ record }) => {
const { color, label } = formatStatus(record.status);
return <Tag color={color}>{label}</Tag>;
},
},
];
export function formatStatus(status: VehicleUsageStatusEnum): {
color: string;
label: string;
value: number;
} {
switch (status) {
case VehicleUsageStatusEnum.Pending:
return {
color: '#ccc',
label: '待审核',
value: VehicleUsageStatusEnum.Pending,
};
case VehicleUsageStatusEnum.Approved:
return {
color: 'green',
label: '已通过',
value: VehicleUsageStatusEnum.Approved,
};
case VehicleUsageStatusEnum.Rejected:
return {
color: 'red',
label: '已拒绝',
value: VehicleUsageStatusEnum.Rejected,
};
default:
return {
color: '#ccc',
label: '待审核',
value: VehicleUsageStatusEnum.Pending,
};
}
}

View File

@ -1,99 +1,182 @@
import Api from '@/api';
import type { FormSchema } from '@/components/core/schema-form/';
import { DictEnum } from '@/enums/dictEnum';
import { VehicleUsageStatusEnum } from '@/enums/vehicleEnum';
import { useDictStore } from '@/store/modules/dict';
import { debounce } from 'lodash-es';
import dayjs from 'dayjs';
import { formatStatus } from './columns';
const { getDictItemsByCode } = useDictStore();
export const formSchemas: FormSchema<API.VehicleUsageDto>[] = [
// {
// field: 'name',
// component: 'Input',
// label: '车辆使用名称',
// rules: [{ required: true, type: 'string' }],
// colProps: {
// span: 12,
// },
// },
// {
// label: '单位',
// component: 'Select',
// field: 'unitId',
// colProps: {
// span: 12,
// },
// componentProps: ({ formInstance, schema, formModel }) => ({
// showSearch: true,
// filterOption: (input: string, option: any) => {
// return option.label.indexOf(input) >= 0;
// },
// fieldNames: {
// label: 'label',
// value: 'value',
// },
// options: getDictItemsByCode(DictEnum.Unit).map((item) => ({
// value: item.id,
// label: item.label,
// })),
export const formSchemas = (isEdit?: boolean): FormSchema<API.VehicleUsageDto>[] => [
{
label: '年度',
component: 'Select',
field: 'year',
colProps: {
span: 6,
},
defaultValue: dayjs().year(),
rules: [{ required: true, type: 'number' }],
componentProps: () => ({
fieldNames: {
label: 'label',
value: 'value',
},
defaultValue: dayjs().year(),
options: Array.from({ length: dayjs().year() - 2010 }).map((_, index) => ({
label: `${dayjs().year() - index}`,
value: dayjs().year() - index,
})),
}),
},
// getPopupContainer: () => document.body,
// defaultActiveFirstOption: true,
// }),
// },
// {
// field: 'companyId',
// component: 'Select',
// label: '所属公司',
// helpMessage: '如未找到对应公司,请先去公司管理添加公司。',
// componentProps: ({ formInstance, schema }) => ({
// showSearch: true,
// filterOption: false,
// fieldNames: {
// label: 'label',
// value: 'value',
// },
// options: [],
// getPopupContainer: () => document.body,
// defaultActiveFirstOption: true,
// onChange: async (value) => {
// if (!value) {
// formInstance?.setFieldsValue({ companyId: undefined });
// const options = await getCompanyOptions();
// const newSchema = {
// field: schema.field,
// componentProps: {
// options,
// },
// };
// formInstance?.updateSchema([newSchema]);
// }
// },
// request: () => {
// return getCompanyOptions();
// },
// onSearch: debounce(async (keyword) => {
// schema.loading = true;
// const newSchema = {
// field: schema.field,
// componentProps: {
// options: [] as LabelValueOptions,
// },
// };
// formInstance?.updateSchema([newSchema]);
// const options = await getCompanyOptions(keyword).finally(() => (schema.loading = false));
// newSchema.componentProps.options = options;
// formInstance?.updateSchema([newSchema]);
// }, 500),
// }),
// },
];
const getCompanyOptions = async (keyword?: string): Promise<LabelValueOptions> => {
const { items: result } = await Api.company.companyList({ pageSize: 100, name: keyword });
return (
result?.map((item) => ({
label: item.name,
{
field: 'vehicleId',
component: 'Select',
label: '车辆名称及车牌号',
rules: [{ required: true, type: 'number' }],
labelWidth: 150,
helpMessage: '如未找到对应车辆,请先去字典管理添加车辆。',
colProps: {
span: 16,
offset: 1,
},
componentProps: ({ formInstance, schema }) => ({
showSearch: true,
filterOption: (input: string, option: any) => {
return option.label.toLocaleLowerCase().indexOf(input.toLocaleLowerCase()) >= 0;
},
fieldNames: {
label: 'label',
value: 'value',
},
options: getDictItemsByCode(DictEnum.Vehicle).map((item) => ({
value: item.id,
})) || []
);
};
label: item.label,
})),
getPopupContainer: () => document.body,
defaultActiveFirstOption: true,
}),
},
{
field: 'applicant',
component: 'Input',
label: '申请人',
rules: [{ required: true, type: 'string' }],
colProps: {
span: 8,
},
},
{
field: 'driver',
component: 'Input',
label: '出行司机',
rules: [{ type: 'string' }],
colProps: {
span: 8,
},
},
{
field: 'partner',
component: 'Input',
label: '随行人员',
rules: [{ type: 'string' }],
colProps: {
span: 8,
},
},
{
label: '预计出行开始时间',
field: 'expectedStartDate',
component: 'DatePicker',
labelWidth: 150,
rules: [{ type: 'date', required: true }],
colProps: {
span: 12,
},
},
{
label: '预计出行结束时间',
field: 'expectedEndDate',
labelWidth: 150,
rules: [{ type: 'date', required: true }],
component: 'DatePicker',
colProps: {
span: 12,
},
},
{
field: 'currentMileage',
component: 'InputNumber',
label: '当前车辆里程数(KM)',
rules: [{ type: 'number' }],
labelWidth: 150,
colProps: {
span: 24,
},
},
{
label: '回城车辆里程数(KM)',
labelWidth: 150,
vIf: isEdit,
field: 'returnMileage',
rules: [{ type: 'number' }],
component: 'InputNumber',
colProps: {
span: 24,
},
},
{
label: '实际回司时间',
field: 'actualReturnTime',
labelWidth: 150,
vIf: isEdit,
rules: [{ type: 'date' }],
component: 'DatePicker',
colProps: {
span: 12,
},
},
{
field: 'purpose',
component: 'InputTextArea',
label: '使用事由',
rules: [{ type: 'string' }],
},
{
field: 'reviewer',
component: 'Input',
label: '审核人',
rules: [{ type: 'string' }],
colProps: {
span: 8,
},
},
{
field: 'status',
label: '审核结果',
component: 'Select',
required: true,
vIf: isEdit,
defaultValue: 0,
colProps: {
span: 8,
},
componentProps: {
allowClear: false,
options: Object.values(VehicleUsageStatusEnum)
.filter((value) => typeof value === 'number')
.map((item) => formatStatus(item as VehicleUsageStatusEnum)),
},
},
{
label: '备注',
field: 'remark',
component: 'Input',
colProps: {
span: 8,
},
},
];

View File

@ -8,12 +8,13 @@
:columns="columns"
:exportFileName="'车辆使用'"
bordered
:scroll="{ x: 1920 }"
size="small"
>
<template #toolbar>
<a-button
type="primary"
:disabled="!$auth('system:role:create')"
:disabled="!$auth('app:vehicle_usage:create')"
@click="openEditModal({})"
>
新增
@ -41,23 +42,7 @@
const [showModal] = useFormModal();
const [fnModal] = useModal();
const isUploadPopupVisiable = ref(false);
const dictStore = useDictStore();
let columns = ref<TableColumnItem[]>();
// const loadData = async (params): Promise<API.VehicleUsageEntity> => {
// console.log('params', params);
// return Api.vehicleUsage.vehicleUsageList(params);
// };
// const loadTableData = async (params: any) => {
// const { company, ...res } = params;
// const data = await Api.vehicleUsage.vehicleUsageList({
// ...res,
// company,
// });
// return data;
// };
const exportFormatter = (columns: TableColumn[], tableData: any[]) => {
return { header: columns.map((item) => item.title), data: [] };
};
onMounted(() => {
columns.value = [
...baseColumns,
@ -65,6 +50,7 @@
title: '附件',
width: 50,
maxWidth: 50,
fixed: 'right',
hideInSearch: true,
hideInExport: true,
dataIndex: 'files',
@ -83,7 +69,7 @@
icon: 'ant-design:edit-outlined',
tooltip: '编辑',
auth: {
perm: 'app:vehicleUsage:update',
perm: 'app:vehicle_usage:update',
effect: 'disable',
},
onClick: () => openEditModal(record),
@ -92,7 +78,7 @@
icon: 'ant-design:delete-outlined',
color: 'red',
tooltip: '删除此车辆使用',
auth: 'app:vehicleUsage:delete',
auth: 'app:vehicle_usage:delete',
popConfirm: {
title: '你确定要删除吗?',
placement: 'left',
@ -113,7 +99,7 @@
isUploadPopupVisiable.value = true;
fnModal.show({
width: 800,
title: `车辆使用: ${record.vechicleId}`,
title: `车辆使用: ${record.vehicleId}`,
content: () => {
return (
<AttachmentUpload
@ -163,7 +149,7 @@
},
formProps: {
labelWidth: 100,
schemas: formSchemas,
schemas: formSchemas(!!record.id),
},
});