Browse Source

课表更改

lrf402788946 5 years ago
parent
commit
785392830f

+ 6 - 0
src/router/index.js

@@ -306,6 +306,12 @@ const train = [
     meta: { title: '期课表' },
     component: () => import('@/views/train-plan/term-lesson.vue'),
   },
+  {
+    path: '/train/plan/class/lesson',
+    name: 'train_plan_class_lesson',
+    meta: { title: '班课表' },
+    component: () => import('@/views/train-plan/class-lesson.vue'),
+  },
   {
     path: '/train/plan/remind',
     name: 'train_plan_remind',

+ 1 - 0
src/views/home/leave.vue

@@ -47,6 +47,7 @@ export default {
             fill: 'black',
           },
         },
+        columnSize: 100,
         forceFit: true,
         data,
         padding: 'auto',

+ 66 - 25
src/views/lesson/detail.vue

@@ -13,22 +13,38 @@
         </template>
         <template #custom="{item}">
           <template v-if="item.model === 'lesson'">
-            <el-table :data="lessons" stripe border>
-              <el-table-column align="center" label="时间" prop="time"></el-table-column>
-              <el-table-column align="center" label="第一天" prop="day1"></el-table-column>
-              <el-table-column align="center" label="第二天" prop="day2"></el-table-column>
-              <el-table-column align="center" label="第三天" prop="day3"></el-table-column>
-              <el-table-column align="center" label="第四天" prop="day4"></el-table-column>
-              <el-table-column align="center" label="第五天" prop="day5"></el-table-column>
-              <el-table-column align="center" label="第六天" prop="day6"></el-table-column>
-              <el-table-column label="操作" align="center">
-                <template v-slot="{ row, $index }">
-                  <el-tooltip :key="$index" effect="dark" content="编辑" placement="bottom">
-                    <el-button type="text" size="mini" icon="el-icon-edit" @click="toEdit(row, $index)"></el-button>
-                  </el-tooltip>
-                </template>
-              </el-table-column>
-            </el-table>
+            <el-row>
+              <el-col :span="24" style="text-align:right; padding:10px">
+                <el-button type="primary" size="mini" @click="drawer = true">添加时间段</el-button>
+              </el-col>
+              <el-col :span="24">
+                <el-table :data="lessons" stripe border>
+                  <el-table-column align="center" label="时间" prop="time"></el-table-column>
+                  <el-table-column align="center" label="第一天" prop="day1"></el-table-column>
+                  <el-table-column align="center" label="第二天" prop="day2"></el-table-column>
+                  <el-table-column align="center" label="第三天" prop="day3"></el-table-column>
+                  <el-table-column align="center" label="第四天" prop="day4"></el-table-column>
+                  <el-table-column align="center" label="第五天" prop="day5"></el-table-column>
+                  <el-table-column align="center" label="第六天" prop="day6"></el-table-column>
+                  <el-table-column label="操作" align="center">
+                    <template v-slot="{ row, $index }">
+                      <el-row type="flex" align="middle" justify="center">
+                        <el-col :span="4">
+                          <el-tooltip :key="$index" effect="dark" content="编辑" placement="bottom">
+                            <el-button type="text" size="mini" icon="el-icon-edit" @click="toEdit(row, $index)"></el-button>
+                          </el-tooltip>
+                        </el-col>
+                        <el-col :span="4">
+                          <el-tooltip :key="$index" effect="dark" content="删除" placement="bottom">
+                            <el-button type="text" size="mini" icon="el-icon-delete" @click="todelete(row, $index)"></el-button>
+                          </el-tooltip>
+                        </el-col>
+                      </el-row>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </el-col>
+            </el-row>
           </template>
         </template>
       </data-form>
@@ -83,6 +99,7 @@
 </template>
 
 <script>
+var moment = require('moment');
 import detailFrame from '@frame/layout/admin/detail-frame';
 import dataForm from '@frame/components/form';
 import { lesson as lessons } from '@frame/config/lesson-template';
