Merge branch 'master' of http://119.29.194.155:8894/zwq/zhxy-jzd
This commit is contained in:
commit
d114fe8c8f
@ -180,3 +180,10 @@ export const jzXsQjListApi = async (params: any) => {
|
||||
export const jzXsQjActivitiHistoryApi = async (params: any) => {
|
||||
return await get("/activiti/history/historicFlow", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取用户最新信息(包含学生信息)
|
||||
*/
|
||||
export const getUserLatestInfoApi = async () => {
|
||||
return await get("/open/login/getLatestInfo");
|
||||
};
|
||||
|
||||
@ -75,14 +75,60 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { ref, computed, onMounted, watch } from "vue";
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
import XsPicker from "@/pages/base/components/XsPicker/index.vue"
|
||||
import { cmsArticlePageApi } from "@/api/base/server";
|
||||
import { cmsArticlePageApi, getUserLatestInfoApi } from "@/api/base/server";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
const { getCurXs } = useUserStore();
|
||||
const { setData, getAppCode } = useDataStore();
|
||||
|
||||
// 刷新相关变量
|
||||
const { getLastRefreshTime, getRefreshInterval, setLastRefreshTime, updateStudentInfo, updateStudentList } = useUserStore();
|
||||
const REFRESH_INTERVAL = 10 * 60 * 1000; // 10分钟刷新一次(测试用)
|
||||
|
||||
// 检查是否需要刷新学生信息
|
||||
const checkAndRefreshStudentInfo = async () => {
|
||||
const lastRefreshTime = getLastRefreshTime;
|
||||
const currentTime = Date.now();
|
||||
|
||||
if (!lastRefreshTime || (currentTime - lastRefreshTime) > REFRESH_INTERVAL) {
|
||||
await refreshStudentInfo();
|
||||
setLastRefreshTime(currentTime);
|
||||
}
|
||||
};
|
||||
|
||||
// 刷新学生信息
|
||||
const refreshStudentInfo = async () => {
|
||||
try {
|
||||
const response = await getUserLatestInfoApi();
|
||||
if (response && response.result) {
|
||||
// 更新学生列表
|
||||
if (response.result.xsList && response.result.xsList.length > 0) {
|
||||
updateStudentList(response.result.xsList);
|
||||
|
||||
// 更新当前学生信息(保持当前选中的学生)
|
||||
const currentXsId = curXs.value?.id;
|
||||
if (currentXsId) {
|
||||
const currentStudent = response.result.xsList.find((xs: any) => xs.id === currentXsId);
|
||||
if (currentStudent) {
|
||||
updateStudentInfo(currentStudent);
|
||||
} else {
|
||||
// 如果当前学生不在列表中,选择第一个学生
|
||||
updateStudentInfo(response.result.xsList[0]);
|
||||
}
|
||||
} else {
|
||||
// 如果没有当前学生,选择第一个学生
|
||||
updateStudentInfo(response.result.xsList[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// 处理错误,静默失败
|
||||
}
|
||||
};
|
||||
|
||||
// 菜单项数据
|
||||
const menuItems = ref([
|
||||
{
|
||||
@ -161,7 +207,6 @@ const goToGlxs = () => {
|
||||
|
||||
// 处理菜单点击
|
||||
function handleMenuClick(item: any) {
|
||||
console.log("点击菜单:", item.title);
|
||||
if (item.path) {
|
||||
uni.navigateTo({
|
||||
url: item.path,
|
||||
@ -183,19 +228,46 @@ function goToDetail(notice: any) {
|
||||
}
|
||||
|
||||
const getArticleList = async () => {
|
||||
if (curXs.value && curXs.value.njmcId) {
|
||||
const params = Object.assign({}, pageParams.value, { njmcId: curXs.value.njmcId });
|
||||
|
||||
cmsArticlePageApi(params).then(res => {
|
||||
announcements.value = res.rows;
|
||||
})
|
||||
.catch((error) => {
|
||||
// 接口调用失败
|
||||
console.error("调用检查通知公告接口失败:", error);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
// 确保有学生年级信息才获取通知公告
|
||||
if (curXs.value && curXs.value.njmcId) {
|
||||
getArticleList();
|
||||
} else {
|
||||
// 如果store中没有学生信息,等待一下再尝试
|
||||
setTimeout(() => {
|
||||
if (curXs.value && curXs.value.njmcId) {
|
||||
getArticleList();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// 初始化时检查是否需要刷新学生信息
|
||||
await checkAndRefreshStudentInfo();
|
||||
});
|
||||
|
||||
// 页面显示时检查是否需要刷新
|
||||
onShow(async () => {
|
||||
await checkAndRefreshStudentInfo();
|
||||
});
|
||||
|
||||
// 监听学生信息变化,当学生信息更新时重新获取通知公告
|
||||
watch(curXs, (newXs, oldXs) => {
|
||||
if (newXs && newXs.njmcId) {
|
||||
getArticleList();
|
||||
}
|
||||
}, { immediate: false });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -24,11 +24,11 @@
|
||||
<view class="notice-content">
|
||||
<view v-if="!descExpanded">
|
||||
<text class="desc-preview">{{ descPreview }}</text>
|
||||
<u-button type="text" size="mini" @click="descExpanded = true">更多</u-button>
|
||||
<u-button type="text" size="mini" class="more-btn" @click="descExpanded = true">更多</u-button>
|
||||
</view>
|
||||
<view v-else>
|
||||
<rich-text :nodes="noticeDetail.jlms" class="desc-rich-text"></rich-text>
|
||||
<u-button type="text" size="mini" @click="descExpanded = false">收起</u-button>
|
||||
<u-button type="text" size="mini" class="more-btn" @click="descExpanded = false">收起</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -53,10 +53,7 @@
|
||||
v-for="stu in studentList"
|
||||
:key="stu.id || stu.xsId"
|
||||
class="name-tag"
|
||||
:class="{
|
||||
received: stu.jlwc_status === 'A',
|
||||
currentStudent: isCurrentStudent(stu)
|
||||
}"
|
||||
:class="{ received: stu.jlwc_status === 'A' }"
|
||||
>
|
||||
<text>{{ stu.xsxm || stu.name }}</text>
|
||||
<view v-if="stu.jlwc_status === 'A'" class="checkmark-icon">
|
||||
@ -68,29 +65,24 @@
|
||||
</view>
|
||||
<view v-else class="empty-state">通知详情未找到</view>
|
||||
</view>
|
||||
<!-- 添加签名组件 -->
|
||||
<BasicSign ref="signCompRef" :title="signTitle" @confirm="onSignConfirm"/>
|
||||
<!-- 添加签名组件 - 只在需要时显示 -->
|
||||
<BasicSign v-if="showSignature" ref="signCompRef" :title="signTitle"></BasicSign>
|
||||
<template #bottom>
|
||||
<view class="flex-row items-center pb-10 pt-5">
|
||||
<u-button
|
||||
text="点击接龙"
|
||||
class="mr-15 mr-7"
|
||||
type="primary"
|
||||
@click="onRelayClick"
|
||||
/>
|
||||
<view class="bottom-actions">
|
||||
<button class="action-btn publish-btn" @click="onRelayClick">接龙</button>
|
||||
</view>
|
||||
</template>
|
||||
</BasicLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, computed, watch} from "vue";
|
||||
import {onLoad} from "@dcloudio/uni-app";
|
||||
import {getByJlIdApi, jlzxFindByJlParamsApi, relayFinishApi} from "@/api/base/server";
|
||||
import {imagUrl} from "@/utils";
|
||||
import {BASE_IMAGE_URL} from "@/config";
|
||||
import {useUserStore} from "@/store/modules/user";
|
||||
import {navigateBack, showLoading, hideLoading} from "@/utils/uniapp";
|
||||
import { ref, computed, watch, nextTick } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { getByJlIdApi, jlzxFindByJlParamsApi, relayFinishApi } from "@/api/base/server";
|
||||
import { imagUrl } from "@/utils";
|
||||
import { BASE_IMAGE_URL } from "@/config";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { showLoading, hideLoading } from "@/utils/uniapp";
|
||||
|
||||
const noticeId = ref<string>("");
|
||||
const noticeDetail = ref<any>(null);
|
||||
@ -102,6 +94,7 @@ const descExpanded = ref(false);
|
||||
const signCompRef = ref<any>(null);
|
||||
const signTitle = ref<string>("签名");
|
||||
const sign_file = ref<string>("");
|
||||
const showSignature = ref<boolean>(false);
|
||||
|
||||
// 获取当前学生信息
|
||||
const userStore = useUserStore();
|
||||
@ -123,19 +116,14 @@ const getFileName = (filePath: string) => {
|
||||
|
||||
// Computed properties for feedback status
|
||||
const receivedCount = computed(() => {
|
||||
return studentList.value.filter((s) => s.jlwc_status === '1').length;
|
||||
return studentList.value.filter((s) => s.jlwc_status === 'A').length;
|
||||
});
|
||||
const totalStudents = computed(() => studentList.value.length);
|
||||
|
||||
// 判断是否为当前学生
|
||||
const isCurrentStudent = (student: any) => {
|
||||
return currentStudent.value && student.xsId === currentStudent.value.id;
|
||||
};
|
||||
|
||||
// 新增:接龙按钮点击逻辑
|
||||
// 接龙按钮点击逻辑
|
||||
async function onRelayClick() {
|
||||
try {
|
||||
const res = await getByJlIdApi({jlId: noticeId.value});
|
||||
const res = await getByJlIdApi({ jlId: noticeId.value });
|
||||
const detail = Array.isArray(res) ? res[0] : res;
|
||||
// 判断当前学生是否已接龙
|
||||
const curStu = studentList.value.find(stu => {
|
||||
@ -149,38 +137,24 @@ async function onRelayClick() {
|
||||
}
|
||||
if (detail && detail.mdqz == 1) {
|
||||
// 需要签名
|
||||
showSignature.value = true;
|
||||
sign_file.value = '';
|
||||
if (signCompRef.value) {
|
||||
onSignConfirm();
|
||||
}
|
||||
// 等待组件渲染完成
|
||||
await nextTick();
|
||||
const data = await signCompRef.value.getSyncSignature();
|
||||
sign_file.value = data.base64;
|
||||
showSignature.value = false;
|
||||
submitRelay();
|
||||
} else {
|
||||
submitRelay();
|
||||
}
|
||||
} catch (e) {
|
||||
showSignature.value = false;
|
||||
uni.showToast({title: '获取详情失败', icon: 'none'});
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:签名确认
|
||||
async function onSignConfirm() {
|
||||
try {
|
||||
if (!sign_file.value) {
|
||||
if (signCompRef.value && signCompRef.value.getSyncSignature) {
|
||||
const data = await signCompRef.value.getSyncSignature();
|
||||
sign_file.value = data.base64;
|
||||
}
|
||||
}
|
||||
if (!sign_file.value) {
|
||||
uni.showToast({title: '请完成签名', icon: 'none'});
|
||||
return;
|
||||
}
|
||||
submitRelay();
|
||||
} catch (e) {
|
||||
uni.showToast({title: '签名流程异常', icon: 'none'});
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:提交接龙
|
||||
// 提交接龙
|
||||
async function submitRelay() {
|
||||
const params: any = {
|
||||
jl_id: noticeId.value,
|
||||
@ -196,7 +170,6 @@ async function submitRelay() {
|
||||
if (res && res.resultCode === 1 ) {
|
||||
uni.showToast({title: '接龙成功', icon: 'success'});
|
||||
await refreshStudentList();
|
||||
|
||||
} else {
|
||||
uni.showToast({title: res?.msg || '接龙失败', icon: 'none'});
|
||||
}
|
||||
@ -206,7 +179,7 @@ async function submitRelay() {
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:刷新学生完成状态
|
||||
// 刷新学生完成状态
|
||||
async function refreshStudentList() {
|
||||
try {
|
||||
const stuRes = await jlzxFindByJlParamsApi({ jlId: noticeId.value });
|
||||
@ -222,29 +195,29 @@ onLoad(async (options) => {
|
||||
isLoading.value = true;
|
||||
// 1. 获取接龙详情(新接口)
|
||||
try {
|
||||
const detailRes = await getByJlIdApi({jlId: noticeId.value});
|
||||
const detailRes = await getByJlIdApi({ jlId: noticeId.value });
|
||||
noticeDetail.value = Array.isArray(detailRes) ? detailRes[0] : {};
|
||||
} catch (e) {
|
||||
uni.showToast({title: "加载接龙详情失败", icon: "none"});
|
||||
uni.showToast({ title: "加载接龙详情失败", icon: "none" });
|
||||
}
|
||||
// 2. 获取学生完成状态
|
||||
try {
|
||||
const stuRes = await jlzxFindByJlParamsApi({jlId: noticeId.value});
|
||||
const stuRes = await jlzxFindByJlParamsApi({ jlId: noticeId.value });
|
||||
studentList.value = stuRes?.rows || stuRes?.result || [];
|
||||
} catch (e) {
|
||||
uni.showToast({title: "加载学生状态失败", icon: "none"});
|
||||
uni.showToast({ title: "加载学生状态失败", icon: "none" });
|
||||
}
|
||||
isLoading.value = false;
|
||||
uni.setNavigationBarTitle({title: "点击接龙"});
|
||||
uni.setNavigationBarTitle({ title: "接龙情况" });
|
||||
} else {
|
||||
uni.showToast({title: "加载失败,缺少通知ID", icon: "none"});
|
||||
uni.showToast({ title: "加载失败,缺少通知ID", icon: "none" });
|
||||
}
|
||||
});
|
||||
|
||||
// 附件预览函数
|
||||
const previewAttachment = (filePath: string) => {
|
||||
if (!filePath) {
|
||||
uni.showToast({title: "附件链接无效", icon: "none"});
|
||||
uni.showToast({ title: "附件链接无效", icon: "none" });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -265,7 +238,7 @@ const previewAttachment = (filePath: string) => {
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showLoading({title: "正在准备附件..."});
|
||||
uni.showLoading({ title: "正在准备附件..." });
|
||||
|
||||
uni.downloadFile({
|
||||
url: fullUrl,
|
||||
@ -280,33 +253,37 @@ const previewAttachment = (filePath: string) => {
|
||||
// 打开文档成功
|
||||
},
|
||||
fail: function (err) {
|
||||
uni.showToast({title: "无法打开该文件类型", icon: "none"});
|
||||
uni.showToast({ title: "无法打开该文件类型", icon: "none" });
|
||||
uni.hideLoading(); // Ensure loading is hidden on failure too
|
||||
},
|
||||
});
|
||||
} else {
|
||||
uni.hideLoading();
|
||||
uni.showToast({title: "下载附件失败", icon: "none"});
|
||||
uni.showToast({ title: "下载附件失败", icon: "none" });
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.hideLoading();
|
||||
uni.showToast({title: "下载附件失败", icon: "none"});
|
||||
uni.showToast({ title: "下载附件失败", icon: "none" });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
watch(noticeDetail, (val) => {
|
||||
// 监听数据变化
|
||||
}, {immediate: true, deep: true});
|
||||
}, { immediate: true, deep: true });
|
||||
|
||||
// 在studentList渲染前打印每个学生的jlwc_status和姓名
|
||||
// 添加学生列表数据监听器,处理状态字段兼容性
|
||||
watch(studentList, (list) => {
|
||||
list.forEach(stu => {
|
||||
// 兼容后端返回的驼峰写法
|
||||
if (stu.jlwcStatus && !stu.jlwc_status) {
|
||||
stu.jlwc_status = stu.jlwcStatus;
|
||||
}
|
||||
// 兼容数字状态,将'1'转换为'A'
|
||||
if (stu.jlwc_status === '1') {
|
||||
stu.jlwc_status = 'A';
|
||||
}
|
||||
});
|
||||
}, { immediate: true, deep: true });
|
||||
</script>
|
||||
@ -578,14 +555,12 @@ watch(studentList, (list) => {
|
||||
box-sizing: border-box;
|
||||
// 调整为每行4个,确保能显示4个汉字
|
||||
flex-basis: calc((100% - 30px) / 4); // 4个学生,3个间隔
|
||||
min-width: 60px; // 最小宽度确保能显示4个汉字
|
||||
height: 30px; // Slightly taller height
|
||||
line-height: 20px; // Adjust line-height for vertical centering
|
||||
border: 1px solid #f4f4f5;
|
||||
// 允许文字换行
|
||||
white-space: normal;
|
||||
word-break: keep-all; // 保持汉字完整性
|
||||
overflow: hidden;
|
||||
word-break: break-all; // Break long names if they don't fit
|
||||
}
|
||||
|
||||
.name-tag {
|
||||
@ -635,6 +610,13 @@ watch(studentList, (list) => {
|
||||
}
|
||||
}
|
||||
|
||||
/* 更多按钮样式 */
|
||||
.more-btn {
|
||||
font-size: 16px !important;
|
||||
color: #409eff !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 列表项样式的卡片 */
|
||||
.list-item-card {
|
||||
padding: 5px 15px; // 减少上下 padding
|
||||
|
||||
@ -206,7 +206,6 @@ const openDicPicker = (xs: any) => {
|
||||
};
|
||||
|
||||
const dicChanged = (dicArr: any) => {
|
||||
console.log(dicArr);
|
||||
const dic = dicOptions.value[0][dicArr[0]];
|
||||
curXs.value.jzxsgxId = dic.dictionaryValue;
|
||||
curXs.value.jzxsgxmc = dic.dictionaryCode;
|
||||
@ -224,11 +223,9 @@ async function afterRead(event: any, index: number) {
|
||||
const result = res.result;
|
||||
if (result && result.length > 0 && result[0].filePath) {
|
||||
students.value[index].xstx = result[0].filePath;
|
||||
console.log(`Student ${index} avatar uploaded:`, result[0].filePath);
|
||||
showToast({ title: "上传成功" });
|
||||
} else {
|
||||
showToast({ title: "上传失败,请重试", icon: "none" });
|
||||
console.error("Upload result format error:", result);
|
||||
}
|
||||
} catch (error) {
|
||||
showToast({ title: "上传出错", icon: "none" });
|
||||
@ -313,7 +310,7 @@ async function submit() {
|
||||
showToast({ title: res.message || "提交失败", icon: "none" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// 处理错误
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,9 +12,11 @@ interface UserState {
|
||||
userdata: any;
|
||||
curXs: any;
|
||||
token: string;
|
||||
auth: string[],
|
||||
ws: any,
|
||||
wsCallback: any
|
||||
auth: string[];
|
||||
lastRefreshTime: number; // 上次刷新时间
|
||||
refreshInterval: number; // 刷新间隔(毫秒)
|
||||
ws: any;
|
||||
wsCallback: any;
|
||||
}
|
||||
|
||||
export const useUserStore = defineStore({
|
||||
@ -28,6 +30,8 @@ export const useUserStore = defineStore({
|
||||
token: '',
|
||||
//用户注册信息
|
||||
auth: [],
|
||||
lastRefreshTime: 0, // 上次刷新时间
|
||||
refreshInterval: 7 * 24 * 60 * 60 * 1000, // 刷新间隔(毫秒)
|
||||
ws: null,
|
||||
wsCallback: defWsCallback
|
||||
}),
|
||||
@ -43,6 +47,12 @@ export const useUserStore = defineStore({
|
||||
},
|
||||
getAuth(): string[] {
|
||||
return this.auth;
|
||||
},
|
||||
getLastRefreshTime(): number {
|
||||
return this.lastRefreshTime;
|
||||
},
|
||||
getRefreshInterval(): number {
|
||||
return this.refreshInterval;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@ -58,6 +68,22 @@ export const useUserStore = defineStore({
|
||||
setAuth(data: string[]) {
|
||||
this.auth = data;
|
||||
},
|
||||
setLastRefreshTime(time: number) {
|
||||
this.lastRefreshTime = time;
|
||||
},
|
||||
setRefreshInterval(interval: number) {
|
||||
this.refreshInterval = interval;
|
||||
},
|
||||
// 更新学生信息
|
||||
updateStudentInfo(studentInfo: any) {
|
||||
this.setCurXs(studentInfo);
|
||||
},
|
||||
// 更新学生列表
|
||||
updateStudentList(studentList: any[]) {
|
||||
if (this.userdata) {
|
||||
this.userdata.xsList = studentList;
|
||||
}
|
||||
},
|
||||
setWsCallback(callback: any) {
|
||||
this.wsCallback = callback;
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user