feat: 优化素材页面
parent
40eeb6899a
commit
9b15be521e
26
index.html
26
index.html
|
|
@ -4,10 +4,19 @@
|
|||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="./favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>%VITE_TITLE% - %VITE_SUBTITLE%</title>
|
||||
<title>%VITE_TITLE% | %VITE_SUBTITLE%</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" class="dark:bg-slate-900 dark:text-slate-200">
|
||||
<div class="loading">
|
||||
<img
|
||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IHJnYigyNTUsIDI1NSwgMjU1KTsgZGlzcGxheTogYmxvY2s7IHNoYXBlLXJlbmRlcmluZzogYXV0bzsiIHdpZHRoPSIyMDBweCIgaGVpZ2h0PSIyMDBweCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1MCA1MCkiPjxnPjxhbmltYXRlVHJhbnNmb3JtIGF0dHJpYnV0ZU5hbWU9InRyYW5zZm9ybSIgdHlwZT0icm90YXRlIiB2YWx1ZXM9IjA7NDUiIGtleVRpbWVzPSIwOzEiIGR1cj0iMC4ycyIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiPjwvYW5pbWF0ZVRyYW5zZm9ybT48cGF0aCBkPSJNMjkuNDkxNTI0MjA2MTE3MjU1IC01LjUgTDM3LjQ5MTUyNDIwNjExNzI1NSAtNS41IEwzNy40OTE1MjQyMDYxMTcyNTUgNS41IEwyOS40OTE1MjQyMDYxMTcyNTUgNS41IEEzMCAzMCAwIDAgMSAyNC43NDI3NDQwNTAxOTg3MzggMTYuOTY0NTY5NDU3MTQ2NzEyIEwyNC43NDI3NDQwNTAxOTg3MzggMTYuOTY0NTY5NDU3MTQ2NzEyIEwzMC4zOTk1OTgyOTk2OTExMTcgMjIuNjIxNDIzNzA2NjM5MDkyIEwyMi42MjE0MjM3MDY2MzkwOTYgMzAuMzk5NTk4Mjk5NjkxMTE0IEwxNi45NjQ1Njk0NTcxNDY3MTYgMjQuNzQyNzQ0MDUwMTk4NzM0IEEzMCAzMCAwIDAgMSA1LjUgMjkuNDkxNTI0MjA2MTE3MjU1IEw1LjUgMjkuNDkxNTI0MjA2MTE3MjU1IEw1LjUgMzcuNDkxNTI0MjA2MTE3MjU1IEwtNS40OTk5OTk5OTk5OTk5OTcgMzcuNDkxNTI0MjA2MTE3MjU1IEwtNS40OTk5OTk5OTk5OTk5OTcgMjkuNDkxNTI0MjA2MTE3MjU1IEEzMCAzMCAwIDAgMSAtMTYuOTY0NTY5NDU3MTQ2NzA1IDI0Ljc0Mjc0NDA1MDE5ODczOCBMLTE2Ljk2NDU2OTQ1NzE0NjcwNSAyNC43NDI3NDQwNTAxOTg3MzggTC0yMi42MjE0MjM3MDY2MzkwODUgMzAuMzk5NTk4Mjk5NjkxMTE3IEwtMzAuMzk5NTk4Mjk5NjkxMTE3IDIyLjYyMTQyMzcwNjYzOTA5MiBMLTI0Ljc0Mjc0NDA1MDE5ODczOCAxNi45NjQ1Njk0NTcxNDY3MTIgQTMwIDMwIDAgMCAxIC0yOS40OTE1MjQyMDYxMTcyNTUgNS41MDAwMDAwMDAwMDAwMDkgTC0yOS40OTE1MjQyMDYxMTcyNTUgNS41MDAwMDAwMDAwMDAwMDkgTC0zNy40OTE1MjQyMDYxMTcyNTUgNS41MDAwMDAwMDAwMDAwMSBMLTM3LjQ5MTUyNDIwNjExNzI1NSAtNS41MDAwMDAwMDAwMDAwMDEgTC0yOS40OTE1MjQyMDYxMTcyNTUgLTUuNTAwMDAwMDAwMDAwMDAyIEEzMCAzMCAwIDAgMSAtMjQuNzQyNzQ0MDUwMTk4NzM4IC0xNi45NjQ1Njk0NTcxNDY3MDUgTC0yNC43NDI3NDQwNTAxOTg3MzggLTE2Ljk2NDU2OTQ1NzE0NjcwNSBMLTMwLjM5OTU5ODI5OTY5MTExNyAtMjIuNjIxNDIzNzA2NjM5MDg1IEwtMjIuNjIxNDIzNzA2NjM5MDkyIC0zMC4zOTk1OTgyOTk2OTExMTcgTC0xNi45NjQ1Njk0NTcxNDY3MTIgLTI0Ljc0Mjc0NDA1MDE5ODczOCBBMzAgMzAgMCAwIDEgLTUuNTAwMDAwMDAwMDAwMDExIC0yOS40OTE1MjQyMDYxMTcyNTUgTC01LjUwMDAwMDAwMDAwMDAxMSAtMjkuNDkxNTI0MjA2MTE3MjU1IEwtNS41MDAwMDAwMDAwMDAwMTIgLTM3LjQ5MTUyNDIwNjExNzI1NSBMNS40OTk5OTk5OTk5OTk5OTggLTM3LjQ5MTUyNDIwNjExNzI1NSBMNS41IC0yOS40OTE1MjQyMDYxMTcyNTUgQTMwIDMwIDAgMCAxIDE2Ljk2NDU2OTQ1NzE0NjcwMiAtMjQuNzQyNzQ0MDUwMTk4NzQgTDE2Ljk2NDU2OTQ1NzE0NjcwMiAtMjQuNzQyNzQ0MDUwMTk4NzQgTDIyLjYyMTQyMzcwNjYzOTA4IC0zMC4zOTk1OTgyOTk2OTExMiBMMzAuMzk5NTk4Mjk5NjkxMTE3IC0yMi42MjE0MjM3MDY2MzkxIEwyNC43NDI3NDQwNTAxOTg3MzggLTE2Ljk2NDU2OTQ1NzE0NjcxNiBBMzAgMzAgMCAwIDEgMjkuNDkxNTI0MjA2MTE3MjU1IC01LjUwMDAwMDAwMDAwMDAxMyBNMCAtMjBBMjAgMjAgMCAxIDAgMCAyMCBBMjAgMjAgMCAxIDAgMCAtMjAiIGZpbGw9IiMwOWYiPjwvcGF0aD48L2c+PC9nPjwvc3ZnPgo="
|
||||
alt="loading"
|
||||
class="loading-image"
|
||||
/>
|
||||
<h1 class="loading-title">欢迎访问%VITE_TITLE%</h1>
|
||||
<div class="loading-tip">资源加载中, 请稍等...</div>
|
||||
</div>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
|
|
@ -17,8 +26,8 @@
|
|||
height: 100%;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
font-family: Inter, "-apple-system", BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "noto sans",
|
||||
"Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-family: Inter, '-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans GB', 'noto sans',
|
||||
'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
#app {
|
||||
width: 100%;
|
||||
|
|
@ -47,18 +56,9 @@
|
|||
.loading-tip {
|
||||
margin-top: 12px;
|
||||
line-height: 1;
|
||||
color: #888;
|
||||
color: #889;
|
||||
}
|
||||
</style>
|
||||
<div class="loading">
|
||||
<img
|
||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IHJnYigyNTUsIDI1NSwgMjU1KTsgZGlzcGxheTogYmxvY2s7IHNoYXBlLXJlbmRlcmluZzogYXV0bzsiIHdpZHRoPSIyMDBweCIgaGVpZ2h0PSIyMDBweCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1MCA1MCkiPjxnPjxhbmltYXRlVHJhbnNmb3JtIGF0dHJpYnV0ZU5hbWU9InRyYW5zZm9ybSIgdHlwZT0icm90YXRlIiB2YWx1ZXM9IjA7NDUiIGtleVRpbWVzPSIwOzEiIGR1cj0iMC4ycyIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiPjwvYW5pbWF0ZVRyYW5zZm9ybT48cGF0aCBkPSJNMjkuNDkxNTI0MjA2MTE3MjU1IC01LjUgTDM3LjQ5MTUyNDIwNjExNzI1NSAtNS41IEwzNy40OTE1MjQyMDYxMTcyNTUgNS41IEwyOS40OTE1MjQyMDYxMTcyNTUgNS41IEEzMCAzMCAwIDAgMSAyNC43NDI3NDQwNTAxOTg3MzggMTYuOTY0NTY5NDU3MTQ2NzEyIEwyNC43NDI3NDQwNTAxOTg3MzggMTYuOTY0NTY5NDU3MTQ2NzEyIEwzMC4zOTk1OTgyOTk2OTExMTcgMjIuNjIxNDIzNzA2NjM5MDkyIEwyMi42MjE0MjM3MDY2MzkwOTYgMzAuMzk5NTk4Mjk5NjkxMTE0IEwxNi45NjQ1Njk0NTcxNDY3MTYgMjQuNzQyNzQ0MDUwMTk4NzM0IEEzMCAzMCAwIDAgMSA1LjUgMjkuNDkxNTI0MjA2MTE3MjU1IEw1LjUgMjkuNDkxNTI0MjA2MTE3MjU1IEw1LjUgMzcuNDkxNTI0MjA2MTE3MjU1IEwtNS40OTk5OTk5OTk5OTk5OTcgMzcuNDkxNTI0MjA2MTE3MjU1IEwtNS40OTk5OTk5OTk5OTk5OTcgMjkuNDkxNTI0MjA2MTE3MjU1IEEzMCAzMCAwIDAgMSAtMTYuOTY0NTY5NDU3MTQ2NzA1IDI0Ljc0Mjc0NDA1MDE5ODczOCBMLTE2Ljk2NDU2OTQ1NzE0NjcwNSAyNC43NDI3NDQwNTAxOTg3MzggTC0yMi42MjE0MjM3MDY2MzkwODUgMzAuMzk5NTk4Mjk5NjkxMTE3IEwtMzAuMzk5NTk4Mjk5NjkxMTE3IDIyLjYyMTQyMzcwNjYzOTA5MiBMLTI0Ljc0Mjc0NDA1MDE5ODczOCAxNi45NjQ1Njk0NTcxNDY3MTIgQTMwIDMwIDAgMCAxIC0yOS40OTE1MjQyMDYxMTcyNTUgNS41MDAwMDAwMDAwMDAwMDkgTC0yOS40OTE1MjQyMDYxMTcyNTUgNS41MDAwMDAwMDAwMDAwMDkgTC0zNy40OTE1MjQyMDYxMTcyNTUgNS41MDAwMDAwMDAwMDAwMSBMLTM3LjQ5MTUyNDIwNjExNzI1NSAtNS41MDAwMDAwMDAwMDAwMDEgTC0yOS40OTE1MjQyMDYxMTcyNTUgLTUuNTAwMDAwMDAwMDAwMDAyIEEzMCAzMCAwIDAgMSAtMjQuNzQyNzQ0MDUwMTk4NzM4IC0xNi45NjQ1Njk0NTcxNDY3MDUgTC0yNC43NDI3NDQwNTAxOTg3MzggLTE2Ljk2NDU2OTQ1NzE0NjcwNSBMLTMwLjM5OTU5ODI5OTY5MTExNyAtMjIuNjIxNDIzNzA2NjM5MDg1IEwtMjIuNjIxNDIzNzA2NjM5MDkyIC0zMC4zOTk1OTgyOTk2OTExMTcgTC0xNi45NjQ1Njk0NTcxNDY3MTIgLTI0Ljc0Mjc0NDA1MDE5ODczOCBBMzAgMzAgMCAwIDEgLTUuNTAwMDAwMDAwMDAwMDExIC0yOS40OTE1MjQyMDYxMTcyNTUgTC01LjUwMDAwMDAwMDAwMDAxMSAtMjkuNDkxNTI0MjA2MTE3MjU1IEwtNS41MDAwMDAwMDAwMDAwMTIgLTM3LjQ5MTUyNDIwNjExNzI1NSBMNS40OTk5OTk5OTk5OTk5OTggLTM3LjQ5MTUyNDIwNjExNzI1NSBMNS41IC0yOS40OTE1MjQyMDYxMTcyNTUgQTMwIDMwIDAgMCAxIDE2Ljk2NDU2OTQ1NzE0NjcwMiAtMjQuNzQyNzQ0MDUwMTk4NzQgTDE2Ljk2NDU2OTQ1NzE0NjcwMiAtMjQuNzQyNzQ0MDUwMTk4NzQgTDIyLjYyMTQyMzcwNjYzOTA4IC0zMC4zOTk1OTgyOTk2OTExMiBMMzAuMzk5NTk4Mjk5NjkxMTE3IC0yMi42MjE0MjM3MDY2MzkxIEwyNC43NDI3NDQwNTAxOTg3MzggLTE2Ljk2NDU2OTQ1NzE0NjcxNiBBMzAgMzAgMCAwIDEgMjkuNDkxNTI0MjA2MTE3MjU1IC01LjUwMDAwMDAwMDAwMDAxMyBNMCAtMjBBMjAgMjAgMCAxIDAgMCAyMCBBMjAgMjAgMCAxIDAgMCAtMjAiIGZpbGw9IiMwOWYiPjwvcGF0aD48L2c+PC9nPjwvc3ZnPgo="
|
||||
alt="loading"
|
||||
class="loading-image"
|
||||
/>
|
||||
<h1 class="loading-title">欢迎访问%VITE_TITLE%</h1>
|
||||
<div class="loading-tip">资源加载中, 请稍等...</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@
|
|||
title="上传文件"
|
||||
title-align="start"
|
||||
v-model:visible="visible"
|
||||
mask-animation-name=""
|
||||
modal-animation-name=""
|
||||
:width="960"
|
||||
:mask-closable="false"
|
||||
:on-before-cancel="onBeforeCancel"
|
||||
|
|
@ -45,11 +43,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-[424px] border-t border-b border-zinc-100 mt-4">
|
||||
<ul v-if="fileList.length" class="overflow-hidden p-0 m-0">
|
||||
<div class="h-[424px] border-t border-b border-zinc-100 mt-2">
|
||||
<ul v-if="fileList.length" class="h-full overflow-hidden p-0 m-0">
|
||||
<a-scrollbar outer-class="h-full overflow-hidden" class="h-full overflow-auto pr-[20px] divide-y">
|
||||
<li v-for="item in fileList" :key="item.uid" class="flex items-center gap-4 py-3">
|
||||
<div class="text-4xl rounded pr-0.5 flex justify-center">
|
||||
<li v-for="item in fileList" :key="item.uid" class="flex items-center gap-3 py-3">
|
||||
<div class="text-3xl rounded pr-0.5 flex justify-center">
|
||||
<i :class="getIcon(item.file?.type ?? 'video')"></i>
|
||||
</div>
|
||||
<div class="flex-1 overflow-hidden">
|
||||
|
|
@ -59,10 +57,10 @@
|
|||
<span class="text-xs text-gray-400 ml-2">{{ numeral(item.file?.size).format('0 b') }}</span>
|
||||
</div>
|
||||
<div v-show="item.status !== 'done'">
|
||||
<a-link v-show="item.status === 'uploading'" @click="pauseItem(item)">停止</a-link>
|
||||
<a-link v-show="item.status === 'error'" @click="retryItem(item)">重试</a-link>
|
||||
<a-link v-show="item.status === 'uploading'" @click="pauseItem(item)"> 停止 </a-link>
|
||||
<a-link v-show="item.status === 'error'" @click="retryItem(item)"> 重试 </a-link>
|
||||
<a-link v-show="item.status === 'init' || item.status === 'error'" @click="removeItem(item)">
|
||||
删除
|
||||
移除
|
||||
</a-link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -70,19 +68,19 @@
|
|||
<div class="flex items-center justify-between gap-2 text-gray-400 mt-1.5 text-xs">
|
||||
<span class="text-xs">
|
||||
<span v-if="item.status === 'init'">
|
||||
<i class="icon-park-outline-hourglass-full"></i>
|
||||
<i class="icon-park-outline-lightning"></i>
|
||||
等待上传
|
||||
</span>
|
||||
<span v-else-if="item.status === 'uploading'" class="text-[rgb(var(--primary-6))]">
|
||||
<i class="icon-park-outline-upload-one"></i>
|
||||
<span v-else-if="item.status === 'uploading'">
|
||||
<i class="icon-park-outline-upload-one text-blue-500"></i>
|
||||
正在上传
|
||||
</span>
|
||||
<span v-else-if="item.status === 'done'" class="text-[rgb(var(--success-6))]">
|
||||
<i class="icon-park-outline-check"></i>
|
||||
<span v-else-if="item.status === 'done'">
|
||||
<i class="icon-park-outline-check-one text-green-500"></i>
|
||||
上传成功
|
||||
</span>
|
||||
<span v-else="item.status === 'error'" class="text-red-500">
|
||||
<i class="icon-park-outline-close"></i>
|
||||
<span v-else="item.status === 'error'" class="">
|
||||
<i class="icon-park-outline-close-one text-red-500"></i>
|
||||
上传失败
|
||||
</span>
|
||||
</span>
|
||||
|
|
@ -135,22 +133,19 @@ const emit = defineEmits<{
|
|||
(event: 'close', count: number): void;
|
||||
}>();
|
||||
|
||||
interface FileInfo {
|
||||
lastTime: number;
|
||||
lastLoaded: number;
|
||||
speed: number;
|
||||
aspeed: number;
|
||||
cost: number;
|
||||
error: string;
|
||||
}
|
||||
|
||||
const visible = ref(false);
|
||||
const uploadRef = ref<UploadInstance | null>(null);
|
||||
const fileList = ref<FileItem[]>([]);
|
||||
const fileMap = reactive<
|
||||
Map<
|
||||
string,
|
||||
{
|
||||
lastTime: number;
|
||||
lastLoaded: number;
|
||||
speed: number;
|
||||
aspeed: number;
|
||||
cost: number;
|
||||
error: string;
|
||||
} | null
|
||||
>
|
||||
>(new Map());
|
||||
const fileMap = reactive<Map<string, FileInfo | null>>(new Map());
|
||||
|
||||
const formatProgress = (item: FileItem, small?: boolean) => {
|
||||
let percent = Math.floor((item.percent || 0) * 100);
|
||||
|
|
@ -239,7 +234,6 @@ const onClose = () => {
|
|||
|
||||
const upload = (option: RequestOption) => {
|
||||
const { fileItem, onError, onProgress, onSuccess } = option;
|
||||
const source = axios.CancelToken.source();
|
||||
if (!fileMap.has(fileItem.uid)) {
|
||||
fileMap.set(fileItem.uid, {
|
||||
lastTime: Date.now(),
|
||||
|
|
@ -250,6 +244,7 @@ const upload = (option: RequestOption) => {
|
|||
error: '网络异常',
|
||||
});
|
||||
}
|
||||
const source = axios.CancelToken.source();
|
||||
const item = fileMap.get(fileItem.uid)!;
|
||||
const startTime = Date.now();
|
||||
const data = { file: fileItem.file as any };
|
||||
|
|
|
|||
|
|
@ -1,43 +1,39 @@
|
|||
<template>
|
||||
<BreadPage>
|
||||
<template #content>
|
||||
<a-tabs class="tabs-page">
|
||||
<a-tab-pane key="1" title="全部素材">
|
||||
<div class="overflow-hidden grid grid-cols-[auto_1fr] gap-2 m-4 mt-1">
|
||||
<!-- <AnGroup class="bg-white p-4 w-[242px]" :current="current" @change="onCategoryChange"></AnGroup> -->
|
||||
<div class="bg-white p-4">
|
||||
<MaterialTable>
|
||||
<template #action>
|
||||
<AnUpload @success="() => tableRef?.refresh()"></AnUpload>
|
||||
</template>
|
||||
</MaterialTable>
|
||||
<AnPreview v-model:visible="viewer.visible" :type="viewer.type" :url="viewer.url"></AnPreview>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" title="分类管理">
|
||||
<div class="overflow-hidden grid grid-cols-[auto_1fr] gap-2 m-4 mt-1">
|
||||
<div class="bg-white p-4">
|
||||
<AnCategory></AnCategory>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="3" title="显示设置"></a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
</BreadPage>
|
||||
<a-tabs class="tabs-page">
|
||||
<a-tab-pane key="1" title="全部素材">
|
||||
<div class="overflow-hidden grid grid-cols-[auto_1fr] gap-2 m-4 mt-0">
|
||||
<!-- <AnGroup class="bg-white p-4 w-[242px]" :current="current" @change="onCategoryChange"></AnGroup> -->
|
||||
<div class="bg-white p-4">
|
||||
<MaterialTable>
|
||||
<template #action>
|
||||
<AnUpload @success="() => tableRef?.refresh()"></AnUpload>
|
||||
</template>
|
||||
</MaterialTable>
|
||||
<AnPreview v-model:visible="viewer.visible" :type="viewer.type" :url="viewer.url"></AnPreview>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" title="分类管理">
|
||||
<div class="overflow-hidden grid grid-cols-[auto_1fr] gap-2 m-4 mt-0">
|
||||
<div class="bg-white p-4">
|
||||
<AnCategory></AnCategory>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="3" title="素材设置"> </a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { FileCategory, api } from '@/api';
|
||||
import { useCreateColumn, useTable, useTableDelete, useUpdateColumn } from '@/components/AnTable';
|
||||
import { FileTypes } from '@/constants/file';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import numeral from 'numeral';
|
||||
import AnCategory from './components/AnCategory.vue';
|
||||
import AnPreview from './components/AnPreview.vue';
|
||||
import AnUpload from './components/AnUpload.vue';
|
||||
import { getIcon } from './components/util';
|
||||
import { FileTypes } from '@/constants/file';
|
||||
|
||||
const current = ref<FileCategory>();
|
||||
const viewer = reactive({ visible: false, url: undefined, type: undefined });
|
||||
|
|
@ -74,7 +70,7 @@ const {
|
|||
dataIndex: 'name',
|
||||
render: ({ record }) => {
|
||||
return (
|
||||
<div class="group flex items-center gap-4">
|
||||
<div class="group flex items-center gap-3">
|
||||
<div class="w-8 flex justify-center">
|
||||
{record.mimetype.startsWith('image1') ? (
|
||||
<a-avatar size={32} shape="square">
|
||||
|
|
@ -92,30 +88,33 @@ const {
|
|||
>
|
||||
{record.name}
|
||||
</span>
|
||||
<span
|
||||
{/* <span
|
||||
class="inline-block w-5 text-xs text-gray-400 ml-0"
|
||||
title="复制地址"
|
||||
onClick={() => copyLink(record)}
|
||||
>
|
||||
<i class="hidden! group-hover:inline-block! icon-park-outline-copy hover:text-gray-700 cursor-pointer"></i>
|
||||
</span>
|
||||
</span> */}
|
||||
</span>
|
||||
<div class="h-5 inline-flex items-center text-xs text-gray-400 space-x-4">
|
||||
{/* <div class="h-5 inline-flex items-center text-xs text-gray-400 space-x-4 ">
|
||||
<span>
|
||||
<i class="icon-park-outline-folder-close mr-1"></i>
|
||||
{record.category?.name ?? '默认分类'}
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '分类',
|
||||
width: 150,
|
||||
render: ({ record }) => record.category?.name ?? '默认分类',
|
||||
},
|
||||
{
|
||||
title: '文件大小',
|
||||
width: 100,
|
||||
align: 'right',
|
||||
render: ({ record }) => <span class="text-gray-500">{numeral(record.size).format('0 b')}</span>,
|
||||
width: 150,
|
||||
render: ({ record }) => numeral(record.size).format('0 b'),
|
||||
},
|
||||
useCreateColumn(),
|
||||
useUpdateColumn(),
|
||||
|
|
@ -206,7 +205,16 @@ const {
|
|||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.tabs-page {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
height: 100%;
|
||||
:deep(.arco-tabs-content) {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
</div> -->
|
||||
<div>
|
||||
<div class="text-gray-500">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
<div class="text-lg mt-1.5">
|
||||
{{ item.count }}
|
||||
</div>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
<div class="text-lg mt-1.5">
|
||||
{{ item.count }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -30,9 +30,11 @@
|
|||
<i class="icon-park-outline-delete text-xs"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-3 px-3 border border-dashed rounded-sm border-gray-400 text-gray-500 hover:bg-gray-100 cursor-pointer">
|
||||
<div
|
||||
class="py-3 px-3 border border-dashed rounded-sm border-gray-400 text-gray-500 hover:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<i class="icon-park-outline-add ml-2"></i>
|
||||
添加服务
|
||||
添加服务1
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white py-4 px-5 mt-4">
|
||||
<div class="bg-white py-4 px-5 mt-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<span>公告</span>
|
||||
<a-link>更多</a-link>
|
||||
|
|
@ -55,7 +57,9 @@
|
|||
<div class="flex justify-between gap-4 mt-4">
|
||||
<ul class="list-none w-full m-0 p-0">
|
||||
<li v-for="i in 8" class="w-full h-6 items-center overflow-hidden justify-between flex gap-2 mb-2">
|
||||
<span class="flex-1 truncate hover:underline underline-offset-2 cursor-pointer">但是预测已加载的数据不足以</span>
|
||||
<span class="flex-1 truncate hover:underline underline-offset-2 cursor-pointer"
|
||||
>但是预测已加载的数据不足以</span
|
||||
>
|
||||
<span class="text-gray-400">3天前</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -74,29 +78,39 @@ const stat = {
|
|||
post: {
|
||||
title: '文章',
|
||||
count: 22,
|
||||
icon: 'icon-park-outline-folder-close'
|
||||
icon: 'icon-park-outline-folder-close',
|
||||
},
|
||||
material: {
|
||||
title: '素材',
|
||||
count: 119,
|
||||
icon: 'icon-park-outline-folder-close'
|
||||
icon: 'icon-park-outline-folder-close',
|
||||
},
|
||||
comment: {
|
||||
title: '评论',
|
||||
count: 1802,
|
||||
icon: 'icon-park-outline-user'
|
||||
icon: 'icon-park-outline-user',
|
||||
},
|
||||
user: {
|
||||
title: '用户',
|
||||
count: 98,
|
||||
icon: 'icon-park-outline-user'
|
||||
icon: 'icon-park-outline-user',
|
||||
},
|
||||
category: {
|
||||
title: '分类',
|
||||
count: 26,
|
||||
icon: 'icon-park-outline-tag'
|
||||
icon: 'icon-park-outline-tag',
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"meta": {
|
||||
"sort": 1000,
|
||||
"title": "概览",
|
||||
"icon": "icon-park-outline-home"
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<ani-group :current="current" @change="onTypeChange"></ani-group>
|
||||
</div>
|
||||
<div class="bg-white p-4">
|
||||
<div :show-icon="false" class="rounded mb-3 bg-gray-100 px-4 py-3">
|
||||
<div :show-icon="false" class="rounded mb-3 bg-gray-200 px-4 py-3">
|
||||
<span class="text-base">
|
||||
<i class="icon-park-outline-folder-close"></i>
|
||||
{{ current?.name }}
|
||||
|
|
|
|||
|
|
@ -41,24 +41,30 @@ const { component: MenuTable, tableRef } = useTable({
|
|||
id = ` => ${record.code}`;
|
||||
}
|
||||
return (
|
||||
<div class="flex items-center gap-1">
|
||||
<a-tag bordered color={MenuTypes.fmt(record.type, 'color')}>
|
||||
{{
|
||||
default: () => MenuTypes.fmt(record.type),
|
||||
}}
|
||||
</a-tag>
|
||||
<div class="flex-1 flex overflow-hidden ml-1">
|
||||
<div class="flex-1">
|
||||
<i class={`${record.icon} mr-1`}></i>
|
||||
<span>{record.name ?? '无'}</span>
|
||||
<span class="text-gray-400 text-xs truncate">{id}</span>
|
||||
</div>
|
||||
<a-switch checked-color="#3c9" size="small"></a-switch>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<i class={`${record.icon} mr-1`}></i>
|
||||
<span>{record.name ?? '无'}</span>
|
||||
<span class="text-gray-400 text-xs truncate">{id}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '标识',
|
||||
width: 200,
|
||||
dataIndex: 'code',
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
width: 200,
|
||||
render: ({ record }) => (
|
||||
<a-tag bordered color={MenuTypes.fmt(record.type, 'color')}>
|
||||
{{
|
||||
default: () => MenuTypes.fmt(record.type),
|
||||
}}
|
||||
</a-tag>
|
||||
),
|
||||
},
|
||||
useCreateColumn(),
|
||||
useUpdateColumn(),
|
||||
{
|
||||
|
|
@ -135,7 +141,7 @@ const { component: MenuTable, tableRef } = useTable({
|
|||
field: 'type',
|
||||
value: 1,
|
||||
label: '类型',
|
||||
setter: 'input',
|
||||
setter: 'select',
|
||||
options: MenuTypes.raw,
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,24 @@
|
|||
<BreadPage :content-padding="false">
|
||||
<template #content>
|
||||
<section class="my-page m-4 bg-white rounded px-4">
|
||||
<div class="bg-white py-4 px-5 mb-4">
|
||||
<div v-for="t1 in types" :key="t1.label" class="flex items-center">
|
||||
{{ t1.label }}:
|
||||
<div class="flex gap-2">
|
||||
<a-tag
|
||||
v-for="t2 in t1.children"
|
||||
:key="t2.value"
|
||||
:checked="search.bk === t2.value"
|
||||
color="blue"
|
||||
:bordered="true"
|
||||
checkable
|
||||
@check="search.bk = t2.value"
|
||||
>
|
||||
{{ t2.label }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-tabs size="large" class="h-full">
|
||||
<a-tab-pane key="8" title="常规设置">
|
||||
<a-form
|
||||
|
|
@ -39,17 +57,10 @@
|
|||
:max-length="140"
|
||||
:show-word-limit="true"
|
||||
></a-textarea>
|
||||
<template #help>
|
||||
启用后,消息通知将在左上角进行提示.
|
||||
</template>
|
||||
<template #help> 启用后,消息通知将在左上角进行提示. </template>
|
||||
</a-form-item>
|
||||
<a-form-item label="站点URL">
|
||||
<a-input
|
||||
v-model="appStore.title"
|
||||
placeholder="请输入"
|
||||
class="!w-[432px]"
|
||||
allow-clear
|
||||
></a-input>
|
||||
<a-input v-model="appStore.title" placeholder="请输入" class="!w-[432px]" allow-clear></a-input>
|
||||
<template #help> 示例:https://www.juetan.cn。用于静态资源前缀、应用接口前缀等用途。 </template>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
|
|
@ -83,7 +94,8 @@
|
|||
<a-input v-model="mail.smtpHost" allow-clear placeholder="请输入" class="!w-[314px]"></a-input>
|
||||
<span class="inline-block px-2">:</span>
|
||||
<a-input-number v-model="mail.smtpPort" :min="0" :max="65535" class="w-24!"></a-input-number>
|
||||
<template #help> 示例: smtp.163.com:25。国内常见有
|
||||
<template #help>
|
||||
示例: smtp.163.com:25。国内常见有
|
||||
<a target="_blank" class="mr-2" href="https://mail.163.com">网易邮箱</a>
|
||||
<a target="_blank" class="mr-2" href="http://mail.aliyun.com/">阿里邮箱</a>
|
||||
<a target="_blank" class="mr-2" href="https://mail.qq.com">QQ邮箱</a>等,默认 25 端口。
|
||||
|
|
@ -164,6 +176,79 @@
|
|||
import { useAppStore } from '@/store';
|
||||
import { reactive } from 'vue';
|
||||
|
||||
const search = reactive({ bk: undefined });
|
||||
const types = [
|
||||
{
|
||||
label: '板块',
|
||||
children: [
|
||||
{
|
||||
label: '全部',
|
||||
value: undefined,
|
||||
},
|
||||
{
|
||||
label: '电影',
|
||||
value: 'fild',
|
||||
},
|
||||
{
|
||||
label: '电视剧',
|
||||
value: 'vs',
|
||||
},
|
||||
{
|
||||
label: '综艺',
|
||||
value: 'zy',
|
||||
},
|
||||
{
|
||||
label: '动漫',
|
||||
value: 'dm',
|
||||
},
|
||||
{
|
||||
label: '短剧',
|
||||
value: 'dj',
|
||||
},
|
||||
{
|
||||
label: '体育',
|
||||
value: 'ty',
|
||||
},
|
||||
{
|
||||
label: '纪录片',
|
||||
value: 'jlp',
|
||||
},
|
||||
{
|
||||
label: '游戏',
|
||||
value: 'yx',
|
||||
},
|
||||
{
|
||||
label: '新闻',
|
||||
value: 'xw',
|
||||
},
|
||||
{
|
||||
label: '娱乐',
|
||||
value: 'yl',
|
||||
},
|
||||
{
|
||||
label: '生活',
|
||||
value: 'sh',
|
||||
},
|
||||
{
|
||||
label: '音乐',
|
||||
value: 'yinyue',
|
||||
},
|
||||
{
|
||||
label: '时尚',
|
||||
value: 'shishang',
|
||||
},
|
||||
{
|
||||
label: '科技',
|
||||
value: 'keji',
|
||||
},
|
||||
{
|
||||
label: '发现',
|
||||
value: 'faxian',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const mail = reactive({
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ declare module '@vue/runtime-core' {
|
|||
ARadioGroup: typeof import('@arco-design/web-vue')['RadioGroup']
|
||||
AScrollbar: typeof import('@arco-design/web-vue')['Scrollbar']
|
||||
ASelect: typeof import('@arco-design/web-vue')['Select']
|
||||
ASlider: typeof import('@arco-design/web-vue')['Slider']
|
||||
ASpace: typeof import('@arco-design/web-vue')['Space']
|
||||
ASpin: typeof import('@arco-design/web-vue')['Spin']
|
||||
ASwitch: typeof import('@arco-design/web-vue')['Switch']
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import { merge } from 'lodash-es';
|
|||
export type DelOptions = string | Partial<Omit<ModalConfig, 'onOk' | 'onCancel'>>;
|
||||
|
||||
export const delOptions: ModalConfig = {
|
||||
maskAnimationName: '',
|
||||
modalAnimationName: '',
|
||||
title: '提示',
|
||||
titleAlign: 'start',
|
||||
width: 432,
|
||||
|
|
|
|||
Loading…
Reference in New Issue