|
@@ -0,0 +1,409 @@
|
|
|
+<script setup lang="tsx">
|
|
|
+import { ContentWrap } from '@/components/ContentWrap'
|
|
|
+import { Search } from '@/components/Search'
|
|
|
+import { useI18n } from '@/hooks/web/useI18n'
|
|
|
+import { ElButton, ElTooltip, ElMessage, ElButtonGroup } from 'element-plus'
|
|
|
+import { Table } from '@/components/Table'
|
|
|
+import { getTableListApi, delTableListApi, saveTableApi, updateTableApi } from '@/api/manage/img'
|
|
|
+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 { ImgData } from '@/api/manage/types'
|
|
|
+import Write from './components/Write.vue'
|
|
|
+import { useIcon } from '@/hooks/web/useIcon'
|
|
|
+import { Qrcode } from '@/components/Qrcode'
|
|
|
+defineOptions({
|
|
|
+ name: 'ImgPage'
|
|
|
+})
|
|
|
+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 EditIcon = useIcon({ icon: 'ep:edit' })
|
|
|
+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<ImgData>({
|
|
|
+ bannerUrl: ''
|
|
|
+})
|
|
|
+const formState = ref<string>('add')
|
|
|
+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: Number(res.data.totalCount)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 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 fileList = ref([])
|
|
|
+const crudSchemas: CrudSchema[] = [
|
|
|
+ {
|
|
|
+ field: 'bannerType',
|
|
|
+ label: '类型',
|
|
|
+ minWidth: 120,
|
|
|
+ table: {
|
|
|
+ hidden: false,
|
|
|
+ formatter: (_: Recordable, _colomun, cellValue: string) => {
|
|
|
+ return cellValue
|
|
|
+ ? cellValue === '0'
|
|
|
+ ? '首页'
|
|
|
+ : cellValue === '1'
|
|
|
+ ? '中间'
|
|
|
+ : cellValue === '2'
|
|
|
+ ? '底部'
|
|
|
+ : ''
|
|
|
+ : ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ component: 'Select',
|
|
|
+ componentProps: {
|
|
|
+ options: [
|
|
|
+ {
|
|
|
+ label: '首页',
|
|
|
+ value: '0'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '中间',
|
|
|
+ value: '1'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '底部',
|
|
|
+ value: '2'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'bannerUrl',
|
|
|
+ label: '图片地址',
|
|
|
+ minWidth: 120,
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ colProps: {
|
|
|
+ span: 24
|
|
|
+ },
|
|
|
+ component: 'Upload',
|
|
|
+ componentProps: {
|
|
|
+ action: '/api/sysApk/uploadFile',
|
|
|
+ limit: 1,
|
|
|
+ class: 'filePageUploader',
|
|
|
+ fileList: currentRow.value.bannerUrl
|
|
|
+ ? [
|
|
|
+ {
|
|
|
+ url: currentRow.value.bannerUrl
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ : [],
|
|
|
+ headers: {
|
|
|
+ token: getStorage('token')
|
|
|
+ },
|
|
|
+ onSuccess: (response) => {
|
|
|
+ currentRow.value.bannerUrl = response.data.virtualPath
|
|
|
+ },
|
|
|
+ onExceed: (_files, responses) => {
|
|
|
+ currentRow.value.bannerUrl = responses[0].response.data.virtualPath
|
|
|
+ },
|
|
|
+ slots: {
|
|
|
+ default: () => <ElButton type="primary">上传文件</ElButton>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'bannerTarget',
|
|
|
+ label: '跳转地址',
|
|
|
+ minWidth: 120,
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ colProps: {
|
|
|
+ span: 24
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'remark',
|
|
|
+ label: '备注',
|
|
|
+ minWidth: 120,
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ colProps: {
|
|
|
+ span: 24
|
|
|
+ },
|
|
|
+ componentProps: {
|
|
|
+ type: 'textarea'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'createTime',
|
|
|
+ label: '创建时间',
|
|
|
+ minWidth: 160,
|
|
|
+ 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,
|
|
|
+ fixed: 'right',
|
|
|
+ slots: {
|
|
|
+ default: (data: any) => {
|
|
|
+ return (
|
|
|
+ <ElButtonGroup>
|
|
|
+ <ElTooltip content="编辑">
|
|
|
+ <ElButton text icon={EditIcon} onClick={() => handleEdit(data.row)} />
|
|
|
+ </ElTooltip>
|
|
|
+ <ElTooltip content="二维码">
|
|
|
+ <ElButton text icon={QRIcon} onClick={() => showQrCode(data.row)} />
|
|
|
+ </ElTooltip>
|
|
|
+ <ElTooltip content="下载">
|
|
|
+ <ElButton text icon={DownLoadIcon} onClick={() => downloadFile(data.row)} />
|
|
|
+ </ElTooltip>
|
|
|
+ <ElTooltip content="复制链接">
|
|
|
+ <ElButton text icon={copyIcon} onClick={() => onCopy(data.row)} />
|
|
|
+ </ElTooltip>
|
|
|
+ <ElTooltip content="删除">
|
|
|
+ <ElButton text icon={DeleteIcon} type="danger" onClick={() => delData(data.row)} />
|
|
|
+ </ElTooltip>
|
|
|
+ </ElButtonGroup>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+// @ts-ignore
|
|
|
+const getSchemas = () => {
|
|
|
+ let localSchemas = appStore.getPageData['ImgPage']
|
|
|
+ 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 handleEdit = (row: ImgData) => {
|
|
|
+ currentRow.value = row
|
|
|
+ formState.value = 'edit'
|
|
|
+ dialogVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+const save = async () => {
|
|
|
+ const write = unref(writeRef)
|
|
|
+ const formData = await write?.submit()
|
|
|
+ if (formData) {
|
|
|
+ delLoading.value = true
|
|
|
+ try {
|
|
|
+ if (formData.id) {
|
|
|
+ let res = await updateTableApi(formData)
|
|
|
+ if (res) {
|
|
|
+ currentPage.value = 1
|
|
|
+ getList()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ 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: ImgData) => {
|
|
|
+ if (!row.id) return
|
|
|
+ id.value = row?.id
|
|
|
+ delLoading.value = true
|
|
|
+ await delList(unref(id).length).finally(() => {
|
|
|
+ delLoading.value = false
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const showQrCode = (row: ImgData) => {
|
|
|
+ QrSrc.value = row.bannerUrl
|
|
|
+ QrVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+const downloadFile = (row: ImgData) => {
|
|
|
+ window.open(row.bannerUrl)
|
|
|
+}
|
|
|
+
|
|
|
+const onCopy = (row: ImgData) => {
|
|
|
+ navigator.clipboard.writeText(row.bannerUrl).then(() => {
|
|
|
+ ElMessage({
|
|
|
+ message: '复制成功!',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const handleAdd = () => {
|
|
|
+ formState.value = 'add'
|
|
|
+ currentRow.value = {
|
|
|
+ bannerUrl: ''
|
|
|
+ }
|
|
|
+ dialogVisible.value = true
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <ContentWrap>
|
|
|
+ <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
|
|
|
+
|
|
|
+ <div class="mb-10px">
|
|
|
+ <el-button type="primary" @click="handleAdd">上传文件</el-button>
|
|
|
+ <TableSetting page="ImgPage" :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="formState == 'add' ? '新增文件' : '编辑文件'">
|
|
|
+ <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;
|
|
|
+}
|
|
|
+.filePageUploader {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+</style>
|