文字文件预览和删除
This commit is contained in:
47
klp-ui/src/api/mes/qc/files.js
Normal file
47
klp-ui/src/api/mes/qc/files.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 模拟获取文件列表
|
||||
export function listFile() {
|
||||
return request({
|
||||
url: '/wms/file/list',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getFileStats() {
|
||||
return request({
|
||||
url: `/wms/file/stats`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteFile(fileName) {
|
||||
return request({
|
||||
url: `/wms/file/delete/${fileName}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function getFileContent(fileName) {
|
||||
return request({
|
||||
url: `/wms/file/content/${fileName}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 清除三个月的内的文件
|
||||
export function clearUp() {
|
||||
return request({
|
||||
url: `/wms/file/cleanup`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 批量删除文件
|
||||
export function batchDeleteFile(fileNames) {
|
||||
return request({
|
||||
url: `/wms/file/batch-delete`,
|
||||
method: 'post',
|
||||
data: fileNames
|
||||
})
|
||||
}
|
||||
225
klp-ui/src/views/mes/qc/files/index.vue
Normal file
225
klp-ui/src/views/mes/qc/files/index.vue
Normal file
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<div style="display: flex; height: calc(100vh - 84px);">
|
||||
<!-- 左侧文件列表 -->
|
||||
<div style="width: 250px; border-right: 1px solid #eee; overflow-y: auto;">
|
||||
<div style="padding: 8px 16px; border-bottom: 1px solid #eee; display: flex; gap: 8px; align-items: center;">
|
||||
<button @click="handleClearAll" style="background: #f56c6c; color: #fff; border: none; border-radius: 3px; padding: 4px 10px; cursor: pointer;">清空全部</button>
|
||||
</div>
|
||||
<div v-if="loadingList" style="padding: 24px; color: #888; text-align: center;">文件列表加载中...</div>
|
||||
<ul v-else style="list-style: none; padding: 0; margin: 0;">
|
||||
<template v-for="(group, groupName) in groupedFiles">
|
||||
<li style="background:#f5f5f5; color:#888; font-weight:bold; padding:8px 16px; display: flex; align-items: center; justify-content: space-between;">
|
||||
<span>{{ groupName }}</span>
|
||||
<button @click.stop="handleClearGroup(groupName)" style="background: #e6a23c; color: #fff; border: none; border-radius: 3px; padding: 2px 8px; font-size: 12px; cursor: pointer;">清空分组</button>
|
||||
</li>
|
||||
<li v-for="file in group" :key="file.fileName"
|
||||
:style="{padding: '12px 16px', cursor: 'pointer', background: file.fileName === selectedFileName ? '#f0f0f0' : ''}"
|
||||
@click="selectFile(file)">
|
||||
{{ file.fileName }}
|
||||
<span style="float: right; color: #f56c6c; cursor: pointer;" @click.stop="handleDeleteFile(file)">删除</span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 右侧文件预览 -->
|
||||
<div style="flex: 1; padding: 24px; overflow-y: auto;">
|
||||
<div v-if="loadingContent" style="color: #888;">内容加载中...</div>
|
||||
<div v-else-if="selectedFile">
|
||||
<h3>{{ selectedFile.fileName }}</h3>
|
||||
<template v-if="selectedFile.fileType === 'text'">
|
||||
<pre style="background: #fafafa; padding: 16px; border-radius: 4px; min-height: 300px;">{{ selectedFile.fileContent }}</pre>
|
||||
</template>
|
||||
<!-- <template v-else-if="selectedFile.fileType === 'image'">
|
||||
<div style="padding: 16px; background: #fafafa; border-radius: 4px; min-height: 300px; display: flex; align-items: center; justify-content: center;">
|
||||
<img :src="selectedFile.fileContent" alt="图片预览" style="max-width: 100%; max-height: 600px;" />
|
||||
</div>
|
||||
</template> -->
|
||||
<template v-else>
|
||||
<div style="background: #fafafa; padding: 16px; border-radius: 4px; min-height: 300px; color: #f56c6c;">{{ selectedFile.fileContent }}</div>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else style="color: #888;">请选择左侧文件进行预览</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listFile, getFileStats, deleteFile, getFileContent, clearUp, batchDeleteFile } from '@/api/mes/qc/files';
|
||||
export default {
|
||||
name: 'FilePreview',
|
||||
data() {
|
||||
return {
|
||||
files: [],
|
||||
selectedFile: null,
|
||||
selectedFileName: '',
|
||||
loadingList: false,
|
||||
loadingContent: false,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fetchFileList();
|
||||
getFileStats()
|
||||
},
|
||||
computed: {
|
||||
groupedFiles() {
|
||||
// 分组规则
|
||||
const groups = {
|
||||
'今天': [],
|
||||
'昨天': [],
|
||||
'一周内': [],
|
||||
'本月': [],
|
||||
'近三个月': [],
|
||||
'更久': [],
|
||||
};
|
||||
const now = new Date();
|
||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
const yesterday = new Date(today);
|
||||
yesterday.setDate(today.getDate() - 1);
|
||||
const weekAgo = new Date(today);
|
||||
weekAgo.setDate(today.getDate() - 6);
|
||||
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||
const threeMonthsAgo = new Date(now.getFullYear(), now.getMonth() - 2, 1);
|
||||
(this.files || []).forEach(file => {
|
||||
const d = file.lastModified ? new Date(file.lastModified) : null;
|
||||
if (!d) {
|
||||
groups['更久'].push(file);
|
||||
return;
|
||||
}
|
||||
if (d >= today) {
|
||||
groups['今天'].push(file);
|
||||
} else if (d >= yesterday) {
|
||||
groups['昨天'].push(file);
|
||||
} else if (d >= weekAgo) {
|
||||
groups['一周内'].push(file);
|
||||
} else if (d >= monthStart) {
|
||||
groups['本月'].push(file);
|
||||
} else if (d >= threeMonthsAgo) {
|
||||
groups['近三个月'].push(file);
|
||||
} else {
|
||||
groups['更久'].push(file);
|
||||
}
|
||||
});
|
||||
// 只返回有文件的分组
|
||||
return Object.fromEntries(Object.entries(groups).filter(([k, v]) => v.length));
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 清空全部文件
|
||||
async handleClearAll() {
|
||||
if (!this.files.length) return this.$message.info('没有可删除的文件');
|
||||
this.$confirm('确定要清空全部文件吗?此操作不可恢复!', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
const names = this.files.map(f => f.fileName);
|
||||
await this.batchDelete(names);
|
||||
}).catch(() => {});
|
||||
},
|
||||
|
||||
// 清空某个分组
|
||||
async handleClearGroup(groupName) {
|
||||
const group = this.groupedFiles[groupName] || [];
|
||||
if (!group.length) return this.$message.info('该分组没有可删除的文件');
|
||||
this.$confirm(`确定要清空分组“${groupName}”下的所有文件吗?`, '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
const names = group.map(f => f.fileName);
|
||||
await this.batchDelete(names);
|
||||
}).catch(() => {});
|
||||
},
|
||||
|
||||
// 批量删除
|
||||
async batchDelete(names) {
|
||||
if (!names.length) return;
|
||||
this.loadingList = true;
|
||||
try {
|
||||
if (typeof this.$api?.mes?.qc?.files?.batchDeleteFile === 'function') {
|
||||
await this.$api.mes.qc.files.batchDeleteFile(names);
|
||||
} else if (typeof batchDeleteFile === 'function') {
|
||||
await batchDeleteFile(names);
|
||||
} else {
|
||||
// fallback: 单个删除
|
||||
for (const name of names) {
|
||||
await deleteFile(name);
|
||||
}
|
||||
}
|
||||
this.$message.success('删除成功');
|
||||
this.fetchFileList();
|
||||
} catch (e) {
|
||||
this.$message.error('批量删除失败: ' + (e.message || '未知错误'));
|
||||
} finally {
|
||||
this.loadingList = false;
|
||||
}
|
||||
},
|
||||
async fetchFileList() {
|
||||
this.loadingList = true;
|
||||
this.files = [];
|
||||
this.selectedFile = null;
|
||||
this.selectedFileName = '';
|
||||
try {
|
||||
const res = await listFile();
|
||||
console.log('文件列表:', res);
|
||||
this.files = res.data || [];
|
||||
} finally {
|
||||
this.loadingList = false;
|
||||
}
|
||||
},
|
||||
|
||||
async selectFile(file) {
|
||||
this.selectedFileName = file.fileName;
|
||||
this.selectedFile = null;
|
||||
this.loadingContent = true;
|
||||
try {
|
||||
const isText = /\.(txt|md|json|js|ts|log|csv|xml|html|css)$/i.test(file.fileName);
|
||||
const isImage = /\.(png|jpe?g|gif|bmp|webp|svg)$/i.test(file.fileName);
|
||||
if (isText) {
|
||||
const textResult = await getFileContent(file.fileName)
|
||||
this.selectedFile = {...textResult.data, fileType: 'text'};
|
||||
}
|
||||
// else if (isImage) {
|
||||
// // 图片文件
|
||||
// let blob = null;
|
||||
// if (typeof this.$options.components?.getFileContent === 'function') {
|
||||
// blob = await this.$options.components.getFileContent(file.fileName);
|
||||
// } else if (typeof window.getFileContent === 'function') {
|
||||
// blob = await window.getFileContent(file.fileName);
|
||||
// }
|
||||
// // blob 可能是base64字符串或Blob对象,需适配
|
||||
// let imgUrl = '';
|
||||
// if (blob instanceof Blob) {
|
||||
// imgUrl = URL.createObjectURL(blob);
|
||||
// } else if (typeof blob === 'string' && blob.startsWith('data:image')) {
|
||||
// imgUrl = blob;
|
||||
// } else if (typeof blob === 'string') {
|
||||
// // 假设后端返回base64
|
||||
// imgUrl = 'data:image/*;base64,' + blob;
|
||||
// }
|
||||
// this.selectedFile = { fileName: file.fileName, fileContent: imgUrl, fileType: 'image' };
|
||||
// }
|
||||
else {
|
||||
this.selectedFile = { fileName: file.fileName, fileContent: '不支持的文件类型', fileType: 'other' };
|
||||
}
|
||||
} finally {
|
||||
this.loadingContent = false;
|
||||
}
|
||||
},
|
||||
handleDeleteFile(file) {
|
||||
deleteFile(file.fileName)
|
||||
.then(() => {
|
||||
this.$message.success('文件删除成功');
|
||||
this.fetchFileList(); // 重新加载文件列表
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error('删除文件失败: ' + (err.message || '未知错误'));
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 可根据需要自定义样式 */
|
||||
</style>
|
||||
Reference in New Issue
Block a user