Files
wechat-clock-mini/pages/plan/plan.wxss
王宏豪 cd04c1b5ef feat(database): 迁移用户关联字段并优化打卡系统
- 修改数据库配置将MYSQL_DB从mys_info_v3改为mys_info_test
- 新增auth_users表wechat_openid字段并建立唯一索引
- 为plan_checkins表添加计划性能索引(idx_plan_period_student)
- 将checkin_records_old表关联方式从student_id改为user_id
- 将plan_checkins表关联方式从student_id改为user_id并更新附件路径
- 移除routes/auth.py中的uuid导入使用安全token生成函数
- 重构routes/checkin.py打卡逻辑去除course_type字段并优化返回结构
- 添加打卡时间限制验证功能防止过期打卡操作
- 实现小组统计功能支持老师查看各组打卡情况
- 更新主页index.html界面适配新的打卡和计划功能
- 调整计划提交时间规则为周五至周四周期
- 添加月度和年度计划提交状态验证机制
2026-09-10 14:11:58 +08:00

249 lines
10 KiB
Plaintext
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.
.page { height: 100vh; display: flex; flex-direction: column; box-sizing: border-box; overflow: hidden; background: #F6F2EC; }
.view-root { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.type-tabs { flex-shrink: 0; display: flex; align-items: center; gap: 8rpx; margin: 24rpx 32rpx 0; padding: 8rpx; background: #EFE7DC; border-radius: 999rpx; }
.type-tab { flex: 1; text-align: center; padding: 16rpx 0; color: #8B7A6A; background: transparent; border-radius: 999rpx; font-size: 28rpx; font-weight: 600; transition: all .18s ease; }
.type-tab.active { background: #fff; color: #C67B30; font-weight: 700; box-shadow: 0 4rpx 12rpx rgba(198,123,48,0.18); }
.type-tab-hover { opacity: .85; }
.view-scroll { flex: 1; min-height: 0; padding: 8rpx 32rpx 32rpx; box-sizing: border-box; }
.overview-head { display: flex; align-items: flex-end; justify-content: space-between; padding: 24rpx 4rpx 16rpx; }
.head-title-wrap { min-width: 0; }
.head-title { font-size: 38rpx; font-weight: 800; color: #2C1810; letter-spacing: 1rpx; }
.head-sub { margin-top: 6rpx; font-size: 24rpx; color: #A99A89; }
.head-pill { flex-shrink: 0; padding: 8rpx 20rpx; border-radius: 999rpx; font-size: 22rpx; background: #fff; color: #C67B30; box-shadow: 0 2rpx 8rpx rgba(44,24,16,0.06); }
.detail-head { display: flex; align-items: center; gap: 16rpx; padding: 28rpx 4rpx 8rpx; }
.detail-title-wrap { min-width: 0; }
.back { color: #C67B30; font-size: 30rpx; flex-shrink: 0; padding: 10rpx 16rpx 10rpx 0; border-radius: 12rpx; font-weight: 600; }
.back-hover { opacity: .7; }
.my-status { display: flex; align-items: center; gap: 18rpx; padding: 24rpx; margin-bottom: 20rpx; border-radius: 20rpx; background: #fff; box-shadow: 0 6rpx 20rpx rgba(44,24,16,0.05); }
.my-status.checked { border-left: 8rpx solid #2E7D32; }
.my-status.unchecked { border-left: 8rpx solid #C0392B; }
.my-state-icon { width: 64rpx; height: 64rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 30rpx; font-weight: 800; flex-shrink: 0; }
.my-state-icon.done { background: linear-gradient(135deg, #2E7D32, #43A047); color: #fff; box-shadow: 0 4rpx 12rpx rgba(46,125,50,0.25); }
.my-state-icon.todo { background: linear-gradient(135deg, #C0392B, #E5736C); color: #fff; box-shadow: 0 4rpx 12rpx rgba(192,57,43,0.22); }
.my-status-left { flex: 1; min-width: 0; }
.my-status-label { font-size: 24rpx; color: #8B7A6A; }
.my-status-text { font-size: 32rpx; font-weight: 800; color: #2C1810; margin-top: 6rpx; }
.btn-mystatus { width: 208rpx; margin: 0; flex-shrink: 0; background: linear-gradient(135deg, #C67B30, #E4A05E); color: #fff; border-radius: 999rpx; font-size: 28rpx; font-weight: 700; box-shadow: 0 6rpx 14rpx rgba(198,123,48,0.3); }
.btn-mystatus.outline { background: #fff; color: #C67B30; border: 2rpx solid #C67B30; box-shadow: none; }
.btn-mystatus[disabled] { background: #D8C7B4; color: #fff; border: none; box-shadow: none; }
.btn-hover { opacity: .9; transform: scale(.98); }
.window-msg { margin: 0 8rpx 20rpx; padding: 14rpx 22rpx; background: #FFF3E6; border-radius: 14rpx; text-align: center; color: #C0392B; font-size: 24rpx; border: 1rpx solid #F7D9B9; }
.my-plan { margin-bottom: 20rpx; padding: 24rpx; border-radius: 20rpx; background: #fff; box-shadow: 0 6rpx 20rpx rgba(44,24,16,0.05); }
.my-plan-head { display: flex; align-items: center; justify-content: space-between; }
.my-plan-title { font-size: 26rpx; font-weight: 700; color: #6B5D50; }
.my-plan-status { padding: 6rpx 16rpx; border-radius: 999rpx; font-size: 22rpx; font-weight: 700; background: #E8F4EB; color: #2E7D32; }
.my-plan-status.pending { background: #FFF3E6; color: #C67B30; }
.my-plan-meta { margin-top: 8rpx; font-size: 22rpx; color: #A99A89; }
.my-plan-content { margin-top: 14rpx; padding: 16rpx 20rpx; background: #FBF7F1; border-radius: 14rpx; font-size: 28rpx; line-height: 1.7; color: #2C1810; white-space: pre-wrap; word-break: break-all; }
.my-plan-thumbs { display: flex; flex-wrap: wrap; gap: 14rpx; margin-top: 16rpx; }
.my-plan-thumb { width: 148rpx; height: 148rpx; border-radius: 14rpx; background: #F2EDE7; box-shadow: 0 2rpx 6rpx rgba(44,24,16,0.08); }
.group-card { background: #fff; border-radius: 20rpx; padding: 22rpx 24rpx; margin-bottom: 18rpx; box-shadow: 0 6rpx 20rpx rgba(44,24,16,0.05); }
.group-card-hover { transform: scale(.99); box-shadow: 0 10rpx 24rpx rgba(44,24,16,0.10); }
.group-row { display: flex; align-items: center; gap: 16rpx; }
.group-avatar { width: 52rpx; height: 52rpx; border-radius: 14rpx; background: linear-gradient(135deg, #F3E3CF, #FBE7D1); color: #C67B30; font-size: 26rpx; font-weight: 800; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.group-name { font-size: 30rpx; font-weight: 800; color: #2C1810; flex-shrink: 0; }
.chevron { color: #CDBFAE; font-size: 32rpx; line-height: 1; flex-shrink: 0; transition: transform .15s ease; }
.group-card-hover .chevron { transform: translateX(4rpx); }
.group-counts { display: flex; align-items: center; justify-content: flex-end; gap: 10rpx; flex: 1; min-width: 0; }
.count { font-size: 22rpx; white-space: nowrap; }
.count.done { color: #2E7D32; background: #E8F4EB; padding: 6rpx 12rpx; border-radius: 999rpx; font-weight: 700; }
.count.total { color: #C67B30; background: #FFF3E6; padding: 6rpx 12rpx; border-radius: 999rpx; font-weight: 700; }
.progress-track { height: 10rpx; border-radius: 999rpx; background: #F2EDE7; margin-top: 18rpx; overflow: hidden; }
.progress-bar { height: 100%; border-radius: 999rpx; background: linear-gradient(90deg, #C67B30, #EFA45D); transition: width .35s ease; box-shadow: 0 2rpx 6rpx rgba(198,123,48,0.35); }
.unassigned { margin: 4rpx 8rpx 20rpx; font-size: 24rpx; color: #8B7A6A; }
.member-list { background: #fff; border-radius: 20rpx; padding: 8rpx 24rpx; box-shadow: 0 6rpx 20rpx rgba(44,24,16,0.05); }
.member-left { display: flex; align-items: center; min-width: 0; }
.member { display: flex; align-items: center; justify-content: space-between; padding: 22rpx 0; border-bottom: 1rpx solid #F2EDE7; }
.member:last-child { border-bottom: none; }
.member-avatar { width: 64rpx; height: 64rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 26rpx; font-weight: 800; flex-shrink: 0; }
.member-avatar.done { background: linear-gradient(135deg, #E8F4EB, #CFEAD5); color: #2E7D32; }
.member-avatar.unchecked { background: linear-gradient(135deg, #FDECEA, #F9D9D5); color: #C0392B; }
.member-info { margin-left: 18rpx; min-width: 0; }
.member-name { font-size: 28rpx; font-weight: 700; color: #2C1810; }
.member-meta { margin-top: 6rpx; font-size: 22rpx; color: #A99A89; }
.badge { flex-shrink: 0; padding: 8rpx 18rpx; border-radius: 999rpx; font-size: 22rpx; font-weight: 700; }
.badge.done { background: #E8F4EB; color: #2E7D32; }
.badge.unchecked { background: #FDECEA; color: #C0392B; }
.state-block { padding: 64rpx 0; text-align: center; color: #A99A89; font-size: 26rpx; }
.state-icon { font-size: 40rpx; margin-bottom: 12rpx; color: #D8C7B4; animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 0%,100%{opacity:.4} 50%{opacity:1} }
.empty { padding: 64rpx 0; text-align: center; color: #A99A89; font-size: 26rpx; }
/* 小组标题 */
.section-title { padding: 8rpx 4rpx 16rpx; font-size: 28rpx; font-weight: 700; color: #6B5D50; }
/* 学员小组 tab:周期选择行 */
.group-period-row {
display: flex;
align-items: center;
padding: 12rpx 8rpx;
font-size: 28rpx;
font-weight: 700;
color: #C67B30;
}
.group-period-text {
flex: 1;
}
/* 学员单小组卡片 */
.student-group { margin-bottom: 20rpx; }
/* 学员 tab 切换 */
.student-tabs {
display: flex;
border-bottom: 1rpx solid #EEE;
margin: 8rpx 0 8rpx;
}
.student-tab {
flex: 1;
text-align: center;
padding: 22rpx 0;
color: #7A6A5C;
transition: color .15s ease;
font-size: 28rpx;
}
.student-tab.active {
color: #C67B30;
font-weight: 700;
border-bottom: 4rpx solid #C67B30;
transform: translateY(-2rpx);
}
.tab-hover {
background: #f6efe6;
}
.student-group-panel {
padding: 4rpx 0 24rpx;
}
.student-history-panel {
padding: 16rpx 0 24rpx;
}
/* 历史记录卡片 */
.history-card {
background: #fff;
border-radius: 20rpx;
padding: 24rpx;
margin-bottom: 18rpx;
box-shadow: 0 6rpx 20rpx rgba(44, 24, 16, 0.05);
}
.history-head {
display: flex;
align-items: center;
justify-content: space-between;
}
.history-period {
font-size: 30rpx;
font-weight: 700;
color: #2C1810;
}
.history-status {
padding: 6rpx 16rpx;
border-radius: 999rpx;
font-size: 22rpx;
font-weight: 700;
}
.history-meta {
margin-top: 8rpx;
font-size: 22rpx;
color: #A99A89;
}
.history-content {
margin-top: 14rpx;
padding: 16rpx 20rpx;
background: #FBF7F1;
border-radius: 14rpx;
font-size: 26rpx;
line-height: 1.7;
color: #2C1810;
white-space: pre-wrap;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}
.history-thumbs {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
margin-top: 14rpx;
}
.history-thumb {
width: 120rpx;
height: 120rpx;
border-radius: 12rpx;
background: #F2EDE7;
}
/* 周期选择相关 */
.head-hover { opacity: .8; }
.head-arrow { color: #C67B30; font-size: 22rpx; }
.picker-mask {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.4);
z-index: 100;
}
.picker-panel {
position: fixed;
left: 0; right: 0; bottom: 0;
background: #fff;
border-radius: 28rpx 28rpx 0 0;
z-index: 101;
max-height: 70vh;
display: flex;
flex-direction: column;
transform: translateY(100%);
transition: transform .28s ease;
}
.picker-panel.show {
transform: translateY(0);
}
.picker-title {
flex-shrink: 0;
padding: 28rpx 32rpx 20rpx;
font-size: 30rpx;
font-weight: 700;
color: #2C1810;
text-align: center;
border-bottom: 1rpx solid #F2EDE7;
}
.picker-list {
flex: 1;
min-height: 0;
padding: 8rpx 0 32rpx;
}
.picker-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
font-size: 28rpx;
color: #2C1810;
}
.picker-item:active {
background: #FBF7F1;
}
.picker-item.active {
color: #C67B30;
font-weight: 700;
}
.picker-check {
font-size: 28rpx;
color: #C67B30;
}
/* 底部留白 */
.bottom-space { height: 40rpx; }