| | |
| | | <view class="divider"></view> |
| | | <view class="stat-item"> |
| | | <text class="count">{{ stats.rejectCount }}</text> |
| | | <text class="label">审查驳回</text> |
| | | <text class="label">不同意</text> |
| | | </view> |
| | | <view class="divider"></view> |
| | | <view class="stat-item"> |
| | | <text class="count">{{ stats.waiveCount }}</text> |
| | | <text class="label">已放弃</text> |
| | | <text class="label">弃权</text> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | <!-- 审查结论 --> |
| | | <view |
| | | class="conclusion-section" |
| | | v-if="review.expertconclusion && review.expertconclusion !== 2" |
| | | v-if="review.expertconclusion !== '' && review.expertconclusion != null && review.expertconclusion != 2" |
| | | > |
| | | <text class="conclusion-label">审查结论:</text> |
| | | <text class="conclusion-content">{{ |
| | |
| | | </button> |
| | | |
| | | <button |
| | | v-if="review.expertconclusion == 2" |
| | | v-if="review.expertconclusion == 0" |
| | | class="action-btn appeal-btn" |
| | | @tap.stop="submitAppeal(review)" |
| | | > |
| | |
| | | </button> |
| | | |
| | | <button |
| | | v-if="review.expertconclusion == 2 || review.expertconclusion == 3" |
| | | v-if="review.expertconclusion == 0 || review.expertconclusion == 3" |
| | | class="action-btn restart-btn" |
| | | @tap.stop="restartReview(review)" |
| | | > |
| | |
| | | onReachBottom, |
| | | } from "@dcloudio/uni-app"; |
| | | import { useDict } from "@/utils/dict"; |
| | | import { useUserStore } from "@/stores/user"; |
| | | |
| | | // 响应式数据 |
| | | const loading = ref(false); |
| | |
| | | const pageNum = ref(1); |
| | | const pageSize = ref(10); |
| | | const dict = ref({}); |
| | | const userStore = useUserStore(); |
| | | |
| | | // 筛选条件 |
| | | const currentStatus = ref("all"); |
| | |
| | | { label: "全部", value: "all" }, |
| | | { label: "待审查", value: "pending" }, |
| | | { label: "审查通过", value: "approved" }, |
| | | { label: "审查驳回", value: "rejected" }, |
| | | { label: "已放弃", value: "abandoned" }, |
| | | { label: "不同意", value: "rejected" }, |
| | | { label: "弃权", value: "abandoned" }, |
| | | ]); |
| | | |
| | | // 字典映射 |
| | | const statusDict = { |
| | | pending: "待审查", |
| | | approved: "审查通过", |
| | | rejected: "审查驳回", |
| | | abandoned: "已放弃", |
| | | rejected: "不同意", |
| | | abandoned: "弃权", |
| | | }; |
| | | |
| | | // 结论映射 |
| | | const conclusionDict = { |
| | | 0: "未审核", |
| | | 1: "审查通过", |
| | | 2: "审查驳回", |
| | | 3: "放弃", |
| | | 0: "不同意", |
| | | 1: "同意", |
| | | 2: "审查中", |
| | | 3: "弃权", |
| | | 4: "修改后同意", |
| | | }; |
| | | |
| | |
| | | params.expertconclusion = 1; // 同意 |
| | | break; |
| | | case "rejected": |
| | | params.expertconclusion = 2; // 不同意 |
| | | params.expertconclusion = 0; // 不同意 |
| | | break; |
| | | case "abandoned": |
| | | params.expertconclusion = 3; // 放弃 |
| | | params.expertconclusion = 3; // 弃权 |
| | | break; |
| | | } |
| | | } |
| | |
| | | }); |
| | | }; |
| | | |
| | | // 下载报告 |
| | | const downloadReport = async (review) => { |
| | | if (!review.conclusionannex) { |
| | | uni.showToast({ |
| | | title: "暂无报告可下载", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 获取文件下载的基础地址: |
| | | // H5 端走同源地址(由部署该页面的 nginx 反向代理 /profile/ 到后端,规避跨域); |
| | | // 小程序 / App 端使用 userStore 中的文件服务器地址 |
| | | const getDownloadBaseUrl = () => { |
| | | // #ifdef H5 |
| | | try { |
| | | const annexes = review.conclusionannex |
| | | .split(";") |
| | | .filter((item) => item.trim()); |
| | | return window.location.origin; |
| | | } catch { |
| | | return userStore.baseUrlHt; |
| | | } |
| | | // #endif |
| | | // #ifndef H5 |
| | | return userStore.baseUrlHt; |
| | | // #endif |
| | | }; |
| | | |
| | | if (annexes.length == 0) { |
| | | // 下载报告:调用后端档案下载接口获取下载地址,再下载文件 |
| | | const downloadReport = async (review) => { |
| | | try { |
| | | // 先调用后端接口获取档案下载地址(与 web 端一致:参数 nitiateId 对应伦理审查发起 id) |
| | | const res = await uni.$uapi.get( |
| | | "/project/ethicalreviewopinions/download", |
| | | { nitiateId: review.nitiateId || review.fcid || review.id }, |
| | | ); |
| | | |
| | | if (res.code != 200 || !res.data || !res.data.downloadUrl) { |
| | | uni.showToast({ |
| | | title: "暂无报告可下载", |
| | | title: res.msg || "暂无报告可下载", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | const downloadUrl = res.data.downloadUrl; |
| | | const downloadName = |
| | | res.data.downloadName || downloadUrl.split("/").pop() || "伦理审查报告.doc"; |
| | | |
| | | // 拼接完整下载地址:base + /profile + downloadUrl(后端 downloadUrl 缺少 /profile 前缀) |
| | | const fullUrl = getDownloadBaseUrl() + "/profile" + downloadUrl; |
| | | |
| | | // #ifdef H5 |
| | | // H5 端:直接触发浏览器下载 |
| | | const link = document.createElement("a"); |
| | | link.href = fullUrl; |
| | | link.download = downloadName; |
| | | link.target = "_blank"; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | return; |
| | | // #endif |
| | | |
| | | // #ifndef H5 |
| | | // 小程序 / App 端:下载后保存并打开 |
| | | uni.showLoading({ |
| | | title: "下载中...", |
| | | mask: true, |
| | | }); |
| | | |
| | | // 下载第一个附件 |
| | | const fileUrl = annexes[0]; |
| | | const token = uni.getStorageSync("token") || ""; |
| | | const downloadTask = uni.downloadFile({ |
| | | url: fileUrl, |
| | | url: fullUrl, |
| | | header: { |
| | | Authorization: token ? `Bearer ${token}` : "", |
| | | }, |
| | | success: (downloadRes) => { |
| | | if (downloadRes.statusCode == 200) { |
| | | const tempFilePath = downloadRes.tempFilePath; |
| | | |
| | | // 保存到本地 |
| | | uni.saveFile({ |
| | | tempFilePath: tempFilePath, |
| | | tempFilePath: downloadRes.tempFilePath, |
| | | success: (saveRes) => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | |
| | | duration: 2000, |
| | | }); |
| | | |
| | | // 在微信小程序中可以打开文件 |
| | | if (uni.getSystemInfoSync().platform == "weixin") { |
| | | uni.openDocument({ |
| | | filePath: saveRes.savedFilePath, |
| | | showMenu: true, |
| | | success: () => { |
| | | console.log("打开文档成功"); |
| | | }, |
| | | fail: (err) => { |
| | | console.error("打开文档失败", err); |
| | | }, |
| | | }); |
| | | } |
| | | uni.openDocument({ |
| | | filePath: saveRes.savedFilePath, |
| | | showMenu: true, |
| | | success: () => { |
| | | console.log("打开文档成功"); |
| | | }, |
| | | fail: (err) => { |
| | | console.error("打开文档失败", err); |
| | | }, |
| | | }); |
| | | }, |
| | | fail: (saveErr) => { |
| | | fail: () => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存文件失败", |
| | |
| | | downloadTask.onProgressUpdate((res) => { |
| | | console.log("下载进度:", res.progress); |
| | | }); |
| | | // #endif |
| | | } catch (error) { |
| | | uni.hideLoading(); |
| | | console.error("下载报告失败:", error); |