feat: 组件
This commit is contained in:
@ -59,6 +59,9 @@
|
||||
"@types/node": "^20.3.1",
|
||||
"@vitejs/plugin-vue": "^4.1.0",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
||||
"@vue-office/docx": "^1.2.0",
|
||||
"@vue-office/excel": "^1.2.2",
|
||||
"@vue-office/pdf": "^1.2.0",
|
||||
"@vue/tsconfig": "^0.4.0",
|
||||
"@vueuse/core": "^10.2.0",
|
||||
"co": "^4.6.0",
|
||||
@ -88,6 +91,8 @@
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-plugin-libcss": "^1.1.0",
|
||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||
"vue-cropper": "1.0.8",
|
||||
"vue-demi": "^0.13.11",
|
||||
"vue-router": "^4.2.2",
|
||||
"vue-tsc": "^1.4.2"
|
||||
}
|
||||
|
42
packages/preview-office-view/index.vue
Normal file
42
packages/preview-office-view/index.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<!--
|
||||
* @Author: zhaojinfeng 121016171@qq.com
|
||||
* @Date: 2023-07-18 12:22:11
|
||||
* @LastEditors: zhaojinfeng 121016171@qq.com
|
||||
* @LastEditTime: 2023-07-18 12:46:10
|
||||
* @FilePath: \vue3\packages\preview-office-view\index.vue
|
||||
* @Description:
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div class="preview-office-view overflow-hidden h-full">
|
||||
<template v-if="src">
|
||||
<VueOfficeDocx v-if="extension === 'docx'" class="h-full" :src="src" />
|
||||
<VueOfficeExcel v-else-if="extension === 'xlsx'" class="h-full" :src="src" />
|
||||
<VueOfficePdf v-else-if="extension === 'pdf'" class="h-full" :src="src" />
|
||||
</template>
|
||||
<el-empty v-else>
|
||||
<template #description>
|
||||
暂不支持.{{ extension }}格式的文件
|
||||
</template>
|
||||
</el-empty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="ThPreviewOfficeView">
|
||||
import VueOfficePdf from '@vue-office/pdf'
|
||||
import VueOfficeDocx from '@vue-office/docx'
|
||||
import VueOfficeExcel from '@vue-office/excel'
|
||||
import '@vue-office/excel/lib/index.css'
|
||||
import '@vue-office/docx/lib/index.css'
|
||||
|
||||
const route = useRoute()
|
||||
const { url, extension } = route.query
|
||||
|
||||
const src = computed(() => {
|
||||
if (typeof url === 'string')
|
||||
return url
|
||||
if (Array.isArray(url))
|
||||
return url[0]
|
||||
return ''
|
||||
})
|
||||
</script>
|
37
packages/preview-office/index.vue
Normal file
37
packages/preview-office/index.vue
Normal file
@ -0,0 +1,37 @@
|
||||
<!--
|
||||
* @Author: zhaojinfeng 121016171@qq.com
|
||||
* @Date: 2023-07-18 12:21:03
|
||||
* @LastEditors: zhaojinfeng 121016171@qq.com
|
||||
* @LastEditTime: 2023-07-18 13:02:44
|
||||
* @FilePath: \vue3\packages\preview-office\index.vue
|
||||
* @Description:
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<iframe v-if="src" class="h-full w-full" title="Office预览" :src="src" />
|
||||
<el-empty v-else />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="ThPreviewOffice">
|
||||
const { file } = defineProps<{
|
||||
/** 待预览的文件对象 */
|
||||
file?: FileVO
|
||||
}>()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const ALLOW_EXTENSION: (string | undefined)[] = ['docx', 'xlsx', 'pdf']
|
||||
|
||||
const src = computed(() => {
|
||||
if (!file || !ALLOW_EXTENSION.includes(file.extension))
|
||||
return ''
|
||||
|
||||
return router.resolve({
|
||||
name: 'preview-office',
|
||||
query: {
|
||||
url: file.url,
|
||||
extension: file.extension,
|
||||
},
|
||||
}).href
|
||||
})
|
||||
</script>
|
8
packages/select-table-modal/index.vue
Normal file
8
packages/select-table-modal/index.vue
Normal file
@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
SelectTableModal
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="ThSelectTableModal">
|
||||
</script>
|
239
packages/upload-avatar/index.vue
Normal file
239
packages/upload-avatar/index.vue
Normal file
@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<div class="upload-avatar">
|
||||
<div class="el-upload el-upload--picture-card" @click="showDialog = true">
|
||||
<image-avatar
|
||||
v-if="avatarUrl"
|
||||
:file-id="avatarUrl"
|
||||
:size="146"
|
||||
/>
|
||||
<el-icon v-else class="avatar-uploader-icon">
|
||||
<plus />
|
||||
</el-icon>
|
||||
</div>
|
||||
<slot name="text">
|
||||
<div class="el-upload__tip w-400px">
|
||||
<slot name="tip">
|
||||
单张图片不大于{{ fileSize }}MB,且格式为jpeg、jpg、png或bmp,只可上传1张
|
||||
</slot>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="showDialog"
|
||||
title="上传头像"
|
||||
width="800px"
|
||||
append-to-body
|
||||
@opened="modalOpened"
|
||||
@closed="closeDialog"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
||||
<VueCropper
|
||||
v-if="visible"
|
||||
ref="cropperRef"
|
||||
:img="cropperURL"
|
||||
:info="true"
|
||||
:auto-crop="options.autoCrop"
|
||||
:auto-crop-width="autoCropWidth"
|
||||
:auto-crop-height="autoCropHeight"
|
||||
:fixed-box="options.fixedBox"
|
||||
:output-type="options.outputType"
|
||||
@real-time="realTime"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
||||
<div
|
||||
class="avatar-upload-preview"
|
||||
:style="imageStyle"
|
||||
>
|
||||
<img
|
||||
v-show="options.previews.url"
|
||||
:src="options.previews.url"
|
||||
:style="options.previews.img"
|
||||
alt="实时预览图片"
|
||||
>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<br>
|
||||
<el-row>
|
||||
<el-col :lg="2" :md="2">
|
||||
<el-button @click="selectImage">
|
||||
选择
|
||||
<el-icon class="el-icon--right">
|
||||
<Upload />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 1, offset: 2 }" :md="2">
|
||||
<el-button icon="Plus" @click="changeScale(1)" />
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
||||
<el-button icon="Minus" @click="changeScale(-1)" />
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
||||
<el-button icon="RefreshLeft" @click="rotateLeft()" />
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
||||
<el-button icon="RefreshRight" @click="rotateRight()" />
|
||||
</el-col>
|
||||
<el-col :lg="{ span: 2, offset: 6 }" :md="2">
|
||||
<el-button type="primary" :loading="loading" @click="confirmUpload">
|
||||
提 交
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="ThUploadAvatar">
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { CSSProperties } from 'vue'
|
||||
import { VueCropper } from 'vue-cropper'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
accpet?: string
|
||||
modelValue?: string
|
||||
/**
|
||||
* 图片大小(单位MB)
|
||||
*
|
||||
* @default 2
|
||||
*/
|
||||
fileSize?: number
|
||||
/** 默认生成截图框宽度 */
|
||||
autoCropHeight?: number
|
||||
/** 默认生成截图框高度 */
|
||||
autoCropWidth?: number
|
||||
uploadFunction?: (...args: any) => Promise<FileVO>
|
||||
}>(), {
|
||||
accpet: '.jpeg,.jpg,.png,.bmp',
|
||||
fileSize: 2,
|
||||
autoCropHeight: 200,
|
||||
autoCropWidth: 200,
|
||||
uploadFunction: () => Promise.resolve({}),
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:modelValue', modelValue?: string): void
|
||||
(event: 'onSuccess', file: FileVO): void
|
||||
(event: 'onError', error: Error): void
|
||||
}>()
|
||||
|
||||
const avatarUrl = useVModel(props, 'modelValue', emit)
|
||||
|
||||
const imageStyle = computed(() => ({
|
||||
height: `${props.autoCropHeight}px`,
|
||||
width: `${props.autoCropWidth}px`,
|
||||
}))
|
||||
|
||||
let loading = $ref(false)
|
||||
|
||||
interface PreviewData {
|
||||
div: CSSProperties
|
||||
h: number
|
||||
html: string
|
||||
img: CSSProperties
|
||||
url: string
|
||||
w: number
|
||||
}
|
||||
|
||||
interface Option {
|
||||
/** 裁剪图片的地址 */
|
||||
img: any
|
||||
/** 是否默认生成截图框 */
|
||||
autoCrop: boolean
|
||||
/** 固定截图框大小 不允许改变 */
|
||||
fixedBox: boolean
|
||||
/** 默认生成截图为PNG格式 */
|
||||
outputType: string
|
||||
/** 预览数据 */
|
||||
previews: Partial<PreviewData>
|
||||
visible: boolean
|
||||
}
|
||||
|
||||
// 图片裁剪数据
|
||||
const options = reactive<Option>({
|
||||
img: '',
|
||||
autoCrop: true,
|
||||
fixedBox: true,
|
||||
outputType: 'png',
|
||||
previews: {},
|
||||
visible: false,
|
||||
})
|
||||
|
||||
const visible = ref(false)
|
||||
|
||||
const cropperRef = $ref<InstanceType<typeof VueCropper>>()
|
||||
const { open, reset, onChange } = useFileDialog()
|
||||
|
||||
let showDialog = $ref(false)
|
||||
/** 向左旋转 */
|
||||
function rotateLeft() {
|
||||
cropperRef?.rotateLeft()
|
||||
}
|
||||
/** 向右旋转 */
|
||||
function rotateRight() {
|
||||
cropperRef?.rotateRight()
|
||||
}
|
||||
/** 打开弹出层结束时的回调 */
|
||||
function modalOpened() {
|
||||
visible.value = true
|
||||
}
|
||||
/** 图片缩放 */
|
||||
function changeScale(num?: number) {
|
||||
cropperRef?.changeScale(num || 1)
|
||||
}
|
||||
/** 实时预览 */
|
||||
function realTime(data: PreviewData) {
|
||||
options.previews = data
|
||||
}
|
||||
const file = shallowRef()
|
||||
const cropperURL = useObjectUrl(file)
|
||||
|
||||
onChange((param) => {
|
||||
file.value = param?.item(0)
|
||||
})
|
||||
|
||||
function selectImage() {
|
||||
open({
|
||||
accept: props.accpet,
|
||||
multiple: false,
|
||||
})
|
||||
}
|
||||
|
||||
async function uploadImg(blob: Blob) {
|
||||
if (blob.size > props.fileSize * 1024 * 1024) {
|
||||
ElMessage.error('您的图片经过剪裁依然很大,请重新选择图片')
|
||||
return
|
||||
}
|
||||
|
||||
loading = true
|
||||
const formData = new FormData()
|
||||
formData.append('file', blob)
|
||||
|
||||
try {
|
||||
const res = await props.uploadFunction(formData)
|
||||
avatarUrl.value = res.url
|
||||
showDialog = false
|
||||
emit('onSuccess', res)
|
||||
}
|
||||
catch (err: any) {
|
||||
emit('onError', err)
|
||||
loading = false
|
||||
}
|
||||
}
|
||||
|
||||
function confirmUpload() {
|
||||
cropperRef?.getCropBlob(uploadImg)
|
||||
}
|
||||
/** 关闭窗口 */
|
||||
function closeDialog() {
|
||||
options.visible = false
|
||||
reset()
|
||||
loading = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url('vue-cropper/dist/index.css');
|
||||
</style>
|
122
packages/upload-table/index.vue
Normal file
122
packages/upload-table/index.vue
Normal file
@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<el-table border :data="fileList">
|
||||
<el-table-column align="center" :label="label1">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.createdBy">
|
||||
{{ row.name }}
|
||||
</template>
|
||||
<el-input
|
||||
v-else v-model.trim="allName[`${row.id}`]" clearable :loading="allLoading[`${row.id}`]"
|
||||
placeholder="不填则为默认文件名称"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" :label="label2">
|
||||
<template #default="{ row, $index }">
|
||||
<upload-file-link v-if="row.createdBy" :file-id="row.id" :file-name="row.name">
|
||||
{{ row.name }}
|
||||
</upload-file-link>
|
||||
<upload-file-single
|
||||
v-else :accept="accept" :auto-upload="false" :index-key="`${row.id}`" :max-size="20"
|
||||
:file-name="allName[`${row.id}`]" :loading="allLoading[`${row.id}`]"
|
||||
@on-change="$event => onChange($event, row.id)" @on-success="$event => onSuccess($event, row, $index)"
|
||||
@on-error="onError(row.id)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" :label="label3" width="200px">
|
||||
<template #default="{ row, $index }">
|
||||
<el-popconfirm v-if="row.createdBy" :title="popconfirm" :disabled="disabled" @confirm="remove($index)">
|
||||
<template #reference>
|
||||
<el-button type="danger" :disabled="disabled" link>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<template v-else>
|
||||
<el-button type="primary" :loading="allLoading[`${row.id}`]" link @click="save(row.id)">
|
||||
保存
|
||||
</el-button>
|
||||
<el-button type="danger" :loading="allLoading[`${row.id}`]" link @click="remove($index)">
|
||||
取消
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="ThUploadTable">
|
||||
import type { UploadFile } from 'element-plus'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
/** 上传格式 */
|
||||
accept?: string
|
||||
/** 列1的文字 */
|
||||
label1?: string
|
||||
/** 列2的文字 */
|
||||
label2?: string
|
||||
/** 列3的文字 */
|
||||
label3?: string
|
||||
disabled?: boolean
|
||||
/** 文件列表,支持v-model */
|
||||
fileList?: FileVO[]
|
||||
/** 删除按钮提示文字 */
|
||||
popconfirm?: string
|
||||
}>(), {
|
||||
accept: '.jpeg,.jpg,.png,.bmp',
|
||||
label1: '文件名称',
|
||||
label2: '图片上传',
|
||||
label3: '操作',
|
||||
fileList: () => [],
|
||||
popconfirm: '是否删除本行?',
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:fileList', fileList?: FileVO[]): void
|
||||
}>()
|
||||
|
||||
const allName = reactive<Record<string, string | undefined>>({})
|
||||
|
||||
const allLoading = reactive<Record<string, boolean | undefined>>({})
|
||||
|
||||
function onSuccess(file: FileVO, row: FileVO, index: number) {
|
||||
const indexKey = `${row.id}`
|
||||
const newList = [...props.fileList.slice(0, index), file, ...props.fileList.slice(index + 1)]
|
||||
emit('update:fileList', newList)
|
||||
allLoading[indexKey] = false
|
||||
}
|
||||
|
||||
function onError(id: number) {
|
||||
const indexKey = `${id}`
|
||||
allLoading[indexKey] = false
|
||||
}
|
||||
|
||||
function onChange(uploadFile: UploadFile, id: number) {
|
||||
const indexKey = `${id}`
|
||||
|
||||
if (uploadFile.status !== 'ready') {
|
||||
allLoading[indexKey] = false
|
||||
return
|
||||
}
|
||||
if (allName[indexKey])
|
||||
return
|
||||
|
||||
const arr = uploadFile.name.split('.')
|
||||
arr.pop()
|
||||
/** 去除拓展名的文件名 */
|
||||
const newFilename = arr.join('.')
|
||||
// 特殊情况时例如:.npmrc 使用原始文件名
|
||||
allName[indexKey] = newFilename || uploadFile.name
|
||||
}
|
||||
|
||||
function save(id: number) {
|
||||
const indexKey = `${id}`
|
||||
allLoading[indexKey] = true
|
||||
}
|
||||
|
||||
function remove(index: number) {
|
||||
const newList = [...props.fileList.slice(0, index), ...props.fileList.slice(index + 1)]
|
||||
emit('update:fileList', newList)
|
||||
}
|
||||
</script>
|
13
stories/PreviewOffice.stories.ts
Normal file
13
stories/PreviewOffice.stories.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import ThPreviewOffice from '../packages/preview-office/index.vue'
|
||||
|
||||
const meta = {
|
||||
title: '数据展示/Office预览/PreviewOffice',
|
||||
component: ThPreviewOffice,
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof ThPreviewOffice>
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Base: Story = {}
|
22
stories/PreviewOfficeView.stories.ts
Normal file
22
stories/PreviewOfficeView.stories.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* @Author: zhaojinfeng 121016171@qq.com
|
||||
* @Date: 2023-07-18 12:22:11
|
||||
* @LastEditors: zhaojinfeng 121016171@qq.com
|
||||
* @LastEditTime: 2023-07-18 12:39:40
|
||||
* @FilePath: \vue3\stories\PreviewOfficeView.stories.ts
|
||||
* @Description:
|
||||
*
|
||||
*/
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import ThPreviewOfficeView from '../packages/preview-office-view/index.vue'
|
||||
|
||||
const meta = {
|
||||
title: '数据展示/Office预览/PreviewOfficeView',
|
||||
component: ThPreviewOfficeView,
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof ThPreviewOfficeView>
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Base: Story = {}
|
13
stories/SelectTableModal.stories.ts
Normal file
13
stories/SelectTableModal.stories.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import ThSelectTableModal from '../packages/select-table-modal/index.vue'
|
||||
|
||||
const meta = {
|
||||
title: '表单组件/SelectTableModal',
|
||||
component: ThSelectTableModal,
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof ThSelectTableModal>
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Base: Story = {}
|
13
stories/UploadAvatar.stories.ts
Normal file
13
stories/UploadAvatar.stories.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import ThUploadAvatar from '../packages/upload-avatar/index.vue'
|
||||
|
||||
const meta = {
|
||||
title: '表单组件/UploadAvatar',
|
||||
component: ThUploadAvatar,
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof ThUploadAvatar>
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Base: Story = {}
|
32
stories/UploadTable.stories.ts
Normal file
32
stories/UploadTable.stories.ts
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* @Author: zhaojinfeng 121016171@qq.com
|
||||
* @Date: 2023-07-18 12:23:37
|
||||
* @LastEditors: zhaojinfeng 121016171@qq.com
|
||||
* @LastEditTime: 2023-07-18 16:11:39
|
||||
* @FilePath: \vue3\stories\UploadTable.stories.ts
|
||||
* @Description:
|
||||
*
|
||||
*/
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import ThUploadTable from '../packages/upload-table/index.vue'
|
||||
|
||||
const meta = {
|
||||
title: '表单组件/UploadTable',
|
||||
component: ThUploadTable,
|
||||
tags: ['autodocs'],
|
||||
args: {
|
||||
accept: '.jpeg,.jpg,.png,.bmp',
|
||||
label1: '文件名称',
|
||||
label2: '图片上传',
|
||||
label3: '操作',
|
||||
fileList: [],
|
||||
},
|
||||
argTypes: {
|
||||
label1: { control: 'select', options: ['small', 'medium', 'large'] },
|
||||
},
|
||||
} satisfies Meta<typeof ThUploadTable>
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Base: Story = {}
|
15
types/components.d.ts
vendored
15
types/components.d.ts
vendored
@ -8,8 +8,23 @@ export {}
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
Button: typeof import('./../packages/button/index.vue')['default']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
Header: typeof import('./../packages/header/index.vue')['default']
|
||||
PreviewOffice: typeof import('./../packages/preview-office/index.vue')['default']
|
||||
PreviewOfficeView: typeof import('./../packages/preview-office-view/index.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SelectTableModal: typeof import('./../packages/select-table-modal/index.vue')['default']
|
||||
UploadAvatar: typeof import('./../packages/upload-avatar/index.vue')['default']
|
||||
UploadTable: typeof import('./../packages/upload-table/index.vue')['default']
|
||||
}
|
||||
}
|
||||
|
27
types/file.d.ts
vendored
Normal file
27
types/file.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
declare interface FileVO {
|
||||
/**
|
||||
* 文件VO
|
||||
*
|
||||
*/
|
||||
id?: number
|
||||
/**
|
||||
* 文件名称
|
||||
*
|
||||
*/
|
||||
name?: string
|
||||
/**
|
||||
* 文件大小(字节)
|
||||
*
|
||||
*/
|
||||
size?: number
|
||||
/**
|
||||
* 文件扩展名
|
||||
*
|
||||
*/
|
||||
extension?: string
|
||||
/**
|
||||
* 文件url
|
||||
*
|
||||
*/
|
||||
url?: string
|
||||
}
|
25
yarn.lock
25
yarn.lock
@ -3480,6 +3480,21 @@
|
||||
"@volar/typescript" "1.4.1-patch.2"
|
||||
"@volar/vue-language-core" "1.6.5"
|
||||
|
||||
"@vue-office/docx@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmmirror.com/@vue-office/docx/-/docx-1.2.0.tgz#7b490cbfd4f37c33bc8bd12c2a64f4a989dee1a0"
|
||||
integrity sha512-aeWr/q+mRFtfaLpz94uZ4RkxAhwUGCJsDfLQQ76n5g2dgVbZPbXx3eKxGuw/1B+phm88bJNLYbT7Onbjs+j9fg==
|
||||
|
||||
"@vue-office/excel@^1.2.2":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.npmmirror.com/@vue-office/excel/-/excel-1.2.2.tgz#345b9b0b3c70a9abb31f1054f949249c2a71566b"
|
||||
integrity sha512-Zei6fF7Nb/j1CNfKsJuE9Yubck3UEuw9HwVVf++atKpgRpKYMlEBV/yDJ5aHhKiW2Do6nuitH4eGqmjpluZ4Lg==
|
||||
|
||||
"@vue-office/pdf@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmmirror.com/@vue-office/pdf/-/pdf-1.2.0.tgz#0abdbf2ed18bb9094a78f441ff659ac4e6fc200e"
|
||||
integrity sha512-1tCl7Oq9lu6JnqB+4zVdIDsvrsQT/tTb5Nv8d6UCWx7S7KBcEjmjHCM+XVEfbr0JPP4c6IRAbNe+Hs+EZMX2aw==
|
||||
|
||||
"@vue/babel-helper-vue-transform-on@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz#9b9c691cd06fc855221a2475c3cc831d774bc7dc"
|
||||
@ -9419,11 +9434,21 @@ vue-component-type-helpers@^1.6.5:
|
||||
resolved "https://registry.npmmirror.com/vue-component-type-helpers/-/vue-component-type-helpers-1.6.5.tgz#ff6b75529063744b0966655725f3e02f30d97cd7"
|
||||
integrity sha512-iGdlqtajmiqed8ptURKPJ/Olz0/mwripVZszg6tygfZSIL9kYFPJTNY6+Q6OjWGznl2L06vxG5HvNvAnWrnzbg==
|
||||
|
||||
vue-cropper@1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.npmmirror.com/vue-cropper/-/vue-cropper-1.0.8.tgz#05853bb7702557d05a4784a8d0cd072b57dd8e4f"
|
||||
integrity sha512-EX9XoT5a/PQ62J6KDZz8hhaFi9ME1k2yBZlRfYCm8iySzTcjw0nDBq8Y65HtyHaH2jJwUKgYfD6mdFCE0GhUzA==
|
||||
|
||||
vue-demi@*, vue-demi@>=0.14.5:
|
||||
version "0.14.5"
|
||||
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.5.tgz#676d0463d1a1266d5ab5cba932e043d8f5f2fbd9"
|
||||
integrity sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==
|
||||
|
||||
vue-demi@^0.13.11:
|
||||
version "0.13.11"
|
||||
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99"
|
||||
integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
|
||||
|
||||
vue-docgen-api@^4.40.0:
|
||||
version "4.72.5"
|
||||
resolved "https://registry.npmmirror.com/vue-docgen-api/-/vue-docgen-api-4.72.5.tgz#446bd2b98ee858740302ec7aaffdb3b1b1e8ca80"
|
||||
|
Reference in New Issue
Block a user