diff --git a/src/api/base/pbApi.ts b/src/api/base/pbApi.ts
new file mode 100644
index 0000000..a966b47
--- /dev/null
+++ b/src/api/base/pbApi.ts
@@ -0,0 +1,57 @@
+import { get, post } from "@/utils/request";
+
+/**
+ * 获取选课排班分页数据
+ */
+export const getPbPageApi = async (params: any) => {
+ return await get("/api/pb/findPage", params);
+};
+
+/**
+ * 根据ID获取选课排班详情
+ */
+export const getPbByIdApi = async (id: string) => {
+ return await get(`/api/pb/${id}`);
+};
+
+/**
+ * 创建选课排班
+ */
+export const createPbApi = async (params: any) => {
+ return await post("/api/pb", params);
+};
+
+/**
+ * 更新选课排班
+ */
+export const updatePbApi = async (params: any) => {
+ return await post("/api/pb/update", params);
+};
+
+/**
+ * 删除选课排班
+ */
+export const deletePbApi = async (id: string) => {
+ return await post(`/api/pb/delete/${id}`);
+};
+
+/**
+ * 根据选课ID获取排班列表
+ */
+export const getPbListByXkIdApi = async (params: any) => {
+ return await get("/api/pb/findByXkId", params);
+};
+
+/**
+ * 课程巡查接口
+ */
+export const getXcCourseListApi = async (params: any) => {
+ return await get("/api/pb/getXcCourseList", params);
+};
+
+/**
+ * 课业辅导巡查接口
+ */
+export const getKyXcCourseListApi = async (params: any) => {
+ return await get("/api/pb/getKyXcCourseList", params);
+};
diff --git a/src/api/base/xkPbApi.ts b/src/api/base/xkPbApi.ts
deleted file mode 100644
index 6c8716e..0000000
--- a/src/api/base/xkPbApi.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { get, post } from "@/utils/request";
-
-/**
- * 获取选课排班分页数据
- */
-export const getXkPbPageApi = async (params: any) => {
- return await get("/api/xkPb/findPage", params);
-};
-
-/**
- * 根据ID获取选课排班详情
- */
-export const getXkPbByIdApi = async (id: string) => {
- return await get(`/api/xkPb/${id}`);
-};
-
-/**
- * 创建选课排班
- */
-export const createXkPbApi = async (params: any) => {
- return await post("/api/xkPb", params);
-};
-
-/**
- * 更新选课排班
- */
-export const updateXkPbApi = async (params: any) => {
- return await post("/api/xkPb/update", params);
-};
-
-/**
- * 删除选课排班
- */
-export const deleteXkPbApi = async (id: string) => {
- return await post(`/api/xkPb/delete/${id}`);
-};
-
-/**
- * 根据选课ID获取排班列表
- */
-export const getXkPbListByXkIdApi = async (params: any) => {
- return await get("/api/xkPb/findByXkId", params);
-};
-
-/**
- * 课程巡查接口
- */
-export const getXcCourseListApi = async (params: any) => {
- return await get("/api/xkPb/getXcCourseList", params);
-};
-
-/**
- * 课业辅导巡查接口
- */
-export const getKyXcCourseListApi = async (params: any) => {
- return await get("/api/xkPb/getKyXcCourseList", params);
-};
diff --git a/src/components/BasicNjBjSelect/demo.vue b/src/components/BasicNjBjSelect/demo.vue
index b7af54c..4f83ca9 100644
--- a/src/components/BasicNjBjSelect/demo.vue
+++ b/src/components/BasicNjBjSelect/demo.vue
@@ -155,3 +155,6 @@ const setDefaultValue = () => {
+
+
+
diff --git a/src/pages/view/quantitativeAssessment/quantitativeSummary/quantitativeSummary.vue b/src/pages/view/quantitativeAssessment/quantitativeSummary/quantitativeSummary.vue
index a29bac6..237867d 100644
--- a/src/pages/view/quantitativeAssessment/quantitativeSummary/quantitativeSummary.vue
+++ b/src/pages/view/quantitativeAssessment/quantitativeSummary/quantitativeSummary.vue
@@ -13,7 +13,7 @@
-
+
{{ zitem }}
@@ -27,7 +27,7 @@
{{ bitem['gradeFullName'] }}
- {{ 100 + parseFloat(bitem['totalScore']) }}
+ {{ calculateTotalScore(bitem) }}
@@ -35,10 +35,10 @@
- {{ bitem['itemScoreMap'][ditem['id']] }}
+ {{ calculateItemScore(bitem, ditem) }}
-
+ {{ getBaseScore(ditem) }}
@@ -65,9 +65,56 @@ onMounted(() => {
height.value = getWindowHeight()
})
-const head = ref([])
+const head = ref([])
const dataLiat = ref([])
+// 获取检查项基础分: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) {
diff --git a/src/pages/view/routine/gwlz/gwFlow.vue b/src/pages/view/routine/gwlz/gwFlow.vue
index 675b9a1..1df893a 100644
--- a/src/pages/view/routine/gwlz/gwFlow.vue
+++ b/src/pages/view/routine/gwlz/gwFlow.vue
@@ -30,70 +30,21 @@
附件
-
+
- 🖼️
- 🎥
- 📄
- 📎
-
-
- {{ gwInfo.fileName || '未知文件' }}
- {{ (gwInfo.fileFormat || 'unknown').toUpperCase() }}
-
-
-
-
-
-
-
-
-
-
-
-
- 🖼️
- 🎥
- 📄
- 📎
{{ getFileName(file) }}
- {{ formatFileSize(file.size) }}
- {{ getFileSuffix(file).toUpperCase() }}
@@ -208,7 +159,6 @@
{{ formatTime(log.operationTime) }}
- {{ log.operationType }}
{{ log.operationContent }}
@@ -265,7 +215,7 @@
-
+
+
+
+
+
+
+
+
+ 文件名:
+ {{ downloadFileName }}
+
+
+ 下载路径:
+ 将下载到默认下载目录
+
+
+ 点击确认后将开始下载文件
+
+
+
+
+ 正在下载文件,请稍候...
+
+
+
+
+
+
+
+
@@ -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;
+// 文件下载 - 支持选择下载路径
+const downloadFileAction = (file: FileInfo, event?: Event) => {
+ // 手动阻止事件冒泡
+ if (event) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
- // 方法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 = 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);
-
- uni.showToast({
- title: '开始下载',
- icon: 'success'
- });
- } catch (fallbackError) {
- console.error('备用下载也失败:', fallbackError);
- uni.showToast({
- title: '下载失败',
- icon: 'error'
- });
- }
- });
+ const finalUrl = file.resourUrl ? imagUrl(file.resourUrl) : imagUrl(file.url);
+ // 获取原始文件名
+ const originalFileName = getOriginalFileName(file);
+
+ 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 = {
@@ -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: 使用fetch下载文件内容,然后创建blob下载
+ 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();
+
+ // 清理DOM和blob 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); }
+}
diff --git a/src/pages/view/routine/gwlz/index.vue b/src/pages/view/routine/gwlz/index.vue
index f5d6f9a..ccaa049 100644
--- a/src/pages/view/routine/gwlz/index.vue
+++ b/src/pages/view/routine/gwlz/index.vue
@@ -79,7 +79,11 @@
@click="previewAttachmentFile(file)"
>
- 📄
+
{{ getFileName(file) }}
@@ -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 {
diff --git a/src/pages/view/routine/kefuxuncha/kyRecord.vue b/src/pages/view/routine/kefuxuncha/kyRecord.vue
index 3e5fd0a..799ffec 100644
--- a/src/pages/view/routine/kefuxuncha/kyRecord.vue
+++ b/src/pages/view/routine/kefuxuncha/kyRecord.vue
@@ -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,
});
// 巡查记录列表
diff --git a/src/pages/view/routine/kefuxuncha/kyXkList.vue b/src/pages/view/routine/kefuxuncha/kyXkList.vue
index 33f442c..faf5300 100644
--- a/src/pages/view/routine/kefuxuncha/kyXkList.vue
+++ b/src/pages/view/routine/kefuxuncha/kyXkList.vue
@@ -91,7 +91,7 @@