选课调整

This commit is contained in:
hebo 2025-09-14 17:28:02 +08:00
parent 80f126c25a
commit e72543cb2b
12 changed files with 722 additions and 186 deletions

View File

@ -155,3 +155,5 @@ const setDefaultValue = () => {

View File

@ -13,7 +13,7 @@
<template v-for="(item,index) in head" :key="index">
<view class="font-w-500 px-5 flex-row justify-between items-center" style="width: 115px" v-if="index==0"
:style="{ position: 'sticky', left: '0', backgroundColor: '#aacbfb', zIndex: 10 }">
<view v-for="(zitem,xindex) in item['name'].split(',')" :key="'z_'+xindex">
<view v-for="(zitem,xindex) in (item['name'] || '').split(',')" :key="'z_'+xindex">
{{ zitem }}
</view>
</view>
@ -27,7 +27,7 @@
<view class="font-13 flex-row justify-between items-center px-5" style="width: 115px" v-if="dindex==0"
:style="{ position: 'sticky', left: '0', backgroundColor: '#f8f8f8', zIndex: 10 }">
<view> {{ bitem['gradeFullName'] }}</view>
<view>{{ 100 + parseFloat(bitem['totalScore']) }}</view>
<view>{{ calculateTotalScore(bitem) }}</view>
</view>
<!-- <view class="font-13 flex-col-center" v-else-if="dindex==1"-->
<!-- :style="{ position: 'sticky', left: '0', backgroundColor: '#f8f8f8', zIndex: 10 }">-->
@ -35,10 +35,10 @@
<!-- </view>-->
<view class="font-13 flex-col-center" v-else>
<view v-if="bitem['itemScoreMap'][ ditem['id']]">
{{ bitem['itemScoreMap'][ditem['id']] }}
{{ calculateItemScore(bitem, ditem) }}
</view>
<view v-else>
<image src="/static/base/tb.jpg" class="wi-50 he-50"></image>
{{ getBaseScore(ditem) }}
</view>
</view>
</template>
@ -65,9 +65,56 @@ onMounted(() => {
height.value = getWindowHeight()
})
const head = ref([])
const head = ref<any[]>([])
const dataLiat = ref<any>([])
// baseScore * 5
function getBaseScore(ditem: any) {
const inspectItem = head.value.find(item => item.id === ditem.id);
if (inspectItem && inspectItem.baseScore) {
return inspectItem.baseScore * 5;
}
return 0;
}
// baseScore * 5 -
function calculateItemScore(bitem: any, ditem: any) {
if (bitem.itemScoreMap && bitem.itemScoreMap[ditem.id]) {
// baseScore
const inspectItem = head.value.find(item => item.id === ditem.id);
if (inspectItem && inspectItem.baseScore) {
const baseScore = inspectItem.baseScore * 5; //
const deduction = bitem.itemScoreMap[ditem.id]; //
// = baseScore * 5 -
return baseScore + deduction; // deduction
}
}
return 0;
}
//
function calculateTotalScore(bitem: any) {
let totalScore = 0;
// head
head.value.forEach(item => {
if (item.id && item.baseScore) {
const baseScore = item.baseScore * 5; //
let deduction = 0; //
//
if (bitem.itemScoreMap && bitem.itemScoreMap[item.id]) {
deduction = bitem.itemScoreMap[item.id];
}
// = baseScore * 5 -
totalScore += baseScore + deduction; // deduction
}
});
return totalScore;
}
async function getWeekData() {
let res = await inspectItemFindAllApi();
let arr: any = [{name: "班级,得分"}];
@ -79,8 +126,25 @@ async function getWeekData() {
// arr.push();
head.value = arr
let res1 = await evaluationGetWeekReportApi();
const grouped = groupBy(res1.result, 'gradeNum');
dataLiat.value = values(grouped);
//
//
const grouped = groupBy(res1.result, (item) => {
// "1"""
const match = item.gradeFullName.match(/^(.+?)(\d+班)$/);
return match ? match[1] : item.gradeFullName;
});
//
const gradeNames = Object.keys(grouped).sort((a, b) => {
//
const numA = parseInt(a.replace(/[^\d]/g, '')) || 0;
const numB = parseInt(b.replace(/[^\d]/g, '')) || 0;
return numA - numB;
});
//
dataLiat.value = gradeNames.map(gradeName => grouped[gradeName]);
// forEach(result, (data) => {
// let rowDatas: any = [];
// if (data && data.length > 0) {

View File

@ -30,70 +30,21 @@
<view class="file-section">
<view class="section-title">附件</view>
<view class="file-list" v-if="hasAttachments">
<!-- 处理单个附件从gwInfo直接获取 -->
<!-- 显示所有解析后的附件 -->
<view
v-if="gwInfo.fileUrl"
v-for="(file, index) in parsedAttachments"
:key="(file as any).id || index"
class="file-item"
@click="previewSingleFile"
>
<view class="file-icon">
<text v-if="isImage(gwInfo.fileFormat || '')">🖼</text>
<text v-else-if="isVideo(gwInfo.fileFormat || '')">🎥</text>
<text v-else-if="canPreview(gwInfo.fileFormat || '')">📄</text>
<text v-else>📎</text>
</view>
<view class="file-info">
<text class="file-name">{{ gwInfo.fileName || '未知文件' }}</text>
<text class="file-type">{{ (gwInfo.fileFormat || 'unknown').toUpperCase() }}</text>
</view>
<view class="file-actions">
<u-button
v-if="canPreview(gwInfo.fileFormat || '') && !isVideo(gwInfo.fileFormat || '')"
text="预览"
size="mini"
type="primary"
@click.stop="previewSingleFile"
<image
:src="getFileIcon(getFileSuffix(file))"
class="icon-image"
mode="aspectFit"
/>
<u-button
v-if="isVideo(gwInfo.fileFormat || '')"
text="播放"
size="mini"
type="success"
@click.stop="previewSingleFile"
/>
<u-button
v-if="isImage(gwInfo.fileFormat || '')"
text="查看"
size="mini"
type="warning"
@click.stop="previewSingleFile"
/>
<u-button
text="下载"
size="mini"
type="info"
@click.stop="downloadSingleFile"
/>
</view>
</view>
<!-- 处理多个附件从files数组获取 -->
<view
v-for="(file, index) in gwInfo.files"
:key="index"
class="file-item"
@click="previewFile(file)"
>
<view class="file-icon">
<text v-if="isImage(getFileSuffix(file))">🖼</text>
<text v-else-if="isVideo(getFileSuffix(file))">🎥</text>
<text v-else-if="canPreview(getFileSuffix(file))">📄</text>
<text v-else>📎</text>
</view>
<view class="file-info">
<text class="file-name">{{ getFileName(file) }}</text>
<text class="file-size">{{ formatFileSize(file.size) }}</text>
<text class="file-type">{{ getFileSuffix(file).toUpperCase() }}</text>
</view>
<view class="file-actions">
<u-button
@ -101,27 +52,27 @@
text="预览"
size="mini"
type="primary"
@click.stop="previewFile(file)"
@click="previewFile(file)"
/>
<u-button
v-if="isVideo(getFileSuffix(file))"
text="播放"
size="mini"
type="success"
@click.stop="previewFile(file)"
@click="previewFile(file)"
/>
<u-button
v-if="isImage(getFileSuffix(file))"
text="查看"
size="mini"
type="warning"
@click.stop="previewFile(file)"
@click="previewFile(file)"
/>
<u-button
text="下载"
size="mini"
type="info"
@click.stop="downloadFile(file)"
@click="downloadFileAction(file)"
/>
</view>
</view>
@ -208,7 +159,6 @@
<text class="time">{{ formatTime(log.operationTime) }}</text>
</view>
<view class="log-content">
<text class="type">{{ log.operationType }}</text>
<text class="content">{{ log.operationContent }}</text>
</view>
<view class="log-detail" v-if="log.beforeChange || log.afterChange">
@ -265,7 +215,7 @@
<!-- 操作记录详情弹窗 -->
<u-popup v-model="showLogDetailModal" mode="center">
<u-popup :show="showLogDetailModal" @close="showLogDetailModal = false" mode="center">
<view class="detail-modal">
<view class="detail-header">
<text class="detail-title">操作详情</text>
@ -287,6 +237,48 @@
</view>
</view>
</u-popup>
<!-- 下载路径选择弹窗 -->
<u-popup :show="showDownloadModal" @close="showDownloadModal = false" mode="center">
<view class="download-modal">
<view class="download-header">
<text class="download-title">文件下载</text>
</view>
<view class="download-content">
<view class="file-info-section">
<text class="file-label">文件名</text>
<text class="file-name">{{ downloadFileName }}</text>
</view>
<view class="path-info-section">
<text class="path-label">下载路径</text>
<text class="path-text">将下载到默认下载目录</text>
</view>
<view class="download-tips">
<text class="tips-text">点击确认后将开始下载文件</text>
</view>
<!-- 下载中状态 -->
<view class="download-progress" v-if="isDownloading">
<view class="progress-spinner"></view>
<text class="progress-text">正在下载文件请稍候...</text>
</view>
</view>
<view class="download-actions" v-if="!isDownloading">
<u-button
text="取消"
type="default"
size="large"
@click="cancelDownload"
style="margin-right: 10px;"
/>
<u-button
text="确认下载"
type="primary"
size="large"
@click="confirmDownload"
/>
</view>
</view>
</u-popup>
</BasicLayout>
</template>
@ -305,7 +297,8 @@ import {
canPreview,
previewFile as previewFileUtil,
previewVideo as previewVideoUtil,
previewImage as previewImageUtil
previewImage as previewImageUtil,
downloadFile
} from "@/utils/filePreview";
//
@ -332,6 +325,7 @@ interface GwInfo {
}
interface FileInfo {
id?: string; // ID
name: string;
size: number;
url: string;
@ -379,6 +373,10 @@ const gwId = ref("");
//
const showLogDetailModal = ref(false);
const showDownloadModal = ref(false);
const downloadUrl = ref('');
const downloadFileName = ref('');
const isDownloading = ref(false);
// store
const { getUser, getJs } = useUserStore();
@ -396,9 +394,54 @@ const ccExpanded = ref(false);
//
const logExpanded = ref(false);
//
const parsedAttachments = computed(() => {
const attachments = [];
// files
if (gwInfo.value.files && gwInfo.value.files.length > 0) {
attachments.push(...gwInfo.value.files);
}
// fileUrl
else if (gwInfo.value.fileUrl) {
const fileUrls = gwInfo.value.fileUrl.split(',').map(url => url.trim()).filter(url => url);
// fileName
let fileNames: string[] = [];
if (gwInfo.value.fileName) {
fileNames = gwInfo.value.fileName.split(',').map(name => name.trim()).filter(name => name);
}
// URL
fileUrls.forEach((url, index) => {
// 使URL
let displayName = fileNames[index] || url.split('/').pop() || `文件${index + 1}`;
const fileFormat = url.split('.').pop() || 'unknown';
// resourName
let resourName = displayName;
if (displayName.includes('.' + fileFormat)) {
resourName = displayName.replace('.' + fileFormat, '');
}
attachments.push({
id: `file_${index}`,
name: displayName, //
url: url,
resourUrl: url,
resourName: resourName, //
resSuf: fileFormat,
size: 0 // URL
});
});
}
return attachments;
});
//
const hasAttachments = computed(() => {
return gwInfo.value.fileUrl || (gwInfo.value.files && gwInfo.value.files.length > 0);
return parsedAttachments.value.length > 0;
});
//
@ -683,7 +726,13 @@ const getCurrentUserApproverId = (currentUserId: string) => {
};
// gwInfo
const previewSingleFile = () => {
const previewSingleFile = (event?: Event) => {
//
if (event) {
event.stopPropagation();
event.preventDefault();
}
if (!gwInfo.value.fileUrl) {
return;
}
@ -706,69 +755,34 @@ const previewSingleFile = () => {
};
//
const downloadSingleFile = () => {
const downloadSingleFile = (event?: Event) => {
//
if (event) {
event.stopPropagation();
event.preventDefault();
}
if (!gwInfo.value.fileUrl) {
return;
}
const fileUrl = imagUrl(gwInfo.value.fileUrl);
const finalUrl = imagUrl(gwInfo.value.fileUrl);
const fileName = gwInfo.value.fileName || '未知文件';
const fileFormat = gwInfo.value.fileFormat || '';
const fullFileName = fileFormat ? `${fileName}.${fileFormat}` : fileName;
// 1: 使 fetch blob
fetch(fileUrl)
.then(response => {
if (!response.ok) {
throw new Error('网络请求失败');
}
return response.blob();
})
.then(blob => {
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = fullFileName; // 使 download
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
uni.showToast({
title: '开始下载',
icon: 'success'
});
})
.catch(error => {
console.error('fetch下载失败:', error);
// 2: fetch
try {
const link = document.createElement('a');
link.href = fileUrl;
link.download = fullFileName;
link.target = '_blank';
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
uni.showToast({
title: '开始下载',
icon: 'success'
});
} catch (fallbackError) {
console.error('备用下载也失败:', fallbackError);
uni.showToast({
title: '下载失败',
icon: 'error'
});
}
});
//
showDownloadPathModal(finalUrl, fullFileName);
};
//
const previewFile = (file: FileInfo) => {
const previewFile = (file: FileInfo, event?: Event) => {
//
if (event) {
event.stopPropagation();
event.preventDefault();
}
// URL
const fileUrl = file.resourUrl ? imagUrl(file.resourUrl) : file.url;
const fileName = file.resourName ? `${file.resourName}.${file.resSuf}` : file.name;
@ -848,65 +862,22 @@ const handlePreviewImageSingle = (imageUrl: string) => {
});
};
//
const downloadFile = (file: FileInfo) => {
downloadFileAction(file);
};
//
const downloadFileAction = (file: FileInfo) => {
const fileUrl = file.resourUrl ? imagUrl(file.resourUrl) : file.url;
const fileName = file.resourName ? `${file.resourName}.${file.resSuf}` : file.name;
// 1: 使 fetch blob
fetch(fileUrl)
.then(response => {
if (!response.ok) {
throw new Error('网络请求失败');
// -
const downloadFileAction = (file: FileInfo, event?: Event) => {
//
if (event) {
event.stopPropagation();
event.preventDefault();
}
return response.blob();
})
.then(blob => {
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = fileName; // 使 download
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
uni.showToast({
title: '开始下载',
icon: 'success'
});
})
.catch(error => {
console.error('fetch下载失败:', error);
// 2: fetch
try {
const link = document.createElement('a');
link.href = fileUrl;
link.download = fileName;
link.target = '_blank';
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
const finalUrl = file.resourUrl ? imagUrl(file.resourUrl) : imagUrl(file.url);
//
const originalFileName = getOriginalFileName(file);
uni.showToast({
title: '开始下载',
icon: 'success'
});
} catch (fallbackError) {
console.error('备用下载也失败:', fallbackError);
uni.showToast({
title: '下载失败',
icon: 'error'
});
}
});
console.log('下载文件:', { finalUrl, originalFileName, file });
//
showDownloadPathModal(finalUrl, originalFileName);
};
//
@ -952,6 +923,31 @@ const getFileSuffix = (file: FileInfo) => {
return 'unknown';
};
//
const getFileIcon = (fileType: string) => {
const type = fileType.toLowerCase();
switch (type) {
case 'pdf':
return '/static/base/view/pdf.png';
case 'doc':
case 'docx':
return '/static/base/view/word.png';
case 'xls':
case 'xlsx':
return '/static/base/view/excel.png';
case 'ppt':
case 'pptx':
return '/static/base/view/ppt.png';
case 'zip':
case 'rar':
case '7z':
return '/static/base/view/zip.png';
default:
return '/static/base/view/more.png';
}
};
//
const getStatusClass = (status: any) => {
const statusMap: Record<string, string> = {
@ -1040,6 +1036,314 @@ const getUrgencyText = (level: string) => {
return levelMap[level] || "未知";
};
//
const getOriginalFileName = (file: FileInfo) => {
// 使resourName使name
let fileName = '';
if (file.resourName) {
// resourName使
if (file.resSuf && !file.resourName.includes('.' + file.resSuf)) {
fileName = `${file.resourName}.${file.resSuf}`;
} else {
fileName = file.resourName;
}
} else if (file.name) {
// name使
if (file.resSuf && !file.name.includes('.' + file.resSuf)) {
fileName = `${file.name}.${file.resSuf}`;
} else {
fileName = file.name;
}
} else {
// URL
const urlFileName = file.url.split('/').pop() || '未知文件';
fileName = urlFileName;
}
return fileName;
};
//
const showDownloadPathModal = (url: string, fileName: string) => {
downloadUrl.value = url;
downloadFileName.value = fileName;
showDownloadModal.value = true;
};
//
const confirmDownload = () => {
//
isDownloading.value = true;
//
const systemInfo = uni.getSystemInfoSync();
const { platform } = systemInfo;
//
const isH5 = platform === 'web' || typeof window !== 'undefined';
console.log('平台检测:', { platform, systemInfo, isH5 });
if (isH5) {
console.log('使用H5下载方式');
// H5使
downloadForH5(downloadUrl.value, downloadFileName.value);
} else {
console.log('使用原生下载方式');
// 使
downloadFile(downloadUrl.value, downloadFileName.value)
.then(() => {
//
isDownloading.value = false;
showDownloadModal.value = false;
uni.showToast({
title: "下载成功",
icon: "success",
});
})
.catch((error) => {
console.error('下载失败:', error);
//
isDownloading.value = false;
showDownloadModal.value = false;
uni.showToast({
title: "下载失败",
icon: "error",
});
});
}
};
// H5
const downloadForH5 = (url: string, fileName: string) => {
try {
console.log('H5下载开始:', { url, fileName });
// 使
forceDownload(url, fileName);
} catch (error) {
console.error('H5下载失败:', error);
// 退
fallbackDownload(url, fileName);
}
};
//
const forceDownload = (url: string, fileName: string) => {
try {
console.log('尝试强制下载:', { url, fileName });
// 1: 使fetchblob
fetch(url, {
method: 'GET',
mode: 'cors',
cache: 'no-cache'
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.blob();
})
.then(blob => {
console.log('文件下载成功创建blob下载');
// blob URL
const blobUrl = window.URL.createObjectURL(blob);
//
const link = document.createElement('a');
link.href = blobUrl;
link.download = fileName;
link.style.display = 'none';
// DOM
document.body.appendChild(link);
link.click();
// DOMblob URL
document.body.removeChild(link);
window.URL.revokeObjectURL(blobUrl);
//
isDownloading.value = false;
showDownloadModal.value = false;
uni.showToast({
title: "下载成功",
icon: "success",
});
})
.catch(error => {
console.error('Fetch下载失败尝试其他方法:', error);
// fetch
tryAlternativeDownload(url, fileName);
});
} catch (error) {
console.error('强制下载失败,尝试其他方法:', error);
tryAlternativeDownload(url, fileName);
}
};
//
const tryAlternativeDownload = (url: string, fileName: string) => {
console.log('尝试替代下载方法');
// 1: 使XMLHttpRequest
try {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function() {
if (xhr.status === 200) {
const blob = xhr.response;
const blobUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = blobUrl;
link.download = fileName;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(blobUrl);
//
isDownloading.value = false;
showDownloadModal.value = false;
uni.showToast({
title: "下载成功",
icon: "success",
});
console.log('XMLHttpRequest下载成功');
} else {
throw new Error(`HTTP error! status: ${xhr.status}`);
}
};
xhr.onerror = function() {
console.error('XMLHttpRequest下载失败');
console.log('调用手动下载提示');
showManualDownloadModal(url, fileName);
};
xhr.send();
} catch (error) {
console.error('XMLHttpRequest失败:', error);
console.log('调用手动下载提示catch');
showManualDownloadModal(url, fileName);
}
};
//
const showManualDownloadModal = (url: string, fileName: string) => {
console.log('尝试原生下载');
// 使
try {
const link = document.createElement('a');
link.href = url;
link.download = fileName;
link.target = '_blank';
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
console.log('原生下载已触发');
//
setTimeout(() => {
isDownloading.value = false;
showDownloadModal.value = false;
}, 1000);
uni.showToast({
title: "开始下载",
icon: "success",
});
} catch (error) {
console.error('原生下载失败:', error);
//
isDownloading.value = false;
showDownloadModal.value = false;
uni.showToast({
title: "下载失败",
icon: "error",
});
}
};
//
const directDownload = (url: string, fileName: string) => {
try {
// URL
const downloadUrl = url.includes('?')
? `${url}&download=1&attachment=1`
: `${url}?download=1&attachment=1`;
const link = document.createElement('a');
link.href = downloadUrl;
link.download = fileName;
link.target = '_self'; // 使_self_blank
link.style.display = 'none';
// DOM
document.body.appendChild(link);
link.click();
// DOM
document.body.removeChild(link);
uni.showToast({
title: "开始下载",
icon: "success",
});
} catch (error) {
console.error('直接下载失败:', error);
//
uni.showModal({
title: '下载提示',
content: `由于浏览器限制,无法自动下载文件。请长按链接手动保存:\n${url}`,
showCancel: false,
confirmText: '知道了'
});
}
};
//
const fallbackDownload = (url: string, fileName: string) => {
try {
console.log('使用备用下载方法');
// 使
directDownload(url, fileName);
} catch (error) {
console.error('备用下载也失败:', error);
//
uni.showModal({
title: '下载提示',
content: `由于浏览器限制,无法自动下载文件。请长按链接手动保存:\n${url}`,
showCancel: false,
confirmText: '知道了'
});
}
};
//
const cancelDownload = () => {
showDownloadModal.value = false;
};
//
const getCreatorName = (tjrId: string) => {
if (!tjrId) return "未知";
@ -1232,9 +1536,16 @@ onMounted(() => {
.file-icon {
margin-right: 12px;
font-size: 24px;
width: 32px;
text-align: center;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
.icon-image {
width: 28px;
height: 28px;
}
}
.file-info {
@ -1524,4 +1835,121 @@ onMounted(() => {
}
}
}
.download-modal {
width: 85vw;
max-width: 450px;
padding: 20px;
background: #fff;
border-radius: 12px;
.download-header {
text-align: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #eee;
.download-title {
font-size: 18px;
font-weight: bold;
color: #333;
}
}
.download-content {
margin-bottom: 25px;
.file-info-section {
display: flex;
align-items: flex-start;
margin-bottom: 15px;
.file-label {
font-weight: 500;
color: #666;
margin-right: 10px;
flex-shrink: 0;
width: 60px;
}
.file-name {
color: #333;
font-size: 14px;
word-break: break-all;
flex: 1;
background: #f8f9fa;
padding: 8px 12px;
border-radius: 6px;
border: 1px solid #e9ecef;
}
}
.path-info-section {
display: flex;
align-items: center;
margin-bottom: 15px;
.path-label {
font-weight: 500;
color: #666;
margin-right: 10px;
flex-shrink: 0;
width: 60px;
}
.path-text {
color: #007aff;
font-size: 14px;
flex: 1;
}
}
.download-tips {
text-align: center;
.tips-text {
color: #999;
font-size: 12px;
}
}
}
.download-actions {
display: flex;
justify-content: center;
gap: 10px;
.u-button {
flex: 1;
max-width: 120px;
}
}
.download-progress {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 0;
.progress-spinner {
width: 24px;
height: 24px;
border: 2px solid #f3f3f3;
border-top: 2px solid #007aff;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 10px;
}
.progress-text {
color: #666;
font-size: 14px;
}
}
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>

View File

@ -79,7 +79,11 @@
@click="previewAttachmentFile(file)"
>
<view class="attachment-icon">
<text>📄</text>
<image
:src="getFileIcon(getFileSuffix(file))"
class="icon-image"
mode="aspectFit"
/>
</view>
<text class="attachment-name">{{ getFileName(file) }}</text>
</view>
@ -529,6 +533,30 @@ const getFileSuffix = (file: FileInfo) => {
return 'unknown';
};
//
const getFileIcon = (fileType: string) => {
const type = fileType.toLowerCase();
switch (type) {
case 'pdf':
return '/static/base/view/pdf.png';
case 'doc':
case 'docx':
return '/static/base/view/word.png';
case 'xls':
case 'xlsx':
return '/static/base/view/excel.png';
case 'ppt':
case 'pptx':
return '/static/base/view/ppt.png';
case 'zip':
case 'rar':
case '7z':
return '/static/base/view/zip.png';
default:
return '/static/base/view/more.png';
}
};
//
watch(dataList, (val) => {
//
@ -810,8 +838,17 @@ onUnmounted(() => {
.attachment-icon {
margin-right: 6px;
font-size: 16px;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
.icon-image {
width: 18px;
height: 18px;
}
}
.attachment-name {

View File

@ -174,6 +174,9 @@ let inspectionParams = ref({
rows: 10,
kyXcId: xkkc.value.id,
jsId: js.value.id,
njId: xkkc.value.njId,
bjId: xkkc.value.bjId,
njmcId: xkkc.value.njmcId,
});
//

View File

@ -269,6 +269,7 @@ const goXc = (xkkc: any) => {
...xkkc,
id: xkkc.id, // ID
pbId: pbData.id, // ID - 使ID
pbJsId: xkkc.id, // IDpbJsId
xclx: pbData.xclx,
xcbt: pbData.xcbt,
xqmc: pbData.xqmc,

View File

@ -521,6 +521,7 @@ const submit = async () => {
njId: xkkc.value.njId || '', // ID
njmcId: xkkc.value.njmcId || '', // ID
bjId: xkkc.value.bjId || '', // ID
pbJsId: xkkc.value.pbJsId || xkkc.value.id, // 使pbJsIdID
xctime: now.format("YYYY-MM-DD HH:mm:ss"),
zp: getImageUrls(),
sp: getVideoUrls(),

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB