feat: 增加文件图标

This commit is contained in:
zhengkunwang223 2023-01-30 10:10:40 +08:00 committed by zhengkunwang223
parent daa40d237a
commit ccf2e77fe2
10 changed files with 309 additions and 234 deletions

View file

@ -1,9 +1,9 @@
@font-face { @font-face {
font-family: "panel"; /* Project id 3575356 */ font-family: "panel"; /* Project id 3575356 */
src: url('iconfont.woff2?t=1664421291278') format('woff2'), src: url('iconfont.woff2?t=1673865903517') format('woff2'),
url('iconfont.woff?t=1664421291278') format('woff'), url('iconfont.woff?t=1673865903517') format('woff'),
url('iconfont.ttf?t=1664421291278') format('truetype'), url('iconfont.ttf?t=1673865903517') format('truetype'),
url('iconfont.svg?t=1664421291278#panel') format('svg'); url('iconfont.svg?t=1673865903517#panel') format('svg');
} }
.panel { .panel {
@ -14,6 +14,42 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.p-file-ppt:before {
content: "\e6e2";
}
.p-file-html:before {
content: "\d123";
}
.p-file-word:before {
content: "\e6e4";
}
.p-file-excel:before {
content: "\e6e6";
}
.p-file-pdf:before {
content: "\e6e7";
}
.p-file-mp3:before {
content: "\e6e8";
}
.p-file-svg:before {
content: "\e6e9";
}
.p-file-jpg:before {
content: "\e6ea";
}
.p-file-video:before {
content: "\e6eb";
}
.p-star:before { .p-star:before {
content: "\e60f"; content: "\e60f";
} }
@ -146,6 +182,10 @@
content: "\e7ac"; content: "\e7ac";
} }
.p-txt:before {
content: "\e6e3";
}
.p-file-zip:before { .p-file-zip:before {
content: "\e606"; content: "\e606";
} }

File diff suppressed because one or more lines are too long

View file

