Browse Source

修改 bug

master
王泽彦 8 months ago
parent
commit
e2cd720267
  1. 8
      admin/src/app/views/campus_pay/components/campus-pay-edit.vue
  2. 2
      niucloud/app/adminapi/controller/campus_pay/CampusPay.php
  3. 2
      niucloud/app/api/controller/apiController/CoachStudent.php
  4. 44
      niucloud/app/job/schedule/HandleCourseSchedule.php
  5. 7
      niucloud/app/service/admin/upload/UploadService.php
  6. 40
      niucloud/app/service/api/apiService/CoachStudentService.php
  7. 32
      niucloud/app/service/api/apiService/PersonnelService.php
  8. 78
      niucloud/test_upload.php
  9. 71
      test-student-orders-api.js
  10. 125
      uniapp/pages-coach/coach/schedule/schedule_table.vue
  11. 256
      uniapp/pages-coach/coach/student/student_list.vue

8
admin/src/app/views/campus_pay/components/campus-pay-edit.vue

@ -22,21 +22,22 @@
</el-form-item>
<el-form-item :label="t('apiclientKey')">
<upload-file v-model="formData.apiclient_key" />
<upload-file v-model="formData.apiclient_key" api="sys/document/cert"/>
</el-form-item>
<el-form-item :label="t('apiclientCert')">
<upload-file v-model="formData.apiclient_cert" />
<upload-file v-model="formData.apiclient_cert" api="sys/document/cert"/>
</el-form-item>
<el-form-item :label="t('wxPayKey')">
<upload-file v-model="formData.wx_pay_key" />
<upload-file v-model="formData.wx_pay_key" api="sys/document/cert"/>
</el-form-item>
<el-form-item :label="t('wxPayKeyId')" prop="wx_pay_key_id">
<el-input v-model="formData.wx_pay_key_id" clearable :placeholder="t('wxPayKeyIdPlaceholder')" class="input-width" />
</el-form-item>
</el-form>
<template #footer>
@ -72,6 +73,7 @@ const initialFormData = {
apiclient_cert: '',
wx_pay_key: '',
wx_pay_key_id: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })

2
niucloud/app/adminapi/controller/campus_pay/CampusPay.php

@ -58,7 +58,6 @@ class CampusPay extends BaseAdminController
["wx_pay_key_id",""],
]);
$this->validate($data, 'app\validate\campus_pay\CampusPay.add');
$id = (new CampusPayService())->add($data);
return success('ADD_SUCCESS', ['id' => $id]);
}
@ -79,7 +78,6 @@ class CampusPay extends BaseAdminController
["wx_pay_key_id",""],
]);
$this->validate($data, 'app\validate\campus_pay\CampusPay.edit');
(new CampusPayService())->edit($id, $data);
return success('EDIT_SUCCESS');
}

2
niucloud/app/api/controller/apiController/CoachStudent.php

@ -37,6 +37,8 @@ class CoachStudent extends BaseApiService
["status", 0], // 学员状态
["course_id", 0], // 课程ID搜索
["class_id", 0], // 班级ID搜索
["page", 1], // 页码
["limit", 10], // 每页数量
["debug", false] // 调试模式
]);

44
niucloud/app/job/schedule/HandleCourseSchedule.php

