123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- <template>
- <com-head :options="[{ name: '媒体库', value: '2' }]">
- <el-form label-width="97px" inline>
- <el-form-item label="名称:">
- <el-input v-model="state.query.name" placeholder="请输入"></el-input>
- </el-form-item>
- <el-form-item label="类型:">
- <el-select v-model="state.query.fileType" clearable placeholder="请选择">
- <el-option label="图片" value="0"></el-option>
- <el-option label="视频" value="1"></el-option>
- <el-option label="音频" value="2"></el-option>
- <el-option label="模型" value="3"></el-option>
- <el-option label="其他" value="4"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="分组:">
- <el-select v-model="state.query.dictId" clearable placeholder="请选择">
- <el-option v-for="group in groupList" :key="group.id" :label="group.dictName" :value="group.id"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item class="searh-btns" style="grid-area: 1 / 4 / 2 / 4">
- <el-button type="primary" @click="refresh">查询</el-button>
- <el-button type="primary" plain @click="queryReset">重置</el-button>
- </el-form-item>
- </el-form>
- </com-head>
- <div class="body-layer">
- <div class="body-head">
- <h3 style="visibility: hidden">媒体列表</h3>
- <div class="table-ctrl-right">
- <el-button type="primary" @click="groupManage" v-pdpath="'group'">分组管理</el-button>
- <el-button type="primary" @click="uploadMediaHandler" v-pdpath="'upload'"> 上传 </el-button>
- </div>
- </div>
- <el-table
- ref="multipleTable"
- :data="state.table.rows"
- size="large"
- style="width: 100%"
- >
- <!-- <el-table-column label="序号" width="70" v-slot:default="{ $index }">
- <div style="text-align: center">
- {{ state.pag.size * (state.pag.currentPage - 1) + $index + 1 }}
- </div>
- </el-table-column> -->
- <el-table-column label="名称">
- <template #default="{ row }">
- <p class="oper-span tip clickable" @click="floadileUrl(row)">{{ row.fileName }}</p>
- </template>
- </el-table-column>
- <el-table-column label="文件类型" prop="fileTypeStr"></el-table-column>
- <el-table-column label="文件格式" prop="fileFormat"></el-table-column>
- <el-table-column label="大小" prop="fileSize">
- <template #default="{ row }">
- {{ formatFileSize(row.fileSize) }}
- </template>
- </el-table-column>
- <el-table-column label="分组" prop="dictName"></el-table-column>
- <el-table-column label="状态" prop="status">
- <template #default="{ row }">
- {{ formatStatus(row.status) }}
- </template>
- </el-table-column>
- <el-table-column label="上传时间" width="200px" prop="updateTime">
- <template #default="{ row }">
- {{ formatDateTime(row.updateTime) }}
- </template>
- </el-table-column>
- <el-table-column label="操作" width="200px" v-slot:default="{ row }">
- <span class="oper-span" @click="downloadMediaHandler(row)" v-pdpath="'view'">下载</span>
- <span class="oper-span" @click="downloadHashHandler(row)" v-pdpath="'view'">hash</span>
- <span class="oper-span" v-if="row.useType != 'animation'" @click="editMediaHandler(row)" v-pdpath="'view'">编辑</span>
- <span class="oper-span delBtn" v-if="row.useType != 'animation'" @click="confirmDelete(row)" v-pdpath="'view'"> 删除 </span>
- </el-table-column>
- </el-table>
- <com-pagination
- @size-change="changPageSize"
- @current-change="changPageCurrent"
- :current-page="state.pag.currentPage"
- :page-size="state.pag.size"
- :total="state.pag.total"
- />
- </div>
- <GroupManage
- v-model:visible="groupManageVisible"
- @refresh="refreshList"
- />
- <UploadMedia
- v-model:visible="uploadVisible"
- :groupList="groupList"
- @refresh="refreshList"
- />
- <EditMedia
- v-model:visible="editVisible"
- :groupList="groupList"
- :mediaData="currentMedia"
- @refresh="refreshList"
- />
- </template>
- <script setup lang="ts">
- import comSelect from "@/components/company-select/index.vue";
- import comPagination from "@/components/pagination/index.vue";
- import comHead from "@/components/head/index.vue";
- import { usePagging } from "@/hook/pagging";
- import { confirm } from "@/helper/message";
- import { ElMessage, ElMessageBox } from "element-plus";
- import { getMediaPagging, uploadNewMedia, deleteMediaItem, Media, getGroupList, downloadMedia, downloadHash } from "@/store/mediaLibrary";
- import { ref, onMounted, watch } from "vue";
- import GroupManage from './groupManage.vue';
- import UploadMedia from './uploadMedia.vue';
- import EditMedia from './editMedia.vue';
- // 分组列表数据
- const groupList = ref<Array<any>>([]);
- // 获取分组列表
- const fetchGroupList = async () => {
- try {
- const result = await getGroupList({type: 1});
- if (result && Array.isArray(result)) {
- groupList.value = result;
- }
- } catch (error) {
- console.error('获取分组列表失败:', error);
- }
- };
- // 在组件挂载时获取分组数据
- onMounted(() => {
- fetchGroupList();
- });
- // 格式化文件大小为MB
- const formatFileSize = (size: string | number) => {
- if (!size && size !== 0) return '-';
-
- // 将字符串转为数字
- const sizeNum = typeof size === 'string' ? parseFloat(size) : size;
-
- // 转换为MB并保留两位小数
- const sizeMB = (sizeNum / (1024 * 1024)).toFixed(2);
-
- return `${sizeMB} MB`;
- };
- // 格式化状态为中文
- const formatStatus = (status: string | number) => {
- if (status === undefined || status === null) return '-';
-
- // 将字符串转为数字
- const statusNum = typeof status === 'string' ? parseInt(status) : status;
-
- // 根据状态码返回对应的中文
- switch (statusNum) {
- case 1:
- return '上传成功';
- case 0:
- return '上传中';
- case -1:
- return '上传失败';
- default:
- return '未知状态';
- }
- };
- // 格式化日期时间
- const formatDateTime = (dateTimeStr: string) => {
- if (!dateTimeStr) return '-';
-
- try {
- // 创建日期对象
- const date = new Date(dateTimeStr);
-
- // 格式化为 YYYY-MM-DD HH:MM:SS
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- const hours = String(date.getHours()).padStart(2, '0');
- const minutes = String(date.getMinutes()).padStart(2, '0');
- const seconds = String(date.getSeconds()).padStart(2, '0');
-
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
- } catch (error) {
- console.error('日期格式化错误:', error);
- return dateTimeStr; // 如果格式化失败,返回原始字符串
- }
- };
- const { state, queryReset, refresh, changPageCurrent, changPageSize, add, del } = usePagging({
- get: getMediaPagging,
- add: uploadNewMedia,
- del: deleteMediaItem,
- paramsTemlate: {
- name: "",
- fileType: "",
- dictId: "",
- },
- mapper: {
- delMsg: "确定要删除该媒体吗?"
- }
- });
- // 上传媒体弹窗
- const uploadVisible = ref(false);
- // 上传媒体处理函数
- const uploadMediaHandler = async () => {
- uploadVisible.value = true;
- };
- // 编辑媒体弹窗
- const editVisible = ref(false);
- const currentMedia = ref({});
- // 编辑媒体处理函数
- const editMediaHandler = async (row: Media) => {
- currentMedia.value = row;
- editVisible.value = true;
- };
- // 通用下载处理函数
- const handleDownload = async (row: Media, type: 'media' | 'hash') => {
- try {
- let url = '';
- let fileName = '';
-
- // 根据类型确定URL和文件名
- if (type === 'media') {
- if (row.downUrl) {
- url = row.downUrl;
- } else {
- // 通过接口获取URL
- url = await downloadMedia(row.id);
- if (!url) {
- ElMessage.error('获取下载链接失败');
- return;
- }
- }
- fileName = `${row.fileName}.${row.fileFormat}` || url.split('/').pop() || `file_${row.id}`;
- } else {
- if (row.hashUrl) {
- url = row.hashUrl;
- } else {
- // 通过接口获取URL
- url = await downloadHash(row.id);
- if (!url) {
- ElMessage.error('获取Hash下载链接失败');
- return;
- }
- }
- fileName = `${row.fileName || 'file'}.txt`;
- }
-
- // 使用fetch获取文件内容
- const response = await fetch(url);
- const blob = await response.blob();
-
- // 创建Blob URL
- const blobUrl = window.URL.createObjectURL(blob);
-
- // 创建下载链接
- const link = document.createElement('a');
- link.href = blobUrl;
- link.setAttribute('download', fileName);
- document.body.appendChild(link);
- link.click();
-
- // 清理
- document.body.removeChild(link);
- window.URL.revokeObjectURL(blobUrl);
-
- ElMessage.success(type === 'media' ? '下载成功' : 'Hash下载成功');
- } catch (error) {
- console.error(type === 'media' ? '下载失败:' : 'Hash下载失败:', error);
- ElMessage.error(type === 'media' ? '下载失败' : 'Hash下载失败');
- }
- };
- // 下载媒体处理函数
- const downloadMediaHandler = async (row: Media) => {
- await handleDownload(row, 'media');
- };
- // 下载hash处理函数
- const downloadHashHandler = async (row: Media) => {
- await handleDownload(row, 'hash');
- };
- // 分组管理弹窗
- const groupManageVisible = ref(false);
- // 打开分组管理弹窗
- const groupManage = () => {
- groupManageVisible.value = true;
- };
- // 刷新列表
- const refreshList = () => {
- refresh();
- fetchGroupList(); // 刷新分组列表
- };
- // 跳转
- const floadileUrl = (row: any) => {
- if (row.fileType == 3) {
- let url = `/code/index.html?title=${row.fileName}&type=${row.fileFormat}&fileUrl=${row.fileUrl}#/sign-model`
- return window.open(url);
- } else {
- return window.open(row.fileUrl);
- }
- }
- // 确认删除
- const confirmDelete = async (row: Media) => {
- try {
- await ElMessageBox.confirm('确定删除吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- });
-
- // 用户点击确认,执行删除操作
- try {
- await deleteMediaItem(row.id);
- ElMessage.success('删除成功');
- refresh(); // 刷新列表
- } catch (error) {
- console.error('删除失败:', error);
- ElMessage.error('删除失败');
- }
- } catch {
- // 用户点击取消,不执行任何操作
- }
- };
- </script>
- <style lang="scss" scoped>
- .mediaLibrary {
- width: 100%;
- height: 100%;
- }
- </style>
|