@ -5,6 +5,69 @@
"css_prefix_text": "p-", "css_prefix_text": "p-",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "26815641",
"name": "PPT",
"font_class": "file-ppt",
"unicode": "e6e2",
"unicode_decimal": 59106
},
{
"icon_id": "26815643",
"name": "HTML",
"font_class": "file-html",
"unicode": "d123",
"unicode_decimal": 53539
},
{
"icon_id": "26815644",
"name": "word",
"font_class": "file-word",
"unicode": "e6e4",
"unicode_decimal": 59108
},
{
"icon_id": "26815647",
"name": "excel",
"font_class": "file-excel",
"unicode": "e6e6",
"unicode_decimal": 59110
},
{
"icon_id": "26815651",
"name": "PDF",
"font_class": "file-pdf",
"unicode": "e6e7",
"unicode_decimal": 59111
},
{
"icon_id": "26815652",
"name": "音频",
"font_class": "file-mp3",
"unicode": "e6e8",
"unicode_decimal": 59112
},
{
"icon_id": "26815654",
"name": "SVG",
"font_class": "file-svg",
"unicode": "e6e9",
"unicode_decimal": 59113
},
{
"icon_id": "26815655",
"name": "JPG",
"font_class": "file-jpg",
"unicode": "e6ea",
"unicode_decimal": 59114
},
{
"icon_id": "26815656",
"name": "视频",
"font_class": "file-video",
"unicode": "e6eb",
"unicode_decimal": 59115
},
{ {
"icon_id": "974125", "icon_id": "974125",
"name": "star", "name": "star",
@ -236,6 +299,13 @@
"unicode": "e7ac", "unicode": "e7ac",
"unicode_decimal": 59308 "unicode_decimal": 59308
}, },
{
"icon_id": "26815646",
"name": "txt",
"font_class": "txt",
"unicode": "e6e3",
"unicode_decimal": 59107
},
{ {
"icon_id": "22761832", "icon_id": "22761832",
"name": "文件类型-压缩包", "name": "文件类型-压缩包",

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View file

@ -137,6 +137,16 @@ let icons = new Map([
['.tar', 'p-file-zip'], ['.tar', 'p-file-zip'],
['.tar.gz', 'p-file-zip'], ['.tar.gz', 'p-file-zip'],
['.tar.xz', 'p-file-zip'], ['.tar.xz', 'p-file-zip'],
['.mp3', 'p-file-mp3'],
['.svg', 'p-file-svg'],
['.txt', 'p-file-txt'],
['.html', 'p-file-html'],
['.word', 'p-file-word'],
['.ppt', 'p-file-ppt'],
['.jpg', 'p-file-jpg'],
['.xlsx', 'p-file-excel'],
['.doc', 'p-file-word'],
['.pdf', 'p-file-pdf'],
]); ]);
export function getIcon(extention: string): string { export function getIcon(extention: string): string {

View file

@ -185,7 +185,7 @@ let searchReq = reactive({
pageSize: 15, pageSize: 15,
name: '', name: '',
tags: [], tags: [],
updated: false, update: false,
}); });
const router = useRouter(); const router = useRouter();
let activeName = ref(i18n.global.t('app.installed')); let activeName = ref(i18n.global.t('app.installed'));
@ -338,7 +338,7 @@ onMounted(() => {
if (path == '/apps/update') { if (path == '/apps/update') {
activeName.value = i18n.global.t('app.canUpdate'); activeName.value = i18n.global.t('app.canUpdate');
mode.value = 'update'; mode.value = 'update';
searchReq.updated = true; searchReq.update = true;
} }
search(); search();
timer = setInterval(() => { timer = setInterval(() => {

View file

@ -1,192 +1,168 @@
<template> <template>
<LayoutContent> <el-row>
<el-row :gutter="20"> <el-col :span="2">
<el-col :span="5"> <el-button :icon="Back" @click="jump(paths.length - 2)" circle :disabled="paths.length == 0" />
<br /> <el-button :icon="Refresh" circle @click="search" />
<el-scrollbar height="85vh"> </el-col>
<el-tree <el-col :span="22">
:data="fileTree" <div style="background-color: #ffffff">
:props="defaultProps" <BreadCrumbs>
:load="loadNode" <BreadCrumbItem @click="jump(-1)" :right="paths.length == 0">/</BreadCrumbItem>
lazy <BreadCrumbItem
v-loading="treeLoading" v-for="(item, key) in paths"
node-key="id" :key="key"
:default-expanded-keys="expandKeys" @click="jump(key)"
@node-click="clickNode" :right="key == paths.length - 1"
> >
<template #default="{ node }"> {{ item }}
<el-icon v-if="node.expanded"><FolderOpened /></el-icon> </BreadCrumbItem>
<el-icon v-else><Folder /></el-icon> </BreadCrumbs>
<span class="custom-tree-node"> </div>
<span>{{ node.data.name }}</span> </el-col>
</span> </el-row>
</template> <LayoutContent :title="$t('file.file')" v-loading="loading">
</el-tree> <template #toolbar>
</el-scrollbar> <el-dropdown @command="handleCreate">
</el-col> <el-button type="primary" icon="Plus">
{{ $t('commons.button.create') }}
<el-col :span="19"> <el-icon class="el-icon--right"><arrow-down /></el-icon>
<br /> </el-button>
<div class="path"> <template #dropdown>
<BreadCrumbs> <el-dropdown-menu>
<BreadCrumbItem @click="jump(-1)" :right="paths.length == 0">/</BreadCrumbItem> <el-dropdown-item command="dir">
<BreadCrumbItem <svg-icon iconName="p-file-folder"></svg-icon>
v-for="(item, key) in paths" {{ $t('file.dir') }}
:key="key" </el-dropdown-item>
@click="jump(key)" <el-dropdown-item command="file">
:right="key == paths.length - 1" <svg-icon iconName="p-file-normal"></svg-icon>
> {{ $t('file.file') }}
{{ item }} </el-dropdown-item>
</BreadCrumbItem> </el-dropdown-menu>
</BreadCrumbs> </template>
</div> </el-dropdown>
<ComplexTable <el-button plain @click="openUpload" style="margin-left: 10px">{{ $t('file.upload') }}</el-button>
:pagination-config="paginationConfig" <el-button plain @click="openWget">{{ $t('file.remoteFile') }}</el-button>
v-model:selects="selects" <el-button plain @click="openMove('copy')" :disabled="selects.length === 0">
:data="data" {{ $t('file.copy') }}
v-loading="loading" </el-button>
@search="search" <el-button plain @click="openMove('cut')" :disabled="selects.length === 0">
> {{ $t('file.move') }}
<template #toolbar> </el-button>
<el-dropdown @command="handleCreate"> <el-button plain @click="openCompress(selects)" :disabled="selects.length === 0">
<el-button type="primary" icon="Plus"> {{ $t('file.compress') }}
{{ $t('commons.button.create') }} </el-button>
<el-icon class="el-icon--right"><arrow-down /></el-icon> <el-button plain @click="openDownload" :disabled="selects.length === 0">
</el-button> {{ $t('file.download') }}
<template #dropdown> </el-button>
<el-dropdown-menu> <div class="search-button">
<el-dropdown-item command="dir"> <el-input
<svg-icon iconName="p-file-folder"></svg-icon> clearable
{{ $t('file.dir') }} @clear="search()"
</el-dropdown-item> suffix-icon="Search"
<el-dropdown-item command="file"> @keyup.enter="search()"
<svg-icon iconName="p-file-normal"></svg-icon> @blur="search()"
{{ $t('file.file') }} :placeholder="$t('commons.button.search')"
</el-dropdown-item> ></el-input>
</el-dropdown-menu> </div>
</template> </template>
</el-dropdown> <template #main>
<el-button-group style="margin-left: 5px"> <ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
<el-button plain @click="openUpload">{{ $t('file.upload') }}</el-button> <el-table-column type="selection" width="55" />
<!-- <el-button type="primary" plain> {{ $t('file.search') }}</el-button> --> <el-table-column :label="$t('commons.table.name')" min-width="250" fix show-overflow-tooltip>
<el-button plain @click="openWget">{{ $t('file.remoteFile') }}</el-button> <template #default="{ row }">
<el-button plain @click="openMove('copy')" :disabled="selects.length === 0"> <svg-icon v-if="row.isDir" className="table-icon" iconName="p-file-folder"></svg-icon>
{{ $t('file.copy') }} <svg-icon v-else className="table-icon" :iconName="getIconName(row.extension)"></svg-icon>
</el-button> <el-link :underline="false" @click="open(row)">{{ row.name }}</el-link>
<el-button plain @click="openMove('cut')" :disabled="selects.length === 0"> <span v-if="row.isSymlink">-> {{ row.linkPath }}</span>
{{ $t('file.move') }}
</el-button>
<el-button plain @click="openCompress(selects)" :disabled="selects.length === 0">
{{ $t('file.compress') }}
</el-button>
<el-button plain @click="openDownload" :disabled="selects.length === 0">
{{ $t('file.download') }}
</el-button>
</el-button-group>
</template> </template>
<el-table-column type="selection" width="55" /> </el-table-column>
<el-table-column :label="$t('commons.table.name')" min-width="250" fix show-overflow-tooltip> <el-table-column :label="$t('file.mode')" prop="mode">
<template #default="{ row }"> <template #default="{ row }">
<svg-icon v-if="row.isDir" className="table-icon" iconName="p-file-folder"></svg-icon> <el-link :underline="false" @click="openMode(row)">{{ row.mode }}</el-link>
<svg-icon v-else className="table-icon" :iconName="getIconName(row.extension)"></svg-icon> </template>
<el-link :underline="false" @click="open(row)">{{ row.name }}</el-link> </el-table-column>
<span v-if="row.isSymlink">-> {{ row.linkPath }}</span> <el-table-column :label="$t('file.user')" prop="user" show-overflow-tooltip></el-table-column>
</template> <el-table-column :label="$t('file.group')" prop="group"></el-table-column>
</el-table-column> <el-table-column :label="$t('file.size')" prop="size">
<el-table-column :label="$t('file.mode')" prop="mode"> <template #default="{ row }">
<template #default="{ row }"> <span v-if="row.isDir">
<el-link :underline="false" @click="openMode(row)">{{ row.mode }}</el-link> <el-button type="primary" link small @click="getDirSize(row)">
</template> <span v-if="row.dirSize == undefined">
</el-table-column> {{ $t('file.calculate') }}
<el-table-column :label="$t('file.user')" prop="user" show-overflow-tooltip></el-table-column> </span>
<el-table-column :label="$t('file.group')" prop="group"></el-table-column> <span v-else>{{ getFileSize(row.dirSize) }}</span>
<el-table-column :label="$t('file.size')" prop="size"> </el-button>
<template #default="{ row }"> </span>
<span v-if="row.isDir"> <span v-else>{{ getFileSize(row.size) }}</span>
<el-button type="primary" link small @click="getDirSize(row)"> </template>
<span v-if="row.dirSize == undefined"> </el-table-column>
{{ $t('file.calculate') }} <el-table-column
</span> :label="$t('file.updateTime')"
<span v-else>{{ getFileSize(row.dirSize) }}</span> prop="modTime"
</el-button> :formatter="dateFormat"
</span> min-width="150"
<span v-else>{{ getFileSize(row.size) }}</span> show-overflow-tooltip
</template> ></el-table-column>
</el-table-column>
<el-table-column
:label="$t('file.updateTime')"
prop="modTime"
:formatter="dateFormat"
min-width="150"
show-overflow-tooltip
></el-table-column>
<fu-table-operations <fu-table-operations
:ellipsis="1" :ellipsis="1"
:buttons="buttons" :buttons="buttons"
:label="$t('commons.table.operate')" :label="$t('commons.table.operate')"
fixed="right" fixed="right"
fix fix
/> />
</ComplexTable> </ComplexTable>
</el-col> </template>
<CreateFile :open="filePage.open" :file="filePage.createForm" @close="closeCreate"></CreateFile>
<ChangeRole :open="modePage.open" :file="modePage.modeForm" @close="closeMode"></ChangeRole> <CreateFile :open="filePage.open" :file="filePage.createForm" @close="closeCreate"></CreateFile>
<Compress <ChangeRole :open="modePage.open" :file="modePage.modeForm" @close="closeMode"></ChangeRole>
:open="compressPage.open" <Compress
:files="compressPage.files" :open="compressPage.open"
:dst="compressPage.dst" :files="compressPage.files"
:name="compressPage.name" :dst="compressPage.dst"
@close="closeCompress" :name="compressPage.name"
></Compress> @close="closeCompress"
<Decompress ></Compress>
:open="deCompressPage.open" <Decompress
:dst="deCompressPage.dst" :open="deCompressPage.open"
:path="deCompressPage.path" :dst="deCompressPage.dst"
:name="deCompressPage.name" :path="deCompressPage.path"
:mimeType="deCompressPage.mimeType" :name="deCompressPage.name"
@close="closeDeCompress" :mimeType="deCompressPage.mimeType"
></Decompress> @close="closeDeCompress"
<CodeEditor ></Decompress>
:open="editorPage.open" <CodeEditor
:language="'json'" :open="editorPage.open"
:content="editorPage.content" :language="'json'"
:loading="editorPage.loading" :content="editorPage.content"
@close="closeCodeEditor" :loading="editorPage.loading"
@qsave="quickSave" @close="closeCodeEditor"
@save="saveContent" @qsave="quickSave"
></CodeEditor> @save="saveContent"
<FileRename ></CodeEditor>
:open="renamePage.open" <FileRename
:path="renamePage.path" :open="renamePage.open"
:oldName="renamePage.oldName" :path="renamePage.path"
@close="closeRename" :oldName="renamePage.oldName"
></FileRename> @close="closeRename"
<Upload :open="uploadPage.open" :path="uploadPage.path" @close="closeUpload"></Upload> ></FileRename>
<Wget :open="wgetPage.open" :path="wgetPage.path" @close="closeWget"></Wget> <Upload :open="uploadPage.open" :path="uploadPage.path" @close="closeUpload"></Upload>
<Move :open="movePage.open" :oldPaths="movePage.oldPaths" :type="movePage.type" @close="clodeMove"></Move> <Wget :open="wgetPage.open" :path="wgetPage.path" @close="closeWget"></Wget>
<Download <Move :open="movePage.open" :oldPaths="movePage.oldPaths" :type="movePage.type" @close="clodeMove"></Move>
:open="downloadPage.open" <Download
:paths="downloadPage.paths" :open="downloadPage.open"
:name="downloadPage.name" :paths="downloadPage.paths"
@close="closeDownload" :name="downloadPage.name"
></Download> @close="closeDownload"
<Process :open="processPage.open" @close="closeProcess"></Process> ></Download>
<Detail ref="detailRef"></Detail> <Process :open="processPage.open" @close="closeProcess"></Process>
</el-row> <Detail ref="detailRef"></Detail>
</LayoutContent> </LayoutContent>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, reactive, ref } from '@vue/runtime-core'; import { onMounted, reactive, ref } from '@vue/runtime-core';
import { import { GetFilesList, DeleteFile, GetFileContent, SaveFileContent, ComputeDirSize } from '@/api/modules/files';
GetFilesList,
GetFilesTree,
DeleteFile,
GetFileContent,
SaveFileContent,
ComputeDirSize,
} from '@/api/modules/files';
import { computeSize, dateFormat, getIcon, getRandomStr } from '@/utils/util'; import { computeSize, dateFormat, getIcon, getRandomStr } from '@/utils/util';
import { File } from '@/api/interface/file'; import { File } from '@/api/interface/file';
import { useDeleteData } from '@/hooks/use-delete-data'; import { useDeleteData } from '@/hooks/use-delete-data';
@ -210,16 +186,14 @@ import { Mimetypes } from '@/global/mimetype';
import Process from './process/index.vue'; import Process from './process/index.vue';
import Detail from './detail/index.vue'; import Detail from './detail/index.vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { Back, Refresh } from '@element-plus/icons-vue';
const router = useRouter(); const router = useRouter();
const data = ref(); const data = ref();
let selects = ref<any>([]); let selects = ref<any>([]);
let req = reactive({ path: '/', expand: true, showHidden: false, page: 1, pageSize: 100 }); let req = reactive({ path: '/', expand: true, showHidden: false, page: 1, pageSize: 100 });
let loading = ref(false); let loading = ref(false);
let treeLoading = ref(false);
const paths = ref<string[]>([]); const paths = ref<string[]>([]);
const fileTree = ref<File.FileTree[]>([]);
const expandKeys = ref<string[]>([]);
const filePage = reactive({ open: false, createForm: { path: '/', isDir: false, mode: 0o755 } }); const filePage = reactive({ open: false, createForm: { path: '/', isDir: false, mode: 0o755 } });
const modePage = reactive({ open: false, modeForm: { path: '/', isDir: false, mode: 0o755 } }); const modePage = reactive({ open: false, modeForm: { path: '/', isDir: false, mode: 0o755 } });
@ -235,12 +209,6 @@ const downloadPage = reactive({ open: false, paths: [''], name: '' });
const processPage = reactive({ open: false }); const processPage = reactive({ open: false });
const detailRef = ref(); const detailRef = ref();
const defaultProps = {
children: 'children',
label: 'name',
id: 'id',
};
const paginationConfig = reactive({ const paginationConfig = reactive({
currentPage: 1, currentPage: 1,
pageSize: 100, pageSize: 100,
@ -300,44 +268,6 @@ const jump = async (index: number) => {
search(); search();
}; };
const getTree = async (req: File.ReqFile, node: File.FileTree | null) => {
treeLoading.value = true;
await GetFilesTree(req)
.then((res) => {
if (node) {
if (res.data.length > 0) {
node.children = res.data[0].children;
}
} else {
fileTree.value = res.data;
expandKeys.value = [];
expandKeys.value.push(fileTree.value[0].id);
}
})
.finally(() => {
treeLoading.value = false;
});
};
const clickNode = async (node: any) => {
if (node.path) {
req.path = node.path;
search();
}
};
const loadNode = (node: any, resolve: (data: File.FileTree[]) => void) => {
if (!node.hasChildNodes) {
if (node.data.path) {
req.path = node.data.path;
getTree(req, node.data);
} else {
getTree(req, null);
}
}
resolve([]);
};
const handleCreate = (commnad: string) => { const handleCreate = (commnad: string) => {
filePage.createForm.path = req.path; filePage.createForm.path = req.path;
filePage.createForm.isDir = false; filePage.createForm.isDir = false;
@ -581,4 +511,9 @@ onMounted(() => {
height: 30px; height: 30px;
margin-bottom: 5px; margin-bottom: 5px;
} }
.search-button {
float: right;
display: inline;
}
</style> </style>