|
@@ -0,0 +1,391 @@
|
|
|
+<script setup lang="tsx">
|
|
|
+import { ContentWrap } from '@/components/ContentWrap'
|
|
|
+import { Search } from '@/components/Search'
|
|
|
+import { useI18n } from '@/hooks/web/useI18n'
|
|
|
+import { ElButton, ElTooltip } from 'element-plus'
|
|
|
+import { Table } from '@/components/Table'
|
|
|
+import { getTableListApi, delTableListApi, saveTableApi } from '@/api/manage/file'
|
|
|
+import { useTable } from '@/hooks/web/useTable'
|
|
|
+import { ref, unref } from 'vue'
|
|
|
+import { useEmitt } from '@/hooks/event/useEmitt'
|
|
|
+import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
|
|
|
+import { TableSetting } from '@/components/TableSetting'
|
|
|
+import { usePageStore } from '@/store/modules/page'
|
|
|
+import { set } from 'lodash-es'
|
|
|
+import { useStorage } from '@/hooks/web/useStorage'
|
|
|
+import { Dialog } from '@/components/Dialog'
|
|
|
+import { FileData } from '@/api/manage/types'
|
|
|
+import Write from './components/Write.vue'
|
|
|
+import { useIcon } from '@/hooks/web/useIcon'
|
|
|
+import { Qrcode } from '@/components/Qrcode'
|
|
|
+
|
|
|
+defineOptions({
|
|
|
+ name: 'FilePage'
|
|
|
+})
|
|
|
+const QRIcon = useIcon({ icon: 'ic:round-qr-code' })
|
|
|
+const DeleteIcon = useIcon({ icon: 'ep:delete' })
|
|
|
+const DownLoadIcon = useIcon({ icon: 'ep:download' })
|
|
|
+const copyIcon = useIcon({ icon: 'ep:document-copy' })
|
|
|
+const id = ref<string>('')
|
|
|
+const QrVisible = ref<boolean>(false)
|
|
|
+const QrSrc = ref<string>('')
|
|
|
+const { getStorage } = useStorage()
|
|
|
+const searchParams = ref({})
|
|
|
+const setSearchParams = (params: any) => {
|
|
|
+ searchParams.value = params
|
|
|
+ getList()
|
|
|
+}
|
|
|
+const currentRow = ref<FileData>()
|
|
|
+
|
|
|
+const { tableRegister, tableState, tableMethods } = useTable({
|
|
|
+ fetchDataApi: async () => {
|
|
|
+ const { currentPage, pageSize } = tableState
|
|
|
+ const res = await getTableListApi({
|
|
|
+ pageNum: unref(currentPage),
|
|
|
+ pageSize: unref(pageSize),
|
|
|
+ ...unref(searchParams)
|
|
|
+ })
|
|
|
+ return {
|
|
|
+ list: res.data.list,
|
|
|
+ total: res.data.total
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fetchDelApi: async () => {
|
|
|
+ const res = await delTableListApi(unref(id))
|
|
|
+ return !!res
|
|
|
+ }
|
|
|
+})
|
|
|
+const { loading, dataList, total, currentPage, pageSize } = tableState
|
|
|
+const { getList, delList, setColumn } = tableMethods
|
|
|
+
|
|
|
+getList()
|
|
|
+
|
|
|
+useEmitt({
|
|
|
+ name: 'getList',
|
|
|
+ callback: (type: string) => {
|
|
|
+ if (type === 'add') {
|
|
|
+ currentPage.value = 1
|
|
|
+ }
|
|
|
+ getList()
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const { t } = useI18n()
|
|
|
+const appStore = usePageStore()
|
|
|
+const dialogVisible = ref(false)
|
|
|
+const crudSchemas: CrudSchema[] = [
|
|
|
+ {
|
|
|
+ field: 'name',
|
|
|
+ label: '名称',
|
|
|
+
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ colProps: {
|
|
|
+ span: 24
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'version',
|
|
|
+ label: '版本号',
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'code',
|
|
|
+ label: '版本序列号',
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ component: 'InputNumber'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'fileName',
|
|
|
+ label: '文件名',
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ hidden: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'virtualPath',
|
|
|
+ label: '文件链接',
|
|
|
+
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ colProps: {
|
|
|
+ span: 24
|
|
|
+ },
|
|
|
+ component: 'Upload',
|
|
|
+ componentProps: {
|
|
|
+ action: '/api/sysApk/uploadFile',
|
|
|
+ limit: 1,
|
|
|
+ class: 'productUploader',
|
|
|
+ headers: {
|
|
|
+ token: getStorage('token')
|
|
|
+ },
|
|
|
+ onSuccess: (response) => {
|
|
|
+ currentRow.value = {
|
|
|
+ ...currentRow.value,
|
|
|
+ ...response.data
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onExceed: (_files, responses) => {
|
|
|
+ currentRow.value = {
|
|
|
+ ...currentRow.value,
|
|
|
+ ...responses[0].response.data
|
|
|
+ }
|
|
|
+ },
|
|
|
+ slots: {
|
|
|
+ default: () => <ElButton type="primary">上传文件</ElButton>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'filePath',
|
|
|
+ label: '文件路径',
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ hidden: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'content',
|
|
|
+ label: '版本更新说明',
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ colProps: {
|
|
|
+ span: 24
|
|
|
+ },
|
|
|
+ componentProps: {
|
|
|
+ type: 'textarea'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'remark',
|
|
|
+ label: '备注',
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ colProps: {
|
|
|
+ span: 24
|
|
|
+ },
|
|
|
+ componentProps: {
|
|
|
+ type: 'textarea'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'createTime',
|
|
|
+ label: '创建时间',
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ hidden: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'action',
|
|
|
+ width: '250px',
|
|
|
+ label: '操作',
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ detail: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false,
|
|
|
+ slots: {
|
|
|
+ default: (data: any) => {
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <ElTooltip content="二维码">
|
|
|
+ <ElButton text icon={QRIcon} onClick={() => showQrCode(data)}></ElButton>
|
|
|
+ </ElTooltip>
|
|
|
+ <ElTooltip content="下载">
|
|
|
+ <ElButton text icon={DownLoadIcon} onClick={() => downloadFile(data)}></ElButton>
|
|
|
+ </ElTooltip>
|
|
|
+ <ElTooltip content="复制链接">
|
|
|
+ <ElButton text icon={copyIcon}></ElButton>
|
|
|
+ </ElTooltip>
|
|
|
+ <ElButton
|
|
|
+ icon={DeleteIcon}
|
|
|
+ text
|
|
|
+ type="danger"
|
|
|
+ onClick={() => delData(data[0].row)}
|
|
|
+ ></ElButton>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+// @ts-ignore
|
|
|
+const getSchemas = () => {
|
|
|
+ let localSchemas = appStore.getPageData['FilePage']
|
|
|
+ if (localSchemas && localSchemas.schemas) {
|
|
|
+ let localSchemasArr = localSchemas.schemas
|
|
|
+ for (let i = 0; i < localSchemasArr.length; i++) {
|
|
|
+ let item = localSchemasArr[i]
|
|
|
+ let index = crudSchemas.findIndex((e) => {
|
|
|
+ return e.field == item.field
|
|
|
+ })
|
|
|
+ if (index > 0) {
|
|
|
+ set(crudSchemas[index], 'table.hidden', item.table.hidden)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+getSchemas()
|
|
|
+let allSchemas = useCrudSchemas(crudSchemas).allSchemas
|
|
|
+// 修改列设置后调用
|
|
|
+const setSchemas = (schemas: CrudSchema[]) => {
|
|
|
+ let arr = schemas.map((item) => {
|
|
|
+ return {
|
|
|
+ field: item.field,
|
|
|
+ path: 'hidden',
|
|
|
+ value: item.table ? item.table.hidden : false
|
|
|
+ }
|
|
|
+ })
|
|
|
+ setColumn(arr)
|
|
|
+}
|
|
|
+const writeRef = ref<ComponentRef<typeof Write>>()
|
|
|
+const save = async () => {
|
|
|
+ const write = unref(writeRef)
|
|
|
+ const formData = await write?.submit()
|
|
|
+ if (formData) {
|
|
|
+ delLoading.value = true
|
|
|
+ try {
|
|
|
+ let res = await saveTableApi(formData)
|
|
|
+ if (res) {
|
|
|
+ currentPage.value = 1
|
|
|
+ getList()
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ } finally {
|
|
|
+ delLoading.value = false
|
|
|
+ dialogVisible.value = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const delLoading = ref(false)
|
|
|
+
|
|
|
+const delData = async (row: FileData) => {
|
|
|
+ if (!row.id) return
|
|
|
+ id.value = row?.id
|
|
|
+ delLoading.value = true
|
|
|
+ await delList(unref(id).length).finally(() => {
|
|
|
+ delLoading.value = false
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const showQrCode = (row: FileData) => {
|
|
|
+ QrSrc.value = row.virtualPath
|
|
|
+ QrVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+const downloadFile = (row: FileData) => {
|
|
|
+ console.log(row)
|
|
|
+ window.open(row.virtualPath)
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <ContentWrap>
|
|
|
+ <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
|
|
|
+
|
|
|
+ <div class="mb-10px">
|
|
|
+ <el-button type="primary" @click="dialogVisible = true">上传文件</el-button>
|
|
|
+ <TableSetting page="FilePage" :data="crudSchemas" @set-schemas="setSchemas" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Table
|
|
|
+ v-model:pageSize="pageSize"
|
|
|
+ v-model:currentPage="currentPage"
|
|
|
+ :columns="allSchemas.tableColumns"
|
|
|
+ :data="dataList"
|
|
|
+ :loading="loading"
|
|
|
+ :pagination="{
|
|
|
+ total: total
|
|
|
+ }"
|
|
|
+ @register="tableRegister"
|
|
|
+ />
|
|
|
+ </ContentWrap>
|
|
|
+ <Dialog v-model="dialogVisible" title="新增文件">
|
|
|
+ <Write ref="writeRef" :form-schema="allSchemas.formSchema" :current-row="currentRow" />
|
|
|
+ <template #footer>
|
|
|
+ <ElButton type="primary" :loading="delLoading" @click="save">
|
|
|
+ {{ t('exampleDemo.save') }}
|
|
|
+ </ElButton>
|
|
|
+ <ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
+ <Dialog v-model="QrVisible" width="430px" title="二维码">
|
|
|
+ <Qrcode
|
|
|
+ :width="395"
|
|
|
+ :options="{
|
|
|
+ color: {
|
|
|
+ dark: '#55D187',
|
|
|
+ light: '#ffffff'
|
|
|
+ }
|
|
|
+ }"
|
|
|
+ :text="QrSrc"
|
|
|
+ />
|
|
|
+ <template #footer>
|
|
|
+ <ElButton @click="QrVisible = false">{{ t('dialogDemo.close') }}</ElButton>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
+</template>
|
|
|
+@/hooks/event/useEmitt
|
|
|
+
|
|
|
+<style lang="less">
|
|
|
+.uploadBtn {
|
|
|
+ display: inline-block;
|
|
|
+ margin-right: 12px;
|
|
|
+}
|
|
|
+</style>
|