fix(Upload): The file name is too long bug
parent
caefaad645
commit
b385f335de
|
@ -13,6 +13,7 @@ const props = defineProps({
|
||||||
api: { type: Function as PropType<(arg?: Recordable) => Promise<Recordable>> },
|
api: { type: Function as PropType<(arg?: Recordable) => Promise<Recordable>> },
|
||||||
params: { type: Object },
|
params: { type: Object },
|
||||||
immediate: propTypes.bool.def(true),
|
immediate: propTypes.bool.def(true),
|
||||||
|
async: propTypes.bool.def(false),
|
||||||
resultField: propTypes.string.def(''),
|
resultField: propTypes.string.def(''),
|
||||||
handleTree: propTypes.string.def(''),
|
handleTree: propTypes.string.def(''),
|
||||||
parentId: propTypes.number.def(0),
|
parentId: propTypes.number.def(0),
|
||||||
|
@ -20,7 +21,7 @@ const props = defineProps({
|
||||||
parentFiled: propTypes.string.def('name'),
|
parentFiled: propTypes.string.def('name'),
|
||||||
alwaysLoad: propTypes.bool.def(true),
|
alwaysLoad: propTypes.bool.def(true),
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['optionsChange', 'change'])
|
const emit = defineEmits(['optionsChange', 'change', 'load-data'])
|
||||||
const attrs = useAttrs()
|
const attrs = useAttrs()
|
||||||
|
|
||||||
const treeData = ref<Recordable[]>([])
|
const treeData = ref<Recordable[]>([])
|
||||||
|
@ -64,6 +65,16 @@ onMounted(() => {
|
||||||
props.immediate && fetch()
|
props.immediate && fetch()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function onLoadData(treeNode) {
|
||||||
|
return new Promise((resolve: (value?: unknown) => void) => {
|
||||||
|
if (isArray(treeNode.children) && treeNode.children.length > 0) {
|
||||||
|
resolve()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
emit('load-data', { treeData, treeNode, resolve })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
const { api } = props
|
const { api } = props
|
||||||
if (!api || !isFunction(api))
|
if (!api || !isFunction(api))
|
||||||
|
@ -102,7 +113,7 @@ async function fetch() {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<TreeSelect v-bind="getAttrs" @change="handleChange">
|
<TreeSelect v-bind="getAttrs" :load-data="async ? onLoadData : undefined" @change="handleChange">
|
||||||
<template v-for="item in Object.keys($slots)" #[item]="data">
|
<template v-for="item in Object.keys($slots)" #[item]="data">
|
||||||
<slot :name="item" v-bind="data || {}" />
|
<slot :name="item" v-bind="data || {}" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, getCurrentInstance, nextTick, onMounted, provide, ref, watch, watchEffect } from 'vue'
|
import { computed, getCurrentInstance, nextTick, onMounted, provide, ref, watch, watchEffect } from 'vue'
|
||||||
import type { SubMenuProvider } from './types'
|
import type { SubMenuProvider } from './types'
|
||||||
import { createSimpleRootMenuContext, type MenuEmitterEvents } from './useSimpleMenuContext'
|
import { type MenuEmitterEvents, createSimpleRootMenuContext } from './useSimpleMenuContext'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { mitt } from '@/utils/mitt'
|
import { mitt } from '@/utils/mitt'
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
import type { InjectionKey, Ref, ComponentInternalInstance } from 'vue'
|
import type { ComponentInternalInstance, InjectionKey, Ref } from 'vue'
|
||||||
import type { Emitter } from '@/utils/mitt'
|
import type { Emitter } from '@/utils/mitt'
|
||||||
import { createContext, useContext } from '@/hooks/core/useContext'
|
import { createContext, useContext } from '@/hooks/core/useContext'
|
||||||
|
|
||||||
export type MenuEmitterEvents = {
|
export interface MenuEmitterEvents {
|
||||||
'on-update-opened':
|
'on-update-opened':
|
||||||
| (string | number)[]
|
| (string | number)[]
|
||||||
| {
|
| {
|
||||||
opend: boolean;
|
opend: boolean
|
||||||
parent?: ComponentInternalInstance | null;
|
parent?: ComponentInternalInstance | null
|
||||||
uidList: number[];
|
uidList: number[]
|
||||||
};
|
}
|
||||||
'on-menu-item-select': string | number;
|
'on-menu-item-select': string | number
|
||||||
'open-name-change': {
|
'open-name-change': {
|
||||||
name: string | number;
|
name: string | number
|
||||||
opened: boolean;
|
opened: boolean
|
||||||
};
|
}
|
||||||
'on-update-active-name:submenu': number[];
|
'on-update-active-name:submenu': number[]
|
||||||
};
|
}
|
||||||
|
|
||||||
export interface SimpleRootMenuContextProps {
|
export interface SimpleRootMenuContextProps {
|
||||||
rootMenuEmitter: Emitter<MenuEmitterEvents>
|
rootMenuEmitter: Emitter<MenuEmitterEvents>
|
||||||
|
|
|
@ -22,47 +22,52 @@ export default defineComponent({
|
||||||
const { columns, actionColumn, dataSource } = props
|
const { columns, actionColumn, dataSource } = props
|
||||||
const columnList = [...columns, actionColumn]
|
const columnList = [...columns, actionColumn]
|
||||||
return (
|
return (
|
||||||
<table class="file-table">
|
// x scrollbar
|
||||||
<colgroup>
|
<div class="overflow-x-auto">
|
||||||
{columnList.map((item) => {
|
<table class="file-table">
|
||||||
const { width = 0, dataIndex } = item
|
<colgroup>
|
||||||
const style: CSSProperties = {
|
|
||||||
width: `${width}px`,
|
|
||||||
minWidth: `${width}px`,
|
|
||||||
}
|
|
||||||
return <col style={width ? style : {}} key={dataIndex} />
|
|
||||||
})}
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr class="file-table-tr">
|
|
||||||
{columnList.map((item) => {
|
{columnList.map((item) => {
|
||||||
const { title = '', align = 'center', dataIndex } = item
|
const { width = 0, dataIndex } = item
|
||||||
|
const style: CSSProperties = {
|
||||||
|
width: `${width}px`,
|
||||||
|
minWidth: `${width}px`,
|
||||||
|
}
|
||||||
|
return <col style={width ? style : {}} key={dataIndex} />
|
||||||
|
})}
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr class="file-table-tr">
|
||||||
|
{columnList.map((item) => {
|
||||||
|
const { title = '', align = 'center', dataIndex } = item
|
||||||
|
return (
|
||||||
|
<th class={['file-table-th', align]} key={dataIndex}>
|
||||||
|
{title}
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{dataSource.map((record = {}, index) => {
|
||||||
return (
|
return (
|
||||||
<th class={['file-table-th', align]} key={dataIndex}>
|
<tr class="file-table-tr" key={`${index + record.name || ''}`}>
|
||||||
{title}
|
{columnList.map((item) => {
|
||||||
</th>
|
const { dataIndex = '', customRender, align = 'center' } = item
|
||||||
|
const render = customRender && isFunction(customRender)
|
||||||
|
return (
|
||||||
|
<td class={['file-table-td break-all', align]} key={dataIndex}>
|
||||||
|
{render
|
||||||
|
? customRender?.({ text: record[dataIndex], record })
|
||||||
|
: record[dataIndex]}
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</tr>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</tr>
|
</tbody>
|
||||||
</thead>
|
</table>
|
||||||
<tbody>
|
</div>
|
||||||
{dataSource.map((record = {}, index) => {
|
|
||||||
return (
|
|
||||||
<tr class="file-table-tr" key={`${index + record.name || ''}`}>
|
|
||||||
{columnList.map((item) => {
|
|
||||||
const { dataIndex = '', customRender, align = 'center' } = item
|
|
||||||
const render = customRender && isFunction(customRender)
|
|
||||||
return (
|
|
||||||
<td class={['file-table-td', align]} key={dataIndex}>
|
|
||||||
{render ? customRender?.({ text: record[dataIndex], record }) : record[dataIndex]}
|
|
||||||
</td>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -109,14 +109,6 @@ function handleRemove(record: FileItem) {
|
||||||
emit('delete', record)
|
emit('delete', record)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 预览
|
|
||||||
// function handlePreview(record: FileItem) {
|
|
||||||
// const { thumbUrl = '' } = record;
|
|
||||||
// createImgPreview({
|
|
||||||
// imageList: [thumbUrl],
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
async function uploadApiByItem(item: FileItem) {
|
async function uploadApiByItem(item: FileItem) {
|
||||||
const { api } = props
|
const { api } = props
|
||||||
if (!api || !isFunction(api))
|
if (!api || !isFunction(api))
|
||||||
|
|
|
@ -47,14 +47,6 @@ function handleRemove(record: PreviewFileItem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // 预览
|
|
||||||
// function handlePreview(record: PreviewFileItem) {
|
|
||||||
// const { url = '' } = record;
|
|
||||||
// createImgPreview({
|
|
||||||
// imageList: [url],
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 下载
|
// 下载
|
||||||
function handleDownload(record: PreviewFileItem) {
|
function handleDownload(record: PreviewFileItem) {
|
||||||
const { url = '' } = record
|
const { url = '' } = record
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import { Progress, Tag } from 'ant-design-vue'
|
import { Progress, Tag } from 'ant-design-vue'
|
||||||
import type { FileItem, PreviewFileItem } from './typing'
|
import type { FileBasicColumn, FileItem, PreviewFileItem } from './typing'
|
||||||
import { UploadResultStatus } from './typing'
|
import { UploadResultStatus } from './typing'
|
||||||
import {
|
import { isImgTypeByName } from './helper'
|
||||||
// checkImgType,
|
|
||||||
isImgTypeByName,
|
|
||||||
} from './helper'
|
|
||||||
import ThumbUrl from './ThumbUrl.vue'
|
import ThumbUrl from './ThumbUrl.vue'
|
||||||
import type { ActionItem, BasicColumn } from '@/components/Table'
|
import type { ActionItem, BasicColumn } from '@/components/Table'
|
||||||
import TableAction from '@/components/Table/src/components/TableAction.vue'
|
import TableAction from '@/components/Table/src/components/TableAction.vue'
|
||||||
|
@ -13,7 +10,7 @@ import { useI18n } from '@/hooks/web/useI18n'
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
// 文件上传列表
|
// 文件上传列表
|
||||||
export function createTableColumns(): BasicColumn[] {
|
export function createTableColumns(): FileBasicColumn[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
dataIndex: 'thumbUrl',
|
dataIndex: 'thumbUrl',
|
||||||
|
@ -39,12 +36,12 @@ export function createTableColumns(): BasicColumn[] {
|
||||||
status = 'success'
|
status = 'success'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span>
|
<div>
|
||||||
<p class="mb-1 truncate" title={text}>
|
<p class="mb-1 max-w-70 truncate" title={text}>
|
||||||
{text}
|
{text}
|
||||||
</p>
|
</p>
|
||||||
<Progress percent={percent} size="small" status={status} />
|
<Progress percent={percent} size="small" status={status} />
|
||||||
</span>
|
</div>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -56,11 +53,6 @@ export function createTableColumns(): BasicColumn[] {
|
||||||
return text && `${(text / 1024).toFixed(2)}KB`
|
return text && `${(text / 1024).toFixed(2)}KB`
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// dataIndex: 'type',
|
|
||||||
// title: '文件类型',
|
|
||||||
// width: 100,
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
title: t('component.upload.fileStatue'),
|
title: t('component.upload.fileStatue'),
|
||||||
|
@ -73,12 +65,12 @@ export function createTableColumns(): BasicColumn[] {
|
||||||
else if (text === UploadResultStatus.UPLOADING)
|
else if (text === UploadResultStatus.UPLOADING)
|
||||||
return <Tag color="blue">{() => t('component.upload.uploading')}</Tag>
|
return <Tag color="blue">{() => t('component.upload.uploading')}</Tag>
|
||||||
|
|
||||||
return text
|
return text || t('component.upload.pending')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
export function createActionColumn(handleRemove: Fn): BasicColumn {
|
export function createActionColumn(handleRemove: Fn): FileBasicColumn {
|
||||||
return {
|
return {
|
||||||
width: 120,
|
width: 120,
|
||||||
title: t('component.upload.operating'),
|
title: t('component.upload.operating'),
|
||||||
|
@ -92,12 +84,6 @@ export function createActionColumn(handleRemove: Fn): BasicColumn {
|
||||||
onClick: handleRemove.bind(null, record),
|
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} />
|
return <TableAction actions={actions} outside={true} />
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { BasicColumn } from '../../Table'
|
||||||
import type { UploadApiResult } from '@/api/base/model/uploadModel'
|
import type { UploadApiResult } from '@/api/base/model/uploadModel'
|
||||||
|
|
||||||
export enum UploadResultStatus {
|
export enum UploadResultStatus {
|
||||||
|
@ -24,7 +25,7 @@ export interface PreviewFileItem {
|
||||||
type: string
|
type: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileBasicColumn {
|
export interface FileBasicColumn extends Omit<BasicColumn, 'customRender'> {
|
||||||
/**
|
/**
|
||||||
* Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config
|
* Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config
|
||||||
* @type Function | ScopedSlot
|
* @type Function | ScopedSlot
|
||||||
|
@ -35,21 +36,9 @@ export interface FileBasicColumn {
|
||||||
* @type any (string | slot)
|
* @type any (string | slot)
|
||||||
*/
|
*/
|
||||||
title: string
|
title: string
|
||||||
|
|
||||||
/**
|
|
||||||
* Width of this column
|
|
||||||
* @type string | number
|
|
||||||
*/
|
|
||||||
width?: number
|
|
||||||
/**
|
/**
|
||||||
* Display field of the data record, could be set like a.b.c
|
* Display field of the data record, could be set like a.b.c
|
||||||
* @type string
|
* @type string
|
||||||
*/
|
*/
|
||||||
dataIndex: string
|
dataIndex: string
|
||||||
/**
|
|
||||||
* specify how content is aligned
|
|
||||||
* @default 'left'
|
|
||||||
* @type string
|
|
||||||
*/
|
|
||||||
align?: 'left' | 'right' | 'center'
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,7 @@
|
||||||
"maxSize": "A single file does not exceed {0}MB ",
|
"maxSize": "A single file does not exceed {0}MB ",
|
||||||
"maxSizeMultiple": "Only upload files up to {0}MB!",
|
"maxSizeMultiple": "Only upload files up to {0}MB!",
|
||||||
"operating": "Operating",
|
"operating": "Operating",
|
||||||
|
"pending": "Pendig",
|
||||||
"preview": "Preview",
|
"preview": "Preview",
|
||||||
"reUploadFailed": "Re-upload failed files",
|
"reUploadFailed": "Re-upload failed files",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
|
|
|
@ -108,6 +108,7 @@
|
||||||
"maxSize": "单个文件不超过{0}MB",
|
"maxSize": "单个文件不超过{0}MB",
|
||||||
"maxSizeMultiple": "只能上传不超过{0}MB的文件!",
|
"maxSizeMultiple": "只能上传不超过{0}MB的文件!",
|
||||||
"operating": "操作",
|
"operating": "操作",
|
||||||
|
"pending": "待上传",
|
||||||
"preview": "预览",
|
"preview": "预览",
|
||||||
"reUploadFailed": "重新上传失败文件",
|
"reUploadFailed": "重新上传失败文件",
|
||||||
"save": "保存",
|
"save": "保存",
|
||||||
|
|
Loading…
Reference in New Issue