You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
4.3 KiB

2 months ago
<template>
<view>
<!-- 文件上传输入框接受 Excel 文件 -->
<input type="file" accept=".xlsx, .xls" @change="handleFileUpload" class="file-input" />
<!-- 上传按钮 -->
<button @click="upload" class="button">上传名单</button>
<view>
<button @click="randomCall" class="button">随机点名</button>
</view>
<view class="list">
<view class="list-header">
<text class="list-left">签到学生名单</text>
<text class="list-mid">状态</text>
<text class="list-right">积分</text>
</view>
<view v-for="(student, index) in selectedStudents" :key="index" class="list-item">
<text class="item-left">{{ student.name }}</text>
<text class="item-mid">{{ student.signed ? '✔' : '' }}</text>
<text class="item-right">{{ student.points }}</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
// 存储上传的学生数据和选中的学生
const rcallData = ref([]);
const selectedStudents = ref([]);
const file = ref(null);
// 处理文件上传
const handleFileUpload = (event) => {
file.value = event.target.files[0]; // 获取上传的文件
console.log("Selected file:", file.value); // 确认文件是否正确获取
};
// 上传文件到服务器
const upload = async () => {
if (!file.value) {
console.warn("请选择一个文件进行上传");
return;
}
const formData = new FormData();
formData.append('file', file.value);
console.log("FormData:", formData.get('file')); // 检查 FormData 中的文件
try {
const response = await uni.request({
url: 'http://10.198.140.41:3000/api/upload',
method: 'POST',
header: {
'Content-Type': 'multipart/form-data'
},
data: formData
});
if (response.statusCode === 200) {
console.log('文件上传成功:', response.data);
rcallData.value = response.data; // 服务器返回学生数据
} else {
console.error('文件上传失败:', response.data);
}
} catch (error) {
console.error('上传过程中发生错误:', error);
}
};
// 随机点名的函数
const randomCall = async () => {
if (rcallData.value.length === 0) {
console.warn("没有学生数据可供点名");
return;
}
const studentCount = Math.floor(Math.random() * (30 - 20 + 1)) + 20;
const shuffledStudents = rcallData.value.sort(() => 0.5 - Math.random());
const selected = shuffledStudents.slice(0, Math.min(studentCount, rcallData.value.length));
selected.forEach(student => {
student.signed = true;
student.points += 1;
});
selectedStudents.value = selected;
await Promise.all(selected.map(student => sendAttendance(student)));
};
const sendAttendance = async (student) => {
try {
const response = await uni.request({
url: "http://10.198.140.41:3000/api/upload",
method: 'PUT',
data: {
name: student.name,
points: student.points
},
header: {
'Content-Type': 'application/json'
}
});
if (response.statusCode === 200) {
console.log('Attendance updated successfully:', response.data);
} else {
console.error('Failed to update attendance:', response.data);
}
} catch (error) {
console.error('Error occurred while updating attendance:', error);
}
};
</script>
<style scoped>
.button {
display: block;
width: 80%;
height: 60px;
margin: 10px auto;
padding: 10px;
background-color: #1E90FF;
color: white;
text-align: center;
border-radius: 5px;
}
.list {
margin: 20px;
background-color: #f9f9f9;
border-bottom: 1px solid #ccc;
padding: 10px;
}
.list-header {
display: flex;
justify-content: space-between;
}
.list-left {
flex-grow: 2;
}
.list-mid {
text-align: center;
flex-grow: 1;
}
.list-right {
padding-left: 15px;
padding-right: 8px;
}
.list-item {
display: flex;
justify-content: space-between;
padding: 5px 0;
}
.item-left {
font-size: 32rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: left;
flex: 6;
}
.item-mid {
text-align: center;
padding-left: 60px;
padding-right: 45px;
flex: 1;
}
.item-right {
text-align: center;
padding-right: 10px;
flex: 1;
}
.button-container {
display: flex;
justify-content: center;
}
</style>