@ -27,7 +27,7 @@ class HandleCourseSchedule extends BaseJob
$lockFile = runtime_path() . 'course_status_update.lock';
if (file_exists($lockFile) && (time() - filemtime($lockFile)) < 300) { // 5分钟锁定
Log::write('课程状态更新任务正在执行中,跳过');
return ['status' => 'skipped', 'reason' => 'locked'];
return false;
}
// 创建锁文件
@ -63,7 +63,19 @@ class HandleCourseSchedule extends BaseJob
$ongoingCount = 0;
$pendingCount = 0;
// 1. 更新已完成课程:course_date < 当天的课程
// 1. 首先重置未来日期的课程为pending状态(待开始)
// 这是核心修正:course_date > 当前日期的所有课程状态改为pending
$futureRows = CourseSchedule::where('course_date', '>', $currentDate)
->where('status', '<>', 'pending')
->update([
'status' => 'pending',
'updated_at' => time()
]);
$pendingCount += $futureRows;
Log::write("重置未来课程状态完成 - 重置为pending(待开始): {$futureRows}个");
// 2. 更新已完成课程:course_date < 当天的课程
$completedRows = CourseSchedule::where('course_date', '<', $currentDate)
->where('status', '<>', 'completed')
->update([
@ -72,7 +84,7 @@ class HandleCourseSchedule extends BaseJob
]);
$completedCount = $completedRows;
// 2. 处理今天的课程,需要根据时间段判断状态
// 3. 处理今天的课程,需要根据时间段判断状态
$todaySchedules = CourseSchedule::where('course_date', '=', $currentDate)
->whereIn('status', ['pending', 'upcoming', 'ongoing'])
->select();
@ -124,36 +136,16 @@ class HandleCourseSchedule extends BaseJob
}
}
// 3. 重置未来日期的课程为pending状态
$futureRows = CourseSchedule::where('course_date', '>', $currentDate)
->where('status', '<>', 'pending')
->update([
'status' => 'pending',
'updated_at' => time()
]);
$pendingCount += $futureRows;
Log::write("课程状态更新完成 - 已完成: {$completedCount}个, 即将开始: {$upcomingCount}个, 进行中: {$ongoingCount}个, 待安排: {$pendingCount}个");
Log::write("课程状态更新完成 - 已完成: {$completedCount}个, 即将开始: {$upcomingCount}个, 进行中: {$ongoingCount}个, 待开始: {$pendingCount}个");
Db::commit();
return [
'status' => 'success',
'completed_count' => $completedCount,
'upcoming_count' => $upcomingCount,
'ongoing_count' => $ongoingCount,
'pending_count' => $pendingCount
];
return true;
} catch (\Exception $e) {
Db::rollback();
Log::write('更新课程状态失败:' . $e->getMessage());
return [
'status' => 'failed',
'total_count' => 0,
'updated_count' => 0,
'error' => $e->getMessage()
];
return false;
}
}

7
niucloud/app/service/admin/upload/UploadService.php

@ -58,8 +58,13 @@ class UploadService extends BaseAdminService
$dir = $this->root_path.'/document/'.$type.'/'.date('Ym').'/'.date('d');
// $dir = $this->root_path.'/document/'.$type.'/'.$name[0];
if ($type != 'cert'){
$storage_type = StorageDict::TENCENT;
}else{
$storage_type = StorageDict::LOCAL;
}
$core_upload_service = new CoreUploadService();
return $core_upload_service->document($file, $type, $dir, StorageDict::TENCENT);
return $core_upload_service->document($file, $type, $dir, $storage_type);
}

40
niucloud/app/service/api/apiService/CoachStudentService.php

@ -45,7 +45,14 @@ class CoachStudentService extends BaseApiService
if (empty($coachId)) {
$res['code'] = 1;
$res['data'] = [];
$res['data'] = [
'list' => [],
'total' => 0,
'page' => 1,
'limit' => 10,
'pages' => 0,
'has_more' => false
];
$res['msg'] = '获取成功';
return $res;
}
@ -55,7 +62,14 @@ class CoachStudentService extends BaseApiService
if (empty($studentIds)) {
$res['code'] = 1;
$res['data'] = [];
$res['data'] = [
'list' => [],
'total' => 0,
'page' => 1,
'limit' => 10,
'pages' => 0,
'has_more' => false
];
$res['msg'] = '获取成功';
return $res;
}
@ -82,12 +96,23 @@ class CoachStudentService extends BaseApiService
$where[] = ['s.status', '=', $data['status']];
}
// 查询学员基础信息
// 分页参数处理
$page = max(1, intval($data['page'] ?? 1));
$limit = max(1, min(50, intval($data['limit'] ?? 10))); // 限制每页最多50条
// 查询总数
$total = Db::table('school_student s')
->leftJoin('school_campus c', 's.campus_id = c.id')
->where($where)
->count();
// 查询学员基础信息(分页)
$list = Db::table('school_student s')
->leftJoin('school_campus c', 's.campus_id = c.id')
->where($where)
->field('s.*, c.campus_name as campus')
->order('s.created_at', 'desc')
->page($page, $limit)
->select()
->toArray();
@ -146,7 +171,14 @@ class CoachStudentService extends BaseApiService
}
$res['code'] = 1;
$res['data'] = $list;
$res['data'] = [
'list' => $list,
'total' => $total,
'page' => $page,
'limit' => $limit,
'pages' => ceil($total / $limit),
'has_more' => $page * $limit < $total
];
} catch (\Exception $e) {
$res['msg'] = '获取失败:' . $e->getMessage();
}

