lrf402788946 5 gadi atpakaļ
vecāks
revīzija
95781414fd

+ 9 - 3
src/router/index.js

@@ -269,10 +269,16 @@ const newPlan = [
     component: () => import('@/views/new-plan/class/name-list.vue'),
   },
   {
-    path: '/classes/quest',
-    name: 'classes_quest',
+    path: '/train/plan/quest',
+    name: 'train_plan_quest',
     meta: { title: '非常用问卷管理' },
-    component: () => import('@/views/new-plan/class/quest.vue'),
+    component: () => import('@/views/train-plan/quest.vue'),
+  },
+  {
+    path: '/train/plan/lesson',
+    name: 'train_plan_lesson',
+    meta: { title: '课表管理管理' },
+    component: () => import('@/views/train-plan/lesson.vue'),
   },
 ];
 

+ 2 - 6
src/views/new-plan/arrange/arrange.vue

@@ -40,12 +40,12 @@
         </el-card>
       </el-col>
     </el-row>
-    <template v-else-if="view == 'school'">
+    <!-- <template v-else-if="view == 'school'">
       <sch-arr :events="events" :year="info.year" :template="template" @toSave="toSave" @toDirector="toDirector"></sch-arr>
     </template>
     <template v-else>
       <dir-arr :events="events"></dir-arr>
-    </template>
+    </template> -->
     <!-- </detail-frame> -->
     <el-drawer :visible.sync="drawer" direction="rtl" title="安排计划" @close="toClose">
       <event
@@ -96,8 +96,6 @@ import detailFrame from '@frame/layout/admin/detail-frame';
 import calendar from '@frame/components/calendar';
 import dataTable from '@frame/components/data-table';
 import event from '../parts/event';
-import schArr from '../parts/school-arrange';
-import dirArr from '../parts/director-arrange';
 import { mapState, createNamespacedHelpers } from 'vuex';
 const { mapActions } = createNamespacedHelpers('trainplan');
 const { mapActions: trainTemplate } = createNamespacedHelpers('trainTemplate');
