1、完善请假相关页面的显示

2、将待办请假的加载业务逻辑提取到qjPageUtil中
This commit is contained in:
ywyonui 2025-09-05 21:11:32 +08:00
parent 5d77454c4d
commit 978f53aa64
9 changed files with 437 additions and 713 deletions

View File

@ -19,6 +19,10 @@
<text class="label">代课老师:</text> <text class="label">代课老师:</text>
<view class="value">{{ item.jsName }}</view> <view class="value">{{ item.jsName }}</view>
</view> </view>
<view class="info-row">
<text class="label">确认状态:</text>
<view class="value">{{ item.statusLabel }}</view>
</view>
</view> </view>
</view> </view>
</view> </view>
@ -67,6 +71,12 @@ const jsTypeMc: any = {
PM: "下午", PM: "下午",
}; };
const qrStatus: any = {
"wait": "待确认",
"approved": "同意",
"rejected": "拒绝",
};
const dkList = ref<any>([]); const dkList = ref<any>([]);
watch( watch(
@ -92,6 +102,7 @@ const init = async () => {
item.jcmc = jsTypeMc[item.jcType] + "第" + item.jc + "节"; item.jcmc = jsTypeMc[item.jcType] + "第" + item.jc + "节";
const xq: number = item.xq - 1; const xq: number = item.xq - 1;
item.xqLabel = wdNameList.value[xq]; item.xqLabel = wdNameList.value[xq];
item.statusLabel = qrStatus[item.qrStatus] || "未知";
return item; return item;
}); });
// //

View File

