2025-08-20 21:26:47 +08:00

349 lines
8.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="back-f8f8f8">
<view class="flex-row items-center justify-between py-15 global-bg-color">
<view class="dk-title">
<BasicTitle line title="代课明细" :isBorder="false" />
</view>
<view @click="getPkkbList">
<BasicIcon type="refreshempty" size="25" />
</view>
</view>
<view class="dk-tabs mb-10" v-if="dkList && dkList.length">
<BasicTabs
class="type-tabs"
ref="tabsRef"
:list="tabList"
bar-width="60px"
scroll-count="4"
:current="curTabIndex"
@change="switchTab"
/>
<view class="dk-card" v-if="curTabIndex === 0">
<view class="card-body">
<view class="info-row">
<text class="label">代课老师:</text>
<view class="value">
<JsPicker
@change="changeJsByTy"
:parent-data="tyDk"
:defualtValue="tyDk.dkJsId"
:multiple="false"
:excludeIds="excludeIds"
/>
</view>
</view>
</view>
</view>
<view v-if="curTabIndex === 1">
<view v-for="(item, index) in kmDkList" :key="index">
<view class="dk-card" style="margin: 0">
<view class="card-body">
<view class="info-row">
<text class="label">排课名称:</text>
<text class="value">{{ item.pkMc }}</text>
</view>
<view class="info-row">
<text class="label">代课老师:</text>
<view class="value">
<JsPicker
@change="changeJsByKm"
:parent-data="item"
:defualtValue="item.dkJsId"
:multiple="false"
:excludeIds="excludeIds"
/>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-if="dkList.length > 0">
<view v-for="(item, index) in dkList" :key="index">
<view class="dk-card">
<view class="card-header">
<text class="applicant-name"
>{{ item.dktime }}{{ wdNameList[item.xq - 1] }}{{
item.jcmc
}}</text
>
</view>
<view class="card-body">
<view class="info-row">
<text class="label">排课名称:</text>
<text class="value">{{ item.pkMc }}</text>
</view>
<view class="info-row">
<text class="label">上课时间:</text>
<text class="value">{{ item.startTime }}-{{ item.endTime }}</text>
</view>
<view class="info-row">
<text class="label">代课老师:</text>
<view class="value" v-if="curTabIndex === 2">
<JsPicker
@change="changeJs"
:parent-data="item"
:defualtValue="item.dkJsId"
:multiple="false"
:excludeIds="excludeIds"
/>
</view>
<view v-else>{{ item.dkJsName }}</view>
</view>
</view>
</view>
</view>
</view>
<view v-else class="p-15 flex-row-center color-9 font-13 white-bg-color"
>暂无数据</view
>
</view>
</template>
<script setup lang="ts">
import { getPkkbByJsRangeTimeApi } from "@/api/base/jsQjApi";
import JsPicker from "@/pages/components/JsPicker/index.vue";
import { useUserStore } from "@/store/modules/user";
const { getJs } = useUserStore();
// 接收外部传入属性
const props = withDefaults(
defineProps<{
data: any;
}>(),
{
data: () => ({
jsId: "",
qjkstime: "", // 请假开始时间
qjjstime: "", // 请假结束时间
}),
}
);
const wdNameList = ref<string[]>([
"周一",
"周二",
"周三",
"周四",
"周五",
"周六",
"周日",
]);
const jsTypeMc: any = {
ZAM: "早自习",
AM: "上午",
PM: "下午",
};
// 代课教师要排除自己
const excludeIds = ref<any>([]);
if (props.data && props.data.jsId && props.data.jsId.length) {
excludeIds.value.push(props.data.jsId);
} else {
excludeIds.value.push(getJs.id);
}
const tyDk = ref<any>({});
const dkList = ref<any>([]);
const kmDkList = ref<any>([]);
const tabList = ref([
{ name: "统一设置", id: "tab-ty" },
{ name: "按排课设置", id: "tab-pk" },
{ name: "按节次设置", id: "tab-jc" },
]);
const curTabIndex = ref(0);
const switchTab = (index: number) => {
curTabIndex.value = index;
};
const getPkkbList = async () => {
const res = await getPkkbByJsRangeTimeApi({
jsId: props.data.jsId,
startTime: props.data.qjkstime,
endTime: props.data.qjjstime,
});
// 记录原始选课的数据
const srcData: any = {};
dkList.value.map((item: any) => {
const key = item.dktime + item.jcType + item.jc;
srcData[key] = {
dkJsId: item.dkJsId,
dkJsName: item.dkJsName,
};
});
const kmMap: any = {};
dkList.value = res.result.map((item: any) => {
item.dktime = item.kbtime.split(" ")[0];
item.njbjmx = item.bc + item.bjmc;
item.jcmc = jsTypeMc[item.jcType] + "第" + item.jc + "节";
const key = item.dktime + item.jcType + item.jc;
const src = srcData[key];
if (src) {
item.dkJsId = src.dkJsId;
item.dkJsName = src.dkJsName;
} else {
item.dkJsId = "";
item.dkJsName = "";
}
kmMap[item.pkId] = kmMap[item.pkId] || {
pkMc: item.pkMc,
pkId: item.pkId,
};
return item;
});
// 将kmMap转换成value对应的数组
kmDkList.value = Object.values(kmMap);
};
const changeJsByTy = (selected: any, item: any) => {
item.dkJsId = selected.value;
item.dkJsName = selected.label;
const newList = dkList.value.map((dk: any) => {
return {
...dk,
dkJsId: item.dkJsId,
dkJsName: item.dkJsName,
};
});
dkList.value = newList;
const newKmList = kmDkList.value.map((km: any) => {
return {
...km,
dkJsId: item.dkJsId,
dkJsName: item.dkJsName,
};
});
kmDkList.value = newKmList;
};
const changeJsByKm = (selected: any, item: any) => {
item.dkJsId = selected.value;
item.dkJsName = selected.label;
// 同时更新主列表中的数据
const newList = dkList.value.map((dk: any) => {
if (dk.pkId === item.pkId) {
return { ...dk, dkJsId: item.dkJsId, dkJsName: item.dkJsName };
}
return dk;
});
dkList.value = newList;
};
const changeJs = (selected: any, item: any) => {
item.dkJsId = selected.value;
item.dkJsName = selected.label;
};
const validate = async () => {
// 如果没有查询到代课信息,重新查询一遍,避免遗漏
if (!dkList.value || !dkList.value.length) {
await getPkkbList();
}
const list = dkList.value;
// 如果还是没有查询需要代课的数据则返回true
if (!list || !list.length) {
return true;
}
// 遍历列表,判断是否有未选择的教师
for (let i = 0; i < list.length; i++) {
const item = list[i];
if (!item.dkJsId) {
return false;
}
}
return true;
};
// 暴露接口给ref调用
const getDkList = () => {
return dkList.value;
};
// 暴露接口给外部调用
defineExpose({
getPkkbList,
validate,
getDkList,
});
</script>
<style lang="scss" scoped>
.dk-tabs {
flex: 1 0 1px;
}
.dk-card {
background-color: #ffffff;
border-radius: 8px;
margin-bottom: 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
overflow: hidden;
}
.card-header {
padding: 12px 15px;
border-bottom: 1px solid #f0f0f0;
.applicant-name {
font-size: 16px;
font-weight: bold;
color: #333;
}
}
.card-body {
padding: 15px;
.info-row {
display: flex;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
.label {
font-size: 14px;
color: #666;
width: 70px;
flex-shrink: 0;
margin-right: 8px;
}
.value {
font-size: 14px;
color: #333;
flex: 1;
display: flex;
.data {
flex: 1;
}
}
}
}
.card-footer {
padding: 12px 15px;
border-top: 1px solid #f0f0f0;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 14px;
color: #888;
cursor: pointer;
.arrow {
font-size: 16px;
color: #ccc;
}
}
</style>