From 01fad2bfe7b38e5aa981ab48b5ab5c49c3e1d371 Mon Sep 17 00:00:00 2001 From: hebo Date: Mon, 10 Nov 2025 16:42:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E9=BE=99=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/base/jl/detail.vue | 228 +++++++++++++++++++++++++++- src/pages/base/jl/detailwb.vue | 264 ++++++++++++++++++++++++++++++++- src/pages/base/jl/index.vue | 14 +- 3 files changed, 502 insertions(+), 4 deletions(-) diff --git a/src/pages/base/jl/detail.vue b/src/pages/base/jl/detail.vue index bce0b3d..2f96908 100644 --- a/src/pages/base/jl/detail.vue +++ b/src/pages/base/jl/detail.vue @@ -31,6 +31,31 @@ 收起 + + + + + 请选择一项: + (您已选择) + + + + + + + + {{ option.key }}. + {{ option.value }} + + + + @@ -69,7 +94,20 @@ @@ -95,6 +133,13 @@ const njId = ref(""); const njmcId = ref(""); const bjId = ref(""); +// 选择题相关 +const optionsList = ref([]); +const selectedOption = ref(""); + +// 接龙成功状态 +const relaySuccess = ref(false); + // 签名相关 const signCompRef = ref(null); const signTitle = ref("签名"); @@ -125,6 +170,34 @@ const receivedCount = computed(() => { }); const totalStudents = computed(() => studentList.value.length); +// 判断当前学生是否已接龙 +const isAlreadyRelayed = computed(() => { + const curStu = studentList.value.find(stu => stu.xsId === currentStudent.value?.id); + return curStu && curStu.jlts === '1'; +}); + +// 选择选项 +function selectOption(key: string) { + // 如果已接龙,不允许修改选择 + if (isAlreadyRelayed.value) { + uni.showToast({ title: '您已接龙,无法修改选择', icon: 'none' }); + return; + } + selectedOption.value = key; +} + +// 返回上一页并刷新列表 +function handleReturn() { + // 通过事件总线或页面跳转参数通知上一页刷新 + // 方案1: 使用 uni.$emit 事件通知 + uni.$emit('jlListRefresh'); + + // 方案2: 返回上一页(index.vue 的 onShow 会自动刷新) + uni.navigateBack({ + delta: 1 + }); +} + // 接龙按钮点击逻辑 async function onRelayClick() { try { @@ -136,6 +209,15 @@ async function onRelayClick() { uni.showToast({ title: '您已参与接龙,无须重复提交', icon: 'none' }); return; } + + // 如果是选择题接龙,必须选择选项 + if (noticeDetail.value.jlType === 'select') { + if (!selectedOption.value) { + uni.showToast({ title: '请选择一项后再提交', icon: 'none' }); + return; + } + } + if (noticeDetail.value && noticeDetail.value.mdqz == 1) { // 需要签名 showSignature.value = true; @@ -164,12 +246,24 @@ async function submitRelay() { if (sign_file.value) { params.qmFile = sign_file.value; } + + // 如果是选择题接龙,添加选中的选项 + if (noticeDetail.value.jlType === 'select' && selectedOption.value) { + params.selectedOption = selectedOption.value; + // 查找选中选项的值 + const selectedOpt = optionsList.value.find(opt => opt.key === selectedOption.value); + if (selectedOpt) { + params.selectedValue = selectedOpt.value; + } + } + showLoading('提交中...'); try { const res:any = await relayFinishApi(params); hideLoading(); if (res && res.resultCode === 1 ) { uni.showToast({title: '接龙成功', icon: 'success'}); + relaySuccess.value = true; // 设置接龙成功状态 await refreshStudentList(); } else { uni.showToast({title: res?.msg || '接龙失败', icon: 'none'}); @@ -192,6 +286,15 @@ async function refreshStudentList() { const stuRes = await jlzxFindByJlParamsApi(params); studentList.value = stuRes?.rows || stuRes?.result || []; + + // 刷新后回显已选择的选项,并设置按钮状态 + const curStu = studentList.value.find(stu => stu.xsId === currentStudent.value?.id); + if (curStu && curStu.jlts === '1') { + relaySuccess.value = true; // 设置接龙成功状态,显示返回按钮 + if (curStu.selectedOption) { + selectedOption.value = curStu.selectedOption; + } + } } catch (e) { uni.showToast({ title: "刷新学生状态失败", icon: "none" }); } @@ -218,6 +321,18 @@ onLoad(async (options) => { try { const detailRes = await getByJlIdApi({ jlId: noticeId.value }); noticeDetail.value = Array.isArray(detailRes) ? detailRes[0] : {}; + + // 解析选项配置 + if (noticeDetail.value.jlType === 'select' && noticeDetail.value.jlOptions) { + try { + optionsList.value = JSON.parse(noticeDetail.value.jlOptions); + // 按 sort 排序 + optionsList.value.sort((a, b) => (a.sort || 0) - (b.sort || 0)); + } catch (e) { + console.error('解析选项配置失败:', e); + optionsList.value = []; + } + } } catch (e) { uni.showToast({ title: "加载接龙详情失败", icon: "none" }); } @@ -232,6 +347,16 @@ onLoad(async (options) => { const stuRes = await jlzxFindByJlParamsApi(params); studentList.value = stuRes?.rows || stuRes?.result || []; + + // 查找当前学生,回显已选择的选项 + const curStu = studentList.value.find(stu => stu.xsId === currentStudent.value?.id); + if (curStu && curStu.jlts === '1') { + // 已接龙,显示返回按钮 + relaySuccess.value = true; + if (curStu.selectedOption) { + selectedOption.value = curStu.selectedOption; + } + } } catch (e) { uni.showToast({ title: "加载学生状态失败", icon: "none" }); } @@ -375,6 +500,16 @@ watch(studentList, (list) => { &.publish-btn:active { background-color: #3a8ee6; } + + &.return-btn { + background-color: #67c23a; + color: #ffffff; + border: none; + } + + &.return-btn:active { + background-color: #5daf34; + } } } @@ -638,6 +773,97 @@ watch(studentList, (list) => { } } +/* 选择题选项区域 */ +.options-section { + margin-top: 20px; + padding-top: 15px; + border-top: 1px solid #f0f0f0; + + .options-title { + display: flex; + align-items: center; + gap: 8px; + font-size: 15px; + font-weight: bold; + color: #333; + margin-bottom: 12px; + + .already-relayed-hint { + font-size: 13px; + font-weight: normal; + color: #67c23a; + } + } + + .options-list { + .option-item { + display: flex; + align-items: flex-start; + padding: 12px; + margin-bottom: 10px; + background-color: #f8f9fa; + border: 2px solid #e9ecef; + border-radius: 8px; + transition: all 0.3s ease; + + &.option-selected { + background-color: #e6f7ff; + border-color: #409eff; + } + + &.option-disabled { + opacity: 0.5; + cursor: not-allowed; + } + + .option-radio { + width: 20px; + height: 20px; + border: 2px solid #d9d9d9; + border-radius: 50%; + margin-right: 10px; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + margin-top: 2px; + transition: all 0.3s ease; + + .radio-checked { + width: 10px; + height: 10px; + background-color: #409eff; + border-radius: 50%; + } + } + + &.option-selected .option-radio { + border-color: #409eff; + } + + .option-content { + flex: 1; + display: flex; + flex-wrap: wrap; + line-height: 1.6; + + .option-key { + font-size: 15px; + font-weight: bold; + color: #333; + margin-right: 6px; + } + + .option-value { + flex: 1; + font-size: 15px; + color: #333; + } + } + } + } +} + /* 更多按钮样式 */ .more-btn { font-size: 16px !important; diff --git a/src/pages/base/jl/detailwb.vue b/src/pages/base/jl/detailwb.vue index be10814..b85aca5 100644 --- a/src/pages/base/jl/detailwb.vue +++ b/src/pages/base/jl/detailwb.vue @@ -31,6 +31,31 @@ 收起 + + + + + 请选择一项: + (您已选择) + + + + + + + + {{ option.key }}. + {{ option.value }} + + + + @@ -69,7 +94,20 @@ @@ -96,6 +134,13 @@ const njmcId = ref(""); const bjId = ref(""); const xsId = ref(""); +// 选择题相关 +const optionsList = ref([]); +const selectedOption = ref(""); + +// 接龙成功状态 +const relaySuccess = ref(false); + // 签名相关 const signCompRef = ref(null); const signTitle = ref("签名"); @@ -126,6 +171,70 @@ const receivedCount = computed(() => { }); const totalStudents = computed(() => studentList.value.length); +// 判断当前学生是否已接龙 +const isAlreadyRelayed = computed(() => { + const curStu = studentList.value.find(stu => stu.xsId === xsId.value); + return curStu && curStu.jlts === '1'; +}); + +// 选择选项 +function selectOption(key: string) { + // 如果已接龙,不允许修改选择 + if (isAlreadyRelayed.value) { + uni.showToast({ title: '您已接龙,无法修改选择', icon: 'none' }); + return; + } + selectedOption.value = key; +} + +// 返回上一页或关闭窗口 +function handleReturn() { + // 获取当前页面栈 + const pages = getCurrentPages(); + + // 如果页面栈只有一个页面,说明是从微信直接打开的,需要关闭窗口 + if (pages.length === 1) { + // #ifdef H5 + // H5环境:尝试关闭窗口 + if (window.opener) { + window.close(); + } else { + // 如果无法关闭,提示用户手动关闭 + uni.showModal({ + title: '提示', + content: '请点击右上角关闭按钮退出', + showCancel: false, + confirmText: '知道了' + }); + } + // #endif + + // #ifdef MP-WEIXIN + // 微信小程序:关闭当前页面 + // @ts-ignore + wx.closeWindow(); + // #endif + + // #ifndef H5 || MP-WEIXIN + // 其他平台:尝试返回 + uni.navigateBack({ + delta: 1, + fail: () => { + uni.showToast({ + title: '无法返回,请手动关闭', + icon: 'none' + }); + } + }); + // #endif + } else { + // 有上一页,正常返回 + uni.navigateBack({ + delta: 1 + }); + } +} + // 接龙按钮点击逻辑 async function onRelayClick() { try { @@ -137,6 +246,15 @@ async function onRelayClick() { uni.showToast({ title: '您已参与接龙,无须重复提交', icon: 'none' }); return; } + + // 如果是选择题接龙,必须选择选项 + if (noticeDetail.value.jlType === 'select') { + if (!selectedOption.value) { + uni.showToast({ title: '请选择一项后再提交', icon: 'none' }); + return; + } + } + if (noticeDetail.value && noticeDetail.value.mdqz == 1) { // 需要签名 showSignature.value = true; @@ -165,12 +283,24 @@ async function submitRelay() { if (sign_file.value) { params.qmFile = sign_file.value; } + + // 如果是选择题接龙,添加选中的选项 + if (noticeDetail.value.jlType === 'select' && selectedOption.value) { + params.selectedOption = selectedOption.value; + // 查找选中选项的值 + const selectedOpt = optionsList.value.find(opt => opt.key === selectedOption.value); + if (selectedOpt) { + params.selectedValue = selectedOpt.value; + } + } + showLoading('提交中...'); try { const res:any = await relayFinishApi(params); hideLoading(); if (res && res.resultCode === 1 ) { uni.showToast({title: '接龙成功', icon: 'success'}); + relaySuccess.value = true; // 设置接龙成功状态 await refreshStudentList(); } else { uni.showToast({title: res?.msg || '接龙失败', icon: 'none'}); @@ -193,6 +323,15 @@ async function refreshStudentList() { const stuRes = await jlzxFindByJlParamsApi(params); studentList.value = stuRes?.rows || stuRes?.result || []; + + // 刷新后回显已选择的选项,并设置按钮状态 + const curStu = studentList.value.find(stu => stu.xsId === xsId.value); + if (curStu && curStu.jlts === '1') { + relaySuccess.value = true; // 设置接龙成功状态,显示返回按钮 + if (curStu.selectedOption) { + selectedOption.value = curStu.selectedOption; + } + } } catch (e) { uni.showToast({ title: "刷新学生状态失败", icon: "none" }); } @@ -220,6 +359,18 @@ onLoad(async (options) => { try { const detailRes = await getByJlIdApi({ jlId: noticeId.value }); noticeDetail.value = Array.isArray(detailRes) ? detailRes[0] : {}; + + // 解析选项配置 + if (noticeDetail.value.jlType === 'select' && noticeDetail.value.jlOptions) { + try { + optionsList.value = JSON.parse(noticeDetail.value.jlOptions); + // 按 sort 排序 + optionsList.value.sort((a, b) => (a.sort || 0) - (b.sort || 0)); + } catch (e) { + console.error('解析选项配置失败:', e); + optionsList.value = []; + } + } } catch (e) { uni.showToast({ title: "加载接龙详情失败", icon: "none" }); } @@ -235,6 +386,16 @@ onLoad(async (options) => { const stuRes = await jlzxFindByJlParamsApi(params); studentList.value = stuRes?.rows || stuRes?.result || []; + + // 查找当前学生,回显已选择的选项 + const curStu = studentList.value.find(stu => stu.xsId === xsId.value); + if (curStu && curStu.jlts === '1') { + // 已接龙,显示返回按钮 + relaySuccess.value = true; + if (curStu.selectedOption) { + selectedOption.value = curStu.selectedOption; + } + } } catch (e) { uni.showToast({ title: "加载学生状态失败", icon: "none" }); } @@ -378,6 +539,16 @@ watch(studentList, (list) => { &.publish-btn:active { background-color: #3a8ee6; } + + &.return-btn { + background-color: #67c23a; + color: #ffffff; + border: none; + } + + &.return-btn:active { + background-color: #5daf34; + } } } @@ -641,6 +812,97 @@ watch(studentList, (list) => { } } +/* 选择题选项区域 */ +.options-section { + margin-top: 20px; + padding-top: 15px; + border-top: 1px solid #f0f0f0; + + .options-title { + display: flex; + align-items: center; + gap: 8px; + font-size: 15px; + font-weight: bold; + color: #333; + margin-bottom: 12px; + + .already-relayed-hint { + font-size: 13px; + font-weight: normal; + color: #67c23a; + } + } + + .options-list { + .option-item { + display: flex; + align-items: flex-start; + padding: 12px; + margin-bottom: 10px; + background-color: #f8f9fa; + border: 2px solid #e9ecef; + border-radius: 8px; + transition: all 0.3s ease; + + &.option-selected { + background-color: #e6f7ff; + border-color: #409eff; + } + + &.option-disabled { + opacity: 0.5; + cursor: not-allowed; + } + + .option-radio { + width: 20px; + height: 20px; + border: 2px solid #d9d9d9; + border-radius: 50%; + margin-right: 10px; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + margin-top: 2px; + transition: all 0.3s ease; + + .radio-checked { + width: 10px; + height: 10px; + background-color: #409eff; + border-radius: 50%; + } + } + + &.option-selected .option-radio { + border-color: #409eff; + } + + .option-content { + flex: 1; + display: flex; + flex-wrap: wrap; + line-height: 1.6; + + .option-key { + font-size: 15px; + font-weight: bold; + color: #333; + margin-right: 6px; + } + + .option-value { + flex: 1; + font-size: 15px; + color: #333; + } + } + } + } +} + /* 更多按钮样式 */ .more-btn { font-size: 16px !important; diff --git a/src/pages/base/jl/index.vue b/src/pages/base/jl/index.vue index 632dd70..a64db1c 100644 --- a/src/pages/base/jl/index.vue +++ b/src/pages/base/jl/index.vue @@ -60,7 +60,7 @@ import {useLayout} from "@/components/BasicListLayout/hooks/useLayout"; import {mobilejzjllistApi} from "@/api/base/server"; import {imagUrl} from "@/utils"; -import {computed, watch, ref} from "vue"; +import {computed, watch, ref, onBeforeUnmount} from "vue"; import {onShow} from "@dcloudio/uni-app"; import { useUserStore } from "@/store/modules/user"; @@ -193,12 +193,22 @@ const formatTime = (timeStr: string) => { )}-${String(date.getDate()).padStart(2, "0")}`; }; +// 监听接龙列表刷新事件 +uni.$on('jlListRefresh', () => { + reload(); +}); + +// 组件卸载时移除事件监听 +onBeforeUnmount(() => { + uni.$off('jlListRefresh'); +}); + onShow(() => { // 确保学生信息已加载 const studentInfo = getStudentInfo(); if (studentInfo.id && studentInfo.njId && studentInfo.njmcId) { - reload(); + reload(); // 每次页面显示都刷新列表 } else { setTimeout(() => { const retryStudentInfo = getStudentInfo();