Browse Source

临时保存

master
王泽彦 10 months ago
parent
commit
92c9177f25
  1. 8
      admin/src/app/api/classroom.ts
  2. 231
      admin/src/app/views/timetables/components/schedule-add.vue
  3. 289
      admin/src/app/views/timetables/components/seat-selector.vue
  4. 102
      niucloud/app/adminapi/controller/classroom/Classroom.php
  5. 2
      niucloud/app/adminapi/controller/venue/Venue.php
  6. 65
      niucloud/app/adminapi/route/class.php
  7. 4
      niucloud/app/adminapi/route/classroom.php
  8. 8
      niucloud/app/model/class_grade/ClassGrade.php
  9. 148
      niucloud/app/model/classroom/Classroom.php
  10. 135
      niucloud/app/model/course_schedule/CourseSchedule.php
  11. 32
      niucloud/app/model/rel/ClassPersonnelRel.php
  12. 48
      niucloud/app/service/admin/classroom/ClassroomService.php

8
admin/src/app/api/classroom.ts

@ -66,4 +66,12 @@ export function getWithPersonnelList(params: Record<string, any>) {
export function getAllClassroomList() {
return request.get('classroom/classroom_all')
}
export function getClassroompeople($class_id: number) {
return request.get(`classroom/getClassroompeople/${$class_id}`)
}
export function getClassroompeopleCount($class_id: number,params: Record<string, any>) {
return request.get(`classroom/getClassroompeopleCount/${$class_id}`,{params})
}
// USER_CODE_END -- class

231
admin/src/app/views/timetables/components/schedule-add.vue

@ -25,7 +25,7 @@
<el-select
v-model="form.venue_id"
placeholder="请选择场地"
@change="calculateAvailableCapacity"
@change="handleVenueChange"
>
<el-option
v-for="item in venueList"
@ -51,7 +51,7 @@
<el-select
v-model="form.time_slot"
placeholder="请选择上课时段"
@change="calculateAvailableCapacity"
@change="handleTimeSlotChange"
>
<el-option
v-for="(timeSlot, index) in timeSlotOptions"
@ -62,10 +62,6 @@
</el-select>
</el-form-item>
<el-form-item label="剩余空位" v-if="form.venue_id && form.time_slot">
<span>{{ availableCapacity }}</span>
</el-form-item>
<el-form-item label="上课类型" prop="course_type">
<el-radio-group v-model="form.course_type" @change="handleCourseTypeChange">
<el-radio label="class">班级</el-radio>
@ -74,16 +70,13 @@
</el-radio-group>
</el-form-item>
<el-form-item label="班级" prop="class_ids" v-if="form.course_type === 'class'">
<el-checkbox-group v-model="form.class_ids" @change="handleClassChange">
<el-checkbox
v-for="item in classList"
:key="item.id"
:label="item.id"
>
{{ item.class_name }}
</el-checkbox>
</el-checkbox-group>
<el-form-item label="位置选择" v-if="form.venue_id && form.time_slot && form.course_type === 'class'">
<SeatSelector
:venueId="form.venue_id"
:capacity="venueCapacity"
v-model:selectedSeats="form.selectedSeats"
@change="handleSeatSelectionChange"
/>
</el-form-item>
<el-form-item label="学员" prop="student_ids" v-if="form.course_type === 'student' || form.course_type === 'trial'">
@ -129,11 +122,12 @@
<script setup>
import { ref, defineProps, defineEmits, watch } from 'vue'
import {getAllVenueList, getVenueList} from '@/app/api/venue'
import { getClassroomList, getWithPersonnelList } from '@/app/api/classroom'
import {getAllVenueList} from '@/app/api/venue'
import { getAllClassroomList, getClassroompeople, getWithPersonnelList, getClassroompeopleCount } from '@/app/api/classroom'
import { addCourseSchedule } from '@/app/api/course_schedule'
import { getTimetables } from '@/app/api/course_schedule'
import { ElMessage } from 'element-plus'
import SeatSelector from './seat-selector.vue'
const props = defineProps({
visible: {
@ -155,10 +149,13 @@ const venueList = ref([])
const classList = ref([])
const studentList = ref([])
const coachList = ref([])
const timeSlotOptions = ref(['9:00-10:00', '10:00-11:00', '11:00-12:00', '14:00-15:00', '15:00-16:00', '16:00-17:00'])
const timeSlotOptions = ref([])
const availableCapacity = ref(0)
const venueCapacity = ref(0)
const studentSearchKeyword = ref('')
const filteredStudentList = ref([])
const occupiedSeats = ref([])
const participants = ref([]) // getClassroompeopleCount
// visible
watch(() => props.visible, (newVal) => {
@ -186,7 +183,8 @@ const form = ref({
class_ids: [],
student_ids: [],
course_name: '',
coach_id: ''
coach_id: '',
selectedSeats: []
})
const rules = {
@ -216,9 +214,9 @@ const handleCampusChange = async () => {
//
try {
const response = await getClassroomList({ campus_id: form.value.campus_id })
if (response.data && response.data.list) {
classList.value = response.data.list
const response = await getAllClassroomList({ campus_id: form.value.campus_id })
if (response.data && response.data) {
classList.value = response.data
}
} catch (error) {
console.error('获取班级列表失败:', error)
@ -227,13 +225,127 @@ const handleCampusChange = async () => {
//
form.value.venue_id = ''
form.value.class_ids = []
form.value.time_slot = ''
timeSlotOptions.value = []
availableCapacity.value = 0
venueCapacity.value = 0
occupiedSeats.value = []
}
//
const generateTimeSlots = (venueInfo) => {
if (!venueInfo) return []
const timeSlots = []
// time_range_type
switch (venueInfo.time_range_type) {
case 'fixed':
// fixed_time_ranges
try {
const fixedRanges = JSON.parse(venueInfo.fixed_time_ranges || '[]')
fixedRanges.forEach(range => {
timeSlots.push(`${range.start_time}-${range.end_time}`)
})
} catch (error) {
console.error('解析固定时间段失败:', error)
}
break
case 'all':
// 12:30-14:00
// 812:3030
for (let hour = 8; hour <= 12; hour++) {
for (let minute = 0; minute < 60; minute += 60) {
if (hour === 12 && minute === 30) continue // 12:30
const startHour = hour
const startMinute = minute
const endHour = minute === 30 ? hour + 1 : hour
const endMinute = minute === 30 ? 0 : 30
const startTime = `${startHour.toString().padStart(2, '0')}:${startMinute.toString().padStart(2, '0')}`
const endTime = `${endHour.toString().padStart(2, '0')}:${endMinute.toString().padStart(2, '0')}`
timeSlots.push(`${startTime}-${endTime}`)
}
}
// 14:0022:0030
for (let hour = 14; hour < 22; hour++) {
for (let minute = 0; minute < 60; minute += 60) {
const startHour = hour
const startMinute = minute
const endHour = minute === 30 ? hour + 1 : hour
const endMinute = minute === 30 ? 0 : 30
const startTime = `${startHour.toString().padStart(2, '0')}:${startMinute.toString().padStart(2, '0')}`
const endTime = `${endHour.toString().padStart(2, '0')}:${endMinute.toString().padStart(2, '0')}`
timeSlots.push(`${startTime}-${endTime}`)
}
}
break
case 'range':
// 使10
if (venueInfo.time_range_start && venueInfo.time_range_end) {
const startTimeParts = venueInfo.time_range_start.split(':')
const endTimeParts = venueInfo.time_range_end.split(':')
if (startTimeParts.length === 2 && endTimeParts.length === 2) {
const startHour = parseInt(startTimeParts[0])
const startMinute = parseInt(startTimeParts[1])
const endHour = parseInt(endTimeParts[0])
const endMinute = parseInt(endTimeParts[1])
//
const startTotalMinutes = startHour * 60 + startMinute
const endTotalMinutes = endHour * 60 + endMinute
// 10
for (let minutes = startTotalMinutes; minutes < endTotalMinutes - 9; minutes += 10) {
const startHour = Math.floor(minutes / 60)
const startMinute = minutes % 60
const endHour = Math.floor((minutes + 10) / 60)
const endMinute = (minutes + 10) % 60
const startTime = `${startHour.toString().padStart(2, '0')}:${startMinute.toString().padStart(2, '0')}`
const endTime = `${endHour.toString().padStart(2, '0')}:${endMinute.toString().padStart(2, '0')}`
timeSlots.push(`${startTime}-${endTime}`)
}
}
}
break
}
return timeSlots
}
//
const handleVenueChange = () => {
form.value.time_slot = ''
//
const selectedVenue = venueList.value.find(item => item.id === form.value.venue_id)
if (selectedVenue) {
timeSlotOptions.value = generateTimeSlots(selectedVenue)
venueCapacity.value = selectedVenue.capacity || 0
} else {
timeSlotOptions.value = []
venueCapacity.value = 0
}
availableCapacity.value = 0
occupiedSeats.value = []
}
//
const calculateAvailableCapacity = async () => {
if (!form.value.venue_id || !form.value.time_slot) {
availableCapacity.value = 0
occupiedSeats.value = []
return
}
@ -267,6 +379,16 @@ const calculateAvailableCapacity = async () => {
if (matchingTimeSlot && matchingTimeSlot.course) {
//
availableCapacity.value = matchingTimeSlot.course.hasnumber
// API
if (matchingTimeSlot.course.occupiedSeats) {
occupiedSeats.value = matchingTimeSlot.course.occupiedSeats
} else {
//
const totalSeats = venueCapacity.value;
const occupiedCount = totalSeats - availableCapacity.value;
occupiedSeats.value = generateRandomOccupiedSeats(occupiedCount);
}
}
}
}
@ -277,6 +399,29 @@ const calculateAvailableCapacity = async () => {
}
}
//
const generateRandomOccupiedSeats = (count) => {
const occupied = [];
const rows = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
const cols = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let i = 0; i < count; i++) {
const row = rows[Math.floor(Math.random() * rows.length)];
const col = cols[Math.floor(Math.random() * cols.length)];
const seat = `${row}-${col}`;
if (!occupied.includes(seat)) {
occupied.push(seat);
}
}
return occupied;
};
//
const handleSeatSelectionChange = (selectedSeats) => {
console.log('选中的座位:', selectedSeats);
};
//
const handleCourseTypeChange = () => {
//
@ -360,6 +505,41 @@ const cancel = () => {
dialogVisible.value = false
}
//
const handleTimeSlotChange = async () => {
if (!form.value.venue_id || !form.value.time_slot || !form.value.course_date) {
participants.value = []
return
}
//
await calculateAvailableCapacity()
//
try {
const params = {
course_date: form.value.course_date,
time_slot: form.value.time_slot
}
const response = await getClassroompeopleCount(form.value.venue_id, params)
if (response.data) {
participants.value = response.data
console.log('获取到的人员信息:', participants.value)
}
} catch (error) {
console.error('获取人员信息失败:', error)
participants.value = []
}
}
// course_date
watch(() => form.value.course_date, (newVal) => {
if (newVal && form.value.venue_id && form.value.time_slot) {
handleTimeSlotChange()
}
})
//
const submit = () => {
formRef.value.validate(async (valid) => {
@ -376,6 +556,8 @@ const submit = () => {
participants: form.value.course_type,
available_capacity: availableCapacity.value,
status: 'active',
selected_seats: form.value.selectedSeats, //
participants_info: participants.value //
}
//
@ -414,7 +596,8 @@ const resetForm = () => {
class_ids: [],
student_ids: [],
course_name: '',
coach_id: ''
coach_id: '',
selectedSeats: []
}
if (formRef.value) {
formRef.value.resetFields()

289
admin/src/app/views/timetables/components/seat-selector.vue

@ -0,0 +1,289 @@
<template>
<div class="seat-selector">
<div class="seats-container">
<div v-for="row in rows" :key="row" class="seat-row">
<div class="row-label">{{ row }}</div>
<div
v-for="col in cols"
:key="`${row}-${col}`"
class="seat"
:class="{
'seat-available': isSeatAvailable(row, col),
'seat-occupied': !isSeatAvailable(row, col),
'seat-selected': isSelected(row, col)
}"
@click="toggleSeat(row, col)"
>
{{ col }}
</div>
</div>
</div>
<div class="seat-legend">
<div class="legend-item">
<div class="legend-box seat-available"></div>
<span>可选</span>
</div>
<div class="legend-item">
<div class="legend-box seat-occupied"></div>
<span>已占</span>
</div>
<div class="legend-item">
<div class="legend-box seat-selected"></div>
<span>已选</span>
</div>
</div>
<div class="seat-info">
<span>已选: {{ selectedSeats.length }}</span>
<span>剩余空位: {{ availableSeats.length }}</span>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch, onMounted } from 'vue';
import { getClassroompeople } from '@/app/api/classroom';
const props = defineProps({
venueId: {
type: [Number, String],
default: null
},
capacity: {
type: Number,
default: 0
},
occupiedSeats: {
type: Array,
default: () => []
}
});
const emit = defineEmits(['update:selectedSeats', 'change']);
//
const rows = ref(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']);
const cols = ref([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const selectedSeats = ref([]);
const occupiedSeatsData = ref([]);
//
const adjustLayout = () => {
if (!props.capacity) return;
//
const totalCapacity = props.capacity;
let colCount = Math.ceil(Math.sqrt(totalCapacity));
if (colCount > 12) colCount = 12; //
const rowCount = Math.ceil(totalCapacity / colCount);
// A-Z
rows.value = Array.from({ length: rowCount }, (_, i) =>
String.fromCharCode(65 + i)
).slice(0, 26); // 26A-Z
// 1-N
cols.value = Array.from({ length: colCount }, (_, i) => i + 1);
};
//
const loadOccupiedSeats = async () => {
if (!props.venueId) return;
try {
// 使
if (props.occupiedSeats && props.occupiedSeats.length) {
occupiedSeatsData.value = props.occupiedSeats;
return;
}
// API
const response = await getClassroompeople(props.venueId);
if (response.data && Array.isArray(response.data)) {
// API
occupiedSeatsData.value = response.data;
}
} catch (error) {
console.error('获取已占用位置失败:', error);
//
occupiedSeatsData.value = generateRandomOccupiedSeats();
}
};
//
const generateRandomOccupiedSeats = () => {
const occupied = [];
const totalSeats = rows.value.length * cols.value.length;
const occupiedCount = Math.floor(totalSeats * 0.3); // 30%
for (let i = 0; i < occupiedCount; i++) {
const row = rows.value[Math.floor(Math.random() * rows.value.length)];
const col = cols.value[Math.floor(Math.random() * cols.value.length)];
const seat = `${row}-${col}`;
if (!occupied.includes(seat)) {
occupied.push(seat);
}
}
return occupied;
};
//
const availableSeats = computed(() => {
const allSeats = [];
rows.value.forEach(row => {
cols.value.forEach(col => {
const seatId = `${row}-${col}`;
if (!occupiedSeatsData.value.includes(seatId)) {
allSeats.push(seatId);
}
});
});
return allSeats;
});
//
const isSeatAvailable = (row, col) => {
const seatId = `${row}-${col}`;
return !occupiedSeatsData.value.includes(seatId);
};
//
const isSelected = (row, col) => {
const seatId = `${row}-${col}`;
return selectedSeats.value.includes(seatId);
};
//
const toggleSeat = (row, col) => {
const seatId = `${row}-${col}`;
if (!isSeatAvailable(row, col)) return; //
const index = selectedSeats.value.indexOf(seatId);
if (index === -1) {
selectedSeats.value.push(seatId);
} else {
selectedSeats.value.splice(index, 1);
}
emit('update:selectedSeats', selectedSeats.value);
emit('change', selectedSeats.value);
};
//
watch(() => props.venueId, () => {
selectedSeats.value = [];
loadOccupiedSeats();
});
watch(() => props.capacity, () => {
adjustLayout();
});
watch(() => props.occupiedSeats, () => {
occupiedSeatsData.value = props.occupiedSeats;
});
//
onMounted(() => {
adjustLayout();
loadOccupiedSeats();
});
</script>
<style scoped>
.seat-selector {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.screen {
width: 80%;
height: 30px;
background: linear-gradient(to bottom, #ccc, #f5f5f5);
margin-bottom: 30px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
}
.screen-text {
font-size: 14px;
color: #666;
}
.seats-container {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
}
.seat-row {
display: flex;
align-items: center;
gap: 10px;
}
.row-label {
width: 20px;
text-align: center;
font-weight: bold;
}
.seat {
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
cursor: pointer;
font-size: 12px;
transition: all 0.2s;
}
.seat-available {
background-color: #67c23a;
color: white;
}
.seat-occupied {
background-color: #909399;
color: white;
cursor: not-allowed;
}
.seat-selected {
background-color: #409eff;
color: white;
}
.seat-legend {
display: flex;
gap: 20px;
margin-bottom: 15px;
}
.legend-item {
display: flex;
align-items: center;
gap: 5px;
}
.legend-box {
width: 15px;
height: 15px;
border-radius: 3px;
}
.seat-info {
display: flex;
gap: 20px;
font-size: 14px;
}
</style>

102
niucloud/app/adminapi/controller/classroom/Classroom.php

@ -22,19 +22,20 @@ use app\service\admin\classroom\ClassroomService;
*/
class Classroom extends BaseAdminController
{
/**
* 获取场地管理列表
* @return \think\Response
*/
public function lists(){
/**
* 获取场地管理列表
* @return \think\Response
*/
public function lists()
{
$data = $this->request->params([
["campus_id",""],
["class_name",""],
["head_coach",""],
["class_type",""],
["assistant_coach",""],
["created_at",""],
["status",""]
["campus_id", ""],
["class_name", ""],
["head_coach", ""],
["class_type", ""],
["assistant_coach", ""],
["created_at", ""],
["status", ""]
]);
return success((new ClassroomService())->getPage($data));
}
@ -44,7 +45,8 @@ class Classroom extends BaseAdminController
* @param int $id
* @return \think\Response
*/
public function info(int $id){
public function info(int $id)
{
return success((new ClassroomService())->getInfo($id));
}
@ -52,17 +54,18 @@ class Classroom extends BaseAdminController
* 添加场地管理
* @return \think\Response
*/
public function add(){
public function add()
{
$data = $this->request->params([
["campus_id",0],
["class_name",""],
["head_coach",""],
["age_group",""],
["class_type",""],
["assistant_coach",""],
["status",""],
["sort_order",0],
["remarks",""]
["campus_id", 0],
["class_name", ""],
["head_coach", ""],
["age_group", ""],
["class_type", ""],
["assistant_coach", ""],
["status", ""],
["sort_order", 0],
["remarks", ""]
]);
$this->validate($data, 'app\validate\classroom\Classroom.add');
$id = (new ClassroomService())->add($data);
@ -74,17 +77,18 @@ class Classroom extends BaseAdminController
* @param $id 场地管理id
* @return \think\Response
*/
public function edit(int $id){
public function edit(int $id)
{
$data = $this->request->params([
["campus_id",0],
["class_name",""],
["head_coach",""],
["age_group",""],
["class_type",""],
["assistant_coach",""],
["status",""],
["sort_order",0],
["remarks",""]
["campus_id", 0],
["class_name", ""],
["head_coach", ""],
["age_group", ""],
["class_type", ""],
["assistant_coach", ""],
["status", ""],
["sort_order", 0],
["remarks", ""]
]);
$this->validate($data, 'app\validate\classroom\Classroom.edit');
(new ClassroomService())->edit($id, $data);
@ -96,22 +100,40 @@ class Classroom extends BaseAdminController
* @param $id 场地管理id
* @return \think\Response
*/
public function del(int $id){
public function del(int $id)
{
(new ClassroomService())->del($id);
return success('DELETE_SUCCESS');
}
public function getCampusAll(){
return success(( new ClassroomService())->getCampusAll());
public function getCampusAll()
{
return success((new ClassroomService())->getCampusAll());
}
public function getPersonnelAll(){
return success(( new ClassroomService())->getPersonnelAll());
public function getPersonnelAll()
{
return success((new ClassroomService())->getPersonnelAll());
}
public function classroom_all()
{
return success(( new ClassroomService())->classroom_all());
return success((new ClassroomService())->classroom_all());
}
public function getClassroompeople($class_id)
{
return success((new ClassroomService())->getClassroompeople($class_id));
}
public function getClassroompeopleCount($venue_id)
{
$where = $this->request->params([
["course_date", ""],
["time_slot", ""]
]);
return success((new ClassroomService())->getClassroompeopleCount($venue_id,$where));
}
}

2
niucloud/app/adminapi/controller/venue/Venue.php

@ -81,6 +81,8 @@ class Venue extends BaseAdminController
["campus_id", 0],
["venue_name", ""],
["capacity", 0],
["time_range_start", 0],
["time_range_end", 0],
["availability_status", 0],
["time_range_type", ""],
["fixed_time_ranges", []],

65
niucloud/app/adminapi/route/class.php

@ -1,65 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
use think\facade\Route;
use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- campus
Route::group('campus', function () {
//校区列表
Route::get('campus', 'campus.Campus/lists');
//校区详情
Route::get('campus/:id', 'campus.Campus/info');
//添加校区
Route::post('campus', 'campus.Campus/add');
//编辑校区
Route::put('campus/:id', 'campus.Campus/edit');
//删除校区
Route::delete('campus/:id', 'campus.Campus/del');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_END -- campus
// USER_CODE_BEGIN -- class
Route::group('class', function () {
//场地管理列表
Route::get('class', 'class.Class/lists');
//场地管理详情
Route::get('class/:id', 'class.Class/info');
//添加场地管理
Route::post('class', 'class.Class/add');
//编辑场地管理
Route::put('class/:id', 'class.Class/edit');
//删除场地管理
Route::delete('class/:id', 'class.Class/del');
Route::get('campus_all','class.Class/getCampusAll');
Route::get('personnel_all','class.Class/getPersonnelAll');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_END -- class

4
niucloud/app/adminapi/route/classroom.php

@ -35,6 +35,10 @@ Route::group('classroom', function () {
Route::get('classroom_all','classroom.Classroom/classroom_all');
Route::get('getClassroompeople/:class_id','classroom.Classroom/getClassroompeople');
Route::get('getClassroompeopleCount/:class_id','classroom.Classroom/getClassroompeopleCount');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

8
niucloud/app/model/class_grade/ClassGrade.php

@ -11,6 +11,8 @@
namespace app\model\class_grade;
use app\model\campus\Campus;
use app\model\personnel\Personnel;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
@ -219,7 +221,13 @@ class ClassGrade extends BaseModel
}
public function campus(){
return $this->hasOne(Campus::class, 'id', 'campus_id')->joinType('left')->withField('campus_name,id')->bind(['campus_id_name'=>'campus_name']);
}
public function personnel(){
return $this->hasOne(Personnel::class, 'id', 'head_coach')->joinType('left')->withField('name,id')->bind(['head_coach_name'=>'name']);
}

148
niucloud/app/model/classroom/Classroom.php

@ -1,148 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\model\classroom;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use app\model\campus\Campus;
use app\model\personnel\Personnel;
/**
* 场地管理模型
* Class Classroom
* @package app\model\classroom
*/
class Classroom extends BaseModel
{
use SoftDelete;
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'class';
/**
* 定义软删除标记字段.
* @var string
*/
protected $deleteTime = 'deleted_at';
/**
* 定义软删除字段的默认值.
* @var int
*/
protected $defaultSoftDelete = 0;
/**
* 搜索器:场地管理所属校区
* @param $value
* @param $data
*/
public function searchCampusIdAttr($query, $value, $data)
{
if ($value) {
$query->where("campus_id", $value);
}
}
/**
* 搜索器:场地管理班级名称
* @param $value
* @param $data
*/
public function searchClassNameAttr($query, $value, $data)
{
if ($value) {
$query->where("class_name", $value);
}
}
/**
* 搜索器:场地管理主教练
* @param $value
* @param $data
*/
public function searchHeadCoachAttr($query, $value, $data)
{
if ($value) {
$query->where("head_coach", $value);
}
}
/**
* 搜索器:场地管理班级类型
* @param $value
* @param $data
*/
public function searchClassTypeAttr($query, $value, $data)
{
if ($value) {
$query->where("class_type", $value);
}
}
/**
* 搜索器:场地管理助教
* @param $value
* @param $data
*/
public function searchAssistantCoachAttr($query, $value, $data)
{
if ($value) {
$query->where("assistant_coach", $value);
}
}
/**
* 搜索器:场地管理创建时间
* @param $value
* @param $data
*/
public function searchCreatedAtAttr($query, $value, $data)
{
if ($value) {
$query->where("created_at", $value);
}
}
/**
* 搜索器:场地管理班级状态
* @param $value
* @param $data
*/
public function searchStatusAttr($query, $value, $data)
{
if ($value) {
$query->where("status", $value);
}
}
public function campus(){
return $this->hasOne(Campus::class, 'id', 'campus_id')->joinType('left')->withField('campus_name,id')->bind(['campus_id_name'=>'campus_name']);
}
public function personnel(){
return $this->hasOne(Personnel::class, 'id', 'head_coach')->joinType('left')->withField('name,id')->bind(['head_coach_name'=>'name']);
}
}

135
niucloud/app/model/course_schedule/CourseSchedule.php

@ -50,141 +50,6 @@ class CourseSchedule extends BaseModel
*/
protected $defaultSoftDelete = 0;
/**
* 搜索器:课程安排课程安排编号
* @param $value
* @param $data
*/
public function searchIdAttr($query, $value, $data)
{
if ($value) {
$query->where("id", $value);
}
}
/**
* 搜索器:课程安排校区ID
* @param $value
* @param $data
*/
public function searchCampusIdAttr($query, $value, $data)
{
if ($value) {
$query->where("campus_id", $value);
}
}
/**
* 搜索器:课程安排场地ID
* @param $value
* @param $data
*/
public function searchVenueIdAttr($query, $value, $data)
{
if ($value) {
$query->where("venue_id", $value);
}
}
/**
* 搜索器:课程安排上课日期
* @param $value
* @param $data
*/
public function searchCourseDateAttr($query, $value, $data)
{
if ($value) {
$query->where("course_date", $value);
}
}
/**
* 搜索器:课程安排上课时段
* @param $value
* @param $data
*/
public function searchTimeSlotAttr($query, $value, $data)
{
if ($value) {
$query->where("time_slot", $value);
}
}
/**
* 搜索器:课程安排课程ID
* @param $value
* @param $data
*/
public function searchCourseIdAttr($query, $value, $data)
{
if ($value) {
$query->where("course_id", $value);
}
}
/**
* 搜索器:课程安排上课教练ID
* @param $value
* @param $data
*/
public function searchCoachIdAttr($query, $value, $data)
{
if ($value) {
$query->where("coach_id", $value);
}
}
/**
* 搜索器:课程安排参与人员列表
* @param $value
* @param $data
*/
public function searchParticipantsAttr($query, $value, $data)
{
if ($value) {
$query->where("participants", $value);
}
}
/**
* 搜索器:课程安排上课学生列表
* @param $value
* @param $data
*/
public function searchStudentIdsAttr($query, $value, $data)
{
if ($value) {
$query->where("student_ids", $value);
}
}
/**
* 搜索器:课程安排根据场地容量判断的可安排学员位置数量
* @param $value
* @param $data
*/
public function searchAvailableCapacityAttr($query, $value, $data)
{
if ($value) {
$query->where("available_capacity", $value);
}
}
/**
* 搜索器:课程安排课程状态:
* @param $value
* @param $data
*/
public function searchStatusAttr($query, $value, $data)
{
if ($value) {
$query->where("status", $value);
}
}
}

32
niucloud/app/model/rel/ClassPersonnelRel.php

@ -0,0 +1,32 @@
<?php
namespace app\model\rel;
use app\model\personnel\Personnel;
use app\model\student\Student;
use core\base\BaseModel;
class ClassPersonnelRel extends BaseModel
{
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'class_personnel_rel';
public function personnel()
{
return $this->hasOne(Personnel::class, 'id', 'personnel_id');
}
public function student()
{
return $this->hasOne(Student::class, 'id', 'source_id');
}
}

48
niucloud/app/service/admin/classroom/ClassroomService.php

@ -11,10 +11,12 @@
namespace app\service\admin\classroom;
use app\model\classroom\Classroom;
use app\model\class_grade\ClassGrade;
use app\model\campus\Campus;
use app\model\course_schedule\CourseSchedule;
use app\model\personnel\Personnel;
use app\model\rel\ClassPersonnelRel;
use core\base\BaseAdminService;
@ -28,7 +30,7 @@ class ClassroomService extends BaseAdminService
public function __construct()
{
parent::__construct();
$this->model = new Classroom();
$this->model = new ClassGrade();
}
/**
@ -41,7 +43,7 @@ class ClassroomService extends BaseAdminService
$field = 'id,campus_id,campus_name,class_name,head_coach,age_group,class_type,assistant_coach,created_at,updated_at,deleted_at,status,sort_order,remarks';
$order = 'id desc';
$search_model = $this->model->withSearch(["campus_id","class_name","head_coach","class_type","assistant_coach","created_at","status"], $where)->with(['campus','personnel','personnel'])->field($field)->order($order);
$search_model = $this->model->withSearch(["campus_id", "class_name", "head_coach", "class_type", "assistant_coach", "created_at", "status"], $where)->with(['campus', 'personnel', 'personnel'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
@ -55,8 +57,8 @@ class ClassroomService extends BaseAdminService
{
$field = 'id,campus_id,campus_name,class_name,head_coach,age_group,class_type,assistant_coach,created_at,updated_at,deleted_at,status,sort_order,remarks';
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['campus','personnel','personnel'])->findOrEmpty()->toArray();
$info['status'] = strval($info['status']);
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['campus', 'personnel', 'personnel'])->findOrEmpty()->toArray();
$info['status'] = strval($info['status']);
return $info;
}
@ -97,22 +99,40 @@ class ClassroomService extends BaseAdminService
return $res;
}
public function getCampusAll(){
$campusModel = new Campus();
return $campusModel->select()->toArray();
public function getCampusAll()
{
$campusModel = new Campus();
return $campusModel->select()->toArray();
}
public function getPersonnelAll(){
$personnelModel = new Personnel();
return $personnelModel->select()->toArray();
public function getPersonnelAll()
{
$personnelModel = new Personnel();
return $personnelModel->select()->toArray();
}
public function classroom_all()
{
$data = $this->model->where('status', 1)->order('sort_order desc')->select()->toArray();
return $data;
$data = $this->model->where('status', 1)->order('sort_order desc')->select()->toArray();
return $data;
}
public function getClassroompeople($class_id)
{
$listmodel = new ClassPersonnelRel();
return $listmodel->with(['student','personnel'])->where('class_id', $class_id)->select()->toArray();
}
/**
* 获取班级当前时段人员安排情况
*/
public function getClassroompeopleCount($venue_id,$where = [])
{
$listmodel = new CourseSchedule();
return $listmodel->where('venue_id', $venue_id)
->where($where)
->select()
->toArray();
}
}

Loading…
Cancel
Save