lrf402788946 5 years ago
parent
commit
3097b0d606

+ 12 - 0
src/router/index.js

@@ -42,6 +42,18 @@ const newPlan = [
     meta: { title: '排课管理' },
     component: () => import('@/views/new-plan/class/lesson.vue'),
   },
+  {
+    path: '/newPlan/classes/setting',
+    name: 'newPlan_classes_setting',
+    meta: { title: '班级设置' },
+    component: () => import('@/views/new-plan/class/setting.vue'),
+  },
+  {
+    path: '/newPlan/classes/bedroom',
+    name: 'newPlan_classes_bedroom',
+    meta: { title: '分寝' },
+    component: () => import('@/views/new-plan/class/bedroom.vue'),
+  },
 ];
 
 const routes = [

+ 11 - 3
src/views/new-plan/arrange.vue

@@ -1,9 +1,10 @@
 <template>
   <div id="arrange">
     <detail-frame :title="pageTitle" :returns="returns">
-      <el-steps :active="view == 'plan' ? 1 : 2" align-center style="padding-bottom:10px">
+      <el-steps :active="view == 'plan' ? 1 : view == 'school' ? 2 : 3" align-center style="padding-bottom:10px">
         <el-step title="安排培训计划"></el-step>
         <el-step title="安排学校计划"></el-step>
+        <el-step title="安排班主任计划"></el-step>
       </el-steps>
       <el-row :gutter="10" type="flex" v-if="view == 'plan'">
         <el-col :span="12">
@@ -37,8 +38,11 @@
           </el-card>
         </el-col>
       </el-row>
+      <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>
-        <sch-arr :events="events" :year="info.year" :template="template" @toSave="toSave"></sch-arr>
+        <dir-arr :events="events"></dir-arr>
       </template>
     </detail-frame>
     <el-drawer :visible.sync="drawer" direction="rtl" title="安排计划" @close="toClose">
@@ -91,6 +95,7 @@ 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');
@@ -98,7 +103,7 @@ const { mapActions: schPlan } = createNamespacedHelpers('schPlan');
 export default {
   name: 'arrange',
   props: {},
-  components: { detailFrame, calendar, dataTable, event, schArr },
+  components: { detailFrame, calendar, dataTable, event, schArr, dirArr },
   data: function() {
     var that = this;
     return {
@@ -450,6 +455,9 @@ export default {
         this.savePlan();
       }
     },
+    toDirector() {
+      this.view = 'director';
+    },
   },
   computed: {
     ...mapState(['user']),

+ 87 - 0
src/views/new-plan/class/bedroom.vue

@@ -0,0 +1,87 @@
+<template>
+  <div id="bedroom">
+    <list-frame v-if="view === 'list'" returns="./index" :title="pageTitle" :needFilter="false" :needAdd="false" :needPag="false">
+      <el-alert type="warning" title="请确认好学生已经报道后再进行分寝" center :closable="false"></el-alert>
+      <el-form :inline="true">
+        <el-form-item>
+          <el-select v-model="prerequisite.term" size="small" @change="toGetBatch" placeholder="请选择要对哪一期进行分寝">
+            <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>
+      <data-table ref="table" :fields="fields" :data="list" :opera="opera" @bedroom="toBedroom"></data-table>
+    </list-frame>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import listFrame from '@frame/layout/admin/list-frame';
+import dataTable from '@frame/components/data-table';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: trainPlan } = createNamespacedHelpers('trainplan');
+const { mapActions: bedroom } = createNamespacedHelpers('bedroom'); //分寝
+export default {
+  name: 'bedroom',
+  props: {},
+  components: { listFrame, dataTable },
+  data: () => {
+    return {
+      view: 'list',
+      termList: [],
+      batchList: [],
+      list: [],
+      prerequisite: {},
+      classInfo: {},
+      opera: [
+        {
+          label: '一键分寝',
+          icon: 'el-icon-s-home',
+          method: 'bedroom',
+        },
+      ],
+      fields: [
+        { label: '批次', prop: 'name' },
+        // { label: '批数', prop: 'batch' },
+      ],
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    ...trainPlan({ getTrainPlan: 'fetch', sendNotice: 'notice' }),
+    ...bedroom({ bedroomApart: 'apart' }),
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      let res = await this.getTrainPlan(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `termList`, _.get(res.data, 'termnum', []));
+      }
+    },
+    toGetBatch(id) {
+      console.log(id);
+      let res = this.termList.find(f => f._id == id);
+      this.$set(this, `list`, res.batchnum || []);
+    },
+    async toBedroom({ data }) {
+      let object = { termid: this.term, trainplanid: this.id, batchid: data._id };
+      let res = await this.bedroomApart(object);
+      this.$checkRes(res, '分寝成功', res.errmsg);
+    },
+  },
+  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>

+ 49 - 6
src/views/new-plan/class/index-class.vue

@@ -1,7 +1,16 @@
 <template>
   <div id="index">
-    <list-frame :title="pageTitle" @query="search" :total="total" :needFilter="false">
-      <data-table :fields="fields" :data="list" :opera="opera" @classes="toClasses" @lesson="lesson"></data-table>
+    <list-frame :title="pageTitle" @query="search" :total="total" :needFilter="false" :needAdd="false">
+      <data-table
+        :fields="fields"
+        :data="list"
+        :opera="opera"
+        @classes="toClasses"
+        @lesson="lesson"
+        @setting="toSetting"
+        @msg="sendMsg"
+        @bedroom="toBedroom"
+      ></data-table>
     </list-frame>
   </div>
 </template>
@@ -14,6 +23,7 @@ import listFrame from '@frame/layout/admin/list-frame';
 import dataTable from '@frame/components/data-table';
 import { mapState, createNamespacedHelpers } from 'vuex';
 const { mapActions: trainplan } = createNamespacedHelpers('trainplan');
+const { mapActions: classes } = createNamespacedHelpers('classes');
 export default {
   name: 'index',
   props: {},
@@ -24,15 +34,30 @@ export default {
       drawer: false,
       opera: [
         {
-          label: '班',
-          icon: 'el-icon-school',
-          method: 'classes',
+          label: '班级设置',
+          icon: 'el-icon-setting',
+          method: 'setting',
         },
         {
           label: '排课',
           icon: 'el-icon-date',
           method: 'lesson',
         },
+        {
+          label: '排班',
+          icon: 'el-icon-school',
+          method: 'classes',
+        },
+        {
+          label: '分寝',
+          icon: 'el-icon-s-home',
+          method: 'bedroom',
+        },
+        {
+          label: '发送确认通知',
+          icon: 'el-icon-message-solid',
+          method: 'msg',
+        },
       ],
       fields: [
         { label: '年度', prop: 'year' },
@@ -62,7 +87,8 @@ export default {
     this.search();
   },
   methods: {
-    ...trainplan(['query', 'create', 'delete', 'update']),
+    ...trainplan(['query', 'create', 'delete', 'update', 'notice']),
+    ...classes({ getClasses: 'query' }),
     async search({ skip = 0, limit = 10, ...info } = {}) {
       const res = await this.query({ skip, limit, ...info });
       if (this.$checkRes(res)) {
@@ -76,6 +102,23 @@ export default {
     lesson({ data }) {
       this.$router.push({ path: './lesson', query: { id: data.id } });
     },
+    toSetting({ data }) {
+      this.$router.push({ path: './setting', query: { id: data.id } });
+    },
+    toBedroom({ data }) {
+      this.$router.push({ path: './bedroom', query: { id: data.id } });
+    },
+    async sendMsg({ data }) {
+      //TODO need test
+      let res = await this.getClasses({ planid: data._id });
+      if (this.$checkRes(res)) {
+        let arr = res.data.map(i => i._id);
+        if (arr.length > 0) {
+          const resNotice = await this.sendNotice({ classids: arr });
+          this.$checkRes(resNotice, '发送成功', '发送失败');
+        }
+      }
+    },
   },
   computed: {
     ...mapState(['user']),

+ 0 - 10
src/views/new-plan/class/lesson.vue

@@ -56,16 +56,6 @@ export default {
           icon: 'el-icon-date',
           method: 'date',
         },
-        {
-          label: '一键分寝',
-          icon: 'el-icon-s-home',
-          method: 'bedroom',
-        },
-        {
-          label: '发送确认通知',
-          icon: 'el-icon-message-solid',
-          method: 'msg',
-        },
       ],
       fields: [
         { label: '班级', prop: 'name' },

+ 1 - 1
src/views/new-plan/class/lesson/lesson-table.vue

@@ -130,7 +130,7 @@ export default {
       lesson.lessons = data;
       let res = await this.update(lesson);
       if (this.$checkRes(res, '课程表保存成功', res.errmsg || '课程表保存失败')) {
-        console.log(`in`);
+        this.$router.push({ path: './index' });
       }
     },
     //点击单元格事件

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

@@ -0,0 +1,138 @@
+<template>
+  <div id="setting">
+    <list-frame v-if="view === 'list'" returns="./index" :title="pageTitle" :needFilter="false" :needAdd="false" :needPag="false">
+      <el-form :inline="true">
+        <el-form-item>
+          <el-select v-model="prerequisite.term" size="small" @change="toGetClass">
+            <el-option-group v-for="(term, index) in termList" :key="index" :label="`第${term.term}期`">
+              <el-option
+                v-for="(batch, bindex) in term.batchnum"
+                :key="`${index}-${bindex}`"
+                :label="batch.type == '0' ? `第${batch.batch}批` : `特殊批`"
+                :value="batch._id"
+              ></el-option>
+            </el-option-group>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <data-table ref="table" :fields="fields" :data="list" :opera="opera" @setting="toSetting"></data-table>
+    </list-frame>
+    <detail-frame v-else title="返回" :returns="deReturn">
+      <setting-detail @save="toSave" :classInfo="classInfo" :locationList="locationList" :lyTeacherList="lyTeacherList"></setting-detail>
+    </detail-frame>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import listFrame from '@frame/layout/admin/list-frame';
+import detailFrame from '@frame/layout/admin/detail-frame';
+import dataTable from '@frame/components/data-table';
+import settingDetail from './setting/detail.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: trainPlan } = createNamespacedHelpers('trainplan');
+const { mapActions: classes } = createNamespacedHelpers('classes');
+const { mapActions: lesson } = createNamespacedHelpers('lesson');
+//setting-detail
+const { mapActions: location } = createNamespacedHelpers('location'); //地点
+const { mapActions: teacher } = createNamespacedHelpers('teacher'); //教师
+const { mapActions: dept } = createNamespacedHelpers('dept'); //配合教师表使用的部门表
+const { mapActions: dirPlan } = createNamespacedHelpers('dirPlan'); //班主任不能上课的列表
+
+export default {
+  name: 'setting',
+  props: {},
+  components: { listFrame, detailFrame, dataTable, settingDetail },
+  data: () => {
+    return {
+      view: 'list',
+      termList: [],
+      batchList: [],
+      list: [],
+      prerequisite: {},
+      classInfo: {},
+      opera: [
+        {
+          label: '设置',
+          icon: 'el-icon-setting',
+          method: 'setting',
+        },
+      ],
+      fields: [
+        { label: '班级', prop: 'name' },
+        // { label: '批数', prop: 'batch' },
+      ],
+      //setting-detail list:
+      locationList: [],
+      lyTeacherList: [],
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    ...trainPlan({ getTrainPlan: 'fetch', sendNotice: 'notice' }),
+    ...classes({ getClass: 'query', updateClass: 'update' }),
+    ...lesson({ autoArrange: 'arrange' }),
+    //setting-detail
+    ...location({ getLocationList: 'query' }),
+    ...teacher({ getTeacherList: 'query' }),
+    ...dirPlan({ dirQuery: 'getDirTeacher' }),
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      let res = await this.getTrainPlan(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `termList`, _.get(res.data, 'termnum', []));
+      }
+    },
+    async toSetting({ data }) {
+      this.view = 'class';
+      this.getSettingLists();
+      this.$set(this, `classInfo`, JSON.parse(JSON.stringify(data)));
+    },
+    async toGetClass(data) {
+      let res = await this.getClass({ batchid: data });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+      }
+    },
+    deReturn() {
+      this.view = 'list';
+    },
+    async getSettingLists() {
+      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);
+      }
+      //TODO 需要重写这个方法,班主任上报的是日期,不是批次,需要查出该班主任上报的事件在不在批次时间中
+      res = await this.dirQuery({ batchid: this.batchid });
+      console.log(res);
+    },
+    async toSave(data) {
+      console.log(data);
+      let res = await this.updateClass(data);
+      if (this.$checkRes(res, '保存成功', res.errmsg || '保存失败')) {
+        this.$router.push({ path: './index' });
+      }
+    },
+  },
+  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>

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

@@ -0,0 +1,74 @@
+<template>
+  <div id="detail">
+    <data-form :data="form" :fields="fields" :rules="{}" @save="handleSave" :reset="false">
+      <template #options="{item, form}">
+        <template v-if="item.model == 'headteacherid'">
+          班主任
+        </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';
+export default {
+  name: 'detail',
+  props: {
+    classInfo: { type: Object, default: () => {} },
+    locationList: { type: Array, default: () => [] },
+    lyTeacherList: { 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: {
+    handleSave({ data }) {
+      this.$emit('save', data);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

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

@@ -0,0 +1,89 @@
+<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 :fields="fields" :data="classList" :opera="opera"></data-table>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import dataTable from '@frame/components/data-table';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions } = createNamespacedHelpers('teaPlan');
+const { mapActions: classes } = createNamespacedHelpers('classes');
+export default {
+  name: 'director-arrange',
+  props: {
+    events: { type: Array, default: () => [] },
+  },
+  components: { dataTable },
+  data: function() {
+    return {
+      classList: [],
+      fields: [
+        { label: '期', prop: 'term' },
+        { label: '批', prop: 'batch' },
+        { label: '班级', prop: 'name' },
+        { label: '班主任', prop: 'headteacherid' },
+      ],
+      opera: [],
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    ...mapActions(['divide']),
+    ...classes(['query']),
+    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));
+        // arr = _.orderBy(arr, ['term', 'batch'], ['asc', 'asc']);
+        this.$set(this, `classList`, arr);
+      }
+    },
+    async toArrange() {
+      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);
+      }
+    },
+    async toSave() {},
+  },
+  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>

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

@@ -10,6 +10,9 @@
       <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>
 
     <!-- 大表 -->
@@ -526,6 +529,11 @@ export default {
       if (!result) return disabled;
       else return '';
     },
+    //班主任计划
+    toDirector() {
+      this.toSave();
+      this.$emit(`toDirector`);
+    },
   },
   filters: {
     getProp(data, prop) {