Merge branch 'master' of http://119.29.194.155:8894/zwq/zhxy-jsd
This commit is contained in:
commit
f372b341cc
57
src/api/base/pbApi.ts
Normal file
57
src/api/base/pbApi.ts
Normal file
@ -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);
|
||||
};
|
||||
@ -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);
|
||||
};
|
||||
@ -155,3 +155,6 @@ const setDefaultValue = () => {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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: 使用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); }
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
});
|
||||
|
||||
// 巡查记录列表
|
||||
|
||||
@ -91,7 +91,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { getKyXcCourseListApi } from "@/api/base/xkPbApi";
|
||||
import { getKyXcCourseListApi } from "@/api/base/pbApi";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||||
@ -121,12 +121,12 @@ onMounted(async () => {
|
||||
// 优先从global获取排班数据,如果没有则从data获取
|
||||
let pbData = dataStore.getGlobal;
|
||||
|
||||
if (!pbData || !pbData.xcbt || !pbData.xcbt.includes('课业辅导巡计划')) {
|
||||
if (!pbData || !pbData.xcbt ) {
|
||||
pbData = dataStore.getData;
|
||||
}
|
||||
|
||||
// 检查数据是否有效
|
||||
if (!pbData || !pbData.xcbt || pbData.xcbt.includes('课业辅导巡计划') === false) {
|
||||
if (!pbData || !pbData.xcbt ) {
|
||||
uni.showToast({
|
||||
title: '数据异常,请重新选择排班',
|
||||
icon: 'none'
|
||||
@ -256,7 +256,7 @@ const goXc = (xkkc: any) => {
|
||||
const pbData = dataStore.getGlobal;
|
||||
|
||||
// 检查排班数据是否有效
|
||||
if (!pbData || !pbData.xcbt || !pbData.xcbt.includes('课业辅导巡计划')) {
|
||||
if (!pbData || !pbData.xcbt ) {
|
||||
uni.showToast({
|
||||
title: '数据异常,请重新选择排班',
|
||||
icon: 'none'
|
||||
@ -269,6 +269,7 @@ const goXc = (xkkc: any) => {
|
||||
...xkkc,
|
||||
id: xkkc.id, // 课程记录ID
|
||||
pbId: pbData.id, // 排班ID - 确保使用正确的排班ID
|
||||
pbJsId: xkkc.id, // 将课程记录ID作为pbJsId传递
|
||||
xclx: pbData.xclx,
|
||||
xcbt: pbData.xcbt,
|
||||
xqmc: pbData.xqmc,
|
||||
@ -309,7 +310,7 @@ const goRecord = (xkkc: any) => {
|
||||
const pbData = dataStore.getGlobal;
|
||||
|
||||
// 检查排班数据是否有效
|
||||
if (!pbData || !pbData.xcbt || !pbData.xcbt.includes('课业辅导巡计划')) {
|
||||
if (!pbData || !pbData.xcbt ) {
|
||||
uni.showToast({
|
||||
title: '数据异常,请重新选择排班',
|
||||
icon: 'none'
|
||||
|
||||
@ -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, // 使用传递的pbJsId或课程记录ID
|
||||
xctime: now.format("YYYY-MM-DD HH:mm:ss"),
|
||||
zp: getImageUrls(),
|
||||
sp: getVideoUrls(),
|
||||
|
||||
@ -69,7 +69,7 @@ import {
|
||||
} from "vue";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { getXkPbPageApi } from "@/api/base/xkPbApi";
|
||||
import { getPbPageApi } from "@/api/base/pbApi";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const { getJs } = useUserStore();
|
||||
@ -114,7 +114,7 @@ const loadPbList = async (isRefresh = false) => {
|
||||
// xqId: '', // 学期ID
|
||||
};
|
||||
|
||||
const res: any = await getXkPbPageApi(params);
|
||||
const res: any = await getPbPageApi(params);
|
||||
|
||||
// 根据实际API响应结构判断成功条件
|
||||
if (res && (res.resultCode == 1 || res.rows || res.result)) {
|
||||
|
||||
@ -103,7 +103,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { jsdXkListApi } from "@/api/base/server";
|
||||
import { getXcCourseListApi } from "@/api/base/xkPbApi";
|
||||
import { getXcCourseListApi } from "@/api/base/pbApi";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||||
|
||||
BIN
src/static/base/view/excel.png
Normal file
BIN
src/static/base/view/excel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
BIN
src/static/base/view/pdf.png
Normal file
BIN
src/static/base/view/pdf.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
BIN
src/static/base/view/ppt.png
Normal file
BIN
src/static/base/view/ppt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
BIN
src/static/base/view/word.png
Normal file
BIN
src/static/base/view/word.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
BIN
src/static/base/view/zip.png
Normal file
BIN
src/static/base/view/zip.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
Loading…
x
Reference in New Issue
Block a user