Просмотр исходного кода

Merge branch 'master' of http://git.cc-lotus.info/new_train/train-center

guhongwei 4 лет назад
Родитель
Сommit
1a5967ca05

+ 6 - 0
src/router/index.js

@@ -457,6 +457,12 @@ const train = [
     meta: { title: '课程培训' },
     component: () => import('@/views/trainVidoe/viewVideo.vue'),
   },
+  {
+    path: '/experience/index',
+    name: 'train_experience',
+    meta: { title: '培训心得' },
+    component: () => import('@/views/train-plan/experience.vue'),
+  },
 ];
 
 const statistics = [

+ 2 - 0
src/store/index.js

@@ -42,6 +42,7 @@ import trainvideo from '@frame/store/trainvideo';
 import personalscore from '@frame/store/personalscore';
 import groupscore from '@frame/store/groupscore';
 import cerconfirm from '@frame/store/cerconfirm';
+import experience from '@frame/store/experience';
 import * as ustate from '@frame/store/user/state';
 import * as umutations from '@frame/store/user/mutations';
 import * as dostate from '@frame/store/setting/state';
@@ -96,6 +97,7 @@ export default new Vuex.Store({
     personalscore,
     groupscore,
     cerconfirm,
+    experience,
   },
   state: { ...ustate, ...dostate },
   mutations: { ...umutations, ...domutations },

+ 2 - 2
src/views/home.vue

@@ -15,12 +15,12 @@
         </el-col>
         <el-col :span="12">
           <el-card shadow="hover">
-            <school :school="data.schs"></school>
+            <leave :qj="data.levelqj" :exit="data.levelexit"></leave>
           </el-card>
         </el-col>
         <el-col :span="24" style="margin-top:20px">
           <el-card shadow="hover">
-            <leave :qj="data.levelqj" :exit="data.levelexit"></leave>
+            <school :school="data.schs"></school>
           </el-card>
         </el-col>
       </el-row>

+ 1 - 1
src/views/home/school.vue

@@ -1,6 +1,6 @@
 <template>
   <div id="school">
-    <div id="schoolPie" style="height:400px;"></div>
+    <div id="schoolPie" style="height:800px;"></div>
   </div>
 </template>
 

+ 2 - 2
src/views/new-plan/teacher-lesson.vue

@@ -49,8 +49,8 @@
         <el-row style="text-align:center" class="msgrow">
           <el-col :span="24">请选择需要安排教师期数</el-col>
           <el-checkbox-group v-model="termForm">
-            <el-col :span="6" v-for="(i, index) in termList" :key="index">
-              <el-checkbox :label="i.id">第{{ i.term }}期</el-checkbox>
+            <el-col :span="6" v-for="(i, index) in plan.termnum" :key="index">
+              <el-checkbox :label="i._id">第{{ i.term }}期</el-checkbox>
             </el-col>
           </el-checkbox-group>
         </el-row>

+ 1 - 0
src/views/teacher/index.vue

@@ -138,6 +138,7 @@ export default {
       { label: '姓名', prop: 'name' },
       { label: '性别', prop: 'gender', options: { width: `80px` } },
       { label: '手机号', prop: 'phone' },
+      { label: '账户密码', prop: 'secret' },
 
       { label: '学校名称', prop: 'schname' },
       { label: '邮箱', prop: 'email' },

+ 140 - 0
src/views/train-plan/experience.vue

@@ -0,0 +1,140 @@
+<template>
+  <div id="experience">
+    <list-frame title="培训心得" @query="search" :total="total" :needFilter="false" :needAdd="false" :needPag="true">
+      <el-form size="small" :inline="true">
+        <el-form-item label="班级">
+          <el-select v-model="searchInfo.classid" placeholder="请选择班级">
+            <el-option v-for="(c, index) in classList" :key="index" :label="`${c.name.includes('班') ? c.name : `${c.name}班`}`" :value="c._id"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <to-export></to-export>
+      <data-table :fields="fields" :data="list" :opera="opera" @view="toView" @delete="toDelete"></data-table>
+    </list-frame>
+    <el-dialog :visible.sync="dialog" title="培训心得" @close="toClose" width="30%">
+      <data-form :data="form" :fields="formFields" :rules="{}" :needSave="false">
+        <template #custom="{item, form}">
+          <template v-if="item.model === 'content'">
+            <el-input type="textarea" v-model="form[item.model]" :readonly="true" :autosize="{ minRows: 4, maxRows: 20 }"></el-input>
+          </template>
+        </template>
+      </data-form>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import toExport from './parts/experience-export.vue';
+import listFrame from '@frame/layout/admin/list-frame';
+import dataForm from '@frame/components/form';
+import dataTable from '@frame/components/data-table';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: experience } = createNamespacedHelpers('experience');
+const { mapActions: classes } = createNamespacedHelpers('classes');
+const { mapActions: trainplan } = createNamespacedHelpers('trainplan');
+export default {
+  metaInfo: { title: '培训心得' },
+  name: 'experience',
+  props: {},
+  components: {
+    listFrame,
+    dataTable,
+    dataForm,
+    toExport,
+  },
+  data: () => ({
+    opera: [
+      {
+        label: '查看',
+        icon: 'el-icon-view',
+        method: 'view',
+      },
+      {
+        label: '删除',
+        icon: 'el-icon-delete',
+        method: 'delete',
+      },
+    ],
+    fields: [
+      { label: '姓名', prop: 'stuname' },
+      { label: '职务', prop: 'stujob' },
+    ],
+    list: [],
+    classList: [],
+    searchInfo: {},
+    total: 0,
+    dialog: false,
+    form: {},
+    formFields: [
+      { label: '姓名', model: 'stuname', type: 'text' },
+      { label: '职务', model: 'stujob', type: 'text' },
+      { label: '培训心得标题', model: 'title', type: 'text' },
+      { label: '培训心得', model: 'content', custom: true },
+    ],
+  }),
+  async created() {
+    await this.getOtherList();
+  },
+  computed: { ...mapState(['user', 'defaultOption']) },
+  methods: {
+    ...classes({ getClass: 'query' }),
+    ...experience(['query']),
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      this.$set(this, `total`, 0);
+      const res = await this.query({ ...this.searchInfo, skip, limit });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    async getOtherList() {
+      const { termid } = this.defaultOption;
+      if (!termid) return;
+      const res = await this.getClass({ termid });
+      if (this.$checkRes(res)) {
+        let duplicate = _.cloneDeep(res.data);
+        duplicate = duplicate.map(i => {
+          if (parseInt(i.name)) {
+            i.order = parseInt(i.name);
+          } else {
+            // i.order = i.name;
+          }
+          return i;
+        });
+        duplicate = _.orderBy(duplicate, ['order'], ['asc']);
+        this.$set(this, `classList`, duplicate);
+      }
+    },
+    // 查看
+    toView({ data }) {
+      this.$set(this, `form`, data);
+      this.dialog = true;
+    },
+    // 删除
+    toDelete({ data }) {
+      console.log(data);
+    },
+    // 保存
+    turnSave({ data }) {},
+    // 关闭
+    toClose() {
+      this.form = {};
+      this.dialog = false;
+    },
+  },
+  watch: {
+    searchInfo: {
+      deep: true,
+      handler(val) {
+        if (val) {
+          const keys = Object.keys(val);
+          if (keys.length > 0) this.search();
+        }
+      },
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 467 - 0
src/views/train-plan/parts/excel-term-lesson.vue

@@ -0,0 +1,467 @@
+<template>
+  <div id="excel-term-lesson">
+    <template v-for="(type, typeIndex) in classType">
+      <el-card :body-style="{ overflowX: 'auto', padding: '10px 15px', marginTop: '10px' }" :key="`ct-${typeIndex}`">
+        <table border="1" cellspacing="0" style="border-collapse: collapse">
+          <tr>
+            <template v-for="(b, bindex) in getBatchData(type.code)">
+              <th :key="`dateHeader-${bindex}`" style="position: sticky;">
+                日期
+                <tr>
+                  <template v-for="(d, dindex) in getBatchDayList(b, type.code)">
+                    <td :key="`date-${dindex}`" style="display: grid;min-width:60px;" :style="{ background: getColor(d, dindex, b) }">{{ getMonthDay(d) }}</td>
+                  </template>
+                </tr>
+              </th>
+
+              <th :key="`dayHeader-${bindex}`">
+                星期
+                <tr>
+                  <template v-for="(d, dindex) in getBatchDayList(b, type.code)">
+                    <td :key="`date-${dindex}`" style="display: grid;min-width:60px;" :style="{ background: getColor(d, dindex, b) }">{{ getDay(d) }}</td>
+                  </template>
+                </tr>
+              </th>
+
+              <th :key="`lessonHeader${bindex}`">
+                课程
+                <tr>
+                  <template v-for="(d, dindex) in getBatchDayList(b, type.code)">
+                    <td :key="`date-${dindex}`" class="out" style="display: grid;width:75px;" :style="{ background: getColor(d, dindex, b) }">
+                      {{ getLesson(d, b) }}
+                    </td>
+                  </template>
+                </tr>
+              </th>
+
+              <template v-for="(c, cindex) in b.class">
+                <th :key="`${bindex}-${cindex}`">
+                  {{ c.name.includes('班') ? c.name : `${c.name}班` }}
+                  <tr>
+                    <template v-for="(d, dindex) in getBatchDayList(b, type.code)">
+                      <td :key="`teacher-${dindex}`" class="teacher_td" :style="computedTeacherTdWidth(d, c, dindex, b)" @click="clickTeacher(d, c)">
+                        {{ getTeacher(d, c) }}<br />
+                        <span style="font-size:14px">{{ getTel(d, c) }}</span>
+                        <el-link v-if="checkMsg(d, c)" :type="checkMsg(d, c)" :underline="false" style="font-weight: 600;">
+                          {{ getMsgWord(checkMsg(d, c)) }}
+                        </el-link>
+                      </td>
+                    </template>
+                  </tr>
+                </th>
+              </template>
+            </template>
+          </tr>
+          <tr>
+            <template v-for="(b, bindex) in getBatchData(type.code)">
+              <td :key="`headteacher${bindex}`" colspan="3" :style="{ borderLeft: `${bindex !== '0' ? '1px solid' : '0'}`, height: '60px' }">班主任</td>
+              <template v-for="(c, cindex) in b.class">
+                <td :key="`classheadteacher${bindex}-${cindex}`" style="border-left:1px solid" :style="computedTeacherTdWidth(null, c)" @click="clickClass(c)">
+                  {{ c.headteacher }} <br />
+                  <span style="font-size:14px">{{ getDirTeaTel(c.headteacherid, 'headTeacher') }}</span>
+                  <br />
+                  <el-link v-if="checkMsgDirTea(c, 'headteacher')" :type="checkMsgDirTea(c, 'headteacher')" :underline="false" style="font-weight: 600;">
+                    {{ getMsgWord(checkMsgDirTea(c, 'headteacher')) }}
+                  </el-link>
+                </td>
+              </template>
+            </template>
+          </tr>
+          <tr>
+            <template v-for="(b, bindex) in getBatchData(type.code)">
+              <td :key="`headteacher${bindex}`" colspan="3" :style="{ borderLeft: `${bindex !== '0' ? '1px solid' : '0'}`, height: '60px' }">礼仪教师</td>
+              <template v-for="(c, cindex) in b.class">
+                <td :key="`classheadteacher${bindex}-${cindex}`" style="border-left:1px solid" :style="computedTeacherTdWidth(null, c)" @click="clickClass(c)">
+                  {{ c.lyteacher }} <br />
+                  <span style="font-size:14px">{{ getDirTeaTel(c.lyteacherid, 'both') }}</span> <br />
+                  <el-link v-if="checkMsgDirTea(c, 'lyteacher')" :type="checkMsgDirTea(c, 'lyteacher')" :underline="false" style="font-weight: 600;">
+                    {{ getMsgWord(checkMsgDirTea(c, 'lyteacher')) }}
+                  </el-link>
+                </td>
+              </template>
+            </template>
+          </tr>
+          <tr>
+            <template v-for="(b, bindex) in getBatchData(type.code)">
+              <td :key="`headteacher${bindex}`" colspan="3" :style="{ borderLeft: `${bindex !== '0' ? '1px solid' : '0'}`, height: '40px' }">教室地点</td>
+              <template v-for="(c, cindex) in b.class">
+                <td :key="`classheadteacher${bindex}-${cindex}`" style="border-left:1px solid" :style="computedTeacherTdWidth(null, c)" @click="clickClass(c)">
+                  {{ c.jslocation }}
+                </td>
+              </template>
+            </template>
+          </tr>
+          <tr>
+            <template v-for="(b, bindex) in getBatchData(type.code)">
+              <td :key="`headteacher${bindex}`" colspan="3" :style="{ borderLeft: `${bindex !== '0' ? '1px solid' : '0'}`, height: '40px' }">开班地点</td>
+              <template v-for="(c, cindex) in b.class">
+                <td :key="`classheadteacher${bindex}-${cindex}`" style="border-left:1px solid" :style="computedTeacherTdWidth(null, c)" @click="clickClass(c)">
+                  {{ c.kbyslocation }}
+                </td>
+              </template>
+            </template>
+          </tr>
+          <tr>
+            <template v-for="(b, bindex) in getBatchData(type.code)">
+              <td :key="`headteacher${bindex}`" colspan="3" :style="{ borderLeft: `${bindex !== '0' ? '1px solid' : '0'}`, height: '40px' }">
+                拓展训练地点
+              </td>
+              <template v-for="(c, cindex) in b.class">
+                <td :key="`classheadteacher${bindex}-${cindex}`" style="border-left:1px solid" :style="computedTeacherTdWidth(null, c)" @click="clickClass(c)">
+                  {{ c.kzjhlocation }}
+                </td>
+              </template>
+            </template>
+          </tr>
+          <tr>
+            <template v-for="(b, bindex) in getBatchData(type.code)">
+              <td :key="`headteacher${bindex}`" colspan="3" :style="{ borderLeft: `${bindex !== '0' ? '1px solid' : '0'}`, height: '40px' }">用餐地点</td>
+              <template v-for="(c, cindex) in b.class">
+                <td :key="`classheadteacher${bindex}-${cindex}`" style="border-left:1px solid" :style="computedTeacherTdWidth(null, c)">{{ c.yclocation }}</td>
+              </template>
+            </template>
+          </tr>
+        </table>
+      </el-card>
+    </template>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+const moment = require('moment');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'excel-term-lesson',
+  props: {
+    data: { type: Array, default: () => [] },
+    classType: { type: Array, default: () => [] },
+    teacherList: { type: Array, default: () => [] },
+    noticeList: { type: Array, default: () => [] },
+    subjectList: { type: Array, default: () => [] },
+    headTeacherList: { type: Array, default: () => [] },
+  },
+  components: {},
+  data: function() {
+    return {
+      colorList: ['#E9E7EF', '#E6E6FA', '#FFF0F5', '#FFE4C4', '#E9F1F6', '#FFF2DF', '#E1FFFF', '#FFFFE0', '#F0FFF0', '#F8F8FF'],
+    };
+  },
+  created() {},
+  methods: {
+    // 获取指定班级类型的头
+    getBatchData(type) {
+      // let data = duplicate.batchnum.filter(f => f.class.every(ce => ce.type === type));
+      let dup = _.cloneDeep(this.data);
+      dup = dup.filter(f => f.type === type);
+      let bg = _.groupBy(dup, 'batchid');
+      let keys = Object.keys(bg);
+      const list = keys.map(key => {
+        let obj = {};
+        obj.batchid = key;
+        obj.class = bg[key];
+        return obj;
+      });
+      return list;
+    },
+    // 获取批次的天列表
+    getBatchDayList(batch, type) {
+      // 首先,获取这个期的所有天
+      let dup = _.cloneDeep(this.data);
+      dup = dup.filter(f => f.type === type);
+      const newOrder = _.orderBy(dup, ['startdate'], ['asc']);
+      const firstDay = _.get(_.head(newOrder), 'startdate');
+      const lastDay = _.get(_.last(newOrder), 'enddate');
+      let dayList = this.getDayList(firstDay, lastDay);
+      let batchDay = _.orderBy(batch.class, ['startdate'], ['asc']);
+      const bfd = _.get(_.head(batchDay), 'startdate');
+      const bld = _.get(_.last(batchDay), 'enddate');
+      dayList = dayList.map(i => {
+        const r = moment(i).isBetween(bfd, bld, null, '[]');
+        if (!r) return '-';
+        else return i;
+      });
+      return dayList;
+    },
+    // 获取科目
+    getLesson(date, batch) {
+      // 一批次的课表都一样,就直接取一个出来就行
+      const h = _.head(batch.class);
+      if (!h) {
+        console.error('取出科目-班级数据错误');
+        return;
+      }
+      const { lesson } = h;
+      if (!lesson) {
+        console.warn('取出科目-search中处理课表出现问题');
+        return;
+      }
+      const { lessons } = lesson;
+      if (!lessons) {
+        console.warn('取出科目-这个班的课表没有内容 或 异步引起的问题');
+        return;
+      }
+      const lessonDay = lessons.filter(f => f.date === date);
+      // 这里取出该天的所有安排
+      const r = lessonDay.find(f => f.subid);
+      if (r) {
+        let word = r.subname;
+        if (h.enddate === date) word = `${word}\n` + `(${r.day === '0' ? '全天' : '半天'})`;
+        return word;
+      }
+      return '-';
+    },
+    // 获取该班该天教师的信息
+    getTeacher(date, cla) {
+      const { lesson } = cla;
+      if (!lesson) return '-';
+      const { lessons } = lesson;
+      if (!lessons) return '-';
+      // 这里取出该天的所有安排
+      const lessonDay = lessons.filter(f => f.date === date);
+      const r = lessonDay.find(f => f.subid);
+      if (r) return r.teaname || '-';
+      return '-';
+    },
+    //获取教师电话
+    getTel(date, cla) {
+      const { lesson } = cla;
+      if (!lesson) return '-';
+      const { lessons } = lesson;
+      if (!lessons) return '-';
+      // 这里取出该天的所有安排
+      const lessonDay = lessons.filter(f => f.date === date);
+      const r = lessonDay.find(f => f.subid);
+      if (r) {
+        const tea = this.teacherList.find(f => f._id === r.teaid);
+        if (tea) return tea.phone || '-';
+      }
+      return '-';
+    },
+    // 消息的确认
+    checkMsg(date, cla) {
+      if (this.getTeacher(date, cla) === '-') return false;
+      const r = this.noticeList.find(f => f.classid === cla._id);
+      // 没找到该班通知返回不显示
+      if (!r) return false;
+      const { notified } = r;
+      // 没有通知人数组返回不显示
+      if (!notified) return false;
+      const { lesson } = cla;
+      // 没有课程数组返回不显示
+      if (!lesson) return false;
+      const { lessons } = lesson;
+      if (!lessons) return false;
+      const l = lessons.find(f => f.date === date);
+      // 没有课程返回不显示
+      if (!l) return false;
+      const { teaid } = l;
+      const msg = notified.find(f => f.notifiedid === teaid);
+      // 没找到信息返回显示,但是是未收到通知,说明没绑定
+      if (!msg) return 'danger';
+      const { status } = msg;
+      if (status === '0') return 'warning';
+      return 'success';
+    },
+    // 文字对应的信息
+    getMsgWord(result) {
+      if (result === 'danger') return '未收到信息';
+      if (result === 'warning') return '未确认';
+      return '已确认';
+    },
+    // 背景颜色
+    getColor(date, index, batch) {
+      if (date === '-') return '#FFFFFF';
+      const clas = _.get(batch, 'class');
+      const cla = _.head(clas);
+      if (!cla) return '#FFFFFF';
+      const { lesson } = cla;
+      // 没有课程数组返回不显示
+      if (!lesson) return '#FFFFFF';
+      const { lessons } = lesson;
+      if (!lessons) return '#FFFFFF';
+      let r = lessons.filter(f => f.date === date);
+      r = r.map(i => {
+        const sub = this.subjectList.find(f => f._id === i.subid);
+        if (sub) i.need_teacher = sub.need_teacher;
+
+        return i;
+      });
+      if (r.some(e => e.need_teacher === '0')) return this.colorList[index];
+      else return '#FFFFFF';
+    },
+    // 计算教师单元格宽度
+    computedTeacherTdWidth(date, cla, index, batch) {
+      let wid = 0;
+      // 班级名称
+      let cname = _.get(cla, 'name', '');
+      // 班主任,礼仪课教师,教室名称,开班地点,拓展训练地点,用餐地点
+      let headteacher = _.get(cla, 'headteacher', '');
+      let lyteacher = _.get(cla, 'lyteacher', '');
+      let jslocation = _.get(cla, 'jslocation', '');
+      let kbyslocation = _.get(cla, 'kbyslocation', '');
+      let kzjhlocation = _.get(cla, 'kzjhlocation', '');
+      let yclocation = _.get(cla, 'yclocation', '');
+      let claArr = [cname.lenth, headteacher.lenth, lyteacher.length, jslocation.length, kbyslocation.length, kzjhlocation.length, yclocation.length];
+      claArr = claArr.sort((a, b) => b - a);
+      let unit = 5;
+      const { lesson } = cla;
+      const clah = _.head(claArr);
+      if (!lesson) {
+        console.error('计算教师单元格宽度-search中处理课表出现问题');
+        if (clah <= 3) wid = 95;
+        else wid = 95 + (clah - 3) * unit;
+        return { width: `${wid}px` };
+      }
+      const { lessons } = lesson;
+      if (!lessons) {
+        console.warn('计算教师单元格宽度-这个班的课表没有内容 或 异步引起的问题');
+        if (clah <= 3) wid = 95;
+        else wid = 95 + (clah - 3) * unit;
+        return { width: `${wid}px` };
+      }
+      let arr = [];
+      for (const l of lessons) {
+        if (l.teaname) arr.push(l.teaname.length);
+      }
+      arr = arr.sort((a, b) => b - a);
+      const h = _.head(arr);
+      // 小于等于3个字 95(虚拟课表是75,没有电话号,这里有电话号,要更长些) 之后多一个字加15
+      if (h && h >= clah) {
+        if (h <= 3) wid = 95;
+        else wid = 95 + (h - 3) * unit;
+      } else {
+        if (clah <= 3) wid = 95;
+        else wid = 95 + (clah - 3) * unit;
+      }
+      let obj = { width: `${wid}px` };
+      if (index && batch) {
+        obj.background = this.getColor(date, index, batch);
+      }
+      return obj;
+    },
+    // 获取班主任/礼仪教师电话
+    getDirTeaTel(id, type) {
+      let res;
+      if (type !== 'both') {
+        const dup = _.cloneDeep(this[`${type}List`]);
+        const r = dup.find(f => f._id === id);
+        if (r) res = r.mobile;
+      } else {
+        let r = this.teacherList.find(f => f._id === id);
+        if (r) res = r.phone;
+        else {
+          r = this.headTeacherList.find(f => f._id === id);
+          if (r) res = r.mobile;
+        }
+      }
+      return res;
+    },
+    // 班主任/礼仪教师消息确认
+    checkMsgDirTea(cla, type) {
+      const id = _.get(cla, `${type}id`);
+      if (!id) return false;
+      const r = this.noticeList.find(f => f.classid === cla._id);
+      // 没找到该班通知返回不显示
+      if (!r) return false;
+      const { notified } = r;
+      // 没有通知人数组返回不显示
+      if (!notified) return false;
+      const msg = notified.find(f => f.notifiedid === id);
+      // 没找到信息返回显示,但是是未收到通知,说明没绑定
+      if (!msg) return 'danger';
+      const { status } = msg;
+      if (status === '0') return 'warning';
+      return 'success';
+    },
+
+    // 点击事件
+    // 修改教师
+    clickTeacher(date, cla) {
+      const { lesson } = cla;
+      if (!lesson) return '-';
+      const { lessons } = lesson;
+      if (!lessons) return '-';
+      // 这里取出该天的所有安排
+      let lessonDay = lessons.filter(f => f.date === date);
+      // 过滤出所有课程
+      lessonDay = lessonDay.filter(f => f.subid);
+      // 过滤出需要教师的课程
+      lessonDay = lessonDay.map(i => {
+        const r = this.subjectList.find(f => f._id === i.subid);
+        if (r) i.need_teacher = r.need_teacher;
+        return i;
+      });
+      lessonDay = lessonDay.filter(f => f.need_teacher == '0');
+      if (lessonDay.length <= 0) {
+        this.$message.warning('该天不需要安排教师');
+        return;
+      } else {
+        const { _id } = lesson;
+        let h = _.head(lessonDay);
+        h = { ...h, lessonObjectId: _id, classname: cla.name };
+        if (cla.enddate === h.date) h.is_last = true;
+        this.$emit('lessonChange', h);
+      }
+    },
+    // 修改班级设置
+    clickClass(cla) {
+      this.$emit('classChange', cla);
+    },
+    // 以下是工具方法
+    getDayList(start, end) {
+      const r = moment(end).diff(start, 'days');
+      const arr = [];
+      for (let i = 0; i < r + 1; i++) {
+        const d = moment(start)
+          .add(i, 'days')
+          .format('YYYY-MM-DD');
+        arr.push(d);
+      }
+      return arr;
+    },
+    // 格式化日期
+    getMonthDay(d) {
+      if (d === '-') return d;
+      const l = _.split(d, '-');
+      return `${l[1]}-${l[2]}`;
+    },
+    // 获取星期
+    getDay(d) {
+      if (d === '-') return d;
+      if (d && d.includes('-')) {
+        let dl = ['日', '一', '二', '三', '四', '五', '六'];
+        return `星期${dl[moment(d).day()]}`;
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+td {
+  text-align: center;
+  min-height: 60px;
+  border-right: 0;
+  border-left: 0;
+  border-bottom: 0;
+}
+.teacher_td {
+  display: grid;
+  word-break: break-all;
+}
+.out {
+  overflow: hidden;
+  white-space: pre;
+  text-overflow: ellipsis;
+}
+</style>

+ 141 - 0
src/views/train-plan/parts/experience-export.vue

@@ -0,0 +1,141 @@
+<template>
+  <div id="experience-export">
+    <el-row class="btn_bar" type="flex" justify="end">
+      <el-col :span="2">
+        <el-button type="primary" size="small" @click="dialog = true">导出培训心得</el-button>
+      </el-col>
+    </el-row>
+    <el-dialog title="请选择要导出培训心得的范围" width="30%" :visible.sync="dialog" center @close="toClose">
+      <el-form size="small">
+        <el-form-item label="年度计划">
+          <el-select clearable v-model="form.planid" @change="toGetTerm">
+            <el-option v-for="(i, index) in planList" :key="index" :label="i.title" :value="i._id"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="期(可选)">
+          <el-select clearable v-model="form.termid" @change="selectTerm">
+            <el-option v-for="(i, index) in termList" :key="index" :label="`第${i.term}期`" :value="i._id"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="批(可选)">
+          <el-select clearable v-model="form.batchid">
+            <el-option v-for="(i, index) in batchList" :key="index" :label="`第${i.batch}批`" :value="i._id"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="班(可选)">
+          <el-select clearable v-model="form.classid" @change="selectClass">
+            <el-option v-for="(c, index) in classList" :key="index" :label="`${c.name.includes('班') ? c.name : `${c.name}班`}`" :value="c._id"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="人(可选)">
+          <el-select clearable v-model="form.studentid">
+            <el-option v-for="(i, index) in studentList" :key="index" :label="`${i.name}(${i.job})`" :value="i._id"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-row type="flex" justify="space-around">
+          <el-col :span="2">
+            <el-button type="primary" size="small" @click="toExport">导出</el-button>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: experience } = createNamespacedHelpers('experience');
+const { mapActions: classes } = createNamespacedHelpers('classes');
+const { mapActions: trainplan } = createNamespacedHelpers('trainplan');
+const { mapActions: student } = createNamespacedHelpers('student');
+export default {
+  name: 'experience-export',
+  props: {},
+  components: {},
+  data: function() {
+    return {
+      dialog: false,
+      form: {},
+      planList: [],
+      termList: [],
+      batchList: [],
+      classList: [],
+      studentList: [],
+    };
+  },
+  async created() {
+    await this.toGetPlan();
+  },
+  methods: {
+    ...experience(['export']),
+    ...student({ getStudent: 'query' }),
+    ...trainplan({ getPlan: 'query' }),
+    ...classes({ getClass: 'query' }),
+    // 查询年度计划
+    async toGetPlan() {
+      const res = await this.getPlan();
+      if (this.$checkRes(res)) this.$set(this, `planList`, res.data);
+    },
+    // 找到期列表
+    async toGetTerm(planid) {
+      const res = await this.planList.find(f => f._id === planid);
+      if (!res) return;
+      const { termnum } = res;
+      this.$set(this, `termList`, termnum);
+    },
+    // 找到批次列表,查询班级列表
+    async selectTerm(termid) {
+      const r = this.termList.find(f => f._id === termid);
+      if (!r) return;
+      const { batchnum } = r;
+      this.$set(this, `batchList`, batchnum);
+      const stures = await this.getClass({ termid });
+      if (this.$checkRes(stures)) {
+        let duplicate = _.cloneDeep(stures.data);
+        duplicate = duplicate.map(i => {
+          if (parseInt(i.name)) {
+            i.order = parseInt(i.name);
+          } else {
+            // i.order = i.name;
+          }
+          return i;
+        });
+        duplicate = _.orderBy(duplicate, ['order'], ['asc']);
+        this.$set(this, `classList`, duplicate);
+      }
+    },
+    // 找到班级的班长,学委
+    async selectClass(classid) {
+      const bzres = await this.getStudent({ classid, job: '班长' });
+      const xwres = await this.getStudent({ classid, job: '学委' });
+      let arr = [];
+      if (this.$checkRes(bzres)) arr = [...arr, ...bzres.data];
+      if (this.$checkRes(xwres)) arr = [...arr, ...xwres.data];
+      this.$set(this, `studentList`, arr);
+    },
+    //导出
+    async toExport() {
+      const res = await this.export(this.form);
+      if (this.$checkRes(res, '导出成功', res.errmsg || '导出失败')) {
+        window.open(res.data);
+      }
+    },
+    toClose() {
+      this.dialog = false;
+      this.$set(this, `form`, {});
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 58 - 97
src/views/train-plan/parts/term-class-from.vue

@@ -1,121 +1,82 @@
 <template>
   <div id="term-class-from">
-    <el-form :model="form" size="mini" style="padding:20px" label-width="100px">
-      <el-form-item :label="label">
-        <el-form-item v-for="(cl, index) in classList" :key="index" :label="`${cl.class_num}班`" label-width="50px">
-          <template v-if="form.type == 'headteacher'">
-            <el-select v-model="cl.id" :placeholder="`请选择${label}`" filterable>
-              <el-option-group v-for="(dept, index) in list" :label="dept.name" :key="index">
-                <el-option v-for="(i, tIndex) in dept.list" :key="`${index}-${tIndex}`" :label="i.name" :value="i._id"></el-option>
-              </el-option-group>
-            </el-select>
-          </template>
-          <el-select v-model="cl.id" :placeholder="`请选择${label}`" filterable v-else>
-            <el-option v-for="(i, index) in list" :key="index" :label="i.name" :value="i._id"></el-option>
-          </el-select>
-        </el-form-item>
-      </el-form-item>
-      <el-form-item>
-        <el-row type="flex" align="middle" justify="center">
-          <el-col :span="2">
-            <el-button type="primary" @click="handleSave">保存</el-button>
-          </el-col>
-        </el-row>
-      </el-form-item>
-    </el-form>
+    <data-form :data="form" :fields="fields" :rules="{}" @save="handleSave">
+      <template #options="{item, form}">
+        <template v-if="item.model == 'headteacherid'">
+          <el-option v-for="(i, tIndex) in headTeacherList" :key="`${item.model}-${tIndex}`" :label="i.name" :value="i._id"></el-option>
+        </template>
+        <template v-if="item.model == 'lyteacherid'">
+          <el-option v-for="(tea, index) in getLyList()" :key="`${item.model}${index}`" :label="tea.name" :value="tea.id"></el-option>
+        </template>
+        <template v-if="item.model == 'jslocationid'">
+          <el-option v-for="(place, index) in locationList" :key="`${item.model}${index}`" :label="place.name" :value="place.id"></el-option>
+        </template>
+        <template v-if="item.model == 'kbyslocationid'">
+          <el-option v-for="(place, index) in locationList" :key="`${item.model}${index}`" :label="place.name" :value="place.id"></el-option>
+        </template>
+        <template v-if="item.model == 'kzjhlocationid'">
+          <el-option v-for="(place, index) in locationList" :key="`${item.model}${index}`" :label="place.name" :value="place.id"></el-option>
+        </template>
+        <template v-if="item.model == 'yclocationid'">
+          <el-option v-for="(place, index) in locationList" :key="`${item.model}${index}`" :label="place.name" :value="place.id"></el-option>
+        </template>
+      </template>
+    </data-form>
   </div>
 </template>
 
 <script>
-import _ from 'lodash';
+const _ = require('lodash');
+import dataForm from '@frame/components/form';
 import { mapState, createNamespacedHelpers } from 'vuex';
 export default {
   name: 'term-class-from',
   props: {
     data: { type: Object, default: () => {} },
-    lyTeacherList: { type: Array, default: () => [] },
+    teacherList: { type: Array, default: () => [] },
     headTeacherList: { type: Array, default: () => [] },
     locationList: { type: Array, default: () => [] },
   },
-  components: {},
+  components: { dataForm },
   data: function() {
+    var that = this;
     return {
-      form: {},
-      classList: [],
-      label: '',
-      list: [],
+      form: _.cloneDeep(that.data),
+      fields: [
+        { label: '班主任', model: 'headteacherid', type: 'select' },
+        { label: '礼仪课教师', model: 'lyteacherid', type: 'select' },
+        { label: '教室地点', model: 'jslocationid', type: 'select' },
+        { label: '开班地点', model: 'kbyslocationid', type: 'select' },
+        { label: '拓展训练地点', model: 'kzjhlocationid', type: 'select' },
+        { label: '用餐地点', model: 'yclocationid', type: 'select' },
+      ],
+      typeList: [
+        {
+          value: '0',
+          label: '教室位置',
+        },
+        {
+          value: '1',
+          label: '开班仪式地点',
+        },
+        {
+          value: '2',
+          label: '拓展计划地点',
+        },
+        {
+          value: '3',
+          label: '用餐地点',
+        },
+      ],
     };
   },
   created() {},
   methods: {
-    handleSave() {
-      let dForm = _.cloneDeep(this.form);
-      let dList = _.cloneDeep(this.classList);
-      dList = dList.map(i => {
-        if (i.id) {
-          let r;
-          let dataList = _.cloneDeep(this.list);
-          if (dForm.type == 'headteacher') {
-            dataList = _.flatten(dataList.map(i => i.list));
-            r = dataList.find(f => f._id == i.id);
-          } else r = dataList.find(f => f._id == i.id);
-          if (r) i.name = r.name;
-        }
-        return i;
-      });
-      let r = {};
-      dList.map(c => {
-        let { class_num, ...info } = c;
-        let keys = Object.keys(info);
-        for (const key of keys) {
-          r[`${key}_${class_num}`] = info[key];
-        }
-      });
-      r = { ...dForm, ...r };
-      this.$emit('save', r);
-    },
-    setData(data) {
-      let { index, batch, date, type, ...others } = data;
-      let obj = { index, batch, date, type };
-      this.$set(this, `form`, obj);
-      this.getAttr();
-      let keys = Object.keys(others);
-      let indexs = _.uniq(keys.map(key => key.match(/\d+(.\d+)?/g)[0]));
-      let arr = indexs.map(i => {
-        let gks = keys.filter(f => f.includes(i));
-        gks = gks.map(gk => {
-          let o = [];
-          o.push(gk.split('_')[0]);
-          o.push(others[gk]);
-          return o;
-        });
-        let res = _.fromPairs(gks);
-        res = { ...res, class_num: i };
-        return res;
-      });
-      this.$set(this, `classList`, arr);
-    },
-    getAttr() {
-      let { type } = this.form;
-      if (type == 'headteacher') {
-        this.$set(this, `list`, this.headTeacherList);
-        this.label = '班主任';
-      } else if (type == 'lyteacher') {
-        this.$set(this, `list`, this.lyTeacherList);
-        this.label = '礼仪课教师';
-      } else {
-        this.$set(this, `list`, this.locationList);
-        this.label = '教室地点';
-      }
+    getLyList() {
+      return [...this.headTeacherList, ...this.teacherList];
     },
-  },
-  watch: {
-    data: {
-      handler(val) {
-        this.setData(val);
-      },
-      immediate: true,
-      deep: true,
+    handleSave() {
+      this.$emit('save', _.cloneDeep(this.form));
     },
   },
   computed: {

+ 89 - 53
src/views/train-plan/parts/term-lesson-form.vue

@@ -1,66 +1,111 @@
 <template>
   <div id="term-lesson-form">
-    <lt :ref="`lt`" :data="form" :classList="classList" @save="toSave" v-bind="$attrs"></lt>
+    <el-form ref="lessonForm" :model="form" size="mini" style="padding:20px" label-width="100px">
+      <el-form-item label="班级">{{ form.classname.includes('班') ? form.classname : `${form.classname}班` }}</el-form-item>
+      <el-form-item label="日期">{{ form.date }}</el-form-item>
+      <el-form-item label="课程安排">
+        <el-select v-model="form.subid" placeholder="请选择课程">
+          <el-option v-for="(i, index) in subjectList" :key="index" :label="i.name" :value="i.id"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="教师安排">
+        <el-input v-model="form.teaname" placeholder="点击选择教师" @click.native="toChooseTeacher()" clearable @clear="toClear()"></el-input>
+        <el-form-item v-if="needReason()" label="修改教师原因" label-width="150px" required style="margin-top:10px">
+          <el-input v-model="form.reason" placeholder="请填写修改教师原因"></el-input>
+        </el-form-item>
+      </el-form-item>
+      <el-form-item label="是否全天" v-if="form.is_last">
+        <el-radio-group v-model="form.day">
+          <el-radio label="0">全天</el-radio>
+          <el-radio label="1">半天</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item>
+        <el-row type="flex" align="middle" justify="center">
+          <el-col :span="2">
+            <el-button type="primary" @click="handleSave">保存</el-button>
+          </el-col>
+        </el-row>
+      </el-form-item>
+    </el-form>
+    <el-dialog title="选择教师" :visible.sync="dialog" :destroy-on-close="true" :append-to-body="true">
+      <teacher-select :schoolList="schoolList" :subjectList="subjectList" :subjectid="form.subid" :date="form.date" @selTea="selTea"> </teacher-select>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import _ from 'lodash';
-import lt from './lesson-table';
+const _ = require('lodash');
+import teacherSelect from './teacher.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: teacher } = createNamespacedHelpers('vuex');
 export default {
   name: 'term-lesson-form',
   props: {
     data: { type: Object, default: () => {} },
+    subjectList: { type: Array, default: () => [] },
+    schoolList: { type: Array, default: () => [] },
+    classList: { type: Array, default: () => [] },
   },
-  components: { lt },
+  components: { teacherSelect },
   data: function() {
+    var that = this;
     return {
-      form: {},
-      classList: [],
+      form: _.cloneDeep(that.data),
+      dialog: false,
+      isChange: undefined,
+      dayType: [{ label: '活动' }, { label: '课程' }],
+      actList: [
+        { label: '--' },
+        { label: '报到+开班仪式' },
+        { label: '午餐+休息' },
+        { label: '晚餐' },
+        { label: '团队组建' },
+        { label: '拓展交流' },
+        { label: '课程作业小组展示' },
+        { label: '课程作业' },
+        { label: '礼仪课小组面试' },
+        { label: '结业仪式' },
+      ],
     };
   },
   created() {},
   methods: {
-    setData(val) {
-      let { index, batch, date, is_last, subname, subid, type: dataType, allday, ...others } = val;
-      let obj = { index, batch, date, is_last, subname, subid, dataType, allday };
-      obj.type = subid ? '课程' : '活动';
-      this.$set(this, `form`, obj);
-      let keys = Object.keys(others);
-      let indexs = _.uniq(
-        keys.map(key => {
-          let r = key.match(/\d+(.\d+)?/g);
-          if (r && r.length > 0) return r[0];
-        })
-      );
-      let arr = indexs.map(i => {
-        let gks = keys.filter(f => f.includes(i));
-        gks = gks.map(gk => {
-          let o = [];
-          o.push(gk.split('_')[0]);
-          o.push(others[gk]);
-          return o;
-        });
-        let res = _.fromPairs(gks);
-        res = { ...res, class_num: i };
-        return res;
-      });
-      this.$set(this, `classList`, arr);
-    },
-    toSave({ form, classList }) {
-      let { dataType: type, ...f } = form;
-      form = { ...f, type };
-      let r = {};
-      classList.map(c => {
-        let { class_num, ...info } = c;
-        let keys = Object.keys(info);
-        for (const key of keys) {
-          r[`${key}_${class_num}`] = info[key];
+    ...teacher(['checkArrange']),
+    handleSave() {
+      const nr = this.needReason();
+      let dForm = _.cloneDeep(this.form);
+      if (nr) {
+        const { reason } = dForm;
+        if (!reason) {
+          this.$message.error('请填写修改教师的原因');
+          return;
         }
-      });
-      r = { ...form, ...r };
-      this.$emit('save', r);
+      }
+      this.$emit('save', dForm);
+    },
+    //选择教师
+    selTea(data) {
+      const { teaid, teaname } = data;
+      this.$set(this.form, 'teaid', teaid);
+      this.$set(this.form, 'teaname', teaname);
+      this.dialog = false;
+    },
+    async toChooseTeacher() {
+      this.dialog = true;
+    },
+    //判断是否修改教师,需要填写修改教师的原因
+    needReason() {
+      let orData = _.cloneDeep(this.data);
+      let nowData = _.cloneDeep(this.form);
+      let { teaid: oteaid, reason } = orData;
+      let { teaid: nteaid } = nowData;
+      if (reason) return true;
+      return oteaid != nteaid;
+    },
+    toClear() {
+      const nd = _.omit(this.form, ['teaid', 'teaname']);
+      this.$set(this, `form`, nd);
     },
   },
   computed: {
@@ -69,15 +114,6 @@ export default {
       return `${this.$route.meta.title}`;
     },
   },
-  watch: {
-    data: {
-      handler(val) {
-        this.setData(val);
-      },
-      immediate: true,
-      deep: true,
-    },
-  },
   metaInfo() {
     return { title: this.$route.meta.title };
   },

+ 36 - 3
src/views/train-plan/print.vue

@@ -38,7 +38,15 @@
       <name-card v-loading="loading" :list="studList"></name-card>
     </detail-frame>
     <detail-frame title="打印证书" v-if="view == 'certList'" :returns="toReturns">
-      <cert-card :list="certstuList" :startdate="startdate" :enddate="enddate" :classname="classname" :term="term"></cert-card>
+      <cert-card
+        :list="certstuList"
+        :startdate="startdate"
+        :enddate="enddate"
+        :classname="classname"
+        :term="term"
+        :classid="classid"
+        @research="certList"
+      ></cert-card>
     </detail-frame>
     <detail-frame title="学生报到表" v-if="view == 'signList'" :returns="toReturns">
       <sign-list v-loading="loading" :list="studList" :signclass="signclass"></sign-list>
@@ -119,6 +127,8 @@ export default {
       certstuList: [],
       // 班级信息
       signclass: {},
+      // 证书的班级信息,用来设置优秀的
+      classid: undefined,
     };
   },
   created() {
@@ -196,14 +206,36 @@ export default {
       this.loading = false;
     },
     async certList({ data }) {
+      console.log(data);
+      if (this.classid) {
+        data = this.tableData.find(f => f._id === this.classid);
+      }
       let { _id: classid, enddate, startdate, name: classname, term } = data;
+      let dup = _.cloneDeep(this.batchList);
+      dup = dup.map(i => i.class).flat();
+      dup = dup.map(i => {
+        if (parseInt(i.name)) i.order = parseInt(i.name);
+        else i.order = i.name;
+        return i;
+      });
+      dup = _.orderBy(dup, ['order'], ['asc']);
+      dup = dup.map((i, index) => {
+        i.classnum = `${index + 1}`;
+        return i;
+      });
       let res = await this.cerconfirmQuery({ classid });
       if (this.$checkRes(res)) {
-        console.log(data);
         this.$set(this, `certstuList`, res.data);
         this.$set(this, `startdate`, startdate);
         this.$set(this, `enddate`, enddate);
-        this.$set(this, `classname`, classname);
+        const r = dup.find(f => f.name === classname);
+        if (r) {
+          const { classnum } = r;
+          this.$set(this, `classname`, classnum);
+        } else {
+          this.$set(this, `classname`, classname);
+        }
+        this.$set(this, `classid`, classid);
         this.$set(this, `term`, term);
       }
       this.view = 'certList';
@@ -242,6 +274,7 @@ export default {
     },
     toReturns() {
       this.view = 'list';
+      this.classid = undefined;
     },
   },
   computed: {

+ 224 - 521
src/views/train-plan/term-lesson.vue

@@ -6,53 +6,36 @@
           <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-button type="primary" size="mini" @click="allSave">保存期课表</el-button> -->
         </el-col>
         <el-col :span="2">
           <el-button type="primary" size="mini" plain @click="toStatus">确定课表</el-button>
         </el-col>
       </el-row>
-      <el-row type="flex" v-loading="loading" style="min-height:500px">
-        <el-col :span="9" v-for="(i, index) in list" :key="index">
-          <lesson-table
-            type="usual"
-            :data="i"
-            :batch="`${index + 1}`"
-            :noticeList="noticeList"
-            :teacherList="inteaList"
-            @lesson="toLesson"
-            @other="toOther"
-            @toOneClass="toOneClass"
-          ></lesson-table>
-        </el-col>
-      </el-row>
-      <el-row type="flex" v-loading="loading" style="min-height:500px" v-for="(i, index) in unusualList" :key="index">
-        <el-col :span="8">
-          <lesson-table
-            type="unusual"
-            :data="i"
-            :batch="`${index + 1}`"
-            :noticeList="noticeList"
-            :teacherList="inteaList"
-            @lesson="toLesson"
-            @other="toOther"
-            @toOneClass="toOneClass"
-          ></lesson-table>
-        </el-col>
-      </el-row>
+      <div style="min-height:800px" v-loading="loading" element-loading-text="期课表加载中,请稍后..." element-loading-background="rgba(0, 0, 0, 0.8)">
+        <excel-term-lesson
+          :classType="ctList"
+          :data="list"
+          :teacherList="teacherList"
+          :noticeList="noticeList"
+          :subjectList="subjectList"
+          :headTeacherList="headTeacherList"
+          @lessonChange="toLessonChange"
+          @classChange="toClassChange"
+        ></excel-term-lesson>
+      </div>
     </detail-frame>
     <el-drawer title="课程安排" :visible.sync="lDrawer" :destroy-on-close="true" @close="toClose">
-      <lesson-form v-if="lDrawer" v-loading="dloading" :data="form" :subjectList="subjectList" :schoolList="schoolList" @save="lessonSave"></lesson-form>
+      <lesson-form v-if="lDrawer" :data="form" :subjectList="subjectList" :schoolList="schoolList" @save="lessonSave"></lesson-form>
     </el-drawer>
-    <el-drawer title="其他安排" :visible.sync="oDrawer" :destroy-on-close="true" @close="toClose">
+    <el-drawer title="班级安排" :visible.sync="cDrawer" :destroy-on-close="true" @close="toClose">
       <class-form
-        v-if="oDrawer"
+        v-if="cDrawer"
         :data="form"
         :locationList="locationList"
         :headTeacherList="headTeacherList"
-        :lyTeacherList="lyTeacherList"
-        v-loading="dloading"
-        @save="lessonSave"
+        :teacherList="teacherList"
+        @save="classSave"
       ></class-form>
     </el-drawer>
   </div>
@@ -63,7 +46,7 @@ import _ from 'lodash';
 import axios from 'axios';
 // const moment = require('moment');
 // moment.locale('zh-cn');
-import lessonTable from './parts/term-lesson-table';
+import excelTermLesson from './parts/excel-term-lesson.vue';
 import lessonForm from './parts/term-lesson-form';
 import classForm from './parts/term-class-from';
 import detailFrame from '@frame/layout/admin/detail-frame';
@@ -81,29 +64,30 @@ const { mapActions: director } = createNamespacedHelpers('director');
 const { mapActions: school } = createNamespacedHelpers('school'); //给选老师组件使用.这个页面请求完就不销毁了
 const { mapActions: subject } = createNamespacedHelpers('subject');
 const { mapActions: notice } = createNamespacedHelpers('notice');
+const { mapActions: ct } = createNamespacedHelpers('classtype');
 export default {
   name: 'term-lesson',
   props: {},
-  components: { detailFrame, lessonTable, lessonForm, classForm },
+  components: { detailFrame, excelTermLesson, lessonForm, classForm },
   data: function() {
     return {
       loading: true,
-      dloading: false,
       lDrawer: false,
-      oDrawer: false,
+      cDrawer: false,
       form: {},
       formType: 'usual',
       options: {},
       list: [],
-      unusualList: [],
       classList: [],
       lessonList: [],
       locationList: [],
-      lyTeacherList: [],
+      teacherList: [],
       deptList: [],
       headTeacherList: [],
       schoolList: [],
       subjectList: [],
+      // 班级类型列表
+      ctList: [],
       //该期通知列表
       noticeList: [],
       //已经选择的教师列表
@@ -133,12 +117,18 @@ export default {
   },
   methods: {
     ...notice({ getNoticeList: 'query' }),
-
-    ...lesson({ getLesson: 'query', plupdate: 'pluralUpdate', autoArrange: 'arrange', confirmLesson: 'confirmLesson', newArrange: 'newArrange' }),
-    ...classes({ getClass: 'query', pcupdate: 'pluralUpdate' }),
-
+    ...lesson({
+      getLesson: 'query',
+      lessonUpdate: 'update',
+      plupdate: 'pluralUpdate',
+      autoArrange: 'arrange',
+      confirmLesson: 'confirmLesson',
+      newArrange: 'newArrange',
+    }),
+    ...classes({ getClass: 'query', pcupdate: 'pluralUpdate', classUpdate: 'update' }),
+    ...ct({ getCt: 'query' }),
     ...subject({ getSubject: 'query' }),
-    ...director({ getDirector: 'fetch' }),
+    ...director({ getDirector: 'fetch', getDirectorList: 'query' }),
     ...school({ getSchool: 'query' }),
     ...location({ getLocationList: 'query' }),
     ...teacher({ getTeacherList: 'query', getTeacher: 'fetch', getTeachers: 'lessonteafetch' }),
@@ -147,22 +137,43 @@ export default {
     ...teaplan(['findTeacher']),
     async search() {
       this.loading = true;
+      // 将 请求班级和 请求课表拆开,以便之后局部修改,保存减少请求次数
+      const res = await this.toGetClass();
+      if (res === 'noClass') {
+        this.loading = false;
+        return;
+      }
+      await this.toGetLesson();
+      this.toSetData();
+      this.toGetNoticeList();
+      this.loading = false;
+    },
+    // 获取班级
+    async toGetClass() {
       let termid = _.get(this.defaultOption, `termid`);
       if (!termid) return;
-      let lessonList = [];
-      let classList = [];
       let classes = await this.getClass({ termid });
+      let classList = [];
       if (this.$checkRes(classes)) {
         classList = classes.data;
-        for (let cla of classList) {
-          cla = await this.searchClassPerson(cla);
-        }
         if (classList.length <= 0) {
           this.$message.error('班级未生成,无法查询课表,请先进行学生分班');
-          return;
+          return 'noClass';
         }
+        classList = classList.map(i => {
+          if (parseInt(i.name)) i.order = parseInt(i.name);
+          else i.order = i.name;
+          return i;
+        });
+        classList = _.orderBy(classList, ['order'], ['asc']);
         this.$set(this, `classList`, classList);
       }
+    },
+    // 获取课程
+    async toGetLesson() {
+      let termid = _.get(this.defaultOption, `termid`);
+      if (!termid) return;
+      let lessonList = [];
       let lessons = await this.getLesson({ termid });
       if (this.$checkRes(lessons)) {
         lessonList = lessons.data;
@@ -172,182 +183,26 @@ export default {
         }
         this.$set(this, `lessonList`, lessonList);
       }
-
-      let unusualList = classList.filter(f => f.type != '0');
-      let usualList = classList.filter(f => f.type == '0');
-      let usualRes = this.dealList(usualList, lessonList);
-      let unusualRes = this.dealList(unusualList, lessonList);
-      this.$set(this, `list`, usualRes);
-      this.$set(this, `unusualList`, unusualRes);
-      this.toGetNoticeList();
-      this.toGetTeachers();
-      this.loading = false;
-    },
-    dealList(classList, lessonList) {
-      let arr = classList.map(i => {
-        let r = lessonList.find(f => f.classid == i._id);
-        if (r) {
-          let { lessons = [] } = r;
-          i.lessons = lessons;
-        }
-        return i;
-      });
-      arr = _.flatten(
-        _.toPairs(
-          _.groupBy(
-            arr.sort((a, b) => a - b),
-            `batch`
-          )
-        )
-      ).filter(f => _.isArray(f));
-      arr = arr.map((i, index) => {
-        // 先转换lessons,此表的情况是:小批次下的班级都是一样的课程,只有教师,教室不一样
-        let a = this.changeLesson(i);
-        let last = this.setAllday(_.last(a));
-        let ht = this.setProp(a, 'headteacher');
-        let lyt = this.setProp(a, 'lyteacher');
-        let js = this.setProp(a, 'jslocation');
-        for (let ind = 0; ind < index; ind++) {
-          a.unshift({});
-        }
-        //找到该班额班主任和礼仪课教师
-        a.push(ht);
-        a.push(lyt);
-        a.push(js);
-        for (let ind = 2; ind > index; ind--) {
-          a.push({});
-        }
-        a.push(last);
-        return a;
-      });
-      return arr;
     },
-    //课程数据=>页面数据形式
-    changeLesson(array) {
-      //{batch,subname(同一批每天课程一样),subid, classid_1,classid_2, teaid_1, teaid_2, lessonid_1,lessonid_2 }
-      //i(map循环)中获取的参数: batch;classid_*;
-      //lesson中获取的参数: subname;subid_*;teaid_*;lessonid_*
-      let duplicate = _.cloneDeep(array);
-      duplicate = duplicate.map(i => {
-        if (parseInt(i.name)) i.orderObj = parseInt(i.name);
+    // 整理班级和课程
+    async toSetData() {
+      let classList = _.cloneDeep(this.classList);
+      classList = classList.map(i => {
+        const lesson = this.lessonList.find(f => f.classid === i._id);
+        if (lesson) i.lesson = lesson;
+        else i.lesson = {};
         return i;
       });
-      duplicate = _.orderBy(duplicate, 'orderObj');
-      //按日期排序
-      let res = duplicate.map((i, index) => {
-        let les = _.flatten(
-          _.toPairs(
-            _.groupBy(
-              // i.lessons.sort((a, b) => moment(a.date).format('X') - moment(b.date).format('X')),
-              _.orderBy(i.lessons, 'date', 'asc'),
-              'date'
-            )
-          )
-        ).filter(f => _.isArray(f));
-        // console.log(i);
-        // console.log(les);
-        //每天按时间排序
-        les = les.map(lesi => _.orderBy(lesi, 'time', 'asc'));
-        let t = les.map(li => {
-          let r = li.find(f => f.subid);
-          // console.log(r);
-          let obj;
-          //有课程,则显示课程;没有,显示安排的活动,反正都是用subname字段
-          if (r) {
-            let { subname, subid, teaid, teaname, _id: lessonid, date, reason } = r;
-            obj = { subname, subid };
-            obj[`id_${index + 1}`] = teaid;
-            obj[`name_${index + 1}`] = teaname;
-            obj[`lessonid_${index + 1}`] = lessonid;
-            obj[`date`] = date;
-            if (reason) obj[`reason_${index + 1}`] = reason;
-          } else {
-            let { subname, _id: lessonid, date } = _.head(li);
-            obj = { subname };
-            obj[`lessonid_${index + 1}`] = lessonid;
-            obj[`date`] = date;
-          }
-          obj.batch = i.batch;
-          obj[`classid_${index + 1}`] = i._id;
-          obj[`class_${index + 1}`] = i.name;
-          obj['type'] = 'lesson';
-          return obj;
-        });
-        return t;
-      });
-      let l = _.get(_.head(res), 'length');
-      let arr = [];
-      for (let i = 0; i < l; i++) {
-        let obj = {};
-        for (const item of res) {
-          obj = { ...obj, ...item[i] };
-        }
-        arr.push(obj);
-      }
-      return arr;
-    },
-    //班主任/礼仪课老师=>页面数据形式
-    setProp(data, type) {
-      if (!(data && data.length > 0)) return {};
-      let head = _.head(data);
-      let res = { type };
-      res.date = type == 'headteacher' ? '班主任' : type == 'lyteacher' ? '礼仪课教师' : '教室';
-      let keys = Object.keys(head).filter(f => f.includes('classid'));
-      for (const key of keys) {
-        let cla_id = head[key];
-        let i = key.match(/\d+(.\d+)?/g)[0];
-        let r = this.classList.find(f => f._id == cla_id);
-        if (r) {
-          res[`id_${i}`] = _.get(r, `${type}id`);
-          res[`name_${i}`] = _.get(r, `${type}name`);
-          res[key] = cla_id;
-        }
-      }
-      return res;
-    },
-    setAllday(data = {}) {
-      let ckeys = Object.keys(data).filter(f => f.includes('classid'));
-      let lkeys = Object.keys(data).filter(f => f.includes('lessonid'));
-      let arr = [];
-      for (let i = 0; i < ckeys.length; i++) {
-        if (data[`${ckeys[i]}`] && data[`${lkeys[i]}`]) {
-          let cla = this.classList.find(f => f._id == data[ckeys[i]]);
-          if (cla) {
-            let { lessons } = cla;
-            let r = lessons.find(f => f._id == data[lkeys[i]]);
-            if (r) {
-              let o = {};
-              o[ckeys[i]] = data[ckeys[i]];
-              o[`day`] = _.get(r, 'day');
-              arr.push(o);
-            }
-          }
-        }
-      }
-      let obj = { type: 'allday' };
-      let r = arr.every(f => f.day == '0');
-      if (r) obj.date = '全天';
-      else {
-        r = arr.every(f => f.day == '1');
-        if (r) obj.date = '半天';
-        else {
-          let str = '';
-          arr.map((i, index) => {
-            str += i.day == '0' ? '全天' : '半天';
-            if (index != arr.length - 1) str += '/';
-          });
-          obj.date = str;
-        }
-      }
-      return obj;
+      this.$set(this, `list`, classList);
     },
+    // 获取地点,学校,部门,科目,教师,班级类型,班主任
     async getSettingLists() {
       let res;
       let arr = [];
       if (this.locationList.length <= 0) {
         arr.push(this.getLocationList());
       }
-      if (this.lyTeacherList.length <= 0) {
+      if (this.teacherList.length <= 0) {
         arr.push(this.getTeacherList());
       }
       if (this.schoolList.length <= 0) {
@@ -359,313 +214,177 @@ export default {
       if (this.subjectList.length <= 0) {
         arr.push(this.getSubject());
       }
+      if (this.ctList.length <= 0) {
+        arr.push(this.getCt());
+      }
+      if (this.headTeacherList.length <= 0) {
+        arr.push(this.getDirectorList());
+      }
       axios.all(arr).then(
-        axios.spread((r1, r2, r3, r4, r5) => {
+        axios.spread((r1, r2, r3, r4, r5, r6, r7) => {
           if (r1) this.$set(this, `locationList`, r1.data);
-          if (r2) this.$set(this, `lyTeacherList`, r2.data);
+          if (r2) this.$set(this, `teacherList`, r2.data);
           if (r3) this.$set(this, `schoolList`, r3.data);
           if (r4) this.$set(this, `deptList`, r4.data);
           if (r5) this.$set(this, `subjectList`, r5.data);
+          if (r6) {
+            let d = _.cloneDeep(r6.data);
+            d = d.map(i => {
+              i.order = parseInt(i.code);
+              return i;
+            });
+            d = _.orderBy(d, ['order'], ['asc']);
+            this.$set(this, `ctList`, d);
+          }
+          if (r7) this.$set(this, `headTeacherList`, r7.data);
         })
       );
     },
-    //初始化,将每个班级的班主任,礼仪课老师,教室id=>名称
-    async searchClassPerson(obj) {
-      let arr = [];
-      if (_.get(obj, 'jslocationid')) {
-        let r = this.locationList.find(f => f._id == _.get(obj, 'jslocationid'));
-        if (r) obj.jslocationname = _.get(r, `name`);
+
+    // 操作部分
+    // 修改教师
+    async lessonSave(data) {
+      console.log(data);
+      // lessonObjectId:lessonList的某项id; _id:lessons中指定的课
+      const { lessonObjectId, _id, is_last, ...info } = data;
+      let lobj = this.lessonList.find(f => f._id === lessonObjectId);
+      if (!lobj) {
+        this.$message.error('未找到该班课表');
+        return;
       }
-      if (_.get(obj, 'headteacherid')) {
-        let r = await this.getDirector(_.get(obj, 'headteacherid'));
-        if (this.$checkRes(r)) obj.headteachername = _.get(r.data, `name`);
+      let { lessons } = lobj;
+      if (!lessons) {
+        this.$message.error('未找到该班的课程');
+        return;
       }
-      if (_.get(obj, 'lyteacherid')) {
-        let r = await this.getDirector(_.get(obj, 'lyteacherid'));
-        if (this.$checkRes(r) && r.data) {
-          obj.lyteachername = _.get(r.data, `name`);
-        } else {
-          r = await this.getTeacher(_.get(obj, 'lyteacherid'));
-          if (this.$checkRes(r) && r.data) obj.lyteachername = _.get(r.data, `name`);
-        }
+      let r = lessons.find(f => f._id === _id);
+      if (!r) {
+        this.$message.error('未找到该课程');
+        return;
       }
-      // if (_.get(obj, 'jslocationid')) {
-      //   arr.push(this.modelFetch({ model: 'director', id: _.get(obj, 'jslocationid') }));
-      // }
-    },
-    toLesson(data, type) {
-      let { is_last, batch } = data;
-      if (is_last) {
-        let last = _.last(this.list[batch - 1]);
-        let { date } = last;
-        data.allday = date;
+      const ri = lessons.findIndex(f => f._id === _id);
+      r = { ...r, ...info };
+      lessons[ri] = r;
+      let sameDay = lessons.find(f => f.date === r.date && f.subid && f._id !== r._id);
+      if (sameDay) {
+        const { teaid, teaname, reason } = data;
+        sameDay.teaid = teaid;
+        sameDay.teaname = teaname;
+        sameDay.reason = reason;
+        let sameDayIndex = lessons.findIndex(f => f.date === r.date && f.subid && f._id !== r._id);
+        lessons[sameDayIndex] = sameDay;
       }
-      this.formType = type;
-      this.$set(this, `form`, data);
-      this.lDrawer = true;
-    },
-    async toOther(data, type) {
-      this.oDrawer = true;
-      this.dloading = true;
-      let { type: ct } = data;
-      if (ct != 'jslocation') await this.getHeadTeacher(data);
-      this.formType = type;
-      this.$set(this, `form`, data);
-      this.dloading = false;
-    },
-    lessonSave(data) {
-      let { index, batch, is_last, allday, listtype, ...info } = data;
-      console.log(data);
-      if (is_last) {
-        //TODO 改变半天/全天
-        if (this.formType == 'usual') this.$set(this.list[batch - 1], this.list[batch - 1].length - 1, { date: allday, type: 'allday' });
-        else this.$set(this.unusualList[batch - 1], this.unusualList[batch - 1].length - 1, { date: allday, type: 'allday' });
+      lobj.lessons = lessons;
+      let msg = this.$message({ duration: 0, message: '正在修改课程信息,请稍后...' });
+      const res = await this.lessonUpdate(lobj);
+      msg.close();
+      if (this.$checkRes(res, null, res.errmsg || '修改失败')) {
+        msg = this.$message({ duration: 0, message: '重新读取课程信息,请稍后...' });
+        await this.toClearSameDay(data);
+        if (is_last) {
+          await this.toChangeDay(data);
+        }
+        await this.toGetLesson();
+        this.toSetData();
+        this.toClose();
+        msg.close();
+        this.$message.success('已完成重新读取课程信息');
       }
-      if (this.formType == 'usual') this.$set(this.list[batch - 1], index, { batch, ...info });
-      else this.$set(this.unusualList[batch - 1], index, { batch, ...info });
-      this.toClose();
-      this.toGetTeachers();
     },
-    toClose() {
-      this.lDrawer = false;
-      this.oDrawer = false;
-      this.formType = 'usual';
-      this.form = {};
-    },
-    async getHeadTeacher(data) {
-      let batchid;
-      let { type } = data;
-      let { planid, termid } = this.defaultOption;
-      let keys = Object.keys(data).filter(f => f.includes('classid'));
-      if (keys.length <= 0) return;
-      let cla = this.classList.find(f => f._id == data[keys[0]]);
-      if (!cla) return;
-      batchid = cla.batchid;
-      let res = await this.findTeacher({ planid, termid, batchid });
-      if (this.$checkRes(res)) {
-        let duplicate = _.cloneDeep(res.data);
-        if (type == 'headteacher') {
-          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);
-        } else if (type == 'lyteacher') {
-          duplicate = duplicate.filter(f => f.islyteacher == '1');
-          this.$set(this, `lyTeacherList`, _.uniqBy([...this.lyTeacherList, ...duplicate], '_id'));
+    // 将该教师其他同一天的安排干掉
+    async toClearSameDay(data) {
+      const { lessonObjectId, date, teaid } = data;
+      let lobjs = this.lessonList.filter(f => f._id !== lessonObjectId);
+      let needUpdate = [];
+      for (let lobj of lobjs) {
+        let { lessons } = lobj;
+        if (!lessons || !_.isArray(lessons)) continue;
+        let ncList = lessons.filter(f => f.date === date && f.teaid === teaid);
+        // 该班课表,该天,没有该教师了,继续下一个
+        if (ncList.length <= 0) continue;
+        // 要是有,就改了,然后放到needUpdate中
+        for (let nc of ncList) {
+          const ri = lessons.findIndex(f => _.isEqual(f, nc));
+          if (ri < 0) continue;
+          nc.teaid = undefined;
+          nc.teaname = undefined;
+          lessons[ri] = nc;
         }
+        lobj.lessons = lessons;
+        delete lobj.meta;
+        needUpdate.push(lobj);
+      }
+      if (needUpdate.length > 0) {
+        const r = await this.plupdate(needUpdate);
       }
     },
-    //全部保存
-    allSave() {
-      //match(/\d+(.\d+)?/g)[0];
-      let duplicate = _.cloneDeep(this.list);
-      let dun = _.cloneDeep(this.unusualList);
-      duplicate = [...duplicate, ...dun];
-      let dClass = _.cloneDeep(this.classList);
-      let dLesson = _.cloneDeep(this.lessonList);
-      duplicate.map(data => {
-        // console.log(data);
-        let day = _.get(_.last(data), 'date', '全天');
-        day = day == '全天' ? '0' : '1';
-        //先以班级分组数据
-        let batch = [];
-        for (const obj of data) {
-          let keys = Object.keys(obj);
-          let r = _.uniq(_.flatten(_.compact(keys.map(key => key.match(/\d+(.\d+)?/g)))));
-          // console.log(`r`);
-          // console.log(r);
-          let notClassKey = keys.filter(f => {
-            for (const num of r) {
-              if (f.includes(num)) return false;
-            }
-            return true;
-          });
-          //获得这条数据公共属性
-          let common = {};
-          notClassKey.map(key => {
-            let o = {};
-            common[key] = obj[key];
-          });
-          // console.log(`common:`);
-          // console.log(common);
-          //获取各班设置
-          let self = [];
-          //获取需要分组的字段
-          let classKey = keys.filter(f => {
-            for (const num of r) {
-              if (f.includes(num)) return true;
-            }
-            return false;
-          });
-          // console.log(`classKey:和各个班级有关的key`);
-          // console.log(classKey);
-          //将分组字段的词根筛出来
-          let words = _.uniq(classKey.map(i => i.split('_')[0]));
-          // console.log(`words:classKey的词根`);
-          // console.log(words);
-          let wvs = [];
-          for (const num of r) {
-            let res = {};
-            words.map(word => {
-              res[word] = obj[`${word}_${num}`];
-            });
-            wvs.push(res);
-          }
-          // console.log(`wv:整理出以班为一个object的数组`);
-          wvs = wvs.map(i => {
-            return { ...i, ...common };
-          });
-          // console.log(wvs);
-          batch = [...batch, ...wvs];
-          // break;
-          // let indexs = _.uniq(keys.map(key => key.match(/\d+(.\d+)?/g)[0]));
-          // console.log(indexs);
-        }
-        // console.log(batch);
-        //按班分组,并将最后一天课按照全天/半天处理好
-        //先按classid分组 => [object] , object => array = [[string,array],...] => 数组维度-1 => [string,array] => 过滤出 数据类型是数组的数据 => [array]
-        let claArr = _.flatten(_.toPairs(_.groupBy(batch, 'classid'))).filter(f => _.isArray(f));
-        claArr = claArr.map(i => {
-          let shouldDeal = i.filter(f => f.type == 'lesson');
-          shouldDeal = _.orderBy(shouldDeal, 'date', 'asc');
-          let last = _.last(shouldDeal);
-          last = { ...last, day };
-          shouldDeal.splice(shouldDeal.length - 1, 1, last);
-          //处理班级的三个设置
-          let noDeal = i.filter(f => f.type !== 'lesson');
-          //此方法返回值为已经修改(班主任,礼仪教师,教室的id)后的班级列表(顺带也把meta除了),这个dClass可以作为修改班级的数据,剩下课表没出来
-          dClass = this.proClass(dClass, noDeal);
-          return shouldDeal;
-        });
-        // console.log(claArr);
-        //接下来改课表,之前整理过,所以课表除了改过的那些数据外,还有2份,一份在班级列表中(dClass中的lessons);还有一份原始数据在课程列表中(dLessons中的lessons)
-        //dClass和dLesson还有claArr可以通过classid建立联系确定唯一
-        //现在claArr中的结构是:[[{}],[{}],...] 内部第一层数组按班级分类,也就是说里面的{}都是一个班的数据
-        claArr.map(i => {
-          let cla_id = _.get(_.head(i), 'classid');
-          let les = dLesson.find(f => f.classid == cla_id);
-          let lesi = dLesson.findIndex(f => f.classid == cla_id);
-          if (!les) return;
-          //确定该班的原数据组(les) 和 现数据组(i)
-          //此处原数据的数据形式:{key(日期):array,...}
-          les = _.get(les, 'lessons', []);
-          les = _.groupBy(_.orderBy(les, ['date', 'time'], 'asc'), 'date');
-          //循环现数据,然后利用日期(date)缩小范围,然后过滤出 当前现数据所对应的原数据
-          i.map(nowi => {
-            let dateStr = _.get(nowi, 'date');
-            if (!dateStr) return;
-            //缩小范围,获取该天的原数据
-            let darr = les[dateStr];
-            //找到该条数据,进行替换
-            let r = darr.find(f => f._id == nowi.lessonid);
-            let ri = darr.findIndex(f => f._id == nowi.lessonid);
-            let o = {};
-            if (!r) return;
-            //数据还原与合并
-            let { _id, date, time } = r;
-            o = this.lessonDataReturn(nowi);
-            o = { ...o, _id, date, time };
-            //sub替换:此处靠数据关联=>自动排过课表后,有课的那天的array中一定会有2条数据,我们只改变第一条数据,第二条数据随着第一条数据改变
-            //所以此处会出现的问题就是:如果课表模板没有一天安排2条课的数据,那么此处会出现问题,不过这都是操作人干的.和程序无关
-            darr.splice(ri, 1, o);
-            let { subid, subname, teaid, teaname } = o;
-            // TODO 添加不需要老师授课的科目不进行同步
-            const subject = this.subjectList.find(f => f._id === subid);
-            let tosync = false;
-            if (subject) {
-              const { need_teacher } = subject;
-              if (need_teacher !== '1') tosync = true;
-            }
-            if (tosync && subid) {
-              let srarr = darr.filter(f => f.subid && f._id != _id);
-              for (const sr of srarr) {
-                let sri = darr.findIndex(f => f._id == sr._id);
-                let sro = { ...sr, subid, subname, teaid, teaname };
-                darr.splice(sri, 1, sro);
-              }
-            }
-          });
-          let dres = _.cloneDeep(les);
-          dres = _.flatten(_.flatten(_.toPairs(dres)).filter(f => _.isArray(f)));
-          dLesson[lesi].lessons = dres;
-        });
-      });
-      let ndClass = dClass.map(i => _.omit(i, ['lessons']));
-      let ndLesson = dLesson.map(i => _.omit(i, ['meta']));
-      // console.log(ndClass, ndLesson);
-      let res = this.checkClassConfig(dClass);
-      if (!res.length > 0) {
-        this.toSubmit(ndLesson, ndClass);
-        return;
+    // 修改班级设置
+    async classSave(data) {
+      let msg = this.$message({ duration: 0, message: '正在修改,请稍后...' });
+      const res = await this.classUpdate(data);
+      msg.close();
+      if (this.$checkRes(res, null, res.errmsg || '修改班级设置失败')) {
+        msg = this.$message({ duration: 0, message: '重新读取班级信息,请稍后...' });
+        await this.toGetClass();
+        this.toSetData();
+        this.toClose();
+        msg.close();
+        this.$message.success('已完成重新读取班级信息');
       }
-      const h = this.$createElement;
-      //[h('p', null, '您没有选择1班的礼仪课教师'), h('p', null, '您没有选择2班的礼仪课教师')]
-      let arrs = [];
-      for (const item of res) {
-        let r;
-        r = h(
-          'p',
-          null,
-          `${item.name}班:${item.headteacher ? '未选择班主任' : ''} ${item.lyteacher ? '未选择礼仪教师' : ''} ${item.jslocation ? '未选择教室' : ''}`
+    },
+    // 修改这一批次的所有课程的最后一天为全天/半天
+    async toChangeDay(data) {
+      const { lessonObjectId, _id, is_last, day, ...info } = data;
+      let lobj = this.lessonList.find(f => f._id === lessonObjectId);
+      if (!lobj) return;
+      const { batchid } = lobj;
+      let lobjs = this.lessonList.filter(f => f.batchid === batchid);
+      for (let o of lobjs) {
+        delete o.meta;
+        let { lessons } = o;
+        if (!(lessons && _.isArray(lessons))) continue;
+        const g = _.groupBy(lessons, 'date');
+        console.log(g);
+        let dkeys = Object.keys(g);
+        dkeys = _.orderBy(
+          dkeys.map(i => ({ date: i })),
+          ['date'],
+          ['asc']
         );
-        arrs.push(r);
+        const k = _.last(dkeys);
+        if (!k) continue;
+        // 将最后一天的所有day改成data的day
+        let needCList = g[k.date];
+        console.log(needCList);
+        for (let nco of needCList) {
+          const i = lessons.findIndex(f => f._id === nco._id);
+          if (i < 0) continue;
+          nco.day = day;
+          console.log(nco);
+          lessons[i] = nco;
+        }
+        o.lessons = lessons;
       }
-      this.$confirm(h('div', null, arrs), '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning',
-      })
-        .then(() => {
-          this.toSubmit(ndLesson, ndClass);
-        })
-        .catch(() => {});
-      // console.log(dLesson);
+      const r = await this.plupdate(lobjs);
     },
-    //提交接口请求
-    async toSubmit(dLesson, dClass) {
-      // 最后数据 dClass,班级列表; dLesson 课程列表
-      let axiosArr = [];
-      axiosArr.push(this.plupdate(dLesson));
-      axiosArr.push(this.pcupdate(dClass));
-      axios.all(axiosArr).then(
-        axios.spread((rl, rc) => {
-          if (!rl && rl.errcode != '0') {
-            this.$message.error(rl.errmsg);
-            return;
-          }
-          if (!rc && rc.errcode != '0') {
-            this.$message.error(rc.errmsg);
-            return;
-          }
-          this.$message.success('保存成功');
-        })
-      );
+    // 页面及其他逻辑
+    // 打开修改课程框
+    toLessonChange(data) {
+      this.$set(this, 'form', data);
+      this.lDrawer = true;
     },
-    lessonDataReturn(data) {
-      let { id: teaid, name: teaname, subid, subname, day = 0, reason } = data;
-      return { teaid, teaname, subid, subname, day, reason };
+    // 打开修改班级设置框
+    toClassChange(data) {
+      this.$set(this, `form`, data);
+      this.cDrawer = true;
     },
-    proClass(classes, data) {
-      let obj = {};
-      data.map(i => {
-        obj.classid = i.classid;
-        obj[`${i.type}id`] = i.id;
-      });
-      classes.splice(
-        classes.findIndex(f => f._id == obj.classid),
-        1,
-        { ...classes.find(f => f._id == obj.classid), ...obj }
-      );
-      classes = classes.map(i => _.omit(i, ['meta']));
-      return classes;
+
+    // 关闭窗口
+    toClose() {
+      this.lDrawer = false;
+      this.cDrawer = false;
+      this.formType = 'usual';
+      this.form = {};
     },
     //检查班主任/教室/礼仪课教师
     checkClassConfig(dClass) {
@@ -690,7 +409,7 @@ export default {
       let planid = _.get(this.defaultOption, 'planid');
       let termid = _.get(this.defaultOption, `termid`);
       if (needAlert)
-        this.$confirm('此操作将会将默认 年度计划 下所有的班级课表重置,若您已经修改过某班的信息,请谨慎使用', '提示', {
+        this.$confirm('此操作将会将后生成且没有课表的班级生成课表,已经生成的课表将不会改变!', '提示', {
           confirmButtonText: '按模板排课',
           cancelButtonText: '取消',
           type: 'warning',
@@ -704,7 +423,6 @@ export default {
             console.log('已取消');
           });
       else {
-        // 先暂停使用此功能,需要修改后
         let msg = this.$message({
           message: '首次进入,计划未排课,正在按模板进行排课中...',
           duration: 0,
@@ -718,33 +436,18 @@ export default {
         }
       }
     },
+    // 确定课表
     async toStatus() {
       let lessonIds = this.lessonList.map(i => i.id);
       const res = await this.confirmLesson(lessonIds);
       this.$checkRes(res, '课表确定成功', res.errmsg || '课表确定失败');
     },
+    // 获取消息
     async toGetNoticeList() {
       const { planid, termid } = this.defaultOption;
       const res = await this.getNoticeList({ planid, termid, type: '4' });
       if (this.$checkRes(res)) this.$set(this, `noticeList`, res.data);
     },
-    async toGetTeachers() {
-      let list = this.list
-        .flat()
-        .filter(f => f.type === 'lesson')
-        .filter(f => {
-          let keys = Object.keys(f);
-          return keys.find(f => f.startsWith('id_'));
-        });
-      let arr = [];
-      list.map(i => {
-        let keys = Object.keys(i).filter(f => f.startsWith('id_'));
-        keys.map(k => arr.push(i[k]));
-      });
-      arr = _.compact(_.uniq(arr));
-      const res = await this.getTeachers(arr);
-      if (this.$checkRes(arr)) this.$set(this, `inteaList`, res.data);
-    },
   },
   computed: {
     ...mapState(['user', 'defaultOption']),