zhxy-jsd/src/pages/base/groupTeaching_bak/studentRollCall.vue

411 lines
9.1 KiB
Vue
Raw Normal View History

2025-06-20 09:51:43 +08:00
<template>
<BasicLayout>
<!-- 课程信息卡片 -->
<view class="course-card mx-15 my-15 bg-white white-bg-color r-md p-15">
<view class="flex-row items-center mb-15">
<view class="course-icon flex-center mr-10">
<u-icon name="calendar" color="#4080ff" size="20"></u-icon>
</view>
<text class="font-16 font-bold">机器人创客</text>
<text class="font-14 cor-999 ml-auto">2024-12-25 (周三)</text>
</view>
<!-- 考勤统计 -->
<view class="attendance-stats flex-row">
<view class="stat-item flex-col items-center">
<text class="font-18 font-bold">18</text>
<text class="font-12 cor-666 mt-3">应到</text>
</view>
<view class="stat-item flex-col items-center">
<text class="font-18 font-bold cor-primary">18</text>
<text class="font-12 cor-666 mt-3">实到</text>
</view>
<view class="stat-item flex-col items-center">
<text class="font-18 font-bold cor-warning">0</text>
<text class="font-12 cor-666 mt-3">请假</text>
</view>
<view class="stat-item flex-col items-center">
<text class="font-18 font-bold cor-danger">0</text>
<text class="font-12 cor-666 mt-3">缺勤</text>
</view>
<view class="stat-circle flex-col flex-center ml-auto">
<text class="font-20 font-bold">18</text>
<text class="font-10 cor-666">总人数</text>
</view>
</view>
</view>
<!-- 学生列表 -->
<view class="student-list mb-30 white-bg-color">
<view class="student-grid">
<view
v-for="(student, index) in studentList"
:key="index"
class="student-item bg-white r-md p-12"
>
<view class="flex-row items-center">
<view class="avatar-container mr-8">
<image
class="student-avatar"
:src="student.avatar || '/static/images/default-avatar.png'"
mode="aspectFill"
></image>
</view>
<view class="flex-1 overflow-hidden">
<view class="flex-row items-center mb-3">
<text class="font-14 font-bold mr-5 text-ellipsis">{{
student.name
}}
</text>
<view
class="status-tag"
:class="getStatusClass(student.status)"
@click="openStatusPicker(student)"
>
{{ student.status }}
<u-icon name="arrow-down" size="10"></u-icon>
</view>
</view>
<text class="font-12 cor-666">{{ student.className }}</text>
<view class="contact-parent mt-8 flex-center">
<text class="font-12 cor-primary">联系家长</text>
<u-icon
name="phone"
color="#4080ff"
size="14"
class="ml-2"
></u-icon>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 状态选择弹窗 -->
<u-picker
:show="statusPickerVisible"
:columns="[statusOptions]"
@confirm="confirmStatus"
@cancel="statusPickerVisible = false"
></u-picker>
<template #bottom>
<view class="submit-btn-wrap py-10 px-20 bg-white">
<button class="submit-btn" @click="submit">提交</button>
</view>
</template>
</BasicLayout>
</template>
<script setup lang="ts">
import {onMounted, ref} from "vue";
import BasicLayout from "@/components/BasicLayout/Layout.vue";
import { useDicStore } from "@/store/modules/dic";
const { findByPid } = useDicStore();
2025-06-20 09:51:43 +08:00
// 模拟学生数据
const studentList = ref([
{
id: 1,
name: "伍添昊",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar1.png",
},
{
id: 2,
name: "时振宇",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar2.png",
},
{
id: 3,
name: "程子璇",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar3.png",
},
{
id: 4,
name: "柘延兴",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar4.png",
},
{
id: 5,
name: "张茜溪",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar5.png",
},
{
id: 6,
name: "孟嘉乐",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar6.png",
},
{
id: 7,
name: "韩汝鑫",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar7.png",
},
{
id: 8,
name: "曹佳毅",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar8.png",
},
{
id: 9,
name: "郎甜",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar9.png",
},
{
id: 10,
name: "萧文懿",
status: "正常",
className: "三年八班",
avatar: "/static/images/avatar10.png",
},
]);
// 状态选择相关
const statusPickerVisible = ref(false);
const statusOptions = ref<Array<{ text: string, value: string }>>([]);
const currentStudent = ref<any>(null);
// 获取状态对应的样式类
const getStatusClass = (status: string) => {
switch (status) {
case "正常":
return "status-normal";
case "请假":
return "status-leave";
case "缺勤":
return "status-absent";
default:
return "status-normal";
}
};
// 获取学生状态选项
const fetchStatusOptions = async () => {
try {
// 假设字典表中出勤状态的pid为810984651根据实际情况修改
const res = await findByPid({pid: 810984651});
2025-06-20 09:51:43 +08:00
if (res && res.result) {
statusOptions.value = res.result.map((item: any) => {
return {
text: item.dictionaryValue,
value: item.dictionaryCode
};
});
}
} catch (error) {
console.error("获取状态选项失败", error);
// 使用默认状态
statusOptions.value = [
{text: "正常", value: "1"},
{text: "请假", value: "2"},
{text: "缺勤", value: "3"}
];
}
};
// 打开状态选择器
const openStatusPicker = (student: any) => {
currentStudent.value = student;
statusPickerVisible.value = true;
};
// 确认选择状态
const confirmStatus = (e: any) => {
if (currentStudent.value && e.value && e.value[0]) {
const selectedStatus = statusOptions.value.find(
(option: any) => option.value === e.value[0]
);
if (selectedStatus) {
// 更新当前学生状态
currentStudent.value.status = selectedStatus.text;
}
}
statusPickerVisible.value = false;
};
// 导航相关方法
const navigateBack = () => {
uni.navigateBack();
};
const toRollCallRecord = () => {
uni.navigateTo({
url: "/pages/base/groupTeaching/rollCallRecord",
});
};
// 联系家长
const contactParent = (student: any) => {
console.log("联系家长", student.name);
};
// 提交数据
const submit = () => {
uni.showToast({
title: "提交成功",
icon: "success",
});
};
// 页面加载时获取状态选项
onMounted(() => {
fetchStatusOptions();
});
</script>
<style scoped lang="scss">
.container {
min-height: 100vh;
background-color: #f5f5f5;
}
.header {
height: 44px;
background-color: #fff;
}
.course-card {
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.course-icon {
width: 30px;
height: 30px;
border-radius: 4px;
background-color: rgba(64, 128, 255, 0.1);
}
.attendance-stats {
padding: 10px 0;
}
.stat-item {
flex: 1;
}
.stat-circle {
width: 60px;
height: 60px;
border-radius: 50%;
}
.student-list {
padding: 0 15px;
}
.student-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
}
.student-item {
position: relative;
}
.avatar-container {
width: 46px;
height: 46px;
border-radius: 50%;
padding: 3px;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.student-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #f5f5f5;
}
.status-tag {
font-size: 10px;
padding: 1px 5px;
border-radius: 4px;
display: flex;
align-items: center;
cursor: pointer;
}
.status-normal {
color: #4080ff;
}
.status-leave {
color: #ff9900;
}
.status-absent {
color: #ff4d4f;
}
.text-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 60px;
}
.contact-parent {
padding: 3px 8px;
border-radius: 4px;
border: 1px solid #4080ff;
display: inline-flex;
}
.submit-btn {
background-color: #4080ff;
color: #fff;
height: 44px;
border-radius: 22px;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.cor-primary {
color: #4080ff;
}
.cor-warning {
color: #ff9900;
}
.cor-danger {
color: #ff4d4f;
}
.cor-666 {
color: #666;
}
.cor-999 {
color: #999;
}
</style>