fix: update upload component
New file |
| | |
| | | @import (reference) '../../../design/index.less'; |
| | | |
| | | .file-table { |
| | | width: 100%; |
| | | border-collapse: collapse; |
| | | // border: 1px solid @border-color-light; |
| | | |
| | | .center { |
| | | text-align: center; |
| | | } |
| | | |
| | | .left { |
| | | text-align: left; |
| | | } |
| | | |
| | | .right { |
| | | text-align: right; |
| | | } |
| | | |
| | | &-th, |
| | | &-td { |
| | | padding: 12px 8px; |
| | | } |
| | | |
| | | thead { |
| | | background-color: @background-color-dark; |
| | | } |
| | | |
| | | table, |
| | | td, |
| | | th { |
| | | border: 1px solid @border-color-light; |
| | | } |
| | | } |
New file |
| | |
| | | import { defineComponent } from 'vue'; |
| | | import { fileListProps } from './props'; |
| | | import { isFunction } from '/@/utils/is'; |
| | | import './FileList.less'; |
| | | |
| | | export default defineComponent({ |
| | | name: 'FileList', |
| | | props: fileListProps, |
| | | setup(props) { |
| | | return () => { |
| | | const { columns, actionColumn, dataSource } = props; |
| | | |
| | | return ( |
| | | <table class="file-table"> |
| | | <colgroup> |
| | | {[...columns, actionColumn].map((item) => { |
| | | const { width = 0 } = item; |
| | | return width ? ( |
| | | <col style={'width:' + width + 'px;min-width:' + width + 'px;'} /> |
| | | ) : ( |
| | | <col /> |
| | | ); |
| | | })} |
| | | </colgroup> |
| | | <thead> |
| | | <tr class="file-table-tr"> |
| | | {[...columns, actionColumn].map((item) => { |
| | | const { title = '', align = 'center' } = item; |
| | | return <th class={['file-table-th', align]}>{title}</th>; |
| | | })} |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | {dataSource.map((record = {}) => { |
| | | return ( |
| | | <tr class="file-table-tr"> |
| | | {[...columns, actionColumn].map((item) => { |
| | | const { dataIndex = '', customRender, align = 'center' } = item; |
| | | if (customRender && isFunction(customRender)) { |
| | | return ( |
| | | <td class={['file-table-td', align]}> |
| | | {customRender({ text: record[dataIndex], record })} |
| | | </td> |
| | | ); |
| | | } else { |
| | | return <td class={['file-table-td', align]}>{record[dataIndex]}</td>; |
| | | } |
| | | })} |
| | | </tr> |
| | | ); |
| | | })} |
| | | </tbody> |
| | | </table> |
| | | ); |
| | | }; |
| | | }, |
| | | }); |
| | |
| | | {{ getUploadBtnText }} |
| | | </a-button> |
| | | </template> |
| | | |
| | | <BasicTable @register="registerTable" :dataSource="fileListRef"> |
| | | <template #toolbar> |
| | | <Upload :accept="getStringAccept" :multiple="multiple" :before-upload="beforeUpload"> |
| | | <a-button type="primary"> 选择文件 </a-button> |
| | | </Upload> |
| | | </template> |
| | | <template #tableTitle> |
| | | <Alert :message="getHelpText" type="info" banner></Alert> |
| | | </template> |
| | | </BasicTable> |
| | | <div class="upload-modal-toolbar"> |
| | | <Alert :message="getHelpText" type="info" banner class="upload-modal-toolbar__text"></Alert> |
| | | <Upload |
| | | :accept="getStringAccept" |
| | | :multiple="multiple" |
| | | :before-upload="beforeUpload" |
| | | class="upload-modal-toolbar__btn" |
| | | > |
| | | <a-button type="primary"> 选择文件 </a-button> |
| | | </Upload> |
| | | </div> |
| | | <FileList :dataSource="fileListRef" :columns="columns" :actionColumn="actionColumn" /> |
| | | </BasicModal> |
| | | </template> |
| | | <script lang="ts"> |
| | | import { defineComponent, reactive, ref, toRefs, unref, computed } from 'vue'; |
| | | import { Upload, Alert } from 'ant-design-vue'; |
| | | import { BasicModal, useModalInner } from '/@/components/Modal'; |
| | | import { BasicTable, useTable } from '/@/components/Table'; |
| | | // import { BasicTable, useTable } from '/@/components/Table'; |
| | | // hooks |
| | | import { useUploadType } from './useUpload'; |
| | | import { useMessage } from '/@/hooks/web/useMessage'; |
| | |
| | | import { uploadApi } from '/@/api/sys/upload'; |
| | | import { isFunction } from '/@/utils/is'; |
| | | import { warn } from '/@/utils/log'; |
| | | |
| | | import FileList from './FileList'; |
| | | export default defineComponent({ |
| | | components: { BasicModal, Upload, BasicTable, Alert }, |
| | | components: { BasicModal, Upload, Alert, FileList }, |
| | | props: basicProps, |
| | | setup(props, { emit }) { |
| | | // 是否正在上传 |
| | |
| | | } |
| | | } |
| | | |
| | | const [registerTable] = useTable({ |
| | | // const [registerTable] = useTable({ |
| | | // columns: createTableColumns(), |
| | | // actionColumn: createActionColumn(handleRemove, handlePreview), |
| | | // pagination: false, |
| | | // inset: true, |
| | | // scroll: { |
| | | // y: 3000, |
| | | // }, |
| | | // }); |
| | | return { |
| | | columns: createTableColumns(), |
| | | actionColumn: createActionColumn(handleRemove, handlePreview), |
| | | pagination: false, |
| | | inset: true, |
| | | scroll: { |
| | | y: 3000, |
| | | }, |
| | | }); |
| | | return { |
| | | register, |
| | | closeModal, |
| | | getHelpText, |
| | | getStringAccept, |
| | | getOkButtonProps, |
| | | beforeUpload, |
| | | registerTable, |
| | | // registerTable, |
| | | fileListRef, |
| | | state, |
| | | isUploadingRef, |
| | |
| | | .ant-table-wrapper .ant-spin-nested-loading { |
| | | padding: 0; |
| | | } |
| | | |
| | | &-toolbar { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 8px; |
| | | |
| | | &__btn { |
| | | margin-left: 8px; |
| | | text-align: right; |
| | | flex: 1; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | @register="register" |
| | | :showOkBtn="false" |
| | | > |
| | | <BasicTable @register="registerTable" :dataSource="fileListRef" /> |
| | | <FileList :dataSource="fileListRef" :columns="columns" :actionColumn="actionColumn" /> |
| | | </BasicModal> |
| | | </template> |
| | | <script lang="ts"> |
| | | import { defineComponent, watch, ref, unref } from 'vue'; |
| | | |
| | | import { BasicTable, useTable } from '/@/components/Table'; |
| | | // import { BasicTable, useTable } from '/@/components/Table'; |
| | | import FileList from './FileList'; |
| | | |
| | | import { BasicModal, useModalInner } from '/@/components/Modal'; |
| | | import { previewProps } from './props'; |
| | | import { PreviewFileItem } from './types'; |
| | |
| | | |
| | | import { createPreviewColumns, createPreviewActionColumn } from './data'; |
| | | export default defineComponent({ |
| | | components: { BasicModal, BasicTable }, |
| | | components: { BasicModal, FileList }, |
| | | props: previewProps, |
| | | setup(props, { emit }) { |
| | | const [register, { closeModal }] = useModalInner(); |
| | |
| | | downloadByUrl({ url }); |
| | | } |
| | | |
| | | const [registerTable] = useTable({ |
| | | columns: createPreviewColumns(), |
| | | pagination: false, |
| | | actionColumn: createPreviewActionColumn({ handleRemove, handlePreview, handleDownload }), |
| | | }); |
| | | |
| | | return { |
| | | register, |
| | | closeModal, |
| | | fileListRef, |
| | | registerTable, |
| | | columns: createPreviewColumns(), |
| | | actionColumn: createPreviewActionColumn({ handleRemove, handlePreview, handleDownload }), |
| | | }; |
| | | }, |
| | | }); |
| | |
| | | width: 100, |
| | | customRender: ({ record }) => { |
| | | const { thumbUrl, type } = (record as FileItem) || {}; |
| | | return <span>{thumbUrl ? <img style={{ maxWidth: '60px' }} src={thumbUrl} /> : type}</span>; |
| | | return <span>{thumbUrl ? <img style={{ maxWidth: '100%' }} src={thumbUrl} /> : type}</span>; |
| | | }, |
| | | }, |
| | | { |
| | |
| | | import type { PropType } from 'vue'; |
| | | import { FileBasicColumn } from './types'; |
| | | |
| | | export const basicProps = { |
| | | helpText: { |
| | |
| | | default: () => [], |
| | | }, |
| | | }; |
| | | |
| | | export const fileListProps = { |
| | | columns: { |
| | | type: [Array] as PropType<FileBasicColumn[]>, |
| | | default: null, |
| | | }, |
| | | actionColumn: { |
| | | type: Object as PropType<FileBasicColumn>, |
| | | default: null, |
| | | }, |
| | | dataSource: { |
| | | type: Array as PropType<any[]>, |
| | | default: null, |
| | | }, |
| | | }; |
| | |
| | | name: string; |
| | | type: string; |
| | | } |
| | | |
| | | export interface FileBasicColumn { |
| | | /** |
| | | * Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config |
| | | * @type Function | ScopedSlot |
| | | */ |
| | | customRender?: Function; |
| | | /** |
| | | * Title of this column |
| | | * @type any (string | slot) |
| | | */ |
| | | title: string; |
| | | |
| | | /** |
| | | * Width of this column |
| | | * @type string | number |
| | | */ |
| | | width?: number; |
| | | /** |
| | | * Display field of the data record, could be set like a.b.c |
| | | * @type string |
| | | */ |
| | | dataIndex: string; |
| | | /** |
| | | * specify how content is aligned |
| | | * @default 'left' |
| | | * @type string |
| | | */ |
| | | align?: 'left' | 'right' | 'center'; |
| | | } |