32
niucloud/app/service/api/apiService/PersonnelService.php

@ -832,22 +832,22 @@ class PersonnelService extends BaseApiService
$where = [];
// 查询销售部门(dept_id=3)下的所有角色ID
$salesRoleIds = SysRole::where('dept_id', 3)
->where('status', 1)
->column('role_id');
if (empty($salesRoleIds)) {
return [
'code' => 1,
'msg' => '暂无销售部门角色',
'data' => []
];
}
// 构建校区人员角色关系查询条件
$campusPersonWhere = [
['role_id', 'in', $salesRoleIds]
];
// $salesRoleIds = SysRole::where('dept_id', 3)
// ->where('status', 1)
// ->column('role_id');
//
// if (empty($salesRoleIds)) {
// return [
// 'code' => 1,
// 'msg' => '暂无销售部门角色',
// 'data' => []
// ];
// }
//
// // 构建校区人员角色关系查询条件
// $campusPersonWhere = [
// ['role_id', 'in', $salesRoleIds]
// ];
// 根据传入的校区进行筛选
if (!empty($campus)) {

78
niucloud/test_upload.php

@ -1,78 +0,0 @@
<?php
/**
* 文件上传测试脚本
* 用于测试文档上传功能
*/
// 创建一个测试文件
$testContent = "这是一个测试文档\n创建时间: " . date('Y-m-d H:i:s');
$testFile = '/tmp/test_document.txt';
file_put_contents($testFile, $testContent);
echo "📄 文件上传测试\n";
echo "================\n";
echo "测试文件: $testFile\n";
echo "文件大小: " . filesize($testFile) . " bytes\n\n";
// 测试上传接口
$url = 'http://niucloud_nginx/api/uploadDocument';
// 创建 CURLFile 对象
$cfile = new CURLFile($testFile, 'text/plain', 'test_document.txt');
$postData = [
'file' => $cfile,
'type' => 'document'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'token: test_token_for_upload_test',
// 注意:不要设置 Content-Type,让curl自动设置为 multipart/form-data
]);
echo "🚀 发送上传请求...\n";
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
echo "HTTP状态码: $httpCode\n";
if ($error) {
echo "CURL错误: $error\n";
}
echo "响应内容:\n";
echo $response . "\n\n";
// 解析响应
$responseData = json_decode($response, true);
if ($responseData) {
if ($responseData['code'] == 1) {
echo "✅ 上传成功!\n";
echo "文件URL: " . $responseData['data']['url'] . "\n";
echo "文件名: " . $responseData['data']['name'] . "\n";
echo "扩展名: " . $responseData['data']['ext'] . "\n";
} else {
echo "❌ 上传失败: " . $responseData['msg'] . "\n";
}
} else {
echo "❌ 响应解析失败\n";
}
// 清理测试文件
unlink($testFile);
echo "\n🗑️ 测试文件已清理\n";
echo "\n📋 调试建议:\n";
echo "1. 检查前端是否使用了正确的参数名 'file'\n";
echo "2. 检查请求是否为 multipart/form-data 格式\n";
echo "3. 检查文件大小是否超过限制\n";
echo "4. 检查服务器错误日志\n";
echo "5. 检查腾讯云COS配置和权限\n";
?>

71
test-student-orders-api.js