@@ -187,19 +204,43 @@ export default {
     },
     handleOsave({ data }) {
       //TODO 将对应另一天的课也改了
-      console.log(data);
+      let { index } = data;
+      if (!_.isArray(_.get(data, 'time'))) {
+        this.$message.error('时间格式错误');
+        console.warning('时间不是数组,之后无法进行转换');
+        return;
+      }
       data.time = _.join(data.time, '-');
-      let index = JSON.parse(JSON.stringify(data.index));
-      let keys = Object.keys(data);
-      let midArr = keys.filter(f => /^day\d$/.test(f));
-      for (const key of midArr) {
-        if (data[`${key}type`] === '课程') data[key] = this.subjectList.find(f => f.id === data[`${key}subid`]).name;
-        else delete data[`${key}subid`];
+      if (index != undefined && index >= 0) {
+        let keys = Object.keys(data);
+        let midArr = keys.filter(f => /^day\d$/.test(f));
+        for (const key of midArr) {
+          if (data[`${key}type`] === '课程') data[key] = this.subjectList.find(f => f.id === data[`${key}subid`]).name;
+          else delete data[`${key}subid`];
+        }
+        data = _.omit(data, ['index']);
+        this.$set(this.lessons, index, data);
+      } else {
+        this.lessons.push(data);
       }
-      data = _.omit(data, ['index']);
-      this.$set(this.lessons, index, data);
+      this.$set(this, `lessons`, this.getOrderForTime(this.lessons));
       this.drawer = false;
     },
+    todelete(row, index) {
+      this.lessons.splice(index, 1);
+    },
+    //根据时间排序
+    getOrderForTime(data) {
+      let duplicate = JSON.parse(JSON.stringify(data));
+      duplicate = duplicate.sort((a, b) => {
+        let a_arr = a.time.split('-');
+        let b_arr = b.time.split('-');
+        let at = moment(`${moment().format('YYYY-MM-DD')} ${a_arr[0]}`).format('X');
+        let bt = moment(`${moment().format('YYYY-MM-DD')} ${b_arr[0]}`).format('X');
+        return at - bt;
+      });
+      return duplicate;
+    },
     toClose() {
       this.drawer = false;
       this.form = {};

+ 143 - 0
src/views/train-plan/class-lesson.vue

@@ -0,0 +1,143 @@
+<template>
+  <div id="class-lesson">
+    <detail-frame title="班级课表" returns="/train/plan/term/lesson">
+      <class-table ref="lesson" :classInfo="classInfo" @saveResult="getRes"></class-table>
+      <el-divider></el-divider>
+      <info-class
+        ref="classes"
+        :classInfo.sync="classInfo"
+        :locationList="locationList"
+        :lyTeacherList="lyTeacherList"
+        :headTeacherList="headTeacherList"
+        @saveResult="getRes"
+      ></info-class>
+      <el-row type="flex" align="middle" justify="center" class="btn_bar">
+        <el-col :span="2">
+          <el-button type="primary" @click="classSave">保存</el-button>
+        </el-col>
+      </el-row>
+    </detail-frame>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import detailFrame from '@frame/layout/admin/detail-frame';
+import classTable from './parts/class-table';
+import infoClass from './parts/class-info';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: classes } = createNamespacedHelpers('classes');
+//info-class
+const { mapActions: location } = createNamespacedHelpers('location'); //地点
+const { mapActions: teacher } = createNamespacedHelpers('teacher'); //教师
+const { mapActions: dirPlan } = createNamespacedHelpers('dirPlan'); //班主任不能上课的列表
+const { mapActions: teaplan } = createNamespacedHelpers('teaPlan');
+const { mapActions: mapDept } = createNamespacedHelpers('dept'); //配合教师表使用的部门表
+export default {
+  name: 'class-lesson',
+  props: {},
+  components: { detailFrame, classTable, infoClass },
+  data: function() {
+    return {
+      classInfo: {},
+      locationList: [],
+      lyTeacherList: [],
+      headTeacherList: [],
+      deptList: [],
+    };
+  },
+  created() {},
+  methods: {
+    ...classes(['fetch']),
+    ...location({ getLocationList: 'query' }),
+    ...teacher({ getTeacherList: 'query' }),
+    ...dirPlan({ dirQuery: 'getDirTeacher' }),
+    ...mapDept({ getDept: 'query' }),
+    ...teaplan(['findTeacher']),
+    async getClassInfo() {
+      let res = await this.fetch(this.classid);
+      if (this.$checkRes(res)) {
+        this.$set(this, `classInfo`, res.data);
+        this.getSettingLists(this.classInfo);
+      }
+    },
+    classSave() {
+      this.$refs.lesson.toSave();
+      this.$refs.classes.toSave();
+    },
+    getRes({ from, result }) {
+      let r = this.result.find(f => f.from == from);
+      if (r) {
+        console.log(`已有${from}的保存结果,未清除`);
+        return;
+      } else {
+        this.result.push({ from, result });
+      }
+      if (this.result.length == 2) {
+        let resR = this.result.every(e => e.result == true);
+        if (resR) this.$message.success('保存成功');
+        this.$set(this, `result`, []);
+      }
+    },
+    async getSettingLists(data) {
+      let res;
+      if (this.locationList.length <= 0) {
+        res = await this.getLocationList();
+        if (this.$checkRes(res)) this.$set(this, `locationList`, res.data);
+      }
+      if (this.lyTeacherList.length <= 0) {
+        res = await this.getTeacherList({ islyteacher: '1', status: '4' });
+        if (this.$checkRes(res)) this.$set(this, `lyTeacherList`, res.data);
+      }
+      if (this.headTeacherList.length <= 0) {
+        res = await this.findTeacher({ planid: data.planid, termid: data.termid, batchid: data.batchid });
+        let duplicate = _.cloneDeep(res.data);
+        if (this.$checkRes(res)) {
+          if (this.deptList.length <= 0) {
+            let dept = await this.getDept();
+            if (this.$checkRes(res)) this.$set(this, `deptList`, dept.data);
+          }
+          //班主任按部门分组
+          let group = _.groupBy(res.data, 'department');
+          let keys = Object.keys(group);
+          let arr = keys.map(key => {
+            let r = this.deptList.find(f => f.id == key);
+            let obj = {};
+            if (r) {
+              obj.name = r.name;
+              obj.list = group[key];
+            }
+            return obj;
+          });
+          this.$set(this, `headTeacherList`, arr);
+          //班主任筛选可以当礼仪老师列表,和 礼仪教师列表合并
+          duplicate = duplicate.filter(f => f.islyteacher == '1');
+          this.$set(this, `lyTeacherList`, [...this.lyTeacherList, ...duplicate]);
+        }
+      }
+    },
+  },
+  watch: {
+    classid: {
+      immediate: true,
+      handler(val) {
+        if (val) this.getClassInfo();
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    classid() {
+      return this.$route.query.classid;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 1 - 0
src/views/train-plan/lesson.vue

@@ -1,5 +1,6 @@
 <template>
   <div id="lesson">
+    <!-- 弃用 -->
     <detail-frame :title="pageTitle" v-show="view == 'list'">
       <el-row type="flex" align="middle" justify="end" class="btn_bar">
         <el-col :span="2">

+ 4 - 1
src/views/train-plan/parts/class-info.vue

@@ -44,7 +44,7 @@ export default {
   data: function() {
     var that = this;
     return {
-      form: _.cloneDeep(that.classInfo),
+      // form: {},
       fields: [
         // { label: '', model: 'name', type: 'text' },
         // { label: '人数', model: 'number', type: 'text' },
@@ -75,6 +75,9 @@ export default {
     pageTitle() {
       return `${this.$route.meta.title}`;
     },
+    form() {
+      return _.cloneDeep(this.classInfo);
+    },
   },
   metaInfo() {
     return { title: this.$route.meta.title };

+ 60 - 11
src/views/train-plan/parts/class-table.vue

@@ -4,9 +4,9 @@
       <template #header>
         <el-row type="flex" align="middle" justify="space-between">
           <el-col :span="4">课程安排</el-col>
-          <!-- <el-col :span="2">
-            <el-button type="primary" size="mini" @click="toSave">保存课表</el-button>
-          </el-col> -->
+          <el-col :span="2">
+            <el-button type="primary" size="mini" @click="drawerTime = true">添加时间段</el-button>
+          </el-col>
         </el-row>
       </template>
       <el-table :data="lessonList" border stripe @cell-click="cellClick">
@@ -45,6 +45,29 @@
         </template>
       </data-form>
     </el-drawer>
+    <el-drawer :visible.sync="drawerTime" direction="rtl" title="课程时间安排" @close="toClose">
+      <el-form :model="form" size="mini" style="padding:20px">
+        <el-form-item label="时间">
+          <el-time-picker
+            v-model="form.time"
+            placeholder="请选择时间"
+            :is-range="true"
+            value-format="HH:mm"
+            :picker-options="{ format: 'HH:mm' }"
+          ></el-time-picker>
+        </el-form-item>
+        <el-form-item>
+          <el-row type="flex" align="middle" justify="center">
+            <el-col :span="4">
+              <el-button type="primary" plain @click="hsavetime('save')">保存</el-button>
+            </el-col>
+            <el-col :span="4">
+              <el-button type="danger" plain v-if="form && form.index >= 0" @click="hsavetime('delete')">删除</el-button>
+            </el-col>
+          </el-row>
+        </el-form-item>
+      </el-form>
+    </el-drawer>
 
     <el-dialog title="选择教师" :visible.sync="dialog" :destroy-on-close="true">
       <teacher-select :schoolList="schoolList" :subjectList="subjectList" :subjectid="form.subid" @selTea="selTea"> </teacher-select>
@@ -82,6 +105,7 @@ export default {
       teacherList: [],
       schoolList: [], //给选老师组件用
       drawer: false,
+      drawerTime: false,
       dialog: false,
       form: {},
       fields: [
@@ -145,13 +169,23 @@ export default {
     },
     //点击单元格事件
     cellClick(row, column) {
-      let date = _.get(column, 'label');
-      let time = _.get(row, 'time');
-      let num = _.get(column, 'property').match(/\d+(.\d+)?/g)[0];
-      let obj = this.getOrderDate(row, num);
-      obj.type = obj.subid ? '课程' : '活动';
-      this.$set(this, `form`, { date, time, ...obj });
-      this.drawer = true;
+      let prop = _.get(column, 'property');
+      if (prop != 'time') {
+        let date = _.get(column, 'label');
+        let time = _.get(row, 'time');
+        let num = _.get(column, 'property').match(/\d+(.\d+)?/g)[0];
+        let obj = this.getOrderDate(row, num);
+        obj.type = obj.subid ? '课程' : '活动';
+        this.$set(this, `form`, { date, time, ...obj });
+        this.drawer = true;
+      } else {
+        let obj = _.cloneDeep(row);
+        let index = this.lessonList.findIndex(f => f.time == obj.time);
+        obj.time = obj.time.split('-');
+        obj.index = index;
+        this.$set(this, `form`, obj);
+        this.drawerTime = true;
+      }
     },
     //抽屉保存
     handleSave({ data }) {
@@ -243,7 +277,7 @@ export default {
       if (_.get(data, `teaid_day${index}`)) obj[`teaid`] = _.get(data, `teaid_day${index}`);
       if (_.get(data, `teaname_day${index}`)) obj[`teaname`] = _.get(data, `teaname_day${index}`);
       if (needDate) {
-        //所有的数据都还原了,没必要index了
+        //所有的数据都还原了,没必要index了
         delete obj.index;
         obj.date = this.dateList[index - 1];
       }
@@ -317,6 +351,7 @@ export default {
     //关闭抽屉
     toClose() {
       this.drawer = false;
+      this.drawerTime = false;
       this.form = {};
     },
     //修改类型清除数据
@@ -343,6 +378,20 @@ export default {
     getProp(data, prop) {
       return _.get(data, prop);
     },
+    //时间处理
+    hsavetime(type) {
+      let { index } = this.form;
+      if (type == 'delete') this.lessonList.splice(index, 1);
+      else {
+        let data = _.cloneDeep(this.form);
+        data.time = data.time.join('-');
+        if (index != undefined && index >= 0) this.$set(this.lessonList, index, data);
+        else this.lessonList.push(data);
+      }
+      this.toClose();
+      //重新排序
+      this.$set(this, `lessonList`, this.getOrderForTime(this.lessonList));
+    },
   },
   computed: {
     ...mapState(['user']),

+ 21 - 4
src/views/train-plan/parts/term-lesson-table.vue

@@ -17,7 +17,11 @@
         :label="`${i.name}班`"
         :prop="`name_${index + 1}`"
         :show-overflow-tooltip="true"
-      ></el-table-column>
+      >
+        <template #header="{column, $index}">
+          <el-link type="primary" :underline="false" @click="handleToClass(index)">{{ column.label }}</el-link>
+        </template>
+      </el-table-column>
       <!-- <el-table-column align="center" label="2班(需要改班级名)" prop="name_2" :show-overflow-tooltip="true"></el-table-column> -->
     </el-table>
   </div>
@@ -75,6 +79,10 @@ export default {
         this.$message.warning('此项不允许更改');
       }
     },
+    handleToClass(index) {
+      let classid = _.get(this.classList[index], 'classid');
+      this.$emit('toOneClass', classid);
+    },
   },
   filters: {
     getWeekDay(date) {
@@ -91,11 +99,20 @@ export default {
       if (this.data.length > 0) {
         let midarr = this.data.filter(f => f.type == 'lesson');
         let mid = _.head(midarr);
-        let keys = Object.keys(mid).filter(f => f.includes('class_'));
+        let keys = Object.keys(mid)
+          .filter(f => f.includes('class'))
+          .map(key => key.match(/\d+(.\d+)?/g)[0]);
+        let ckeys = Object.keys(mid).filter(f => f.match(/(class*)/g));
         for (const key of keys) {
-          let name = mid[key];
-          res.push({ name });
+          let r = ckeys.filter(f => f.includes(key));
+          let obj = {};
+          for (const ckey of r) {
+            if (ckey.includes('id')) obj.classid = mid[ckey];
+            else obj.name = mid[ckey];
+          }
+          res.push(obj);
         }
+        res = _.uniqBy(res, 'classid');
       }
       return res;
     },

+ 48 - 10
src/views/train-plan/term-lesson.vue

@@ -1,14 +1,17 @@
 <template>
   <div id="term-lesson">
-    <detail-frame :title="pageTitle" returns="/train/plan/lesson">
-      <el-row type="flex" align="middle" justify="end" class="btn_bar">
+    <detail-frame :title="pageTitle">
+      <el-row type="flex" align="middle" justify="end" class="btn_bar" v-if="!loading">
         <el-col :span="2">
-          <el-button type="primary" size="mini" @click="allSave" v-if="!loading">保存期课表</el-button>
+          <el-button type="primary" size="mini" plain @click="toArrange">按模板排课</el-button>
+        </el-col>
+        <el-col :span="2">
+          <el-button type="primary" size="mini" @click="allSave">保存期课表</el-button>
         </el-col>
       </el-row>
       <el-row type="flex" v-loading="loading" style="min-height:500px">
         <el-col :span="8" v-for="(i, index) in list" :key="index">
-          <lesson-table :data="i" :batch="`${index + 1}`" @lesson="toLesson" @other="toOther"></lesson-table>
+          <lesson-table :data="i" :batch="`${index + 1}`" @lesson="toLesson" @other="toOther" @toOneClass="toOneClass"></lesson-table>
         </el-col>
       </el-row>
     </detail-frame>
@@ -117,6 +120,12 @@ export default {
       let lessons = await this.getLesson({ termid });
       if (this.$checkRes(lessons)) {
         lessonList = lessons.data;
+        if (lessonList.length <= 0) {
+          this.toArrange(false);
+          // this.$message.warning('班级没有按模板初始化,请按模板初始化后再进入期课表');
+          // this.loading = false;
+          return;
+        }
         this.$set(this, `lessonList`, lessonList);
       }
       let classes = await this.getClass({ termid });
@@ -127,11 +136,7 @@ export default {
         }
         this.$set(this, `classList`, classList);
       }
-      if (this.lessonList.length <= 0) {
-        this.$message.warning('班级没有按模板初始化,请按模板初始化后再进入期课表');
-        this.loading = false;
-        return;
-      }
+
       let arr = classList.map(i => {
         let r = lessonList.find(f => f.classid == i._id);
         if (r) {
@@ -354,7 +359,6 @@ export default {
       this.$set(this, `form`, data);
       this.dloading = false;
     },
-    toDeleteDate() {},
     lessonSave(data) {
       let { index, batch, is_last, allday, ...info } = data;
       if (is_last) {
@@ -607,6 +611,40 @@ export default {
       }
       return res;
     },
+    //查看某班课表
+    toOneClass(classid) {
+      this.$router.push({ path: '/train/plan/class/lesson', query: { classid } });
+    },
+    //课表模板排课
+    async toArrange(needAlert = true) {
+      let planid = _.get(this.defaultOption, 'planid');
+      if (needAlert)
+        this.$confirm('此操作将会将默认 年度计划 下所有的班级课表重置,若您已经修改过某班的信息,请谨慎使用', '提示', {
+          confirmButtonText: '按模板排课',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+          .then(async () => {
+            let res = await this.autoArrange(planid);
+            this.$checkRes(res, '排课成功', res.errmsg || '排课失败');
+          })
+          .catch(async () => {
+            console.log('已取消');
+          });
+      else {
+        let msg = this.$message({
+          message: '首次进入,计划未排课,正在按模板进行排课中...',
+          duration: 0,
+        });
+        let res = await this.autoArrange(planid);
+        msg.close();
+        if (this.$checkRes(res, '排课成功', res.errmsg || '排课失败')) {
+          this.search();
+        } else {
+          this.loading = false;
+        }
+      }
+    },
   },
   computed: {
     ...mapState(['user', 'defaultOption']),