@ -23,8 +23,11 @@
</view> </view>
<!-- 代课信息 --> <!-- 代课信息 -->
<view v-show="showDkTab && curTabIndex === 1"> <view v-show="curTabIndex === 1">
<JsQjDetailDk <view v-if="!showDkFlag" class="empty-dk">
<view>{{ showDkEmptyLabel }}</view>
</view>
<JsQjDetailDk v-else
:qjId="qjId" :qjId="qjId"
@loadDkList="handleDkListLoaded" @loadDkList="handleDkListLoaded"
/> />
@ -54,24 +57,18 @@ import ProgressList from "./components/progressList.vue";
const { getData, setData } = useDataStore(); const { getData, setData } = useDataStore();
const tabList = ref<any>([{ name: "请假信息", id: "tab-qj" }]); const tabList = ref<any>([
{ name: "请假信息", id: "tab-qj" },
{ name: "代课信息", id: "tab-dk" },
{ name: "审批流程", id: "tab-sp" }
]);
const curTabIndex = ref(0); const curTabIndex = ref(0);
const dbFlag = ref(false); const dbFlag = ref(false);
const qjId = computed(() => getData.id); const qjId = computed(() => getData.id);
const showDkTab = ref(false); const showDkFlag = ref(false);
const showDkEmptyLabel = ref('');
// Tab
const rebuildTabList = (showDk: boolean) => {
// Tab
tabList.value = [
{ name: "请假信息", id: "tab-qj" },
];
if (showDk) {
tabList.value.push({ name: "代课信息", id: "tab-dk" });
}
tabList.value.push({ name: "审批流程", id: "tab-sp" });
};
// Tab // Tab
const switchTab = (index: number) => { const switchTab = (index: number) => {
@ -80,8 +77,15 @@ const switchTab = (index: number) => {
const handleQjDataLoaded = (data: any) => { const handleQjDataLoaded = (data: any) => {
setData(data); setData(data);
showDkTab.value = !!(data && data.dkfs != 2); data = data || {};
rebuildTabList(showDkTab.value); const dkfs = typeof(data.dkfs) === "string" ? parseInt(data.dkfs) : (data.dkfs || 2);
const bpmStatus = typeof(data.bpmStatus) === "string" ? parseInt(data.bpmStatus) : (data.bpmStatus || 1);
showDkFlag.value = dkfs === 0 || (dkfs === 1 && bpmStatus > 4);
if (dkfs === 1) {
showDkEmptyLabel.value = "等待教科处协调";
} else if (dkfs === 2) {
showDkEmptyLabel.value = "无需代课";
}
}; };
const handleDkListLoaded = (list: any[]) => { const handleDkListLoaded = (list: any[]) => {
@ -101,4 +105,12 @@ const goHome = () => {
background-color: #f5f7fa; background-color: #f5f7fa;
} }
.empty-dk {
margin: 15px;
background-color: #fff;
border-radius: 8px;
padding: 50px 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
text-align: center;
}
</style> </style>

View File

@ -1,289 +1,212 @@
<template> <template>
<BasicLayout> <BasicLayout>
<view class="p-15"> <template #top>
<!-- 请假信息卡片 --> <view>
<view class="info-card"> <BasicTabs
<view class="card-header"> class="detail-tabs"
<text class="applicant-name">教师{{ qjData.jsName }}的请假申请</text> :list="tabList"
</view> bar-width="60px"
<view class="card-content"> scroll-count="4"
<view class="info-row"> :current="curTabIndex"
<text class="label">请假老师:</text> @change="switchTab"
<text class="value">{{ qjData.jsName }}</text> />
</view>
<view class="info-row">
<text class="label">请假类型:</text>
<text class="value">{{ qjData.qjlx }}</text>
</view>
<view class="info-row">
<text class="label">请假时间:</text>
<text class="value">{{ qjData.qjkstime }} {{ qjData.qjjstime }}</text>
</view>
<view class="info-row">
<text class="label">请假时长:</text>
<text class="value">{{ qjData.qjsc }}</text>
</view>
<view class="info-row">
<text class="label">请假事由:</text>
<text class="value">{{ qjData.qjsy }}</text>
</view>
</view> </view>
</template>
<view class="qj-detail">
<!-- 请假信息 -->
<view v-show="curTabIndex === 0">
<JsQjDetailInfo
:qjId="qjId"
:dbFlag="dbFlag"
@loadQjData="handleQjDataLoaded"
/>
</view> </view>
<!-- 代课信息 --> <!-- 代课信息 -->
<view class="dk-info-card"> <view v-show="showDkTab && curTabIndex === 1">
<view class="card-header"> <JsQjDetailDk
<text class="card-title">代课信息</text> :qjId="qjId"
</view> @loadDkList="handleDkListLoaded"
<view class="card-content"> />
<view class="info-row">
<text class="label">代课时间:</text>
<text class="value">{{ dkData.dktime }}</text>
</view>
<view class="info-row">
<text class="label">课程名称:</text>
<text class="value">{{ dkData.kcmc }}</text>
</view>
<view class="info-row">
<text class="label">班级:</text>
<text class="value">{{ dkData.bjmc }}</text>
</view>
</view>
</view> </view>
<!-- 确认操作 --> <!-- 审批流程 -->
<view class="action-section"> <view v-show="curTabIndex === 2">
<view class="action-title">确认代课</view> <ProgressList :qjId="qjId" />
<view class="action-buttons"> </view>
<u-button </view>
text="拒绝代课" <template #bottom>
type="error" <view class="white-bg-color py-5">
@click="handleReject" <view class="flex-row items-center pb-10 pt-5">
class="action-btn" <u-button text="驳回" class="ml-15 mr-7" :plain="true" @click="showDlg" />
/> <u-button text="同意" class="mr-15 mr-7" type="primary" @click="submit" />
<u-button </view>
text="确认代课" </view>
type="primary" </template>
@click="handleConfirm" <!-- 驳回弹窗 -->
class="action-btn" <u-popup
:show="dlgFlag"
mode="center"
:closeOnClickOverlay="false"
@close="closeDlg"
>
<view class="popup-content">
<view class="popup-title">驳回原因</view>
<u-input
v-model="rejectReason"
type="textarea"
placeholder="请填写驳回原因"
:autoHeight="true"
maxlength="200"
/> />
<view class="popup-actions flex-row justify-end mt-4">
<u-button class="mr-2" @click="closeDlg">取消</u-button>
<u-button type="primary" @click="handleReject">确定</u-button>
</view> </view>
</view> </view>
</view> </u-popup>
</BasicLayout> </BasicLayout>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onLoad } from "@dcloudio/uni-app";
import { jsQjDkQrApi } from "@/api/base/jsQjApi"; import { jsQjDkQrApi } from "@/api/base/jsQjApi";
import { findQjById, findDkByIdApi } from "@/api/base/jsQjApi";
import { xxtsFindByIdApi } from "@/api/base/server";
import { useUserStore } from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data"; import { useDataStore } from "@/store/modules/data";
import { navigateBack } from "@/utils/uniapp";
import { onLoad } from "@dcloudio/uni-app";
import { ref } from "vue"; import { ref } from "vue";
import JsQjDetailInfo from "./components/jsQjDetailInfo.vue";
import JsQjDetailDk from "./components/jsQjDetailDk.vue";
import ProgressList from "./components/progressList.vue";
import { QjPageUtils } from "@/utils/qjPageUtils";
const { getJs, loginByOpenId } = useUserStore(); const { getJs } = useUserStore();
const { getData, setXxts, setData, getXxts } = useDataStore(); const { setData } = useDataStore();
const tabList = ref<any>([{ name: "请假信息", id: "tab-qj" }]);
const curTabIndex = ref(0);
const dbFlag = ref(false); const dbFlag = ref(false);
const qjId = ref<string>(); const qjId = ref('');
const dkId = ref<string>(); const showDkTab = ref(false);
const qjData = ref<any>({});
const dkData = ref<any>({});
// const dlgFlag = ref(false);
const loadQjData = async () => { const rejectReason = ref("");
try {
const result: any = await findQjById({ id: qjId.value });
if (result.code === 1) { // Tab
qjData.value = result.data; const rebuildTabList = (showDk: boolean) => {
} // Tab
} catch (error) { tabList.value = [
console.error('获取请假信息失败:', error); { name: "请假信息", id: "tab-qj" },
];
if (showDk) {
tabList.value.push({ name: "代课信息", id: "tab-dk" });
} }
tabList.value.push({ name: "审批流程", id: "tab-sp" });
}; };
// // Tab
const loadDkData = async () => { const switchTab = (index: number) => {
try { curTabIndex.value = index;
const result: any = await findDkByIdApi({ id: dkId.value });
if (result.code === 1) {
dkData.value = result.data;
}
} catch (error) {
console.error('获取代课信息失败:', error);
}
}; };
// const handleQjDataLoaded = (data: any) => {
const handleConfirm = async () => { setData(data);
showDkTab.value = !!(data && data.dkfs != 2);
rebuildTabList(showDkTab.value);
};
const handleDkListLoaded = (list: any[]) => {
// JsQjDetail
};
const showDlg = () => {
dlgFlag.value = true;
};
const closeDlg = () => {
dlgFlag.value = false;
};
const submit = async () => {
const params = { const params = {
qjId: qjId.value, qjId: qjId.value,
jsId: getJs.id, jsId: getJs.id,
qrStatus: "1", // 1 spStatus: "approved",
remark: "确认代课" spRemark: "同意",
}; };
uni.showLoading({ title: "确认中..." }); uni.showLoading({ title: "确认中..." });
try {
await jsQjDkQrApi(params); await jsQjDkQrApi(params);
uni.showToast({ title: "确认成功", icon: "success" });
navigateBack();
} catch (error) {
uni.showToast({ title: "确认失败", icon: "error" });
}
uni.hideLoading(); uni.hideLoading();
setTimeout(() => {
uni.reLaunch({ url: '/pages/base/message/index' });
}, 1000);
}; };
// //
const handleReject = async () => { const handleReject = async () => {
uni.showModal({ if (!rejectReason.value.trim()) {
title: "确认拒绝", uni.showToast({ title: "请填写驳回意见", icon: "none" });
content: "确定要拒绝代课吗?", return;
success: async (res) => { }
if (res.confirm) {
const params = { const params = {
qjId: qjId.value, qjId: qjId.value,
jsId: getJs.id, jsId: getJs.id,
qrStatus: "2", // 2 spStatus: "rejected",
remark: "拒绝代课" spRemark: rejectReason.value,
}; };
uni.showLoading({ title: "正在驳回..." });
uni.showLoading({ title: "处理中..." });
try {
await jsQjDkQrApi(params); await jsQjDkQrApi(params);
uni.showToast({ title: "已拒绝", icon: "success" });
navigateBack();
} catch (error) {
uni.showToast({ title: "操作失败", icon: "error" });
}
uni.hideLoading(); uni.hideLoading();
} closeDlg();
} setTimeout(() => {
}); uni.reLaunch({ url: '/pages/base/message/index' });
}, 1000);
}; };
onLoad(async (data?: any) => { onLoad(async (data?: any) => {
// const ret = await QjPageUtils.init(data);
console.log(data); if (!ret || !ret.success) {
if (data && data.from && data.from == "db") {
dbFlag.value = true;
//
const isLoggedIn = await loginByOpenId(data.openId);
if (!isLoggedIn) {
console.log("用户未登录,跳过处理");
return; return;
} }
qjId.value = ret.qjId;
try { dbFlag.value = ret.dbFlag;
// urlidXxts
const xxtsRes = await xxtsFindByIdApi({ id: data.id });
if (xxtsRes && xxtsRes.result) {
const xxts = xxtsRes.result;
//
if (xxts.dbZt === "B") {
setData({ id: xxts.xxzbId });
let url = "/pages/view/hr/jsQj/detail";
uni.navigateTo({ url });
return;
}
setXxts(xxts);
qjId.value = xxts.xxzbId;
dkId.value = xxts.xxglId
loadQjData();
loadDkData();
}
} catch (error) {
console.error("获取待办信息失败", error);
// Xxts退
const xxtsData = getXxts;
if (xxtsData && xxtsData.dbZt === "B") {
setData({ id: data.id });
let url = "/pages/view/hr/jsQj/detail";
uni.navigateTo({ url });
return;
}
qjId.value = data.id;
}
} else {
dbFlag.value = false;
//
qjId.value = getData.id || '';
}
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.info-card, .qj-detail {
.dk-info-card { background-color: #f5f7fa;
background: white;
border-radius: 8px;
margin-bottom: 15px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
} }
.info-card {
margin: 15px;
background-color: #fff;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
.card-header { .card-header {
padding: 15px;
border-bottom: 1px solid #eee;
.applicant-name,
.card-title {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
color: #333; color: #333;
}
}
.card-content {
padding: 15px;
}
.info-row {
display: flex;
margin-bottom: 10px; margin-bottom: 10px;
&:last-child { .applicant-name {
margin-bottom: 0;
}
.label {
width: 80px;
font-size: 14px;
color: #666;
flex-shrink: 0;
}
.value {
flex: 1;
font-size: 14px;
color: #333;
}
}
.action-section {
background: white;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
.action-title {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
color: #333; color: #333;
}
}
.divider {
height: 1px;
background-color: #eee;
margin-bottom: 15px; margin-bottom: 15px;
text-align: center;
} }
.action-buttons { .card-body {
display: flex; padding: 15px;
gap: 15px;
.action-btn {
flex: 1;
}
} }
} }
</style> </style>

View File

@ -74,14 +74,14 @@ import { navigateBack } from "@/utils/uniapp";
import { jsQjJwcQrApi } from "@/api/base/jsQjApi"; import { jsQjJwcQrApi } from "@/api/base/jsQjApi";
import { useUserStore } from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data"; import { useDataStore } from "@/store/modules/data";
import { ref, computed } from "vue"; import { ref } from "vue";
import { xxtsFindByIdApi } from "@/api/base/server";
import JsQjDetailInfo from "./components/jsQjDetailInfo.vue"; import JsQjDetailInfo from "./components/jsQjDetailInfo.vue";
import JsQjDetailDk from "./components/jsQjDetailDk.vue"; import JsQjDetailDk from "./components/jsQjDetailDk.vue";
import ProgressList from "./components/progressList.vue"; import ProgressList from "./components/progressList.vue";
import { QjPageUtils } from "@/utils/qjPageUtils";
const { getJs, loginByOpenId } = useUserStore(); const { getJs } = useUserStore();
const { getData, setXxts, setData, getXxts } = useDataStore(); const { setData } = useDataStore();
const tabList = ref<any>([{ name: "请假信息", id: "tab-qj" }]); const tabList = ref<any>([{ name: "请假信息", id: "tab-qj" }]);
const curTabIndex = ref(0); const curTabIndex = ref(0);
@ -162,50 +162,12 @@ const handleReject = async () => {
}; };
onLoad(async (data?: any) => { onLoad(async (data?: any) => {
// const ret = await QjPageUtils.init(data);
console.log(data); if (!ret || !ret.success) {
if (data && data.from && data.from == "db") {
dbFlag.value = true;
//
const isLoggedIn = await loginByOpenId(data.openId);
if (!isLoggedIn) {
console.log("用户未登录,跳过处理");
return; return;
} }
qjId.value = ret.qjId;
try { dbFlag.value = ret.dbFlag;
// urlidXxts
const xxtsRes = await xxtsFindByIdApi({ id: data.id });
if (xxtsRes && xxtsRes.result) {
const xxts = xxtsRes.result;
//
if (xxts.dbZt === "B") {
setData({ id: xxts.xxzbId });
let url = "/pages/view/hr/jsQj/detail";
uni.navigateTo({ url });
return;
}
setXxts(xxts);
qjId.value = xxts.xxzbId;
}
} catch (error) {
console.error("获取待办信息失败", error);
// Xxts退
const xxtsData = getXxts;
if (xxtsData && xxtsData.dbZt === "B") {
setData({ id: data.id });
let url = "/pages/view/hr/jsQj/detail";
uni.navigateTo({ url });
return;
}
qjId.value = data.id;
}
} else {
dbFlag.value = false;
//
qjId.value = getData.id || '';
}
}); });
</script> </script>

View File

@ -1,366 +1,176 @@
<template> <template>
<BasicLayout> <BasicLayout>
<view class="p-15"> <template #top>
<!-- 请假信息卡片 --> <view>
<view class="info-card"> <BasicTabs
<view class="card-header"> class="detail-tabs"
<text class="applicant-name">教师{{ qjData.jsName }}的请假申请</text> :list="tabList"
</view> bar-width="60px"
<view class="card-content"> scroll-count="4"
<view class="info-row"> :current="curTabIndex"
<text class="label">请假类型:</text> @change="switchTab"
<text class="value">{{ qjData.qjlx }}</text>
</view>
<view class="info-row">
<text class="label">请假时间:</text>
<text class="value">{{ qjData.qjkstime }} {{ qjData.qjjstime }}</text>
</view>
<view class="info-row">
<text class="label">请假时长:</text>
<text class="value">{{ qjData.qjsc }}</text>
</view>
<view class="info-row">
<text class="label">请假事由:</text>
<text class="value">{{ qjData.qjsy }}</text>
</view>
</view>
</view>
<!-- 代课安排 -->
<view class="dk-arrange-card">
<view class="card-header">
<text class="card-title">代课安排</text>
</view>
<view class="card-content">
<view class="dk-list">
<view
v-for="(dk, index) in dkList"
:key="index"
class="dk-item"
>
<view class="dk-header">
<text class="dk-title">代课{{ index + 1 }}</text>
<u-button
text="删除"
size="mini"
type="error"
@click="removeDk(index)"
/> />
</view> </view>
<view class="dk-content"> </template>
<view class="info-row"> <view class="qj-detail">
<text class="label">代课教师:</text> <!-- 请假信息 -->
<text class="value">{{ dk.jsName }}</text> <view v-show="curTabIndex === 0">
</view> <JsQjDetailInfo
<view class="info-row"> :qjId="qjId"
<text class="label">代课时间:</text> :dbFlag="dbFlag"
<text class="value">{{ dk.dktime }}</text> @loadQjData="handleQjDataLoaded"
</view>
<view class="info-row">
<text class="label">课程名称:</text>
<text class="value">{{ dk.kcmc }}</text>
</view>
<view class="info-row">
<text class="label">班级:</text>
<text class="value">{{ dk.bjmc }}</text>
</view>
</view>
</view>
</view>
<view class="add-dk-section">
<u-button
text="添加代课安排"
type="primary"
@click="showDkSelector"
class="add-btn"
/> />
</view> </view>
</view>
<!-- 代课信息 -->
<view v-show="curTabIndex === 1" class="px-15">
<JsQjDkEdit :data="qjData" ref="dkRef" />
</view> </view>
<!-- 提交按钮 --> <!-- 审批流程 -->
<view class="submit-section"> <view v-show="curTabIndex === 2">
<u-button <ProgressList :qjId="qjId" />
text="提交协调结果"
type="primary"
@click="handleSubmit"
class="submit-btn"
/>
</view> </view>
</view> </view>
<template #bottom>
<!-- 代课教师选择弹窗 --> <view class="white-bg-color py-5">
<u-popup <view class="flex-row items-center pb-10 pt-5">
:show="showSelector" <u-button text="取消" class="ml-15 mr-7" :plain="true" @click="navigateBack" />
mode="bottom" <u-button text="提交" class="mr-15 mr-7" type="primary" @click="submit" />
height="70%"
@close="closeSelector"
>
<view class="selector-container">
<view class="selector-header">
<text class="selector-title">选择代课教师</text>
<u-button text="确定" type="primary" @click="confirmSelection" />
</view>
<view class="selector-content">
<u-checkbox-group v-model="selectedDkIds">
<view
v-for="dk in availableDkList"
:key="dk.id"
class="dk-option"
>
<u-checkbox
:value="dk.id"
:label="`${dk.jsName} - ${dk.kcmc} - ${dk.bjmc}`"
/>
</view>
</u-checkbox-group>
</view> </view>
</view> </view>
</u-popup> </template>
</BasicLayout> </BasicLayout>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { jsQjJwcXtApi } from "@/api/base/jsQjApi";
import { findQjById, getPkkbByJsRangeTimeApi } from "@/api/base/jsQjApi";
import { useUserStore } from "@/store/modules/user";
import { navigateBack } from "@/utils/uniapp";
import { onLoad } from "@dcloudio/uni-app"; import { onLoad } from "@dcloudio/uni-app";
import { navigateBack } from "@/utils/uniapp";
import { jsQjJwcXtApi } from "@/api/base/jsQjApi";
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
import { ref } from "vue"; import { ref } from "vue";
import JsQjDetailInfo from "./components/jsQjDetailInfo.vue";
import JsQjDkEdit from "./components/jsQjDkEdit.vue";
import ProgressList from "./components/progressList.vue";
import { QjPageUtils } from "@/utils/qjPageUtils";
const { getJs } = useUserStore(); const { getJs } = useUserStore();
const { setData, getData } = useDataStore();
const qjId = ref<string>(); const tabList = ref<any>([
const qjData = ref<any>({}); { name: "请假信息", id: "tab-qj" },
const dkList = ref<any[]>([]); { name: "代课信息", id: "tab-dk" },
const availableDkList = ref<any[]>([]); { name: "审批流程", id: "tab-sp" }
const selectedDkIds = ref<string[]>([]); ]);
const showSelector = ref(false); const curTabIndex = ref(1);
// const dbFlag = ref(false);
const loadQjData = async () => { const qjId = ref('');
try {
const result = await findQjById({ id: qjId.value }); const qjData = computed(() => getData);
if (result.code === 1) { const dkRef = ref<any>(null);
qjData.value = result.data;
// // Tab
await loadAvailableDkList(); const switchTab = (index: number) => {
curTabIndex.value = index;
};
const updateDk = () => {
nextTick(() => {
if (dkRef.value) {
dkRef.value.getPkkbList();
} }
} catch (error) {
console.error('获取请假信息失败:', error);
}
};
//
const loadAvailableDkList = async () => {
try {
const params = {
jsId: qjData.value.jsId,
startTime: qjData.value.qjkstime,
endTime: qjData.value.qjjstime
};
const result = await getPkkbByJsRangeTimeApi(params);
if (result.code === 1) {
availableDkList.value = result.data || [];
}
} catch (error) {
console.error('获取可用代课安排失败:', error);
}
};
//
const showDkSelector = () => {
selectedDkIds.value = [];
showSelector.value = true;
};
//
const closeSelector = () => {
showSelector.value = false;
selectedDkIds.value = [];
};
//
const confirmSelection = () => {
const selectedDks = availableDkList.value.filter(dk =>
selectedDkIds.value.includes(dk.id)
);
//
selectedDks.forEach(dk => {
const dkItem = {
jsId: dk.jsId,
jsName: dk.jsName,
dktime: dk.dktime,
kcmc: dk.kcmc,
bjmc: dk.bjmc,
pkkbId: dk.id
};
dkList.value.push(dkItem);
}); });
closeSelector();
}; };
// const handleQjDataLoaded = (data: any) => {
const removeDk = (index: number) => { setData(data);
dkList.value.splice(index, 1); updateDk();
}; };
// const handleDkListLoaded = (list: any[]) => {
const handleSubmit = async () => { // JsQjDetail
if (dkList.value.length === 0) { };
uni.showToast({
title: "请至少添加一个代课安排",
icon: "none"
});
return;
}
const submit = async () => {
const params = { const params = {
qjId: qjId.value, qjId: qjId.value,
jsId: getJs.id, jsId: getJs.id,
dkList: dkList.value dkList: [],
}; };
const flag = await dkRef.value.validate();
if (!flag) {
uni.showToast({
title: "请选择代课教师",
icon: "none",
});
return;
}
let dkList = dkRef.value.getDkList() || [];
if (dkList.length) {
params.dkList = dkList.map((item: any) => {
const newItem = { ...item };
newItem.jsId = item.dkJsId;
newItem.jsName = item.dkJsName;
newItem.pkkbId = item.id;
newItem.dktime = item.dktime + " 00:00:00";
newItem.id = "";
newItem.qjId = "";
return newItem;
});
}
uni.showLoading({ title: "提交中..." }); uni.showLoading({ title: "提交中..." });
try {
await jsQjJwcXtApi(params); await jsQjJwcXtApi(params);
uni.showToast({ title: "协调成功", icon: "success" });
navigateBack();
} catch (error) {
uni.showToast({ title: "协调失败", icon: "error" });
}
uni.hideLoading(); uni.hideLoading();
setTimeout(() => {
uni.reLaunch({ url: '/pages/base/message/index' });
}, 1000);
}; };
onLoad((options) => { onLoad(async (data?: any) => {
if (options.qjId) { const ret = await QjPageUtils.init(data);
qjId.value = options.qjId; if (!ret || !ret.success) {
loadQjData(); return;
} }
qjId.value = ret.qjId;
dbFlag.value = ret.dbFlag;
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.info-card, .qj-detail {
.dk-arrange-card { background-color: #f5f7fa;
background: white;
border-radius: 8px;
margin-bottom: 15px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
} }
.info-card {
margin: 15px;
background-color: #fff;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
.card-header { .card-header {
padding: 15px; font-size: 16px;
border-bottom: 1px solid #eee; font-weight: bold;
color: #333;
margin-bottom: 10px;
.applicant-name, .applicant-name {
.card-title {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
color: #333; color: #333;
} }
} }
.card-content { .divider {
height: 1px;
background-color: #eee;
margin-bottom: 15px;
}
.card-body {
padding: 15px; padding: 15px;
} }
.info-row {
display: flex;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
.label {
width: 80px;
font-size: 14px;
color: #666;
flex-shrink: 0;
}
.value {
flex: 1;
font-size: 14px;
color: #333;
}
}
.dk-list {
.dk-item {
border: 1px solid #eee;
border-radius: 6px;
margin-bottom: 10px;
.dk-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background-color: #f5f5f5;
border-bottom: 1px solid #eee;
.dk-title {
font-size: 14px;
font-weight: bold;
color: #333;
}
}
.dk-content {
padding: 10px;
}
}
}
.add-dk-section {
margin-top: 15px;
text-align: center;
.add-btn {
width: 100%;
}
}
.submit-section {
margin-top: 20px;
.submit-btn {
width: 100%;
}
}
.selector-container {
height: 100%;
display: flex;
flex-direction: column;
.selector-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
border-bottom: 1px solid #eee;
.selector-title {
font-size: 16px;
font-weight: bold;
}
}
.selector-content {
flex: 1;
padding: 15px;
overflow-y: auto;
.dk-option {
padding: 10px 0;
border-bottom: 1px solid #f0f0f0;
}
}
} }
</style> </style>

View File

@ -23,8 +23,11 @@
</view> </view>
<!-- 代课信息 --> <!-- 代课信息 -->
<view v-show="showDkTab && curTabIndex === 1"> <view v-show="curTabIndex === 1">
<JsQjDetailDk <view v-if="!showDkFlag" class="empty-dk">
<view>{{ showDkEmptyLabel }}</view>
</view>
<JsQjDetailDk v-else
:qjId="qjId" :qjId="qjId"
@loadDkList="handleDkListLoaded" @loadDkList="handleDkListLoaded"
/> />
@ -56,21 +59,26 @@ import { navigateBack } from "@/utils/uniapp";
import { jsQjSpApi } from "@/api/base/jsQjApi"; import { jsQjSpApi } from "@/api/base/jsQjApi";
import { useUserStore } from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data"; import { useDataStore } from "@/store/modules/data";
import { ref, computed } from "vue"; import { ref } from "vue";
import { xxtsFindByIdApi } from "@/api/base/server";
import JsQjDetailInfo from "./components/jsQjDetailInfo.vue"; import JsQjDetailInfo from "./components/jsQjDetailInfo.vue";
import JsQjDetailDk from "./components/jsQjDetailDk.vue"; import JsQjDetailDk from "./components/jsQjDetailDk.vue";
import ProgressList from "./components/progressList.vue"; import ProgressList from "./components/progressList.vue";
import { QjPageUtils } from "@/utils/qjPageUtils";
const { getJs, loginByOpenId } = useUserStore(); const { getJs } = useUserStore();
const { getData, setXxts, setData, getXxts } = useDataStore(); const { setData } = useDataStore();
const tabList = ref<any>([{ name: "请假信息", id: "tab-qj" }]); const tabList = ref<any>([
{ name: "请假信息", id: "tab-qj" },
{ name: "代课信息", id: "tab-dk" },
{ name: "审批流程", id: "tab-sp" }
]);
const curTabIndex = ref(0); const curTabIndex = ref(0);
const dbFlag = ref(false); const dbFlag = ref(false);
const qjId = ref(''); const qjId = ref('');
const showDkTab = ref(false); const showDkFlag = ref(false);
const showDkEmptyLabel = ref('');
const [register, { getValue }] = useForm({ const [register, { getValue }] = useForm({
schema: [ schema: [
@ -90,7 +98,7 @@ const [register, { getValue }] = useForm({
}, },
}, },
{ {
field: "spYj", field: "spRemark",
label: "审批说明", label: "审批说明",
component: "BasicInput", component: "BasicInput",
required: true, required: true,
@ -105,18 +113,6 @@ const [register, { getValue }] = useForm({
], ],
}); });
// Tab
const rebuildTabList = (showDk: boolean) => {
// Tab
tabList.value = [
{ name: "请假信息", id: "tab-qj" },
];
if (showDk) {
tabList.value.push({ name: "代课信息", id: "tab-dk" });
}
tabList.value.push({ name: "审批流程", id: "tab-sp" });
};
// Tab // Tab
const switchTab = (index: number) => { const switchTab = (index: number) => {
curTabIndex.value = index; curTabIndex.value = index;
@ -124,8 +120,14 @@ const switchTab = (index: number) => {
const handleQjDataLoaded = (data: any) => { const handleQjDataLoaded = (data: any) => {
setData(data); setData(data);
showDkTab.value = !!(data && data.dkfs != 2); data = data || {};
rebuildTabList(showDkTab.value); const dkfs = typeof(data.dkfs) === "string" ? parseInt(data.dkfs) : (data.dkfs || 2);
showDkFlag.value = dkfs === 0;
if (dkfs === 1) {
showDkEmptyLabel.value = "审批同意后由教科处协调";
} else if (dkfs === 2) {
showDkEmptyLabel.value = "无需代课";
}
}; };
const handleDkListLoaded = (list: any[]) => { const handleDkListLoaded = (list: any[]) => {
@ -135,7 +137,7 @@ const handleDkListLoaded = (list: any[]) => {
const submit = async () => { const submit = async () => {
try { try {
const formData = await getValue(); const formData = await getValue();
if (!formData.spStatus || !formData.spYj) { if (!formData.spStatus || !formData.spRemark) {
uni.showToast({ uni.showToast({
title: '请填写完整的审批信息', title: '请填写完整的审批信息',
icon: 'none' icon: 'none'
@ -147,7 +149,7 @@ const submit = async () => {
qjId: qjId.value, qjId: qjId.value,
jsId: getJs.id, jsId: getJs.id,
spStatus: formData.spStatus, spStatus: formData.spStatus,
spYj: formData.spYj, spRemark: formData.spRemark,
}; };
uni.showLoading({ uni.showLoading({
@ -161,11 +163,9 @@ const submit = async () => {
title: '审批提交成功', title: '审批提交成功',
icon: 'success' icon: 'success'
}); });
setTimeout(() => { setTimeout(() => {
navigateBack(); uni.reLaunch({ url: '/pages/base/message/index' });
}, 1500); }, 1000);
} catch (error) { } catch (error) {
uni.hideLoading(); uni.hideLoading();
uni.showToast({ uni.showToast({
@ -177,50 +177,12 @@ const submit = async () => {
}; };
onLoad(async (data?: any) => { onLoad(async (data?: any) => {
// const ret = await QjPageUtils.init(data);
console.log(data); if (!ret || !ret.success) {
if (data && data.from && data.from == "db") {
dbFlag.value = true;
//
const isLoggedIn = await loginByOpenId(data.openId);
if (!isLoggedIn) {
console.log("用户未登录,跳过处理");
return; return;
} }
qjId.value = ret.qjId;
try { dbFlag.value = ret.dbFlag;
// urlidXxts
const xxtsRes = await xxtsFindByIdApi({ id: data.id });
if (xxtsRes && xxtsRes.result) {
const xxts = xxtsRes.result;
//
if (xxts.dbZt === "B") {
setData({ id: xxts.xxzbId });
let url = "/pages/view/hr/jsQj/detail";
uni.navigateTo({ url });
return;
}
setXxts(xxts);
qjId.value = xxts.xxzbId;
}
} catch (error) {
console.error("获取待办信息失败", error);
// Xxts退
const xxtsData = getXxts;
if (xxtsData && xxtsData.dbZt === "B") {
setData({ id: data.id });
let url = "/pages/view/hr/jsQj/detail";
uni.navigateTo({ url });
return;
}
qjId.value = data.id;
}
} else {
dbFlag.value = false;
//
qjId.value = getData.id || '';
}
}); });
</script> </script>
@ -229,34 +191,12 @@ onLoad(async (data?: any) => {
background-color: #f5f7fa; background-color: #f5f7fa;
} }
.info-card { .empty-dk {
margin: 15px; margin: 15px;
background-color: #fff; background-color: #fff;
border-radius: 8px; border-radius: 8px;
padding: 15px; padding: 50px 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
text-align: center;
.card-header {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
.applicant-name {
font-size: 16px;
font-weight: bold;
color: #333;
}
}
.divider {
height: 1px;
background-color: #eee;
margin-bottom: 15px;
}
.card-body {
padding: 15px;
}
} }
</style> </style>

View File

@ -147,7 +147,7 @@ const mediaData = ref({
photoList: [], photoList: [],
videoList: [] videoList: []
}); });
const dmPsRef = ref(null); const dmPsRef = ref<any>(null);
const now = dayjs(); const now = dayjs();
let wDay = now.day(); let wDay = now.day();

View File

@ -240,6 +240,8 @@ const goDm = (xkkc: any) => {
} else { } else {
msg = "上课时间未到,无法点名"; msg = "上课时间未到,无法点名";
} }
// TODO:
dmFlag = true;
if (dmFlag) { if (dmFlag) {
setData(xkkc); setData(xkkc);
uni.navigateTo({ uni.navigateTo({

64
src/utils/qjPageUtils.ts Normal file
View File

@ -0,0 +1,64 @@
import { xxtsFindByIdApi } from "@/api/base/server";
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
const { loginByOpenId } = useUserStore();
const { getData, setXxts, setData, getXxts } = useDataStore();
export const QjPageUtils = {
async init(data?: any) {
let ret = {
success: true,
dbFlag: false,
qjId: getData.id,
};
if (!data || !data.from || data.from != "db") {
return ret;
}
// 从待办过来的,需要从后端获取数据
ret.dbFlag = true;
// 检查登录状态
const isLoggedIn = await loginByOpenId(data.openId);
if (!isLoggedIn) {
console.log("用户未登录,跳过处理");
ret.success = false;
return ret;
}
let url = "/pages/base/message/index";
try {
// 优先从后端根据url中的id去查询Xxts
const xxtsRes = await xxtsFindByIdApi({ id: data.id });
if (xxtsRes && xxtsRes.result) {
const xxts = xxtsRes.result;
// 检查待办状态
if (xxts.dbZt === "B") {
setData({ id: xxts.xxzbId });
url = "/pages/view/hr/jsQj/detail";
uni.reLaunch({ url });
ret.success = false;
} else {
setXxts(xxts);
ret.qjId = xxts.xxzbId;
}
} else {
uni.showToast({
title: "获取消息推送数据失败",
icon: "error",
});
uni.reLaunch({ url });
ret.success = false;
}
return ret;
} catch (error) {
console.error("获取待办信息失败", error);
// 如果获取Xxts失败回退到原来的逻辑
const xxtsData = getXxts;
if (xxtsData && xxtsData.dbZt === "B") {
setData({ id: data.id });
uni.reLaunch({ url });
ret.success = false;
return ret;
}
}
}
}