@ -1,71 +0,0 @@
// 测试学员端订单接口
const axios = require('axios');
const BASE_URL = 'http://localhost:20080/api';
async function testStudentOrdersAPI() {
console.log('🧪 开始测试学员端订单接口...\n');
try {
// 测试订单列表接口
console.log('📋 测试订单列表接口...');
const listResponse = await axios.get(`${BASE_URL}/xy/student/orders`, {
params: {
student_id: 31,
page: 1,
limit: 10
}
});
console.log('✅ 订单列表接口响应:');
console.log('状态码:', listResponse.status);
console.log('响应数据:', JSON.stringify(listResponse.data, null, 2));
console.log('');
// 测试订单统计接口
console.log('📊 测试订单统计接口...');
const statsResponse = await axios.get(`${BASE_URL}/xy/student/orders/stats`, {
params: {
student_id: 31
}
});
console.log('✅ 订单统计接口响应:');
console.log('状态码:', statsResponse.status);
console.log('响应数据:', JSON.stringify(statsResponse.data, null, 2));
console.log('');
// 如果有订单数据,测试订单详情接口
if (listResponse.data.code === 1 && listResponse.data.data && listResponse.data.data.data && listResponse.data.data.data.length > 0) {
const firstOrder = listResponse.data.data.data[0];
console.log('📄 测试订单详情接口...');
const detailResponse = await axios.get(`${BASE_URL}/xy/student/orders/detail`, {
params: {
id: firstOrder.id,
student_id: 31
}
});
console.log('✅ 订单详情接口响应:');
console.log('状态码:', detailResponse.status);
console.log('响应数据:', JSON.stringify(detailResponse.data, null, 2));
} else {
console.log('ℹ️ 没有订单数据,跳过详情接口测试');
}
console.log('\n🎉 所有接口测试完成!');
} catch (error) {
console.error('❌ 接口测试失败:');
if (error.response) {
console.error('状态码:', error.response.status);
console.error('响应数据:', JSON.stringify(error.response.data, null, 2));
} else {
console.error('错误信息:', error.message);
}
}
}
// 运行测试
testStudentOrdersAPI();

125
uniapp/pages-coach/coach/schedule/schedule_table.vue

