签到调整
This commit is contained in:
parent
daf902029b
commit
1a154398b9
@ -694,6 +694,14 @@
|
|||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/view/routine/qd/confirmself",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "签到确认",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"path": "pages/view/routine/JiaoXueZiYuan/add-resource",
|
"path": "pages/view/routine/JiaoXueZiYuan/add-resource",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@ -54,34 +54,27 @@ async function forceRefreshPermission(changeTime?: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function goByJs(js: any) {
|
function goByqd(data: any) {
|
||||||
// 检查是否有签到相关参数
|
if (data && data.qdId) {
|
||||||
const globalData = getGlobal;
|
|
||||||
console.log('goByJs - globalData:', globalData);
|
|
||||||
console.log('goByJs - js:', js);
|
|
||||||
|
|
||||||
if (globalData && globalData.qdId) {
|
|
||||||
// 有签到参数,重定向到签到确认页面
|
// 有签到参数,重定向到签到确认页面
|
||||||
let confirmUrl = `/pages/view/routine/qd/confirm?qdId=${globalData.qdId}`;
|
let confirmUrl = `/pages/view/routine/qd/confirm?qdId=${data.qdId}`;
|
||||||
if (globalData.rqgqtime) {
|
if (data.rqgqtime) {
|
||||||
confirmUrl += `&rqgqtime=${globalData.rqgqtime}`;
|
confirmUrl += `&rqgqtime=${data.rqgqtime}`;
|
||||||
}
|
}
|
||||||
if (globalData.timestampqd) {
|
if (data.timestampqd) {
|
||||||
confirmUrl += `×tampqd=${globalData.timestampqd}`;
|
confirmUrl += `×tampqd=${data.timestampqd}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('重定向到签到确认页面:', confirmUrl);
|
console.log('重定向到签到确认页面:', confirmUrl);
|
||||||
uni.reLaunch({
|
uni.reLaunch({
|
||||||
url: confirmUrl
|
url: confirmUrl
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getGlobal && getGlobal.type === '1') {
|
}
|
||||||
uni.reLaunch({
|
|
||||||
url: "/pages/view/routine/xk/qd?from=login"
|
function goByJs(js: any) {
|
||||||
});
|
|
||||||
}
|
|
||||||
if (js.confirmStatus == "A") {
|
if (js.confirmStatus == "A") {
|
||||||
// 跳转到自助服务首页
|
// 跳转到自助服务首页
|
||||||
uni.reLaunch({
|
uni.reLaunch({
|
||||||
@ -102,20 +95,15 @@ function goByJs(js: any) {
|
|||||||
|
|
||||||
onLoad(async (data: any) => {
|
onLoad(async (data: any) => {
|
||||||
console.log('launchPage onLoad - 接收到的参数:', data);
|
console.log('launchPage onLoad - 接收到的参数:', data);
|
||||||
|
|
||||||
if (data && data.openId) {
|
if (data && data.openId) {
|
||||||
setGlobal(data);
|
|
||||||
console.log('launchPage onLoad - 设置global数据后:', getGlobal);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await checkOpenId({
|
const res = await checkOpenId({
|
||||||
openId: data.openId,
|
openId: data.openId,
|
||||||
appCode: "JS",
|
appCode: "JS",
|
||||||
});
|
});
|
||||||
|
if (data && data.qdId) {
|
||||||
console.log('launchPage onLoad - checkOpenId结果:', res);
|
goByqd(data);
|
||||||
|
}else if (res.resultCode == 1 && res.result) {
|
||||||
if (res.resultCode == 1 && res.result) {
|
|
||||||
// 执行登录操作
|
// 执行登录操作
|
||||||
afterLoginAction(res.result);
|
afterLoginAction(res.result);
|
||||||
|
|
||||||
|
|||||||
717
src/pages/view/routine/qd/confirmself.vue
Normal file
717
src/pages/view/routine/qd/confirmself.vue
Normal file
@ -0,0 +1,717 @@
|
|||||||
|
<template>
|
||||||
|
<view class="confirm-page">
|
||||||
|
<!-- 确认签到阶段 -->
|
||||||
|
<view v-if="currentStep === 'confirm'" class="confirm-step">
|
||||||
|
<view class="confirm-header">
|
||||||
|
<text class="confirm-title">确认签到</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="meeting-info">
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议名称:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdmc || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议时间:</text>
|
||||||
|
<text class="info-value">{{ formatTime(meetingInfo?.qdkstime) }} - {{ formatTime(meetingInfo?.qdjstime) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议地点:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdwz || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">签到人员:</text>
|
||||||
|
<text class="info-value">{{ userInfo?.jsxm || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="sign_file" class="signature-preview">
|
||||||
|
<text class="preview-label">签名预览:</text>
|
||||||
|
<image :src="sign_file" class="signature-preview-img" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button @click="submitSignIn" class="submit-btn">确认签到</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 签到成功阶段 -->
|
||||||
|
<view v-else-if="currentStep === 'success'" class="success-step">
|
||||||
|
<view class="success-content">
|
||||||
|
<u-icon name="checkmark-circle" size="80" color="#67C23A" />
|
||||||
|
<text class="success-title">签到成功</text>
|
||||||
|
<text class="success-time">{{ formatTime(new Date()) }}</text>
|
||||||
|
<text class="success-tip">您已成功完成签到</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 不在签到名单阶段 -->
|
||||||
|
<view v-else-if="currentStep === 'notInList'" class="not-in-list-step">
|
||||||
|
<view class="not-in-list-content">
|
||||||
|
<u-icon name="close-circle" size="80" color="#F56C6C" />
|
||||||
|
<text class="not-in-list-title">您不在签到名单中</text>
|
||||||
|
<text class="not-in-list-subtitle">抱歉,您没有在此次会议的签到名单中</text>
|
||||||
|
<text class="not-in-list-tip">请联系会议组织者确认您的参会资格</text>
|
||||||
|
|
||||||
|
<view class="meeting-info-card">
|
||||||
|
<text class="card-title">会议信息</text>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议名称:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdmc || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议时间:</text>
|
||||||
|
<text class="info-value">{{ formatTime(meetingInfo?.qdkstime) }} - {{ formatTime(meetingInfo?.qdjstime) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议地点:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdwz || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button @click="goBack" class="back-btn">返回</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 签到时间未开始阶段 -->
|
||||||
|
<view v-else-if="currentStep === 'timeNotStarted'" class="time-not-started-step">
|
||||||
|
<view class="time-not-started-content">
|
||||||
|
<u-icon name="clock" size="80" color="#409EFF" />
|
||||||
|
<text class="time-not-started-title">签到时间未开始</text>
|
||||||
|
<text class="time-not-started-subtitle">签到打卡时间还未开始,请耐心等待</text>
|
||||||
|
<text class="time-not-started-tip">请关注签到开始时间</text>
|
||||||
|
|
||||||
|
<view class="meeting-info-card">
|
||||||
|
<text class="card-title">会议信息</text>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议名称:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdmc || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">签到时间:</text>
|
||||||
|
<text class="info-value">{{ formatTime(meetingInfo?.qdkstime) }} - {{ formatTime(meetingInfo?.qdjstime) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">打卡开始:</text>
|
||||||
|
<text class="info-value">{{ formatTime(meetingInfo?.dkkstime) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议地点:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdwz || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">当前时间:</text>
|
||||||
|
<text class="info-value">{{ formatTime(new Date()) }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button @click="goBack" class="back-btn">返回</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 签到时间已结束阶段 -->
|
||||||
|
<view v-else-if="currentStep === 'timeExpired'" class="time-expired-step">
|
||||||
|
<view class="time-expired-content">
|
||||||
|
<u-icon name="clock" size="80" color="#E6A23C" />
|
||||||
|
<text class="time-expired-title">签到时间已结束</text>
|
||||||
|
<text class="time-expired-subtitle">抱歉,本次签到的时间已经结束</text>
|
||||||
|
<text class="time-expired-tip">请关注下次签到通知</text>
|
||||||
|
|
||||||
|
<view class="meeting-info-card">
|
||||||
|
<text class="card-title">会议信息</text>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议名称:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdmc || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议时间:</text>
|
||||||
|
<text class="info-value">{{ formatTime(meetingInfo?.qdkstime) }} - {{ formatTime(meetingInfo?.qdjstime) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议地点:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdwz || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">当前时间:</text>
|
||||||
|
<text class="info-value">{{ formatTime(new Date()) }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button @click="goBack" class="back-btn">返回</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 重复签到阶段 -->
|
||||||
|
<view v-else-if="currentStep === 'alreadySigned'" class="already-signed-step">
|
||||||
|
<view class="already-signed-content">
|
||||||
|
<u-icon name="checkmark-circle" size="80" color="#67C23A" />
|
||||||
|
<text class="already-signed-title">您已签到成功</text>
|
||||||
|
<text class="already-signed-subtitle">您已经完成本次签到,请勿重复签到</text>
|
||||||
|
<text class="already-signed-tip">如需重新签到,请联系会议组织者</text>
|
||||||
|
|
||||||
|
<view class="meeting-info-card">
|
||||||
|
<text class="card-title">会议信息</text>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议名称:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdmc || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议时间:</text>
|
||||||
|
<text class="info-value">{{ formatTime(meetingInfo?.qdkstime) }} - {{ formatTime(meetingInfo?.qdjstime) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">会议地点:</text>
|
||||||
|
<text class="info-value">{{ meetingInfo?.qdwz || '未设置' }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="info-label">签到时间:</text>
|
||||||
|
<text class="info-value">{{ formatTime(qdzxRecord?.qdwctime) }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button @click="goBack" class="back-btn">返回</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 签名组件 -->
|
||||||
|
<BasicSign v-if="showSignature" ref="signCompRef" :title="signTitle"></BasicSign>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue';
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { qdFindByIdApi, qdzxSignInApi, qdzxFindByQdParamsApi, qdzxFindByQdAndJsApi } from '@/api/base/server';
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
const { checkToken } = useUserStore();
|
||||||
|
|
||||||
|
// 页面参数
|
||||||
|
const options = ref<any>({});
|
||||||
|
|
||||||
|
// 页面加载时接收参数
|
||||||
|
onLoad((params) => {
|
||||||
|
console.log('confirmself.vue onLoad - 接收到的参数:', params);
|
||||||
|
|
||||||
|
// 只从URL参数中获取qdId
|
||||||
|
if (params && params.qdId) {
|
||||||
|
console.log('confirmself.vue onLoad - 检测到qdId参数:', params.qdId);
|
||||||
|
options.value = params;
|
||||||
|
// 延迟执行,确保页面完全加载
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('confirmself.vue onLoad - 开始执行initializePage');
|
||||||
|
initializePage();
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
console.log('confirmself.vue onLoad - 没有qdId参数,显示错误');
|
||||||
|
uni.showToast({ title: '缺少签到ID参数', icon: 'none' });
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack();
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 签到相关变量
|
||||||
|
const qdId = ref('');
|
||||||
|
const qdzxId = ref('');
|
||||||
|
|
||||||
|
// 当前步骤
|
||||||
|
const currentStep = ref<'sign' | 'confirm' | 'success' | 'notInList' | 'timeNotStarted' | 'timeExpired' | 'alreadySigned'>('confirm');
|
||||||
|
|
||||||
|
// 用户信息
|
||||||
|
const userInfo = ref<any>(null);
|
||||||
|
|
||||||
|
// 会议信息
|
||||||
|
const meetingInfo = ref<any>(null);
|
||||||
|
|
||||||
|
// 签到执行记录
|
||||||
|
const qdzxRecord = ref<any>(null);
|
||||||
|
|
||||||
|
// 签名组件相关
|
||||||
|
const signCompRef = ref<any>(null);
|
||||||
|
const signTitle = ref<string>("签到签名");
|
||||||
|
const sign_file = ref<string>("");
|
||||||
|
const showSignature = ref<boolean>(false);
|
||||||
|
|
||||||
|
// 获取用户store
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
// 页面初始化函数
|
||||||
|
const initializePage = async () => {
|
||||||
|
console.log('confirmself.vue initializePage - 开始初始化');
|
||||||
|
console.log('confirmself.vue initializePage - options.value:', options.value);
|
||||||
|
|
||||||
|
// 获取签到ID
|
||||||
|
qdId.value = options.value.qdId;
|
||||||
|
console.log('confirmself.vue initializePage - 设置qdId:', qdId.value);
|
||||||
|
|
||||||
|
|
||||||
|
// 第一步:获取缓存的教师信息
|
||||||
|
const jsData = userStore.getJs;
|
||||||
|
console.log('confirmself.vue initializePage - 获取教师信息:', jsData);
|
||||||
|
|
||||||
|
if (jsData && Object.keys(jsData).length > 0) {
|
||||||
|
userInfo.value = jsData;
|
||||||
|
console.log('confirmself.vue initializePage - 教师信息有效,继续执行');
|
||||||
|
} else {
|
||||||
|
console.log('confirmself.vue initializePage - 教师信息无效,跳转登录页面');
|
||||||
|
uni.showToast({ title: '请先登录', icon: 'none' });
|
||||||
|
// 跳转到登录页面
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/system/login/login'
|
||||||
|
});
|
||||||
|
}, 1500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 第二步:通过qdId和教师ID查询该教师是否能签到
|
||||||
|
console.log('confirmself.vue initializePage - 准备调用checkTeacherSignInPermission');
|
||||||
|
await checkTeacherSignInPermission();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面初始化
|
||||||
|
onMounted(async () => {
|
||||||
|
// 如果页面已经在onLoad中初始化完成,这里不需要额外操作
|
||||||
|
// 但可以添加一些DOM相关的初始化逻辑
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查教师签到权限
|
||||||
|
const checkTeacherSignInPermission = async () => {
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - 开始检查签到权限');
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - qdId:', qdId.value);
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - userInfo.value.id:', userInfo.value?.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - 准备调用qdzxFindByQdAndJsApi');
|
||||||
|
const result = await qdzxFindByQdAndJsApi({
|
||||||
|
qdId: qdId.value,
|
||||||
|
jsId: userInfo.value.id
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - API调用结果:', result);
|
||||||
|
|
||||||
|
if (result && result.resultCode === 1 && result.result) {
|
||||||
|
// 找到签到记录
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - 找到签到记录');
|
||||||
|
qdzxRecord.value = result.result;
|
||||||
|
qdzxId.value = result.result.id;
|
||||||
|
|
||||||
|
// 第三步:获取签到详情,验证是否需要签名
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - 准备调用loadMeetingInfo');
|
||||||
|
await loadMeetingInfo();
|
||||||
|
} else if (result && result.resultCode === 0) {
|
||||||
|
// 后端明确返回未找到记录
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - 未找到签到记录');
|
||||||
|
currentStep.value = 'notInList';
|
||||||
|
await loadMeetingInfo(); // 仍然加载会议信息用于显示
|
||||||
|
} else {
|
||||||
|
// 其他错误情况
|
||||||
|
console.log('confirmself.vue checkTeacherSignInPermission - 查询失败:', result);
|
||||||
|
uni.showToast({ title: '查询签到权限失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('confirmself.vue checkTeacherSignInPermission - 网络异常:', error);
|
||||||
|
uni.showToast({ title: '网络异常,请重试', icon: 'none' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载会议信息
|
||||||
|
const loadMeetingInfo = async () => {
|
||||||
|
try {
|
||||||
|
const result = await qdFindByIdApi({ id: qdId.value });
|
||||||
|
if (result && result.resultCode === 1) {
|
||||||
|
meetingInfo.value = result.result;
|
||||||
|
|
||||||
|
// 1. 验证签到时间
|
||||||
|
const currentTime = new Date();
|
||||||
|
const startTime = meetingInfo.value?.dkkstime ? new Date(meetingInfo.value.dkkstime) : null;
|
||||||
|
const endTime = meetingInfo.value?.qdjstime ? new Date(meetingInfo.value.qdjstime) : null;
|
||||||
|
|
||||||
|
// 检查签到时间是否未开始
|
||||||
|
if (startTime && currentTime < startTime) {
|
||||||
|
// 签到时间未开始,显示"签到时间未开始"界面
|
||||||
|
currentStep.value = 'timeNotStarted';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查签到时间是否已结束
|
||||||
|
if (endTime && currentTime > endTime) {
|
||||||
|
// 签到时间已结束,显示"签到时间已结束"界面
|
||||||
|
currentStep.value = 'timeExpired';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只有在找到qdzxId时才检查是否需要签名
|
||||||
|
if (qdzxId.value) {
|
||||||
|
// 检查是否已经签到
|
||||||
|
if (qdzxRecord.value?.qdStatus === '1') {
|
||||||
|
// 已经签到,跳转到重复签到界面
|
||||||
|
currentStep.value = 'alreadySigned';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否需要签名
|
||||||
|
if (meetingInfo.value?.mdqz === '1') {
|
||||||
|
// 需要签名,调用签名组件
|
||||||
|
await handleSignature();
|
||||||
|
} else {
|
||||||
|
// 不需要签名,直接到确认界面
|
||||||
|
currentStep.value = 'confirm';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
uni.showToast({ title: '加载会议信息失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理签名
|
||||||
|
const handleSignature = async () => {
|
||||||
|
try {
|
||||||
|
showSignature.value = true;
|
||||||
|
sign_file.value = '';
|
||||||
|
signTitle.value = "签到签名";
|
||||||
|
|
||||||
|
// 等待组件渲染完成
|
||||||
|
await nextTick();
|
||||||
|
const data = await signCompRef.value.getSyncSignature();
|
||||||
|
sign_file.value = data.base64;
|
||||||
|
showSignature.value = false;
|
||||||
|
|
||||||
|
// 签名完成后,跳转到确认界面
|
||||||
|
currentStep.value = 'confirm';
|
||||||
|
} catch (error) {
|
||||||
|
showSignature.value = false;
|
||||||
|
uni.showToast({ title: '签名失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交签到
|
||||||
|
const submitSignIn = async () => {
|
||||||
|
try {
|
||||||
|
const params: any = {
|
||||||
|
qdzxId: qdzxId.value,
|
||||||
|
signInTime: new Date().toISOString() // 转换为ISO字符串格式
|
||||||
|
};
|
||||||
|
|
||||||
|
// 如果有签名文件,添加到参数中
|
||||||
|
if (sign_file.value) {
|
||||||
|
params.signatureImage = sign_file.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await qdzxSignInApi(params);
|
||||||
|
|
||||||
|
if (result && result.resultCode === 1) {
|
||||||
|
currentStep.value = 'success';
|
||||||
|
} else {
|
||||||
|
const errorMsg = result?.message || '签到失败';
|
||||||
|
uni.showToast({ title: errorMsg, icon: 'none' });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
uni.showToast({ title: '网络异常,请重试', icon: 'none' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 格式化时间
|
||||||
|
const formatTime = (time: string | Date) => {
|
||||||
|
if (!time) return '未设置';
|
||||||
|
const date = new Date(time);
|
||||||
|
return date.toLocaleString('zh-CN', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: '2-digit',
|
||||||
|
day: '2-digit',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 返回上一页
|
||||||
|
const goBack = () => {
|
||||||
|
uni.navigateBack();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.confirm-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认签到阶段
|
||||||
|
.confirm-step {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
.confirm-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-info {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
min-width: 80px;
|
||||||
|
text-align: right !important;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
flex: 1;
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-preview {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
.preview-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-preview-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 44px;
|
||||||
|
background: linear-gradient(135deg, #67C23A 0%, #85ce61 100%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 签到成功阶段
|
||||||
|
.success-step {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 40px 24px;
|
||||||
|
margin-top: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-content {
|
||||||
|
.success-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin: 16px 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-time {
|
||||||
|
display: block;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-tip {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不在签到名单阶段
|
||||||
|
.not-in-list-step {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-top: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-in-list-content {
|
||||||
|
.not-in-list-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin: 16px 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-in-list-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-in-list-tip {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-info-card {
|
||||||
|
background: #f9f9f9;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
min-width: 80px;
|
||||||
|
text-align: right !important;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
flex: 1;
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 44px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
color: #666;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 签到时间未开始阶段 */
|
||||||
|
.time-not-started-step {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 40px 24px;
|
||||||
|
margin-top: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-not-started-content {
|
||||||
|
.time-not-started-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin: 16px 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-not-started-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-not-started-tip {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 签到时间已结束阶段 */
|
||||||
|
.time-expired-step {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 40px 24px;
|
||||||
|
margin-top: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-expired-content {
|
||||||
|
.time-expired-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin: 16px 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-expired-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-expired-tip {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 重复签到阶段 */
|
||||||
|
.already-signed-step {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 40px 24px;
|
||||||
|
margin-top: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.already-signed-content {
|
||||||
|
.already-signed-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin: 16px 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.already-signed-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.already-signed-tip {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -84,22 +84,34 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="card-footer">
|
<view class="card-footer">
|
||||||
<view class="footer-actions">
|
<view class="footer-actions">
|
||||||
<image
|
<view class="action-item" @click="goToQRCode(data.id)">
|
||||||
src="/static/base/qr-code.png"
|
<image
|
||||||
class="footer-action-icon qr-icon"
|
src="/static/base/qr-code.png"
|
||||||
@click="goToQRCode(data.id)"
|
class="footer-action-icon qr-icon"
|
||||||
/>
|
/>
|
||||||
<image
|
<view v-if="showTooltip" class="tooltip">二维码</view>
|
||||||
src="/static/base/details.png"
|
</view>
|
||||||
class="footer-action-icon details-icon"
|
<view class="action-item" @click="goToSignIn(data.id)">
|
||||||
@click="goToFeedback(data.id)"
|
<image
|
||||||
/>
|
src="/static/base/view/qdself.png"
|
||||||
<image
|
class="footer-action-icon qdself-icon"
|
||||||
v-if="data.qdStatus === 'A'"
|
/>
|
||||||
src="/static/base/push.png"
|
<view v-if="showTooltip" class="tooltip">签到</view>
|
||||||
class="footer-action-icon push-icon"
|
</view>
|
||||||
@click="goToPush(data.id)"
|
<view class="action-item" @click="goToFeedback(data.id)">
|
||||||
/>
|
<image
|
||||||
|
src="/static/base/details.png"
|
||||||
|
class="footer-action-icon details-icon"
|
||||||
|
/>
|
||||||
|
<view v-if="showTooltip" class="tooltip">详情</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="data.qdStatus === 'A'" class="action-item" @click="goToPush(data.id)">
|
||||||
|
<image
|
||||||
|
src="/static/base/push.png"
|
||||||
|
class="footer-action-icon push-icon"
|
||||||
|
/>
|
||||||
|
<view v-if="showTooltip" class="tooltip">推送</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -124,6 +136,7 @@
|
|||||||
import { qdFindPageApi } from "@/api/base/server";
|
import { qdFindPageApi } from "@/api/base/server";
|
||||||
import { ref, reactive, onMounted } from "vue";
|
import { ref, reactive, onMounted } from "vue";
|
||||||
import { onShow } from "@dcloudio/uni-app";
|
import { onShow } from "@dcloudio/uni-app";
|
||||||
|
import { useUserStore } from "@/store/modules/user";
|
||||||
|
|
||||||
interface QdItem {
|
interface QdItem {
|
||||||
id: string;
|
id: string;
|
||||||
@ -149,6 +162,9 @@ const searchForm = reactive({
|
|||||||
const dataList = ref<QdItem[]>([]);
|
const dataList = ref<QdItem[]>([]);
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
|
||||||
|
// 气泡提示显示状态
|
||||||
|
const showTooltip = ref(true);
|
||||||
|
|
||||||
// 开始时间选择
|
// 开始时间选择
|
||||||
const onStartTimeChange = (e: any) => {
|
const onStartTimeChange = (e: any) => {
|
||||||
searchForm.startTime = e.detail.value;
|
searchForm.startTime = e.detail.value;
|
||||||
@ -258,6 +274,43 @@ const goToQRCode = (id: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 跳转到签到页面
|
||||||
|
const goToSignIn = (id: string) => {
|
||||||
|
// 获取用户store
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
// 获取缓存的教师信息
|
||||||
|
const jsData = userStore.getJs;
|
||||||
|
|
||||||
|
// 找到对应的签到项目
|
||||||
|
const qdItem = dataList.value.find(item => item.id === id);
|
||||||
|
|
||||||
|
if (!qdItem) {
|
||||||
|
uni.showToast({ title: '签到信息不存在', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证发布者权限
|
||||||
|
if (jsData && jsData.id && qdItem.jsId) {
|
||||||
|
if (jsData.id !== qdItem.jsId) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '只有发布者才能使用点击签到功能',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: '用户信息获取失败,请重新登录', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 权限验证通过,跳转到签到页面
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/view/routine/qd/confirmself?qdId=${id}`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 页面显示时刷新数据
|
// 页面显示时刷新数据
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
getQdList();
|
getQdList();
|
||||||
@ -266,6 +319,11 @@ onShow(() => {
|
|||||||
// 页面加载时也调用一次
|
// 页面加载时也调用一次
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getQdList();
|
getQdList();
|
||||||
|
|
||||||
|
// 6秒后隐藏气泡提示
|
||||||
|
setTimeout(() => {
|
||||||
|
showTooltip.value = false;
|
||||||
|
}, 6000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -474,6 +532,14 @@ onMounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
|
.action-item {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.footer-action-icon {
|
.footer-action-icon {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
@ -484,6 +550,22 @@ onMounted(() => {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.qdself-icon {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.details-icon {
|
.details-icon {
|
||||||
width: 22px;
|
width: 22px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
@ -498,6 +580,43 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 气泡提示样式
|
||||||
|
.tooltip {
|
||||||
|
position: absolute;
|
||||||
|
top: -35px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
color: white;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 1000;
|
||||||
|
animation: tooltipFadeIn 0.3s ease-out;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border: 4px solid transparent;
|
||||||
|
border-top-color: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes tooltipFadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50%) translateY(-5px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(-50%) translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 新增按钮 - 固定在底部
|
// 新增按钮 - 固定在底部
|
||||||
.add-button-fixed {
|
.add-button-fixed {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@ -42,8 +42,23 @@
|
|||||||
</picker>
|
</picker>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 自定义教师选择 -->
|
||||||
|
<view class="filter-row" v-if="selectType === 0">
|
||||||
|
<view class="filter-label">{{ getSecondSelectLabel() }}</view>
|
||||||
|
<view class="custom-teacher-picker">
|
||||||
|
<BasicJsPicker
|
||||||
|
:defaultValue="customSelectedTeachers"
|
||||||
|
:multiple="true"
|
||||||
|
@change="onCustomTeacherChange"
|
||||||
|
placeholder="请选择教师"
|
||||||
|
title="选择教师"
|
||||||
|
ref="customTeacherPickerRef"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 具体选择 -->
|
<!-- 具体选择 -->
|
||||||
<view class="filter-row" v-if="selectType && selectType !== 1">
|
<view class="filter-row" v-if="selectType && selectType !== 1 && selectType !== 0">
|
||||||
<view class="filter-label">{{ getSecondSelectLabel() }}</view>
|
<view class="filter-label">{{ getSecondSelectLabel() }}</view>
|
||||||
<view class="multi-select-container">
|
<view class="multi-select-container">
|
||||||
<view class="selected-items-display" @click="showMultiSelectModal">
|
<view class="selected-items-display" @click="showMultiSelectModal">
|
||||||
@ -60,6 +75,11 @@
|
|||||||
<text class="tip-text">💡 提示:选择"所有老师"将直接加载所有教师数据</text>
|
<text class="tip-text">💡 提示:选择"所有老师"将直接加载所有教师数据</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 自定义教师提示 -->
|
||||||
|
<view class="filter-tip" v-if="selectType === 0">
|
||||||
|
<text class="tip-text">💡 提示:选择"自定义教师"可以手动选择特定的教师</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 多选弹窗 -->
|
<!-- 多选弹窗 -->
|
||||||
<view v-if="showModal" class="modal-overlay" @click="hideMultiSelectModal">
|
<view v-if="showModal" class="modal-overlay" @click="hideMultiSelectModal">
|
||||||
<view class="modal-content" @click.stop>
|
<view class="modal-content" @click.stop>
|
||||||
@ -159,6 +179,7 @@ import {
|
|||||||
kmFindAllApi,
|
kmFindAllApi,
|
||||||
zwFindAllApi
|
zwFindAllApi
|
||||||
} from "@/api/base/server";
|
} from "@/api/base/server";
|
||||||
|
import BasicJsPicker from '@/components/BasicJsPicker/Picker.vue';
|
||||||
|
|
||||||
interface TeacherInfo {
|
interface TeacherInfo {
|
||||||
id: string;
|
id: string;
|
||||||
@ -177,8 +198,13 @@ const selectedTeachers = ref<TeacherInfo[]>([]);
|
|||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const showModal = ref(false); // 控制多选弹窗的显示
|
const showModal = ref(false); // 控制多选弹窗的显示
|
||||||
|
|
||||||
|
// 自定义教师选择相关
|
||||||
|
const customTeacherPickerRef = ref<any>(null);
|
||||||
|
const customSelectedTeachers = ref<string[]>([]);
|
||||||
|
|
||||||
// 选择类别选项
|
// 选择类别选项
|
||||||
const selectTypeOptions = [
|
const selectTypeOptions = [
|
||||||
|
{ value: 0, label: '自定义教师' },
|
||||||
{ value: 1, label: '所有老师' },
|
{ value: 1, label: '所有老师' },
|
||||||
{ value: 2, label: '按科目' },
|
{ value: 2, label: '按科目' },
|
||||||
{ value: 3, label: '按班主任' },
|
{ value: 3, label: '按班主任' },
|
||||||
@ -207,6 +233,8 @@ const getZwTypeText = () => {
|
|||||||
// 获取第二个选择框的标签
|
// 获取第二个选择框的标签
|
||||||
const getSecondSelectLabel = () => {
|
const getSecondSelectLabel = () => {
|
||||||
switch (selectType.value) {
|
switch (selectType.value) {
|
||||||
|
case 0:
|
||||||
|
return '选择教师';
|
||||||
case 1:
|
case 1:
|
||||||
return '年级/班级';
|
return '年级/班级';
|
||||||
case 2:
|
case 2:
|
||||||
@ -241,6 +269,12 @@ const onSelectTypeChange = async (e: any) => {
|
|||||||
selectType.value = selectTypeOptions[e.detail.value].value;
|
selectType.value = selectTypeOptions[e.detail.value].value;
|
||||||
selectTwoType.value = [];
|
selectTwoType.value = [];
|
||||||
selectedTeachers.value = [];
|
selectedTeachers.value = [];
|
||||||
|
customSelectedTeachers.value = [];
|
||||||
|
|
||||||
|
// 如果选择"自定义教师",清空选择
|
||||||
|
if (selectType.value === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 如果选择"所有老师",直接加载所有教师数据
|
// 如果选择"所有老师",直接加载所有教师数据
|
||||||
if (selectType.value === 1) {
|
if (selectType.value === 1) {
|
||||||
@ -293,6 +327,25 @@ const confirmMultiSelect = () => {
|
|||||||
loadTeachers();
|
loadTeachers();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 自定义教师选择变化处理
|
||||||
|
const onCustomTeacherChange = (teachers: any[]) => {
|
||||||
|
console.log('自定义教师选择变化:', teachers);
|
||||||
|
|
||||||
|
// 更新自定义选择的教师ID列表
|
||||||
|
customSelectedTeachers.value = teachers.map(teacher => teacher.value || teacher.id);
|
||||||
|
|
||||||
|
// 转换为统一的教师信息格式
|
||||||
|
selectedTeachers.value = teachers.map(teacher => ({
|
||||||
|
id: teacher.id || teacher.value,
|
||||||
|
jsxm: teacher.jsxm || teacher.label,
|
||||||
|
jsId: teacher.id || teacher.value,
|
||||||
|
dzzw: teacher.dzzw || '',
|
||||||
|
qtzw: teacher.qtzw || ''
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log('处理后的自定义教师数据:', selectedTeachers.value);
|
||||||
|
};
|
||||||
|
|
||||||
// 从localStorage加载所有教师数据
|
// 从localStorage加载所有教师数据
|
||||||
const loadAllTeachersFromStorage = async () => {
|
const loadAllTeachersFromStorage = async () => {
|
||||||
try {
|
try {
|
||||||
@ -1114,6 +1167,10 @@ const ensureTeacherDataCached = async () => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-teacher-picker {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.selected-items-display {
|
.selected-items-display {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
BIN
src/static/base/view/qdself.png
Normal file
BIN
src/static/base/view/qdself.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
Loading…
x
Reference in New Issue
Block a user