@@ -111,8 +109,6 @@ export default {
     calendar,
     // dataTable,
     event,
-    schArr,
-    dirArr,
   },
   data: function() {
     var that = this;

+ 0 - 1
src/views/new-plan/class/setting.vue

@@ -120,7 +120,6 @@ export default {
         res = await this.getTeacherList({ islyteacher: '1', status: '4' });
         if (this.$checkRes(res)) this.$set(this, `lyTeacherList`, res.data);
       }
-      //TODO 需要重写这个方法,班主任上报的是日期,不是批次,需要查出该班主任上报的事件在不在批次时间中
       if (this.headTeacherList.length <= 0) {
         res = await this.findTeacher({ planid: data.planid, termid: data.termid, batchid: data.batchid });
         let duplicate = _.cloneDeep(res.data);

+ 0 - 160
src/views/new-plan/parts/director-arrange.vue

@@ -1,160 +0,0 @@
-<template>
-  <div id="director-arrange">
-    <el-row type="flex" align="middle" justify="end" style="padding-bottom:10px">
-      <el-col :span="2">
-        <el-button type="success" size="mini" @click="toSave">保存班主任计划</el-button>
-      </el-col>
-      <el-col :span="2">
-        <el-button type="primary" size="mini" @click="toArrange">一键分配</el-button>
-      </el-col>
-    </el-row>
-    <data-table v-loading="loading" :fields="fields" :data="classList" :opera="opera" @edit="toEdit" :toFormat="toFormat"></data-table>
-    <el-dialog title="选择班主任" :visible.sync="dialog" width="20%">
-      <data-form :data="form" :fields="fields" :rules="{}" @save="handleSave">
-        <template #options="{item,form}">
-          <template v-if="item.model == 'headteacherid'">
-            <el-option-group v-for="(dept, index) in htList" :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>
-          </template>
-        </template>
-      </data-form>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import _ from 'lodash';
-import dataTable from '@frame/components/data-table';
-import dataForm from '@frame/components/form';
-import { mapState, createNamespacedHelpers } from 'vuex';
-const { mapActions } = createNamespacedHelpers('teaPlan');
-const { mapActions: classes } = createNamespacedHelpers('classes');
-const { mapActions: mapDept } = createNamespacedHelpers('dept');
-const { mapActions: director } = createNamespacedHelpers('director');
-export default {
-  name: 'director-arrange',
-  props: {
-    events: { type: Array, default: () => [] },
-  },
-  components: { dataTable, dataForm },
-  data: function() {
-    return {
-      loading: true,
-      dialog: false,
-      form: {},
-      classList: [],
-      htList: [],
-      dirList: [],
-      deptList: [],
-      fields: [
-        { label: '期', prop: 'term', model: 'term', type: 'text' },
-        { label: '批', prop: 'batch', model: 'batch', type: 'text' },
-        { label: '班级', prop: 'name', model: 'name', type: 'text' },
-        { label: '班主任', prop: 'headteacherid', model: 'headteacherid', type: 'select', format: true }, //
-      ],
-      opera: [
-        {
-          label: '选择班主任',
-          icon: 'el-icon-edit',
-          method: 'edit',
-        },
-      ],
-    };
-  },
-  async created() {
-    await this.getOtherList();
-    this.search();
-  },
-  methods: {
-    ...director({ getDirList: 'query' }),
-    ...mapDept({ getDept: 'query' }),
-    ...mapActions(['divide', 'findTeacher']),
-    ...classes(['query', 'upHeadTea']),
-    async search() {
-      let res = await this.query({ planid: this.id });
-      if (this.$checkRes(res)) {
-        let arr = res.data.map(i => {
-          let e = this.events.find(f => f.termid == i.termid && f._id == i.batchid);
-          if (e) {
-            i.term = _.get(e, `term`);
-            i.batch = _.get(e, `batch`);
-          }
-          return i;
-        });
-        arr = _.reverse(arr.sort((a, b) => a.term - b.term && a.batch - b.batch));
-        this.$set(this, `classList`, arr);
-        this.loading = false;
-      }
-    },
-    async toArrange() {
-      this.loading = true;
-      let res = await this.divide({ trainplanid: this.id });
-      if (this.$checkRes(res)) {
-        let arr = this.classList.map(i => {
-          let r = res.data.find(f => f.classid == i._id);
-          if (r) i.headteacherid = r.headteacherid;
-          return i;
-        });
-        this.$set(this, `classList`, arr);
-      }
-      this.loading = false;
-    },
-    async toEdit({ data, index }) {
-      let res = await this.findTeacher({ planid: data.planid, termid: data.termid, batchid: data.batchid });
-      if (this.$checkRes(res)) {
-        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, `htList`, arr);
-      }
-      this.dialog = true;
-      this.$set(this, `form`, { ...JSON.parse(JSON.stringify(data)), index });
-    },
-    handleSave({ data }) {
-      let { index, ...info } = data;
-      this.$set(this.classList, index, info);
-      this.dialog = false;
-    },
-    async toSave() {
-      let data = JSON.parse(JSON.stringify(this.classList));
-      let res = await this.upHeadTea(data);
-      if (this.$checkRes(res, '保存成功', res.errmsg || '保存失败')) console.log(res);
-    },
-    async getOtherList() {
-      let res = await this.getDept();
-      if (this.$checkRes(res)) this.$set(this, `deptList`, res.data);
-      res = await this.getDirList();
-      if (this.$checkRes(res)) this.$set(this, `dirList`, res.data);
-    },
-    toFormat({ model, value }) {
-      if (model == 'headteacherid') {
-        let r = this.dirList.find(f => f._id == value);
-        if (r) return r.name;
-      }
-    },
-  },
-  computed: {
-    ...mapState(['user']),
-    pageTitle() {
-      return `${this.$route.meta.title}`;
-    },
-    id() {
-      return this.$route.query.id;
-    },
-  },
-  metaInfo() {
-    return { title: this.$route.meta.title };
-  },
-};
-</script>
-
-<style lang="less" scoped></style>

+ 0 - 581
src/views/new-plan/parts/school-arrange.vue

@@ -1,581 +0,0 @@
-<template>
-  <div id="school-arrange">
-    <el-row type="flex" align="middle" justify="end" style="padding-bottom:10px">
-      <el-col :span="2">
-        <el-button type="success" size="mini" @click="toSave">保存计划</el-button>
-      </el-col>
-      <el-col :span="2">
-        <el-button type="primary" size="mini" @click="toArrange">一键分配</el-button>
-      </el-col>
-      <el-col :span="2">
-        <el-button type="primary" size="mini" plain @click="dialog = true">查看汇总</el-button>
-      </el-col>
-      <el-col :span="2">
-        <el-button size="mini" icon="el-icon-right" @click="toDirector">班主任计划</el-button>
-      </el-col>
-    </el-row>
-
-    <!-- 大表 -->
-    <el-card v-loading="!already" style="min-height:500px">
-      <el-table
-        :data="list"
-        border
-        stripe
-        size="mini"
-        height="650px"
-        @cell-click="cellClick"
-        :cell-style="cellStyle"
-        :cell-class-name="cellClass"
-        v-if="already"
-      >
-        <el-table-column label="学校" fixed align="center" prop="name" width="180">
-          <template v-slot="{ row }">
-            <el-row>
-              <el-col :span="24">
-                {{ row.name }}
-              </el-col>
-              <el-col :span="24" v-if="row.number"> 名额:{{ row.number }} </el-col>
-            </el-row>
-          </template>
-        </el-table-column>
-        <el-table-column align="center" v-for="(i, index) in termList" :key="index" :label="`第${i.term}期`">
-          <el-table-column align="center" width="95" :prop="`term${index + 1}`">
-            <template #header>
-              <el-row>
-                <el-col :span="24">{{ i.start }}</el-col>
-                <el-col :span="24">至</el-col>
-                <el-col :span="24">{{ i.end }}</el-col>
-              </el-row>
-            </template>
-          </el-table-column>
-        </el-table-column>
-      </el-table>
-    </el-card>
-
-    <el-drawer :visible.sync="drawer" direction="rtl" title="名额分配" @close="toClose">
-      <el-row type="flex" align="middle" justify="center" style="padding:20px" :gutter="20">
-        <el-col :span="12">
-          <el-card>
-            <el-form size="mini">
-              <el-form-item label="学校">{{ form | getProp('sch.name') }}</el-form-item>
-              <el-form-item label="学校层次">{{ form | getProp('sch.level') }}</el-form-item>
-              <el-form-item label="需要派车">{{ form | getProp('sch.hascar') }}</el-form-item>
-              <el-form-item label="总名额">{{ form | getProp('sch.number') }}</el-form-item>
-              <el-form-item label="剩余名额">{{ form | getProp('sch.remaining') }}</el-form-item>
-            </el-form>
-          </el-card>
-        </el-col>
-        <el-col :span="12">
-          <el-card>
-            <el-form size="mini">
-              <el-form-item label="期数">{{ form | getProp('term.term') }}</el-form-item>
-              <el-form-item label="开始时间">{{ form | getProp('term.start') }}</el-form-item>
-              <el-form-item label="结束时间">{{ form | getProp('term.end') }}</el-form-item>
-              <el-form-item label="总名额">{{ form | getProp('term.tpt') }}</el-form-item>
-              <el-form-item label="剩余名额">{{ form | getProp('term.remaining') }}</el-form-item>
-            </el-form>
-          </el-card>
-        </el-col>
-      </el-row>
-      <el-card style="padding:20px">
-        <el-row type="flex" align="middle" justify="center" :gutter="20">
-          <el-col :span="24">
-            <el-form size="mini" label-width="150px">
-              <el-form-item label="分配给该期的名额">
-                <el-input-number
-                  v-model="form.num"
-                  type="number"
-                  placeholder="请输入分配给该期的名额"
-                  :max="dGetMax(form)"
-                  :min="0"
-                  style="width:250px"
-                  @change="dComputed"
-                ></el-input-number>
-              </el-form-item>
-              <el-form-item>
-                <el-row type="flex" align="middle" justify="start" :gutter="20">
-                  <el-col :span="4">
-                    <el-button type="primary" @click="toSend">分配</el-button>
-                  </el-col>
-                  <el-col :span="4">
-                    <el-button @click="toClose">取消</el-button>
-                  </el-col>
-                </el-row>
-              </el-form-item>
-            </el-form>
-          </el-col>
-        </el-row>
-      </el-card>
-    </el-drawer>
-
-    <!-- 数据汇总 -->
-    <el-dialog :visible.sync="dialog" title="数据汇总">
-      <el-collapse v-model="activeName" accordion>
-        <el-collapse-item :title="`各期情况 (${isOk() ? '已完成' : '未完成'})`" name="1">
-          <el-table :data="totalList" border stripe size="mini">
-            <el-table-column prop="type"></el-table-column>
-            <el-table-column v-for="(i, index) in termList" align="center" :key="index" :label="`第${i.term}期`" :prop="`term${i.term}`"> </el-table-column>
-          </el-table>
-        </el-collapse-item>
-        <el-collapse-item :title="`车辆统计 共计(${getAllCarTotal()})`" name="2">
-          <el-table :data="carList" border stripe size="mini" height="500px">
-            <el-table-column type="expand">
-              <template v-slot="{ row }">
-                <el-row>
-                  <el-col :span="24" v-for="(i, index) in row.carTerm" :key="index">
-                    <span v-if="i.num > 0">第 {{ i.term }} 期需要 {{ i.num }} 辆车</span>
-                  </el-col>
-                </el-row>
-              </template>
-            </el-table-column>
-            <el-table-column label="学校" align="center" prop="name" width="180"></el-table-column>
-            <el-table-column label="车辆需求总数" align="center">
-              <template v-slot="{ row }">
-                {{ getTableCarTotal(row.carTerm) }}
-              </template>
-            </el-table-column>
-          </el-table>
-        </el-collapse-item>
-      </el-collapse>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import _ from 'lodash';
-var moment = require('moment');
-import { mapState, createNamespacedHelpers } from 'vuex';
-const { mapActions: school } = createNamespacedHelpers('school');
-const { mapActions: schPlan } = createNamespacedHelpers('schPlan');
-export default {
-  name: 'school-arrange',
-  props: {
-    events: { type: Array, default: () => [] },
-    year: { type: String, default: `${new Date().getFullYear()}` },
-    template: { type: Object, default: () => {} },
-  },
-  components: {},
-  data: () => {
-    return {
-      list: [],
-      termList: [],
-      totalList: [],
-      carList: [],
-      dialog: false,
-      drawer: false,
-      form: {},
-      activeName: '1',
-      already: false,
-    };
-  },
-  async created() {
-    await this.getSchool();
-  },
-  methods: {
-    ...school(['query']),
-    ...schPlan({ schPlanQuery: 'query', createSchPlan: 'create', updateSchPlan: 'update' }),
-    //请求,处理学校列表
-    async getSchool() {
-      const res = await this.query();
-      if (this.$checkRes(res)) {
-        let school = res.data.map(i => {
-          i = _.omit(i, ['meta', 'id', '_id', 'logourl']);
-          if (i.number) i.remaining = JSON.parse(JSON.stringify(i.number));
-          else i.remaining = 0;
-          return i;
-        });
-        this.$set(this, `list`, school);
-        await this.getSchoolPlan();
-        await this.getTotal();
-      }
-    },
-    //自动安排
-    toArrange() {
-      this.toReset();
-      let school = this.list.filter(f => f.daterange);
-      //整理之后的学校列表
-      school = _.reverse(_.sortBy(school, ['level', 'hascar']));
-      //整理每个学校的daterange:[{start,end}]的形式
-      school = this.changeRange(school);
-      let termList = JSON.parse(JSON.stringify(this.termList));
-      for (const sch of school) {
-        for (const t of termList) {
-          if (t.remaining && t.remaining <= 0) continue;
-          let { result } = this.$tqInRange(t.start, t.end, sch.daterange);
-          //result为true:说明该期复合要求
-          if (result) {
-            if (sch.remaining > t.remaining) {
-              //学校名额>本期剩余名额:
-              //学校剩余名额 = 学校剩余名额(原) - 本期剩余名额
-              //学校在该期的名额数量 = 本期剩余名额
-              //本期剩余名额=0;
-              sch.remaining = sch.remaining - t.remaining;
-              sch[`term${t.term}`] = t.remaining;
-              sch[`id_term${t.term}`] = t.termid;
-              t.remaining = 0;
-              continue;
-            } else if (sch.remaining <= t.remaining) {
-              //学校名额<=本期剩余名额:
-              //本期剩余名额 = 本期剩余名额(原) - 学校剩余名额;
-              //学校在该期的名额数量 = 学校剩余名额
-              //学校剩余名额 = 0
-              t.remaining = t.remaining - sch.remaining;
-              sch[`term${t.term}`] = sch.remaining;
-              sch[`id_term${t.term}`] = t.termid;
-              sch.remaining = 0;
-              break;
-            }
-          }
-        }
-        let index = _.findIndex(this.list, f => f.code == sch.code);
-        if (index >= 0) this.$set(this.list, index, sch);
-      }
-      this.listClear();
-      this.$set(this, `termList`, termList);
-      this.getTotal();
-      this.getCarTotal();
-    },
-    //保存整体计划
-    toSave() {
-      //修改学校上报计划,整理数据
-      let schPlan = this.list.map(i => {
-        let plan = _.cloneDeep(i.plan);
-        let keys = Object.keys(i).filter(f => _.startsWith(f, 'term'));
-        for (const key of keys) {
-          let object = {};
-          object.termnum = key.match(/\d+(.\d+)?/g)[0];
-          object._id = i[`_id_term${object.termnum}`];
-          object.number = i[`term${object.termnum}`];
-          object.termid = i[`id_term${object.termnum}`];
-          if (i.carTerm) {
-            let car = i.carTerm.find(f => f.term == object.termnum);
-            if (car) object.carnum = car.num;
-          }
-          plan.term.push(object);
-        }
-        if (plan) return plan;
-      });
-      schPlan = _.compact(schPlan);
-      schPlan = schPlan.map(i => {
-        i.term = _.uniqBy(this.checkTerm(i.term), '_id');
-        return i;
-      });
-      this.$emit('toSave', schPlan);
-    },
-    //手动更改
-    cellClick(row, column) {
-      //获取指定期
-      let term = this.termList.find(f => f.term == column.property.match(/\d+(.\d+)?/g)[0]);
-      //学校上报时间转换
-      row = this.changeRange(row);
-      let { result } = this.$tqInRange(term.start, term.end, row.daterange);
-      if (result) {
-        this.form.term = JSON.parse(JSON.stringify(term));
-        this.form.sch = JSON.parse(JSON.stringify(row));
-        this.$set(this.form, `num`, row[`term${term.term}`] * 1 || 0);
-        this.drawer = true;
-        //可以输入,整理显示数据
-      } else this.$message.error(`第 ${term.term} 期(${term.start} 至 ${term.end})不在 ${row.name} 上报的时间内!`);
-    },
-    toSend() {
-      let num = _.get(this.form, 'num');
-      let term = _.get(this.form, 'term');
-      let sch = _.get(this.form, 'sch');
-      let tn = term.term;
-      sch[`term${tn}`] = num;
-      sch[`id_term${tn}`] = term.termid;
-      // sch[`remaining`] = sch.remaining;
-      // term.remaining = term.remaining;
-      let si = _.findIndex(this.list, f => f.code == sch.code);
-      let ti = _.findIndex(this.termList, f => f.term == term.term);
-      this.$set(this.list, si, sch);
-      this.$set(this.termList, ti, term);
-      this.toClose();
-      this.getTotal();
-      this.getCarTotal();
-    },
-    //将学校上报的月份数组[String]=>[{start,end}]方法
-    changeRange(data) {
-      let c = r => {
-        return r.map(mon => {
-          if (_.isObject(mon)) return mon;
-          let start = moment()
-            .year(this.year)
-            .month(mon * 1 - 1)
-            .date('1')
-            .format('YYYY-MM-DD');
-          let end = moment()
-            .year(this.year)
-            .month(mon * 1)
-            .date('1')
-            .subtract(1, 'days')
-            .format('YYYY-MM-DD');
-          return { start, end };
-        });
-      };
-      let duplicate = JSON.parse(JSON.stringify(data));
-      if (_.isArray(duplicate)) {
-        duplicate = duplicate.map(i => {
-          let daterange = _.get(i, `daterange`, []); //['4','5','6']形式
-          i.daterange = c(daterange);
-          return i;
-        });
-      } else if (_.isObject(duplicate)) {
-        duplicate.daterange = c(duplicate.daterange);
-      }
-
-      return duplicate;
-    },
-    //学校匹配学校计划
-    async getSchoolPlan() {
-      const res = await this.schPlanQuery({ planid: this.id });
-      if (this.$checkRes(res)) {
-        let nl = this.list.map(i => {
-          let r = res.data.find(f => f.schid == i.code);
-          if (r) {
-            i.daterange = r.daterange;
-            i = this.changeRange(i);
-            let term = _.get(r, `term`);
-            term = this.checkTerm(term);
-            if (term) {
-              i.carTerm = [];
-              for (const t of term) {
-                i[`term${t.termnum}`] = t.number;
-                i[`id_term${t.termnum}`] = t.termid;
-                i[`_id_term${t.termnum}`] = t._id;
-                i.carTerm.push({ term: t.termnum, num: t.carnum });
-              }
-              i.remaining = i.remaining - term.reduce((prev, next) => prev + (next.number * 1 || 0), 0);
-            }
-            i.plan = r;
-          }
-          return i;
-        });
-        this.$set(this, `list`, nl);
-      }
-      this.$set(this, `already`, true);
-    },
-    //检查已分配的数据是否与现在的期对应
-    checkTerm(term) {
-      let res = term.map(i => {
-        let r = this.termList.find(f => f.termid == i.termid);
-        if (r) return i;
-      });
-      res = _.compact(res);
-      return res;
-    },
-    //整理期(事件)列表
-    getTermList() {
-      let arr = _.toPairs(_.groupBy(this.events, 'termid'));
-      let res = arr.map(i => {
-        i = _.flatten(_.remove(i, r => _.isArray(r)));
-        let tpt = i.reduce((prev, next) => {
-          let num = next.number ? next.number * 1 * next.class : next.class * _.get(this.template, 'stunum', 0);
-          return prev + num;
-        }, 0);
-        let { start, term, termid } = _.head(i);
-        let { end } = _.last(i);
-        return { start, end, term, tpt, remaining: tpt, termid }; //tpt:该期总人数 ,remaining:剩余人数
-      });
-      this.$set(this, `termList`, res);
-    },
-    //名额统计
-    getTotal() {
-      let res = this.termList.map((i, index) => {
-        i.total = this.list.reduce((prev, next) => prev + (next[`term${i.term}`] * 1 || 0), 0);
-        return i;
-      });
-      let aObject = { type: '已分配' };
-      let rObject = { type: '未分配' };
-      res.map(i => {
-        aObject[`term${i.term}`] = i.total || 0;
-        i.remaining = i.tpt - i.total || 0;
-        rObject[`term${i.term}`] = i.remaining || 0;
-      });
-      this.$set(this, `totalList`, [aObject, rObject]);
-    },
-    //车辆统计
-    getCarTotal() {
-      let school = this.list.filter(f => f.hascar == '1');
-      let carpnum = this.template.carpnum;
-      school.map(sch => {
-        let keys = Object.keys(sch).filter(f => _.startsWith(f, 'term'));
-        let pt = 0; //人数总数
-        sch.carTerm = [];
-        for (const key of keys) {
-          let term = key.match(/\d+(.\d+)?/g)[0];
-          let num = Math.ceil(sch[key] / carpnum);
-          sch.carTerm.push({ term, num });
-        }
-      });
-      this.$set(this, `carList`, school);
-    },
-    //计算车辆
-    getTableCarTotal(data) {
-      return data.reduce((prev, next) => {
-        return prev + (next.num || 0);
-      }, 0);
-    },
-    //所有车辆和计算
-    getAllCarTotal() {
-      return this.carList.reduce((prev, next) => {
-        let num = next.carTerm.reduce((p, n) => p + (n.num || 0), 0);
-        return prev + num;
-      }, 0);
-    },
-    //是否分配完毕,按期来说
-    isOk() {
-      let res = true;
-      let obj = this.totalList[1];
-      if (obj) {
-        let keys = Object.keys(obj).filter(f => f != 'type');
-        for (const key of keys) {
-          if (obj[key] > 0) {
-            res = false;
-            break;
-          }
-        }
-      } else res = false;
-
-      return res;
-    },
-    //分配重置
-    async toReset() {
-      this.getTermList();
-      let list = this.list.map(i => {
-        let object = _.pick(i, ['address', 'code', 'daterange', 'hascar', 'level', 'name', 'shortname', 'number', 'plan']);
-        object.remaining = object.number;
-        return object;
-      });
-      this.$set(this, `list`, list);
-    },
-    //将分配为0的数据清除
-    listClear() {
-      let list = this.list.map(i => {
-        let keys = Object.keys(i).filter(f => _.startsWith(f, 'term'));
-        for (const key of keys) {
-          if (i[key] == 0) {
-            delete i[key];
-            delete i[`id_${key}`];
-          }
-        }
-        return i;
-      });
-      this.$set(this, `list`, list);
-    },
-    //抽屉名额响应式计算
-    dComputed(cv, ov) {
-      let sch = this.form.sch;
-      let term = this.form.term;
-      let keys = Object.keys(sch)
-        .filter(f => _.startsWith(f, 'term'))
-        .filter(f => f != `term${term.term}`);
-      let sr = keys.reduce((prev, next) => prev - sch[next], sch.number) - cv;
-      let tr = this.list.reduce((prev, next) => {
-        if (next.code != sch.code) return prev - (next[`term${term.term}`] * 1 || 0);
-        else return prev;
-      }, term.tpt);
-      tr = tr - cv;
-      this.$set(this.form.sch, `remaining`, sr);
-      this.$set(this.form.term, `remaining`, tr);
-    },
-    //计算抽屉最大值
-    dGetMax(data) {
-      if (!this.drawer) return 0;
-      let res = 0;
-      let t = this.termList.find(f => f.termid == this.form.term.termid);
-      let sch = this.list.find(f => f.code == this.form.sch.code);
-      let s = _.get(data, 'sch');
-      let tr = _.get(data, 'term.remaining', 0) * 1;
-      let sr = _.get(data, 'sch.remaining', 0) * 1;
-      let num = this.form.num;
-      if (s.remaining == 0) return num;
-      if (tr > sr) {
-        res = sch.number * 1 || 0;
-      } else if (tr == sr) {
-        let keys = Object.keys(s)
-          .filter(f => _.startsWith(f, 'term'))
-          .filter(f => f != `term${t.term}`);
-        let nsr = keys.reduce((prev, next) => prev - s[next], s.number);
-        res = nsr;
-      } else {
-        res = t.tpt * 1 - t.total * 1 || 0;
-      }
-      return res * 1;
-    },
-    //关闭抽屉
-    toClose() {
-      this.drawer = false;
-      this.form = {};
-    },
-    //单元格样式
-    cellStyle({ row, column, rowIndex, columnIndex }) {
-      let disabled = { background: '#F56C6C' }; //{ background: '#F56C6C' }  ' disabled'
-      if (column.property == 'name') return '';
-      if (!_.get(row, 'daterange')) return disabled;
-      let term = this.termList.find(f => f.term == column.property.match(/\d+(.\d+)?/g)[0]);
-      //学校上报时间转换
-      row = this.changeRange(row);
-      let { result } = this.$tqInRange(term.start, term.end, row.daterange);
-      if (!result) return disabled;
-      else return '';
-    },
-    cellClass({ row, column, rowIndex, columnIndex }) {
-      let disabled = ' disabled_point';
-      if (column.property == 'name') return '';
-      if (!_.get(row, 'daterange')) return disabled;
-      let term = this.termList.find(f => f.term == column.property.match(/\d+(.\d+)?/g)[0]);
-      //学校上报时间转换
-      row = this.changeRange(row);
-      let { result } = this.$tqInRange(term.start, term.end, row.daterange);
-      if (!result) return disabled;
-      else return '';
-    },
-    //班主任计划
-    toDirector() {
-      this.toSave();
-      this.$emit(`toDirector`);
-    },
-  },
-  filters: {
-    getProp(data, prop) {
-      if (prop.includes('hascar')) {
-        let res = _.get(data, prop);
-        return res == '1' ? '需要' : '不需要';
-      } else return _.get(data, prop);
-    },
-  },
-  computed: {
-    ...mapState(['user']),
-    pageTitle() {
-      return `${this.$route.meta.title}`;
-    },
-    id() {
-      return this.$route.query.id;
-    },
-  },
-  watch: {
-    events: {
-      handler(val) {
-        if (val.length > 0) this.getTermList();
-      },
-      deep: true,
-      immediate: true,
-    },
-  },
-  metaInfo() {
-    return { title: this.$route.meta.title };
-  },
-};
-</script>
-
-<style lang="less" scoped>
-.el-table {
-  overflow: visible !important;
-}
-</style>
-<style>
-.disabled_point {
-  cursor: not-allowed;
-}
-</style>

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

@@ -0,0 +1,205 @@
+<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">
+          <el-button type="primary" size="mini" plain @click="toArrange">按模板排课</el-button>
+        </el-col>
+        <el-col :span="2">
+          <el-button type="primary" size="mini">查看本期课表</el-button>
+        </el-col>
+      </el-row>
+      <data-table :fields="fields" :data="list" :opera="opera" @edit="toEdit" :usePage="false"></data-table>
+    </detail-frame>
+    <detail-frame v-if="view == 'classView'" title="班级课表" :returns="() => (view = 'list')">
+      <class-table ref="lesson" :classInfo="classInfo" @saveResult="getRes"></class-table>
+      <el-divider></el-divider>
+      <info-class
+        ref="classes"
+        :classInfo="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 dataTable from '@frame/components/filter-page-table';
+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');
+const { mapActions: lesson } = createNamespacedHelpers('lesson');
+//info-class
+const { mapActions: location } = createNamespacedHelpers('location'); //地点
+const { mapActions: teacher } = createNamespacedHelpers('teacher'); //教师
+const { mapActions: dept } = createNamespacedHelpers('dept'); //配合教师表使用的部门表
+const { mapActions: dirPlan } = createNamespacedHelpers('dirPlan'); //班主任不能上课的列表
+const { mapActions: teaplan } = createNamespacedHelpers('teaPlan');
+const { mapActions: mapDept } = createNamespacedHelpers('dept');
+export default {
+  name: 'lesson',
+  props: {},
+  components: { detailFrame, dataTable, classTable, infoClass },
+  data: function() {
+    return {
+      view: 'list',
+      list: [],
+      opera: [
+        {
+          label: '查看本班课表',
+          icon: 'el-icon-view',
+          method: 'edit',
+        },
+      ],
+      fields: [
+        { label: '期', prop: 'term' },
+        { label: '批', prop: 'batch' },
+        { label: '班级', prop: 'name' },
+      ],
+      options: {},
+      classInfo: {},
+      //info-class
+      lyTeacherList: [],
+      locationList: [],
+      headTeacherList: [],
+      deptList: [],
+      result: [],
+    };
+  },
+  created() {},
+  methods: {
+    ...classes(['query']),
+    ...lesson({ autoArrange: 'arrange' }),
+    //info-class
+    ...location({ getLocationList: 'query' }),
+    ...teacher({ getTeacherList: 'query' }),
+    ...dirPlan({ dirQuery: 'getDirTeacher' }),
+    ...mapDept({ getDept: 'query' }),
+    ...teaplan(['findTeacher']),
+    async search() {
+      let termid = _.get(this.defaultOption, 'termid');
+      if (!termid) return;
+      let res = await this.query({ termid });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+      }
+    },
+    toEdit({ data }) {
+      this.getSettingLists(data);
+      this.$set(this, `classInfo`, data);
+      this.view = 'classView';
+    },
+    async toArrange() {
+      this.$confirm('此操作将会将默认 年度计划 下所有的班级课表重置,若您已经修改过某班的信息,请谨慎使用', '提示', {
+        confirmButtonText: '按模板排课',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+        .then(async () => {
+          let planid = _.get(this.defaultOption, 'planid');
+          let res = await this.autoArrange(planid);
+          this.$checkRes(res, '排课成功', res.errmsg || '排课失败');
+        })
+        .catch(async () => {
+          console.log('已取消');
+        });
+    },
+    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]);
+        }
+      }
+    },
+    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`, []);
+      }
+    },
+  },
+  watch: {
+    defaultOption: {
+      immediate: true,
+      deep: true,
+      handler(val) {
+        if (!_.get(this, 'options')) {
+          this.$set(this, `options`, _.cloneDeep(val));
+          this.search();
+        } else {
+          let ntermid = _.get(val, 'termid');
+          let otermid = _.get(this.options, 'termid');
+          if (ntermid && !_.isEqual(ntermid, otermid)) {
+            this.$set(this, `options`, _.cloneDeep(val));
+            this.search();
+          }
+        }
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user', 'defaultOption']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 85 - 0
src/views/train-plan/parts/class-info.vue

@@ -0,0 +1,85 @@
+<template>
+  <div id="class-info">
+    <data-form ref="form" :inline="true" :needSave="false" :data="form" :fields="fields" :rules="{}" @save="handleSave" :reset="false">
+      <template #options="{item, form}">
+        <template v-if="item.model == 'headteacherid'">
+          <el-option-group v-for="(dept, index) in headTeacherList" :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>
+        </template>
+        <template v-if="item.model == 'lyteacherid'">
+          <el-option v-for="(tea, index) in lyTeacherList" :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';
+import dataForm from '@frame/components/form';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: classes } = createNamespacedHelpers('classes');
+export default {
+  name: 'class-info',
+  props: {
+    classInfo: { type: Object, default: () => {} },
+    locationList: { type: Array, default: () => [] },
+    lyTeacherList: { type: Array, default: () => [] },
+    headTeacherList: { type: Array, default: () => [] },
+  },
+  components: { dataForm },
+  data: function() {
+    var that = this;
+    return {
+      form: _.cloneDeep(that.classInfo),
+      fields: [
+        // { label: '', model: 'name', type: 'text' },
+        // { label: '人数', model: 'number', type: 'text' },
+        { 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' },
+      ],
+    };
+  },
+  created() {},
+  methods: {
+    ...classes(['update']),
+    toSave() {
+      this.$refs.form.save();
+    },
+    async handleSave({ data }) {
+      let res = await this.update(data);
+      if (this.$checkRes(res, null, res.errmsg || '保存失败')) {
+        this.$emit('saveResult', { from: 'info', result: true });
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 353 - 0
src/views/train-plan/parts/class-table.vue

@@ -0,0 +1,353 @@
+<template>
+  <div id="class-table">
+    <el-card>
+      <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-row>
+      </template>
+      <el-table :data="lessonList" border stripe @cell-click="cellClick">
+        <el-table-column align="center" label="时间" prop="time"></el-table-column>
+        <el-table-column align="center" v-for="(i, index) in dateList" :key="index" :label="i" :prop="`subname_day${index + 1}`">
+          <template v-slot="{ row, $index }">
+            <el-row>
+              <el-col :span="24">{{ getProp(row, `subname_day${index + 1}`) }}</el-col>
+              <el-col :span="24" v-if="getProp(row, `teaname_day${index + 1}`)">{{ getProp(row, `teaname_day${index + 1}`) }}</el-col>
+            </el-row>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <el-drawer :visible.sync="drawer" direction="rtl" title="课程安排" @close="toClose">
+      <data-form :data="form" :fields="fields" :rules="{}" @save="handleSave" :reset="false">
+        <template #radios="{item, form}">
+          <template v-if="item.model == 'type'">
+            <el-radio @change="radioClearForm" v-for="(i, index) in dayType" :key="index" :label="i.label">{{ i.label }}</el-radio>
+          </template>
+        </template>
+        <template #options="{item, form}">
+          <template v-if="item.model == 'subname'">
+            <el-option v-for="(i, index) in actList" :key="index" :label="i.label" :value="i.label"></el-option>
+          </template>
+          <template v-if="item.model == 'subid'">
+            <el-option v-for="(i, index) in subjectList" :key="index" :label="i.name" :value="i.id"></el-option>
+          </template>
+        </template>
+
+        <template #custom="{item, form}">
+          <template v-if="item.model == 'teaname'">
+            <el-input v-model="form.teaname" :readonly="true" placeholder="点击选择教师" @click.native="toChooseTeacher"></el-input>
+          </template>
+        </template>
+      </data-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>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+var moment = require('moment');
+import _ from 'lodash';
+import dataForm from '@frame/components/form';
+import teacherSelect from './teacher.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: lesson } = createNamespacedHelpers('lesson');
+const { mapActions: mapUtil } = createNamespacedHelpers('util');
+const { mapActions: subject } = createNamespacedHelpers('subject');
+const { mapActions: teacher } = createNamespacedHelpers('teacher');
+const { mapActions: school } = createNamespacedHelpers('school'); //给选老师组件使用.这个页面请求完就不销毁了
+
+// 本页的组合数据,变量用x表示: _id_day[x];subname_day[x];subid_day[x];teaid_day[x];teaname_day:[x]
+export default {
+  name: 'class-table',
+  props: {
+    classInfo: { type: Object, default: () => {} },
+  },
+  components: { dataForm, teacherSelect },
+  data: function() {
+    var that = this;
+    return {
+      lessonInfo: {},
+      lessonList: [],
+      dateList: [],
+      timeList: [],
+      subjectList: [],
+      teacherList: [],
+      schoolList: [], //给选老师组件用
+      drawer: false,
+      dialog: false,
+      form: {},
+      fields: [
+        { label: '日期', model: 'date', type: 'text' },
+        { label: '时间', model: 'time', type: 'text' },
+        { label: '类型', model: 'type', type: 'radio' },
+        { label: '课程安排', model: 'subid', type: 'select', display: (fields, form) => that.fieldDisplay(fields, form) },
+        { label: '活动安排', model: 'subname', type: 'select', display: (fields, form) => that.fieldDisplay(fields, form) },
+        { label: '教师', model: 'teaname', custom: true, display: (fields, form) => that.fieldDisplay(fields, form) },
+      ],
+      dayType: [{ label: '活动' }, { label: '课程' }],
+      actList: [
+        { label: '--' },
+        { label: '报道+开班仪式' },
+        { label: '午餐+休息' },
+        { label: '晚餐' },
+        { label: '团队组建' },
+        { label: '拓展交流' },
+        { label: '课程作业小组展示' },
+        { label: '课程作业' },
+        { label: '礼仪课小组面试' },
+        { label: '结业仪式' },
+      ],
+    };
+  },
+  created() {
+    this.getOtherList();
+  },
+  methods: {
+    ...mapUtil(['fetch']),
+    ...lesson(['query', 'create', 'update']),
+    ...subject({ getSubject: 'query' }),
+    ...teacher({ getTeacher: 'query' }),
+    ...school({ getSchool: 'query' }),
+    async search() {
+      let res = await this.fetch({ model: 'lesson', classid: _.get(this.classInfo, '_id') });
+      if (this.$checkRes(res)) {
+        if (!_.get(res.data, 'lessons') || res.data.lessons.length <= 0) {
+          this.$message.warning('请先将本期的课程按模板进行初始化');
+          return;
+        }
+        this.$set(this, `lessonInfo`, _.omit(res.data, ['lessons']));
+        let arr = _.get(res.data, `lessons`, []);
+        let x = this.getX(JSON.parse(JSON.stringify(arr)));
+        this.getY(JSON.parse(JSON.stringify(arr)));
+        this.$set(this, `dateList`, x);
+        arr = this.aData(arr);
+        this.$set(this, `lessonList`, arr);
+      }
+    },
+    async toSave() {
+      //整理成原数据形式,提交
+      let data = JSON.parse(JSON.stringify(this.lessonList));
+      data = this.returnData(data);
+      let lesson = JSON.parse(JSON.stringify(this.lessonInfo));
+      lesson.lessons = data;
+      let res = await this.update(lesson);
+      if (this.$checkRes(res, null, res.errmsg || '课程表保存失败')) {
+        this.$emit('saveResult', { from: 'lesson', result: true });
+      }
+    },
+    //点击单元格事件
+    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;
+    },
+    //抽屉保存
+    handleSave({ data }) {
+      let num = _.get(data, 'index');
+      let type = _.get(data, `type`);
+      let time = _.get(data, `time`);
+      let yIndex = this.lessonList.findIndex(f => f.time == time);
+      let obj = {};
+      if (type == '课程') {
+        obj = _.pick(data, ['subid', 'teaid', 'teaname', '_id']);
+        let r = this.subjectList.find(f => f.id == obj.subid);
+        if (r) obj.subname = r.name;
+      } else {
+        obj = _.pick(data, ['subname', '_id']);
+      }
+      obj = this.resetData(obj, num);
+      this.$set(this.lessonList, yIndex, { ...this.lessonList[yIndex], ...obj });
+      this.drawer = false;
+    },
+    //提交整理数据
+    returnData(data) {
+      let returnArr = [];
+      data.map(i => {
+        let keys = Object.keys(i);
+        let time = _.get(i, `time`);
+        let arr = _.compact(_.uniq(_.flatten(keys.map(i => i.match(/\d+(.\d+)?/g)))));
+        arr.map(index => {
+          let obj = this.getOrderDate(i, index, true);
+          obj.time = time;
+          obj.day = '0';
+          returnArr.push(obj);
+        });
+      });
+      let r = returnArr.filter(f => f.date == _.last(this.dateList));
+      let allday = '0';
+      let res = r.find(f => {
+        //TODO 根据开始时间不超过12点判断是 整天还是半天
+        if (f.subname != '--') {
+          let ts = f.time.split('-');
+          let time = moment(`${f.date} ${ts[0]}`).format('X');
+          let twl = moment(`${f.date} 12:00`).format('X');
+          return twl <= time;
+        }
+      });
+      if (res) allday = '1';
+      returnArr = returnArr.map(i => {
+        if (i.date == _.last(this.dateList)) i.allday = allday;
+        else i.allday = '0';
+        return i;
+      });
+      return returnArr;
+    },
+    //field的显示
+    fieldDisplay(f, form) {
+      if (f.model == 'teaname' || f.model == 'subid') {
+        return form.type == '课程';
+      } else return form.type == '活动';
+    },
+    //请求后整理数据方法
+    aData(data) {
+      let duplicate = JSON.parse(JSON.stringify(data));
+      //按时间分组
+      duplicate = _.flatten(_.toPairs(_.groupBy(data, 'time'))).filter(f => _.isArray(f));
+      let r = duplicate.map(i => {
+        //按日期排序
+        let aa = i.sort((a, b) => moment(a.date).format('X') - moment(b.date).format('X'));
+        //组合数据:{time,day1,id_day1,subid_day1}
+        let object = { time: _.get(i[0], 'time') };
+        aa.map(a => {
+          let index = this.dateList.findIndex(f => f == a.date);
+          if (index >= 0) {
+            index = index + 1;
+          }
+          let obj = this.resetData(a, index);
+          object = { ...object, ...obj };
+        });
+        return object;
+      });
+      r = this.getOrderForTime(r);
+      return r;
+    },
+    //获取指定数据
+    getOrderDate(data, index, needDate = false) {
+      let obj = { index: index };
+      if (_.get(data, `_id_day${index}`)) obj[`_id`] = _.get(data, `_id_day${index}`);
+      obj[`subname`] = _.get(data, `subname_day${index}`, `--`);
+      if (_.get(data, `subid_day${index}`)) obj[`subid`] = _.get(data, `subid_day${index}`);
+      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了
+        delete obj.index;
+        obj.date = this.dateList[index - 1];
+      }
+      return obj;
+    },
+    //整理,匹配数据是哪天,该显示在哪
+    resetData(data, index) {
+      let obj = {};
+      if (_.get(data, '_id')) obj[`_id_day${index}`] = _.get(data, '_id');
+      obj[`subname_day${index}`] = _.get(data, 'subname', '--');
+      if (_.get(data, 'subid')) obj[`subid_day${index}`] = _.get(data, 'subid');
+      if (_.get(data, 'teaid')) obj[`teaid_day${index}`] = _.get(data, 'teaid');
+      if (_.get(data, 'teaname')) obj[`teaname_day${index}`] = _.get(data, 'teaname');
+      return obj;
+    },
+    //修改:
+    //根据时间排序
+    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;
+    },
+    //整理出标头,根据日期排序
+    getX(data) {
+      let r = _.uniqBy(data, 'date').map(i => i.date);
+      r = r.sort((a, b) => moment(a).format('X') - moment(b).format('X'));
+      return r;
+    },
+    //获得时间列表
+    getY(data) {
+      let duplicate = JSON.parse(JSON.stringify(data));
+      let arr = _.uniqBy(
+        duplicate.map(i => _.pick(i, ['time'])),
+        'time'
+      );
+      arr = this.getOrderForTime(arr);
+      this.$set(
+        this,
+        `timeList`,
+        arr.map(i => i.time)
+      );
+    },
+    //教师列表,课程列表
+    async getOtherList() {
+      let res = await this.getSubject();
+      if (this.$checkRes(res)) this.$set(this, `subjectList`, res.data);
+      res = await this.getTeacher({ status: '4' });
+      if (this.$checkRes(res)) this.$set(this, `teacherList`, res.data);
+    },
+    //关闭抽屉
+    toClose() {
+      this.drawer = false;
+      this.form = {};
+    },
+    //修改类型清除数据
+    radioClearForm(data) {
+      if (data == '活动') {
+        delete this.form.subid;
+        this.form.subname = '--';
+      }
+    },
+    //打开选择教师的dialog
+    async toChooseTeacher() {
+      this.dialog = true;
+      if (this.schoolList.length <= 0) {
+        let res = await this.getSchool();
+        if (this.$checkRes(res)) this.$set(this, `schoolList`, res.data);
+      }
+    },
+    //选择教师
+    selTea(data) {
+      this.dialog = false;
+      this.$set(this, `form`, { ...this.form, ...data });
+    },
+    //显示
+    getProp(data, prop) {
+      return _.get(data, prop);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  watch: {
+    classInfo: {
+      handler(val) {
+        let id = _.get(val, '_id');
+        if (id) this.search();
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 97 - 0
src/views/train-plan/parts/teacher.vue

@@ -0,0 +1,97 @@
+<template>
+  <div id="teacher">
+    <el-tabs v-model="teaTab">
+      <el-tab-pane style="padding:10px" label="申请授课教师" name="apply">
+        <filter-table :data="applyList" :fields="teaFields" :opera="opera" @select="selectTeacher" :total="applyTotal" @query="toGetApplyList"></filter-table>
+      </el-tab-pane>
+      <el-tab-pane style="padding:10px" label="可授课教师" name="list">
+        <filter-table
+          :data="teacherList"
+          :fields="teaFields"
+          :opera="opera"
+          @select="selectTeacher"
+          :total="teacherTotal"
+          @query="toGetTeacherList"
+        ></filter-table>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import filterTable from '@frame/components/filter-page-table.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: teacher } = createNamespacedHelpers('teacher'); //教师
+const { mapActions: teaPlan } = createNamespacedHelpers('teaPlan'); //教师申请
+export default {
+  name: 'teacher',
+  props: {
+    schoolList: { type: Array, default: () => [] },
+    subjectList: { type: Array, default: () => [] },
+    subjectid: { type: String, default: () => '' },
+  },
+  components: { filterTable },
+  data: function() {
+    return {
+      teaTab: 'apply',
+      teaFields: [
+        { label: '姓名', prop: 'name', filter: 'input' },
+        { label: '学校', prop: 'schname' },
+        { label: '资料评分', prop: 'zlscore' },
+        { label: '面试评分', prop: 'msscore' },
+      ],
+      opera: [
+        {
+          label: '选择教师',
+          icon: 'el-icon-check',
+          method: 'select',
+        },
+      ],
+      applyList: [],
+      applyTotal: 0,
+      teacherList: [],
+      teacherTotal: 0,
+    };
+  },
+  created() {},
+  methods: {
+    ...teacher({ getTeacherList: 'query' }),
+    ...teaPlan({ getApplyTeacherList: 'applyQuery' }),
+    async toGetTeacherList({ skip = 0, limit = 10, ...info } = {}) {
+      let res = await this.getTeacherList({ skip, limit, ...info, subid: this.subjectid, status: '4' });
+      this.$set(this, `teacherTotal`, res.total);
+      this.$set(this, `teacherList`, res.data);
+    },
+    async toGetApplyList({ skip = 0, limit = 10, ...info } = {}) {
+      let res = await this.getApplyTeacherList({ skip, limit, ...info, subid: this.subjectid, status: '4' });
+      this.$set(this, `applyTotal`, res.total);
+      this.$set(this, `applyList`, res.data);
+    },
+    selectTeacher({ data }) {
+      this.$emit('selTea', { teaname: data.name, teaid: data._id });
+    },
+  },
+  watch: {
+    subjectid: {
+      handler(val, oval) {
+        if (val && val != oval) {
+          this.toGetApplyList();
+          this.toGetTeacherList();
+        }
+      },
+      immediate: true,
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 0 - 1
src/views/new-plan/class/quest.vue

@@ -79,7 +79,6 @@ export default {
       }
       if (this.$checkRes(res)) {
         let ids = _.get(res.data, `questionnaireid`);
-        console.log(ids);
         this.$set(this.form, `termid`, termid);
         this.$set(this.form, `id`, _.get(res.data, `_id`));
         if (ids) {