@ -126,36 +126,31 @@
<!-- 右侧内容区域 -->
<view class="schedule-content-area">
<!-- 表头 -->
<scroll-view
class="date-header-scroll"
scroll-x
:scroll-left="scrollLeft"
>
<view class="date-header-container" :style="{ width: tableWidth + 'rpx', minWidth: '1260rpx' }">
<!-- 日期列 -->
<view
class="date-header-cell"
v-for="(date, index) in weekDates"
:key="index"
>
<view class="date-week">{{ date.weekName }}</view>
<view class="date-day">{{ date.dateStr }}</view>
<view class="date-courses">{{ date.courseCount }}节课</view>
</view>
</view>
</scroll-view>
<!-- 内容滚动区域 -->
<!-- 合并的滚动区域表头+内容 -->
<scroll-view
class="schedule-scroll"
scroll-x
scroll-y
:scroll-left="scrollLeft"
:scroll-top="scrollTop"
@scroll="onScroll"
>
<view class="schedule-grid" :style="{ width: tableWidth + 'rpx', minWidth: '1260rpx' }">
<view class="schedule-container-inner" :style="{ width: tableWidth + 'rpx', minWidth: '1260rpx' }">
<!-- 表头 -->
<view class="date-header-container">
<!-- 日期列 -->
<view
class="date-header-cell"
v-for="(date, index) in weekDates"
:key="index"
>
<view class="date-week">{{ date.weekName }}</view>
<view class="date-day">{{ date.dateStr }}</view>
<view class="date-courses">{{ date.courseCount }}节课</view>
</view>
</view>
<!-- 内容网格 -->
<view class="schedule-grid">
<!-- 时间模式内容 -->
<template v-if="activeFilter === 'time' || activeFilter === ''">
<view
@ -299,6 +294,7 @@
</view>
</view>
</template>
</view>
</view>
</scroll-view>
</view>
@ -432,9 +428,7 @@ export default {
selectedClasses: [],
//
scrollLeft: 0,
scrollTop: 0,
scrollAnimationFrame: null, //
//
tableWidth: 1500, // 7 (7*180+120=1380rpx)
@ -526,23 +520,29 @@ export default {
this.initCurrentWeek()
this.initTimeSlots()
//
this.handleResize()
//
this.loadFilterOptions().then(() => {
this.loadScheduleList()
})
//
window.addEventListener('resize', this.handleResize)
// H5
// #ifndef MP-WEIXIN
if (typeof window !== 'undefined') {
window.addEventListener('resize', this.handleResize)
}
// #endif
},
beforeDestroy() {
//
window.removeEventListener('resize', this.handleResize)
//
if (this.scrollAnimationFrame) {
cancelAnimationFrame(this.scrollAnimationFrame)
// H5
// #ifndef MP-WEIXIN
if (typeof window !== 'undefined') {
window.removeEventListener('resize', this.handleResize)
}
// #endif
},
methods: {
@ -782,14 +782,8 @@ export default {
this.filterParams.class_id = '';
//
this.scrollLeft = 0;
this.scrollTop = 0;
//
if (this.scrollAnimationFrame) {
cancelAnimationFrame(this.scrollAnimationFrame);
}
//
this.loadScheduleList();
}
@ -812,7 +806,6 @@ export default {
//
await this.loadScheduleList()
this.scrollLeft = 0
this.scrollTop = 0
//
@ -1162,24 +1155,12 @@ export default {
});
},
//
// -
onScroll(e) {
if (this.scrollAnimationFrame) {
cancelAnimationFrame(this.scrollAnimationFrame)
//
if (e.detail.scrollTop !== undefined) {
this.scrollTop = e.detail.scrollTop
}
this.scrollAnimationFrame = requestAnimationFrame(() => {
//
if (e.detail.scrollLeft !== undefined) {
this.scrollLeft = e.detail.scrollLeft
}
if (e.detail.scrollTop !== undefined) {
this.scrollTop = e.detail.scrollTop
// :scroll-top
}
})
},
//
@ -1334,7 +1315,24 @@ export default {
//
handleResize() {
//
const width = window.innerWidth
let width = 375 //
// #ifdef MP-WEIXIN
try {
const systemInfo = uni.getSystemInfoSync()
width = systemInfo.screenWidth || systemInfo.windowWidth || 375
} catch (e) {
console.warn('获取系统信息失败,使用默认宽度:', e)
width = 375
}
// #endif
// #ifndef MP-WEIXIN
if (typeof window !== 'undefined') {
width = window.innerWidth
}
// #endif
if (width <= 375) {
this.tableWidth = 1220 // 7*160+100=1220rpx
} else if (width <= 768) {
@ -1531,15 +1529,20 @@ export default {
overflow: hidden;
}
.date-header-scroll {
overflow: hidden;
border-bottom: 2px solid #29d3b4;
//
.schedule-container-inner {
display: flex;
flex-direction: column;
min-width: 1260rpx; /* 7天 * 180rpx = 1260rpx */
}
.date-header-container {
display: flex;
background: #434544;
min-width: 1260rpx; /* 7天 * 180rpx = 1260rpx */
border-bottom: 2px solid #29d3b4;
position: sticky;
top: 0;
z-index: 2;
}
.date-header-cell {

256
uniapp/pages-coach/coach/student/student_list.vue

@ -4,37 +4,65 @@
<uni-icons type="search" size="22" color="#00d18c" />
<text class="search-placeholder">搜索学员...</text>
</view>
<!-- 统计信息 -->
<view class="stats-bar">
<text class="stats-text">共找到 {{ pagination.total }} 名学员</text>
</view>
<view class="content">
<view v-if="studentList.length === 0" class="empty-box">
<image :src="$util.img('/static/icon-img/empty.png')" mode="aspectFit" class="empty-img"></image>
<text class="empty-text">暂无学员数据</text>
</view>
<view v-else class="student-list">
<view v-for="(item, index) in studentList" :key="index" class="student-item" @click="goToDetail(item)">
<view class="student-card">
<view class="student-avatar">
<image :src="item.avatar || $util.img('/static/icon-img/avatar.png')" mode="aspectFill" class="avatar-img"></image>
</view>
<view class="student-info">
<view class="student-name">{{item.name}}</view>
<view class="info-row">
<text class="info-label">所属校区</text>
<text class="info-value">{{item.campus}}</text>
</view>
<view class="info-row">
<text class="info-label">剩余课程</text>
<text class="info-value">{{ getRemainingCourses(item) }}</text>
</view>
<view class="info-row">
<text class="info-label">到期时间</text>
<text class="info-value">{{item.end_date}}</text>
<view v-else>
<scroll-view
class="student-list-scroll"
scroll-y
@scrolltolower="loadMore"
lower-threshold="100"
>
<view class="student-list">
<view v-for="(item, index) in studentList" :key="index" class="student-item" @click="goToDetail(item)">
<view class="student-card">
<view class="student-avatar">
<image :src="item.avatar || $util.img('/static/icon-img/avatar.png')" mode="aspectFill" class="avatar-img"></image>
</view>
<view class="student-info">
<view class="student-name">{{item.name}}</view>
<view class="info-row">
<text class="info-label">所属校区</text>
<text class="info-value">{{item.campus}}</text>
</view>
<view class="info-row">
<text class="info-label">剩余课程</text>
<text class="info-value">{{ getRemainingCourses(item) }}</text>
</view>
<view class="info-row">
<text class="info-label">到期时间</text>
<text class="info-value">{{item.end_date}}</text>
</view>
</view>
<view class="arrow-right">
<uni-icons type="right" size="16" color="#CCCCCC"></uni-icons>
</view>
</view>
</view>
<view class="arrow-right">
<uni-icons type="right" size="16" color="#CCCCCC"></uni-icons>
</view>
<!-- 加载更多提示 -->
<view class="load-more" v-if="studentList.length > 0">
<view v-if="pagination.loading" class="loading">
<uni-icons type="spinner-cycle" size="24" color="#00d18c" class="loading-icon"></uni-icons>
<text class="loading-text">加载中...</text>
</view>
<view v-else-if="pagination.hasMore" class="load-more-text">
上拉加载更多
</view>
<view v-else class="no-more">
已显示全部 {{ pagination.total }} 名学员
</view>
</view>
</view>
</scroll-view>
</view>
</view>
<!-- 搜索弹窗 -->
@ -141,13 +169,21 @@ import apiRoute from '@/api/apiRoute.js';
phone: '',
lessonCount: '',
leaveCount: '',
courseId: null,
classId: null,
course_id: null,
class_id: null,
},
selectedCourseName: '',
selectedClassName: '',
courseList: [],
classList: [],
//
pagination: {
current: 1,
limit: 10,
total: 0,
hasMore: false,
loading: false
},
}
},
onLoad() {
@ -158,14 +194,48 @@ import apiRoute from '@/api/apiRoute.js';
navigateBack() {
uni.navigateBack();
},
async getStudentList() {
async getStudentList(reset = false) {
try {
// 使
const res = await apiRoute.coach_getMyStudents(this.searchForm);
//
if (reset) {
this.pagination.current = 1;
this.studentList = [];
}
//
if (this.pagination.loading) {
return;
}
this.pagination.loading = true;
//
const params = {
...this.searchForm,
page: this.pagination.current,
limit: this.pagination.limit
};
const res = await apiRoute.coach_getMyStudents(params);
console.log('获取教练端学员列表响应:', res);
if(res.code == 1) {
this.studentList = res.data || [];
const data = res.data || {};
const list = data.list || [];
//
this.pagination.total = data.total || 0;
this.pagination.hasMore = data.has_more || false;
//
if (reset) {
this.studentList = list;
} else {
this.studentList = [...this.studentList, ...list];
}
console.log('教练端学员列表更新成功:', this.studentList);
console.log('分页信息:', this.pagination);
} else {
console.error('API返回错误:', res);
uni.showToast({
@ -173,13 +243,14 @@ import apiRoute from '@/api/apiRoute.js';
icon: 'none'
});
}
}catch ( error) {
} catch (error) {
console.error('获取学员列表错误', error);
uni.showToast({
title: '获取学员列表失败',
icon: 'none'
});
return;
} finally {
this.pagination.loading = false;
}
},
goToDetail(student) {
@ -205,6 +276,16 @@ import apiRoute from '@/api/apiRoute.js';
return totalHours - usedHours;
},
//
async loadMore() {
if (!this.pagination.hasMore || this.pagination.loading) {
return;
}
this.pagination.current++;
await this.getStudentList(false);
},
//
onNameInput(e) {
this.searchForm.name = e;
@ -221,23 +302,23 @@ import apiRoute from '@/api/apiRoute.js';
//
onCourseChange(e) {
this.searchForm.courseId = e.value;
this.searchForm.course_id = e.value;
this.selectedCourseName = e.text;
},
onClassChange(e) {
this.searchForm.classId = e.value;
this.searchForm.class_id = e.value;
this.selectedClassName = e.text;
},
//
clearCourseSelection(e) {
e.stopPropagation(); //
this.searchForm.courseId = null;
this.searchForm.course_id = null;
this.selectedCourseName = '';
},
clearClassSelection(e) {
e.stopPropagation(); //
this.searchForm.classId = null;
this.searchForm.class_id = null;
this.selectedClassName = '';
},
@ -251,33 +332,50 @@ import apiRoute from '@/api/apiRoute.js';
this.showSearch = false;
},
//
//
async getClassesList() {
try {
const res = await apiRoute.jlGetClassesList();
if (res.code == 1) {
// API
this.classList = res.data.classes || [];
this.courseList = res.data.course || [];
//
const [courseRes, classRes] = await Promise.all([
apiRoute.getCourseListForSchedule(),
apiRoute.getClassListForSchedule()
]);
//
if (courseRes.code == 1) {
this.courseList = courseRes.data.list || courseRes.data || [];
} else {
uni.showToast({
title: res.msg || '获取班级列表失败',
icon: 'none'
});
console.warn('获取课程列表失败:', courseRes.msg);
this.courseList = [];
}
//
if (classRes.code == 1) {
this.classList = classRes.data.list || classRes.data || [];
} else {
console.warn('获取班级列表失败:', classRes.msg);
this.classList = [];
}
console.log('课程列表:', this.courseList);
console.log('班级列表:', this.classList);
} catch (error) {
console.error('获取班级列表错误', error);
console.error('获取课程和班级列表错误', error);
uni.showToast({
title: '获取班级列表失败',
title: '获取筛选数据失败',
icon: 'none'
});
//
this.courseList = [];
this.classList = [];
}
},
doSearch() {
// searchForm
this.showSearch = false;
this.getStudentList()
this.getStudentList(true) //
},
doSearchAndClose() {
@ -290,12 +388,12 @@ import apiRoute from '@/api/apiRoute.js';
phone: '',
lessonCount: '',
leaveCount: '',
courseId: null,
classId: null,
course_id: null,
class_id: null,
};
this.selectedCourseName = '';
this.selectedClassName = '';
this.getStudentList();
this.getStudentList(true); //
}
}
}
@ -708,4 +806,62 @@ import apiRoute from '@/api/apiRoute.js';
color: #fff;
}
}
//
.stats-bar {
padding: 20rpx 30rpx;
background: #23232a;
border-bottom: 1px solid #333;
margin: 24rpx;
}
.stats-text {
color: #00d18c;
font-size: 28rpx;
font-weight: 500;
}
//
.student-list-scroll {
height: calc(100vh - 300rpx);
background: #18181c;
}
//
.load-more {
padding: 30rpx;
text-align: center;
background: #18181c;
}
.loading {
display: flex;
align-items: center;
justify-content: center;
gap: 10rpx;
}
.loading-icon {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
color: #00d18c;
font-size: 28rpx;
}
.load-more-text {
color: #bdbdbd;
font-size: 26rpx;
}
.no-more {
color: #666;
font-size: 24rpx;
}
</style>
Loading…
Cancel
Save