123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570 |
- <template>
- <div class="courseArrangeClassSchedule">
- <van-cell-group title="学生">
- <van-cell
- v-for="stu in students"
- :key="stu.userId"
- :title="stu.username"
- :value="stu.phone"
- ></van-cell>
- </van-cell-group>
- <van-cell-group title="课程信息">
- <!-- <van-cell
- title="分部"
- :value="formData.fenbu ? formData.fenbu.name : '请选择'"
- is-link
- @click="show.fenbu = true"
- ></van-cell> -->
- <van-cell
- title="课程类型"
- :value="activeCourse.name"
- ></van-cell>
- <!-- <van-cell
- title="课程形式"
- :value="activeCourse.name"
- ></van-cell> -->
- <van-cell title="排课声部" :value="activeCourse.subjectName"></van-cell>
- <van-cell
- title="乐团主管"
- :value="educational.userId ? educational.realName : '请选择'"
- is-link
- @click="onShowEducational"
- ></van-cell>
- </van-cell-group>
- <van-cell-group title="课程安排">
- <van-cell
- title="单课时时长"
- :value="activeCourse.courseTime + '分钟'"
- ></van-cell>
- <van-cell title="可排课时" :value="courseNum"></van-cell>
- <!-- <van-cell
- v-if="activeCourse.coursesStartTime"
- title="最早排课时间"
- :value="activeCourse.coursesStartTime"
- ></van-cell>
- <van-cell
- v-if="activeCourse.coursesEndTime"
- title="最晚排课时间"
- :value="activeCourse.coursesEndTime"
- ></van-cell> -->
- <van-field
- label="线上课次数"
- input-align="right"
- placeholder="请输入排课次数"
- type="digit"
- v-model="frequency.online"
- :formatter="formatterOnline"
- ></van-field>
- <van-field
- v-if="this.activityId != 0"
- label="线下课次数"
- input-align="right"
- placeholder="请输入排课次数"
- type="digit"
- v-model="frequency.offline"
- :formatter="formatterOffline"
- ></van-field>
- <van-cell
- v-if="frequency.offline > 0"
- title="线下课地址"
- :value="adddress.id ? adddress.name : '请选择'"
- is-link
- @click="onShowAddress"
- ></van-cell>
- <van-cell
- title="排课开始时间"
- :value="formatterDate(formData.time)"
- is-link
- @click="show.date = true"
- ></van-cell>
- </van-cell-group>
- <van-cell-group style="margin: 12px 16px;">
- <van-cell v-for="(item, index) in scheduleList" :key="index">
- <template #title>
- <div class="course-item">
- <span>{{ item.type }}</span>
- <span style="margin: 0 16px;">{{ item.weekStr }}</span>
- <span>{{ item.startTime }} ~ {{ item.endTime }}</span>
- <van-icon
- class="clear-icon"
- name="cross"
- size="18"
- @click="onDeleteSchedule(index)"
- />
- </div>
- </template>
- </van-cell>
- <van-cell>
- <template #title>
- <div class="course-item" style="justify-content: center;">
- <van-button size="small" icon="plus" @click="show.course = true"
- >添加课时安排</van-button
- >
- </div>
- </template>
- </van-cell>
- </van-cell-group>
- <van-cell
- title="排课列表"
- value="查看"
- is-link
- @click="onShowCourseList"
- ></van-cell>
- <div style="padding: 10px 30px">
- <van-button round block type="info" @click="onSubmit">确认</van-button>
- </div>
- <van-popup v-model="show.teacher" position="bottom">
- <!-- <TeacherModal
- @close="show.teacher = false"
- @onSelectTeacher="onSelectTeacher"
- /> -->
- </van-popup>
- <!-- 排课开始时间 -->
- <van-popup v-model="show.date" position="bottom">
- <van-datetime-picker
- v-model="formData.time"
- type="date"
- @cancel="show.date = false"
- @confirm="show.date = false"
- />
- </van-popup>
- <!-- 课时安排 -->
- <van-popup v-model="show.course" position="bottom">
- <CourseModal
- :scheduleList="scheduleList"
- :singleClassMinutes="activeCourse.courseTime"
- @close="show.course = false"
- />
- </van-popup>
- <!-- 课表展示 -->
- <van-popup v-model="show.timeTable" position="bottom">
- <van-row>
- <van-col span="12">上课类型</van-col>
- <van-col span="12">上课时间</van-col>
- </van-row>
- <div class="tableContainer">
- <van-row v-for="(item, index) in timeTable" :key="index">
- <van-col span="12">
- {{ item.teachMode == "ONLINE" ? "线上" : "线下" }}
- </van-col>
- <van-col span="12">
- {{ item.classDate }} {{ item.startClassTimeStr }}
- </van-col>
- </van-row>
- </div>
- </van-popup>
- <!-- 乐团主管 -->
- <van-popup v-model="show.fenbu" position="bottom">
- <van-picker
- title="乐团主管"
- :loading="educationalLoading"
- :columns="educationalList"
- value-key="userName"
- show-toolbar
- @cancel="show.fenbu = false"
- @confirm="onSetEducational"
- />
- </van-popup>
- <!-- 选择线下课地址 -->
- <van-popup
- v-model="show.address"
- :lock-scroll="true"
- position="bottom"
- :style="{ height: '5.16rem', overflow: 'hidden' }"
- class="studentChose"
- >
- <AddressList
- @close="show.address = false"
- :teacherId="teacher.id"
- @submit="onSelectAddress"
- />
- </van-popup>
- </div>
- </template>
- <script>
- import AddressList from "./modal/addressList.vue";
- // import TeacherModal from "../applyActive/modal/teacher-modal";
- import CourseModal from "./modal/course";
- import MHeader from "../../components/MHeader.vue";
- import { findSubSubjects, findEducationUsers } from "@/api/teacher";
- import {
- createPracticeGroup,
- createVipCourse,
- getActiveCourseInfo,
- } from "./api.js";
- import dayjs from "dayjs";
- export default {
- name: "classSchedule",
- components: { CourseModal, AddressList, MHeader},
- data() {
- return {
- activityId: this.$route.query.activityId,
- show: {
- fenbu: false,
- teacher: false,
- date: false,
- course: false,
- timeTable: false,
- address: false,
- },
- students: [],
- activeCourse: {},
- frequency: {
- // 线上,线下排课
- online: "",
- offline: "",
- },
- formData: {
- time: new Date(),
- fenbu: "",
- fullOrganId: "",
- },
- teacher: {},
- adddress: {},
- educational: {},
- scheduleList: [], // 课时安排
- timeTable: [], // 生成的课表
- allBranch: [], // 分部
- educationalList: [], //乐团主管
- educationalLoading: false
- };
- },
- computed: {
- courseNum() {
- const mins = this.students.map((n) => parseInt(n.subCourseNum));
- return Math.min(...mins);
- },
- },
- async mounted() {
- this.students = this.$store.state.activeStudents;
- this.activeCourse = this.$store.state.activeCourse;
- // await this.$store.dispatch("setAllBranch");
- // this.allBranch = this.$store.state.allBranch;
- // if (this.allBranch.length) {
- // this.formData.fenbu = this.allBranch[0];
- // }
- },
- methods: {
- onSelectTeacher(val) {
- this.teacher = {
- id: val.id,
- realName: val.realName,
- };
- },
- onSetBranch(val) {
- // 设置分部
- console.log(val);
- this.formData.fenbu = val;
- this.show.fenbu = false;
- },
- formatterOnline(val) {
- // 线上排课次数
- const n = this.courseNum - this.frequency.offline || 0;
- if (val > n) {
- return n;
- }
- return val;
- },
- formatterOffline(val) {
- // 线下排课次数
- const n = this.courseNum - this.frequency.online || 0;
- if (val > n) {
- return n;
- }
- return val;
- },
- formatterDate(date) {
- return dayjs(date).format("YYYY-MM-DD");
- },
- onDeleteSchedule(index) {
- // 删除课时安排
- this.scheduleList.splice(index, 1);
- },
- async onShowEducational(){ // 显示乐团主管
- this.show.fenbu = true
- if (this.educationalList.length) return
- this.educationalLoading = true
- try {
- const {data} = await findEducationUsers()
- // console.log(data)
- if (data.code == 200 && data.data && data.data.EDUCATION) {
- const EDUCATION = data.data.EDUCATION || [];
- this.educationalList = EDUCATION;
- } else {
- this.$toast("暂无乐团主管");
- }
- } catch (error) {
-
- }
- this.educationalLoading = false
- },
- onSetEducational(val){
- this.educational = val
- this.show.fenbu = false;
- },
- onShowAddress() {
- this.show.address = true;
- },
- onSelectAddress(val) {
- // 设置线下课地址
- this.adddress = val;
- this.show.address = false;
- },
- onShowCourseList(isShowPopup = true) {
- // 展示排课列表
- if (!this.scheduleList.length) {
- return this.$toast("缺少课时安排");
- }
- const online = parseInt(this.frequency.online || 0);
- const offline = parseInt(this.frequency.offline || 0);
- if (!online && !offline) {
- return this.$toast("缺少线上或线下上课次数");
- }
- if (online + offline > this.courseNum) {
- return this.$toast("线上 + 线下 总课时不能大于可排课次数");
- }
- if (online && !this.scheduleList.filter((n) => n.type == "线上").length) {
- return this.$toast("课时安排缺少线上课类型");
- }
- if (
- offline &&
- !this.scheduleList.filter((n) => n.type == "线下").length
- ) {
- return this.$toast("课时安排缺少线下课类型");
- }
- if (offline && !this.adddress.id) {
- this.$toast("请选择线下教学地址");
- return;
- }
- if (!this.formData.time) {
- return this.$toast("缺少排课开始时间");
- }
- this.setTimeTable();
- isShowPopup && (this.show.timeTable = true);
- },
- setTimeTable() {
- // 重置排课列表
- let timeTable = [];
- let online = parseInt(this.frequency.online);
- let offline = parseInt(this.frequency.offline);
- let scheduleList = this.scheduleList;
- let totalCount = parseInt(online || 0) + parseInt(offline || 0);
- let dateOperation = new Date(this.formData.time);
- // console.log(dateOperation.toLocaleDateString());
- let forMark = 0;
- // console.log('totalCount',totalCount)
- while (totalCount && totalCount > 0) {
- for (let i = 0; i < scheduleList.length; i++) {
- if (online == 0 && offline == 0) break;
- let num = scheduleList[i].weekIndex - dateOperation.getDay();
- // 如果是同一天一个周期会出现排课都排到一天
- if (forMark > 0 && num == 0 && i == 0) {
- num = num + 7;
- }
- if (num < 0) {
- // 如果为负数则为下周
- num = num + 7;
- }
- let dataStr = this.getThinkDate(dateOperation, num);
- // 判断是否大于当前时间
- let nowGetTime = new Date().getTime();
- let courseTime = new Date(
- dataStr.replace(/-/gi, "/") +
- " " +
- scheduleList[i].startTime +
- ":00"
- ).getTime();
- // console.log(nowGetTime < courseTime)
- if (nowGetTime < courseTime) {
- let tempArr = {
- classDate: dataStr,
- startClassTimeStr: scheduleList[i].startTime,
- endClassTimeStr: scheduleList[i].endTime,
- };
- if (scheduleList[i].type == "线上" && online > 0) {
- tempArr.teachMode = "ONLINE";
- timeTable.push(tempArr);
- online--;
- totalCount--;
- } else if (scheduleList[i].type == "线下" && offline > 0) {
- tempArr.teachMode = "OFFLINE";
- timeTable.push(tempArr);
- offline--;
- totalCount--;
- }
- }
- }
- // 加一周
- if (scheduleList.length == 1) {
- dateOperation.setDate(dateOperation.getDate() + 7);
- } else if (
- scheduleList.every((item) => item.weekStr === scheduleList[0].weekStr)
- ) {
- // 标记循环次数(标记判断课程安排是不是同一天)
- forMark++;
- }
- }
- timeTable.sort((a, b) => {
- let aStr = dayjs(
- dayjs(a.classDate).format("YYYY-MM-DD") +
- " " +
- a.startClassTimeStr +
- ":00"
- ).valueOf();
- let bStr = dayjs(
- dayjs(b.classDate).format("YYYY-MM-DD") +
- " " +
- b.startClassTimeStr +
- ":00"
- ).valueOf();
- return aStr - bStr;
- });
- this.timeTable = timeTable;
- },
- getThinkDate(date, num) {
- let Stamp = date;
- Stamp.setDate(date.getDate() + num); // 获取当前月数的第几天
- return dayjs(Stamp).format("YYYY-MM-DD");
- },
- async onSubmit() {
- if (!this.educational.userId) {
- this.$toast("选择乐团主管");
- return;
- }
- // 排课
- this.onShowCourseList(false);
- if (!this.timeTable.length) return;
- const online = parseInt(this.frequency.online || 0)
- const offline = parseInt(this.frequency.offline || 0)
- const total = online + offline
- let params = {
- courseSchedules: this.timeTable,
- vipGroupApplyBaseInfo: {
- vipGroupCategoryId: this.activityId,
- subjectId: this.activeCourse.subjectId,
- subjectIdList: this.activeCourse.subjectId,
- singleClassMinutes: this.activeCourse.courseTime,
- totalClassTime: total,
- allCourseNum: total,
- studentNum: this.students.length,
- coursesStart: dayjs(this.formData.time).format("YYYY-MM-DD"),
- organId: this.formData.fenbu.id,
- studentIdList: this.students.map((n) => n.userId).join(","),
- studentId:this.students.map((n) => n.userId).join(","),
- onlineClassesNum: online,
- offlineClassesNum: offline,
- userId: this.teacher.id,
- },
- };
- if (params.vipGroupApplyBaseInfo.offlineClassesNum) {
- // 教学点
- params.vipGroupApplyBaseInfo.teacherSchoolId = this.adddress.id;
- }
- // console.log(params)
- if (this.activityId == 0) {
- params.practiceGroupApplyBaseInfoDto = params.vipGroupApplyBaseInfo
- delete params.vipGroupApplyBaseInfo
- let res = await createPracticeGroup(params);
- if (res.code == 200) {
- this.$toast("排课成功");
- setTimeout(() => {
- history.go(-2);
- }, 1000);
- }
- } else {
- let res = await createVipCourse(params);
- if (res.code == 200) {
- this.$toast("排课成功");
- setTimeout(() => {
- history.go(-2);
- }, 1000);
- }
- }
- },
- },
- };
- </script>
- <style>
- body{
- background: #f3f4f8;
- }
- </style>
- <style lang="less" scoped>
- .course-item {
- display: flex;
- align-content: center;
- .clear-icon {
- display: flex;
- align-items: center;
- margin-left: auto;
- }
- }
- </style>
- <style lang="less">
- .courseArrangeClassSchedule {
- .van-cell__value,
- .van-field__label {
- color: #323233;
- }
- }
- .van-row {
- line-height: 0.4rem;
- border-top: 1px solid #edeef0;
- text-align: center;
- font-size: 0.14rem;
- &:first-child {
- border-top: 0;
- background: #edeef0;
- color: #444;
- font-size: 0.15rem;
- }
- }
- .tableContainer {
- max-height: 2.44rem;
- overflow: auto;
- .van-row {
- color: #444;
- &:first-child {
- border-top: 0;
- background: #fff;
- font-size: 0.14rem;
- }
- }
- }
- </style>
|