Browse Source

重构底层上传组件,支持表格动态渲染

master
wangxiang 3 years ago
parent
commit
2b1a47a096
  1. 4
      src/api/platform/core/entity/upload.ts
  2. 2
      src/api/platform/system/controller/file.ts
  3. 2
      src/components/AMap/src/AMapDesigner/index.vue
  4. 75
      src/components/AMap/src/amap.data.ts
  5. 20
      src/components/AMap/src/components/TaskModal.vue
  6. 2
      src/components/Table/src/componentMap.ts
  7. 2
      src/components/Table/src/components/editable/EditableCell.vue
  8. 3
      src/components/Table/src/types/componentType.ts
  9. 35
      src/components/Upload/src/UploadModal.vue
  10. 13
      src/components/Upload/src/UploadPreviewModal.vue
  11. 29
      src/components/Upload/src/data.tsx
  12. 2
      src/components/Upload/src/helper.ts
  13. 4
      src/components/Upload/src/typing.ts

4
src/api/platform/core/entity/upload.ts

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
/** oss上传返回结果对象 */
export interface UploadResult {
message: string;
code: number;
bucketName: string;
fileName: string;
url: string;
}

2
src/api/platform/system/controller/file.ts

@ -20,7 +20,7 @@ enum Api { @@ -20,7 +20,7 @@ enum Api {
export const listFile = (params?: Partial<FileParams>) => defHttp.get<FileResult>({ url: Api.list, params }, { isReturnResultResponse: true });
/** 获取文件 */
export const getFile = (bucket: string, fileName: string) => Promise.resolve(downloadByUrl({ url: `${apiUrl}/${Api.get}/${bucket}/${fileName}`, fileName: fileName }));
export const getFile = (bucket: string, fileName: string) => Promise.resolve(downloadByUrl({ url: `${apiUrl}${Api.get}/${bucket}/${fileName}`, fileName: fileName }));
/** 获取本地模板文件 */
export const getLocalFile = (fileName: string) => defHttp.get({ url: `${Api.getLocal}/${fileName}` });

2
src/components/AMap/src/AMapDesigner/index.vue

@ -82,7 +82,7 @@ @@ -82,7 +82,7 @@
</template>
<script lang="ts" setup>
import AMapLoader from '@amap/amap-jsapi-loader';
import {reactive, watchEffect, getCurrentInstance, onBeforeMount, onUnmounted, ref} from 'vue';
import { reactive, watchEffect, getCurrentInstance, onBeforeMount, onUnmounted, ref } from 'vue';
import { columns } from '../amap.data';
import hospital from '/@/assets/images/hospital.svg';
import medicalKit from '/@/assets/images/medical-kit.svg';

75
src/components/AMap/src/amap.data.ts

@ -1,4 +1,8 @@ @@ -1,4 +1,8 @@
import { BasicColumn } from '/@/components/Table';
import { listHospital } from '/@/api/platform/common/controller/hospital';
import { listUser } from '/@/api/platform/system/controller/user';
import { listOrg } from '/@/api/platform/common/controller/org';
import { commonUpload } from '/@/api/platform/core/controller/upload';
/**
* @program: kicc-ui
@ -38,55 +42,49 @@ export const columns: BasicColumn[] = [ @@ -38,55 +42,49 @@ export const columns: BasicColumn[] = [
/** 表格普通任务列 */
export const taskColumns: BasicColumn[] = [
{
title: '下级医院',
dataIndex: 'small_hospital_id',
title: '医院',
dataIndex: 'hospitalId',
editRow: true,
editRule: true,
editComponent: 'Select',
editComponent: 'ApiSelect',
editComponentProps: {
options: [
{
label: 'Option1',
value: '1'
},
{
label: 'Option2',
value: '2'
},
{
label: 'Option3',
value: '3'
}
]
api: listHospital,
params: { size: 40 },
labelField: 'name',
valueField: 'id',
resultField: 'data'
}
},
{
title: '上级医院',
dataIndex: 'largeHospitalId',
title: '医检',
dataIndex: 'orgId',
editRow: true,
editRule: true,
editComponent: 'Select',
editComponent: 'ApiSelect',
editComponentProps: {
options: [
{
label: 'Option1',
value: '1'
},
{
label: 'Option2',
value: '2'
},
{
label: 'Option3',
value: '3'
}
]
api: listOrg,
params: { size: 40 },
labelField: 'name',
valueField: 'id',
resultField: 'data'
}
},
{
title: '上传文件',
dataIndex: 'file'
dataIndex: 'fileId',
editRow: true,
editComponent: 'Upload',
editComponentProps: {
multiple: true,
maxSize: 20,
maxNumber: 10,
showUploadSaveBtn: true,
showPreviewNumber: false,
emptyHidePreview: true,
api: commonUpload,
accept: ['image/*']
}
},
// todo: 第二版功能
/*{
title: '要求时间',
dataIndex: 'timeRequired',
@ -215,7 +213,8 @@ export const formMutualTaskSettingColumns: BasicColumn[] = [ @@ -215,7 +213,8 @@ export const formMutualTaskSettingColumns: BasicColumn[] = [
]
}
},
{
// todo: 第二版功能
/*{
title: '要求时间',
dataIndex: 'timeRequired',
editRow: true,
@ -224,7 +223,7 @@ export const formMutualTaskSettingColumns: BasicColumn[] = [ @@ -224,7 +223,7 @@ export const formMutualTaskSettingColumns: BasicColumn[] = [
valueFormat: 'YYYY-MM-DD',
format: 'YYYY-MM-DD',
}
}
}*/
];
export const formMapDataSettingsColumns = [

20
src/components/AMap/src/components/TaskModal.vue

@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
import { reactive } from 'vue';
import {BasicModal, ModalProps, useModal, useModalInner} from '/@/components/Modal';
import { BasicTable, useTable, EditRecordRow, BasicColumn, ActionItem, TableAction } from '/@/components/Table';
import { formTaskColumns, formMutualTaskColumns, largeHospitalMapList, smallHospitalMapList, } from '../amap.data';
import { taskColumns, taskPresetColumns, largeHospitalMapList, smallHospitalMapList, } from '../amap.data';
import { buildUUID } from '/@/utils/uuid';
import TaskPresetModal from './TaskPresetModal.vue';
@ -71,7 +71,7 @@ @@ -71,7 +71,7 @@
const [taskPresetRegisterModal, { openModal }] = useModal();
const [registerTable, { reload, getDataSource }] = useTable({
title: '普通任务',
columns: formTaskColumns,
columns: taskColumns,
pagination: {
pageSize: 3,
showSizeChanger: false
@ -91,7 +91,7 @@ @@ -91,7 +91,7 @@
});
const [schemeRegisterTable, { reload: schemeReload, getDataSource: getMutualDataSource, setProps }] = useTable({
title: '交接任务',
columns: formMutualTaskColumns,
columns: taskPresetColumns,
pagination: {
pageSize: 3,
showSizeChanger: false
@ -113,16 +113,18 @@ @@ -113,16 +113,18 @@
/** 处理任务新增 */
function handleTaskAdd() {
getDataSource().push({
smallHospitalId: '',
largeHospitalId: ''
hospitalId: '',
orgId: '',
fileId: []
});
}
/** 处理任务新增 */
function handleMutualTaskAdd() {
getMutualDataSource().push({
smallHospitalId: '',
largeHospitalId: ''
hospitalId: '',
orgId: '',
fileId: []
});
}
@ -226,9 +228,9 @@ @@ -226,9 +228,9 @@
taskDataSource.forEach(item => {
// ID
const key = buildUUID();
const smallHospital = smallHospitalMapList.find(index => index.id == item.smallHospitalId);
const smallHospital = smallHospitalMapList.find(index => index.id == item.hospitalId);
if(smallHospital) smallHospitalPositions.push([key, new AMap.LngLat(smallHospital.lng, smallHospital.lat)]);
const largeHospital = largeHospitalMapList.find(index => index.id == item.largeHospitalId);
const largeHospital = largeHospitalMapList.find(index => index.id == item.orgId);
if(largeHospital) largeHospitalPositions.push([key, new AMap.LngLat(largeHospital.lng, largeHospital.lat)]);
});
//

2
src/components/Table/src/componentMap.ts

@ -10,6 +10,7 @@ import { @@ -10,6 +10,7 @@ import {
} from 'ant-design-vue';
import type { ComponentType } from './types/componentType';
import { ApiSelect, ApiTreeSelect } from '/@/components/Form';
import { BasicUpload } from "/@/components/Upload";
const componentMap = new Map<ComponentType, Component>();
@ -22,6 +23,7 @@ componentMap.set('Switch', Switch); @@ -22,6 +23,7 @@ componentMap.set('Switch', Switch);
componentMap.set('Checkbox', Checkbox);
componentMap.set('DatePicker', DatePicker);
componentMap.set('TimePicker', TimePicker);
componentMap.set('Upload', BasicUpload);
export function add(compName: ComponentType, component: Component) {
componentMap.set(compName, component);

2
src/components/Table/src/components/editable/EditableCell.vue

@ -187,7 +187,7 @@ @@ -187,7 +187,7 @@
currentValueRef.value = (e as ChangeEvent).target.value;
} else if (component === 'Checkbox') {
currentValueRef.value = (e as ChangeEvent).target.checked;
} else if (isString(e) || isBoolean(e) || isNumber(e)) {
} else if (isString(e) || isBoolean(e) || isNumber(e) || isArray(e)) {
currentValueRef.value = e;
}
const onChange = props.column?.editComponentProps?.onChange;

3
src/components/Table/src/types/componentType.ts

@ -7,4 +7,5 @@ export type ComponentType = @@ -7,4 +7,5 @@ export type ComponentType =
| 'Checkbox'
| 'Switch'
| 'DatePicker'
| 'TimePicker';
| 'TimePicker'
| 'Upload';

35
src/components/Upload/src/UploadModal.vue

@ -48,32 +48,28 @@ @@ -48,32 +48,28 @@
</BasicModal>
</template>
<script lang="ts">
import {defineComponent, reactive, ref, toRefs, unref, computed, PropType, watch} from 'vue';
import { defineComponent, reactive, ref, toRefs, unref, computed, PropType } from 'vue';
import { Upload, Alert } from 'ant-design-vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
// import { BasicTable, useTable } from '/@/components/Table';
// hooks
import { useUploadType } from './useUpload';
import { useMessage } from '/@/hooks/web/useMessage';
// types
import {FileItem, PreviewFileItem, UploadResultStatus} from './typing';
import { FileItem, UploadResultStatus } from './typing';
import { basicProps } from './props';
import { createTableColumns, createActionColumn } from './data';
// utils
import { checkImgType, getBase64WithFile } from './helper';
import { buildUUID } from '/@/utils/uuid';
import {isArray, isFunction} from '/@/utils/is';
import { isFunction } from '/@/utils/is';
import { warn } from '/@/utils/log';
import FileList from './FileList.vue';
import { useI18n } from '/@/hooks/web/useI18n';
import {useTimeoutFn} from '/@/hooks/core/useTimeout';
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
export default defineComponent({
components: { BasicModal, Upload, Alert, FileList },
props: {
...basicProps,
previewFileList: {
type: Array as PropType<string[]>,
type: Array as PropType<FileItem[]>,
default: () => [],
},
},
@ -83,18 +79,11 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout'; @@ -83,18 +79,11 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout';
fileList: [],
});
//
//
const isUploadingRef = ref(false);
const fileListRef = ref<FileItem[]>([]);
const { accept, helpText, maxNumber, maxSize } = toRefs(props);
watch(() => props.previewFileList, (value) => {
if (!isArray(value)) value = [];
fileListRef.value = value.filter((item) => !!item);
},
{ immediate: true }
);
const { t } = useI18n();
const [register, { closeModal }] = useModalInner();
@ -155,7 +144,6 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout'; @@ -155,7 +144,6 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout';
//
if (checkImgType(file)) {
// beforeUpload
// file.thumbUrl = await getBase64(file);
getBase64WithFile(file).then(({ result: thumbUrl }) => {
fileListRef.value = [
...unref(fileListRef),
@ -178,14 +166,6 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout'; @@ -178,14 +166,6 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout';
emit('delete', record);
}
//
// function handlePreview(record: FileItem) {
// const { thumbUrl = '' } = record;
// createImgPreview({
// imageList: [thumbUrl],
// });
// }
async function uploadApiByItem(item: FileItem) {
const { api } = props;
if (!api || !isFunction(api)) {
@ -252,7 +232,7 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout'; @@ -252,7 +232,7 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout';
}
}
//
//
function handleOk() {
const { maxNumber } = props;
@ -299,7 +279,6 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout'; @@ -299,7 +279,6 @@ import {useTimeoutFn} from '/@/hooks/core/useTimeout';
getStringAccept,
getOkButtonProps,
beforeUpload,
// registerTable,
fileListRef,
state,
isUploadingRef,

13
src/components/Upload/src/UploadPreviewModal.vue

@ -12,7 +12,6 @@ @@ -12,7 +12,6 @@
</template>
<script lang="ts">
import { defineComponent, watch, ref } from 'vue';
// import { BasicTable, useTable } from '/@/components/Table';
import FileList from './FileList.vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { previewProps } from './props';
@ -21,6 +20,8 @@ @@ -21,6 +20,8 @@
import { createPreviewColumns, createPreviewActionColumn } from './data';
import { useI18n } from '/@/hooks/web/useI18n';
import { isArray } from '/@/utils/is';
import { useGlobSetting } from '/@/hooks/setting';
const { apiUrl } = useGlobSetting();
export default defineComponent({
components: { BasicModal, FileList },
@ -61,18 +62,10 @@ @@ -61,18 +62,10 @@
}
}
// //
// function handlePreview(record: PreviewFileItem) {
// const { url = '' } = record;
// createImgPreview({
// imageList: [url],
// });
// }
//
function handleDownload(record: PreviewFileItem) {
const { url = '' } = record;
downloadByUrl({ url });
downloadByUrl({ url: `${apiUrl}${url}` });
}
return {

29
src/components/Upload/src/data.tsx

@ -1,14 +1,12 @@ @@ -1,14 +1,12 @@
import type { BasicColumn, ActionItem } from '/@/components/Table';
import { FileItem, PreviewFileItem, UploadResultStatus } from './typing';
import {
// checkImgType,
isImgTypeByName,
} from './helper';
import { isImgTypeByName } from './helper';
import { Progress, Tag } from 'ant-design-vue';
import TableAction from '/@/components/Table/src/components/TableAction.vue';
import ThumbUrl from './ThumbUrl.vue';
import { useI18n } from '/@/hooks/web/useI18n';
import {useGlobSetting} from '/@/hooks/setting';
const { apiUrl } = useGlobSetting();
const { t } = useI18n();
// 文件上传列表
@ -20,7 +18,7 @@ export function createTableColumns(): BasicColumn[] { @@ -20,7 +18,7 @@ export function createTableColumns(): BasicColumn[] {
width: 100,
customRender: ({ record }) => {
const { thumbUrl } = (record as FileItem) || {};
return thumbUrl && <ThumbUrl fileUrl={thumbUrl} />;
return thumbUrl && <ThumbUrl fileUrl={ thumbUrl } />;
},
},
{
@ -55,11 +53,6 @@ export function createTableColumns(): BasicColumn[] { @@ -55,11 +53,6 @@ export function createTableColumns(): BasicColumn[] {
return text && (text / 1024).toFixed(2) + 'KB';
},
},
// {
// dataIndex: 'type',
// title: '文件类型',
// width: 100,
// },
{
dataIndex: 'status',
title: t('component.upload.fileStatue'),
@ -92,12 +85,6 @@ export function createActionColumn(handleRemove: Function): BasicColumn { @@ -92,12 +85,6 @@ export function createActionColumn(handleRemove: Function): BasicColumn {
onClick: handleRemove.bind(null, record),
},
];
// if (checkImgType(record)) {
// actions.unshift({
// label: t('component.upload.preview'),
// onClick: handlePreview.bind(null, record),
// });
// }
return <TableAction actions={actions} outside={true} />;
},
};
@ -111,7 +98,7 @@ export function createPreviewColumns(): BasicColumn[] { @@ -111,7 +98,7 @@ export function createPreviewColumns(): BasicColumn[] {
width: 100,
customRender: ({ record }) => {
const { url } = (record as PreviewFileItem) || {};
return isImgTypeByName(url) && <ThumbUrl fileUrl={url} />;
return isImgTypeByName(url) && <ThumbUrl fileUrl={ apiUrl + url } />;
},
},
{
@ -123,9 +110,9 @@ export function createPreviewColumns(): BasicColumn[] { @@ -123,9 +110,9 @@ export function createPreviewColumns(): BasicColumn[] {
}
export function createPreviewActionColumn({
handleRemove,
handleDownload,
}: {
handleRemove,
handleDownload,
}: {
handleRemove: Fn;
handleDownload: Fn;
}): BasicColumn {

2
src/components/Upload/src/helper.ts

@ -1,8 +1,6 @@ @@ -1,8 +1,6 @@
export function checkFileType(file: File, accepts: string[]) {
const newTypes = accepts.join('|');
// const reg = /\.(jpg|jpeg|png|gif|txt|doc|docx|xls|xlsx|xml)$/i;
const reg = new RegExp('\\.(' + newTypes + ')$', 'i');
return reg.test(file.name);
}

4
src/components/Upload/src/typing.ts

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
import { UploadApiResult } from '/@/api/sys/model/uploadModel';
import { UploadResult } from '/@/api/platform/core/entity/upload';
export enum UploadResultStatus {
SUCCESS = 'success',
@ -14,7 +14,7 @@ export interface FileItem { @@ -14,7 +14,7 @@ export interface FileItem {
percent: number;
file: File;
status?: UploadResultStatus;
responseData?: UploadApiResult;
responseData?: UploadResult;
uuid: string;
}

Loading…
Cancel
Save