lrf402788946 5 yıl önce
ebeveyn
işleme
ce7cc38519

+ 173 - 106
src/views/new-plan/arrange/school-arrange.vue

@@ -2,7 +2,7 @@
   <div id="school-arrange">
     <detail-frame :title="pageTitle">
       <!-- 大表 -->
-      <!-- <el-card v-loading="!already" style="min-height:500px">
+      <el-card v-loading="!already" style="min-height:500px">
         <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>
@@ -14,7 +14,7 @@
             <el-button type="primary" size="mini" plain @click="dialog = true">查看汇总</el-button>
           </el-col>
         </el-row>
-        <el-table :data="list" border stripe size="mini" max-height="650px" @cell-click="cellClick" :show-summary="true" v-if="already">
+        <!-- <el-table :data="list" border stripe size="mini" max-height="650px" @cell-click="cellClick" :show-summary="true" v-if="already">
           <el-table-column label="学校" fixed align="center" prop="name" width="180">
             <template v-slot="{ row }">
               <el-row>
@@ -36,9 +36,16 @@
               </template>
             </el-table-column>
           </el-table-column>
-        </el-table>
-      </el-card> -->
-      <a-table :termList="termList"></a-table>
+        </el-table> -->
+        <a-table
+          :termList="termList"
+          :data="list"
+          @cellClick="cellClick"
+          :getDesignate="getDesignate"
+          :changeRange="changeRange"
+          :proAffix="proAffix"
+        ></a-table>
+      </el-card>
     </detail-frame>
 
     <el-drawer :visible.sync="drawer" direction="rtl" title="名额分配" @close="toClose">
@@ -146,9 +153,76 @@ export default {
   components: { detailFrame, aTable },
   data: () => {
     return {
-      list: [],
+      list: [
+        {
+          code: '10183',
+          name: '吉林大学',
+          level: '本科',
+          address: '长春',
+          hascar: '1',
+          shortname: '吉大',
+          cynum: 100,
+          jynum: 200,
+          mznum: 0,
+          number: 300,
+          remaining: 300,
+          daterange: [{ start: '2020-06-01', end: '2020-10-31' }],
+          carTerm: [],
+          plan: {
+            meta: { state: 0, createdAt: '2020-06-22T01:30:46.633Z', updatedAt: '2020-06-22T06:34:32.640Z' },
+            daterange: ['6', '7', '8', '9', '10'],
+            _id: '5ef009c620af53716453aab1',
+            schid: '10183',
+            year: '2020',
+            planid: '5eec849a8b3bc60be869867e',
+            term: [{ _id: '5ef050f8a4cae173b00e8a4c', termnum: '336', number: '100', termid: '5eec89778b3bc60be8698703', carnum: '2' }],
+            __v: 10,
+            id: '5ef009c620af53716453aab1',
+          },
+        },
+      ],
       plan: {},
-      termList: [],
+      termList: [
+        {
+          batchnum: [
+            {
+              _id: '5eec89778b3bc60be8698704',
+              batch: '1',
+              class: '2',
+              type: '0',
+              number: '56',
+              color: '#FF9D00',
+              name: '第336期第1批次',
+              term: '336',
+              termid: '5eec89778b3bc60be8698703',
+              start: '2020-06-28',
+              end: '2020-07-03',
+              bpt: 112,
+              remaining: 112,
+            },
+            {
+              _id: '5eec89778b3bc60be8698705',
+              batch: '2',
+              class: '2',
+              type: '0',
+              number: '56',
+              color: '#FF9D00',
+              name: '第336期第2批次',
+              term: '336',
+              termid: '5eec89778b3bc60be8698703',
+              start: '2020-06-29',
+              end: '2020-07-04',
+              bpt: 112,
+              remaining: 112,
+            },
+          ],
+          _id: '5eec89778b3bc60be8698703',
+          term: '336',
+          classnum: '4',
+          total: 0,
+          remaining: 0,
+        },
+      ],
       totalList: [],
       carList: [],
       template: {},
@@ -162,8 +236,9 @@ export default {
   },
   async created() {
     await this.toGetTrainPlan();
-    // await this.toGetTrainTemplate();
-    // await this.getSchool();
+    await this.toGetTrainTemplate();
+    await this.getSchool();
+    // this.already = true;
   },
   methods: {
     ...util({ modelFetch: 'fetch' }),
@@ -207,42 +282,47 @@ export default {
       //整理每个学校的daterange:[{start,end}]的形式
       school = this.changeRange(school);
       let termList = JSON.parse(JSON.stringify(this.termList));
+      let setInfo = (sch, b) => {
+        sch[this.proAffix(b._id, 'term_batch')] = b.termid; //记录这期和批次的对应关系 term_batch-${batchid} = termid
+        sch[this.proAffix(b.termid, 'term')] = b.term; //记录该期 term-${termid} = term
+        sch[this.proAffix(b._id, 'batch')] = b.batch; //记录该批次 batch-${batchid} = batch
+        //之前添加 批次分配的人数 batch_total-${batchid} = 人数
+      };
       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;
+          for (const b of t.batchnum) {
+            if (b.remaining && b.remaining <= 0) continue;
+            let { result } = this.$tqInRange(b.start, b.end, sch.daterange);
+            if (result) {
+              //学校名额>本批次剩余名额:
+              if (sch.remaining > b.remaining) {
+                sch.remaining = sch.remaining - b.remaining; //学校剩余名额 = 学校剩余名额(原) - 本批次剩余名额
+                if (b.remaining > 0) {
+                  sch[this.proAffix(b._id, 'batch_total')] = b.remaining; //学校哪一批次有多少人,表格上显示的
+                  setInfo(sch, b);
+                }
+                b.remaining = 0; //本批次剩余名额=0;
+                continue;
+              } else {
+                //学校名额<=本批次剩余名额
+                b.remaining = b.remaining - sch.remaining; //本批次剩余名额 = 本批次剩余名额(原) - 学校剩余名额;
+                if (sch.remaining > 0) {
+                  sch[this.proAffix(b._id, 'batch_total')] = sch.remaining; //学校哪一批次有多少人,表格上显示的
+                  setInfo(sch, b);
+                }
+                sch.remaining = 0; //学校剩余名额 = 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();
+      // this.listClear();
+      // this.getTotal();
+      // this.getCarTotal();
     },
     //保存整体计划
     async toSave() {
@@ -273,21 +353,7 @@ export default {
       const res = await this.setSchPlan(schPlan);
       this.$checkRes(res, '保存成功', res.errmsg);
     },
-    //手动更改
-    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} 上报的时间内!`);
-    },
+    cellClick() {},
     toSend() {
       let num = _.get(this.form, 'num');
       let term = _.get(this.form, 'term');
@@ -330,7 +396,7 @@ export default {
         });
         res = dr;
       } else if (len && len > 1) {
-        //TODO 长度大于1也就是说明最少上报了2个月份
+        //长度大于1也就是说明最少上报了2个月份
         //先排序,然后按照连续性分组
         let afterSort = data.sort((a, b) => a * 1 - b * 1);
         let newRange = this.getConRange(afterSort);
@@ -382,18 +448,21 @@ export default {
           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[`term${t.termnum}`] = t.number;
+                // i[`id_term${t.termnum}`] = t.termid;
+                // i[`_id_term${t.termnum}`] = t._id;
+                //TODO 车辆需要之后计算
+                // i.carTerm.push({ term: t.termnum, num: t.carnum });
               }
-              i.remaining = i.remaining - term.reduce((prev, next) => prev + (next.number * 1 || 0), 0);
+              // i.remaining = i.remaining - term.reduce((prev, next) => prev + (next.number * 1 || 0), 0);
             }
             i.plan = r;
           }
@@ -404,6 +473,7 @@ export default {
       this.$set(this, `already`, true);
     },
     //检查已分配的数据是否与现在的期对应
+    //TODO term=>arrange {termid,batchid都需要检测}
     checkTerm(term) {
       let res = term.map(i => {
         let r = this.termList.find(f => f.termid == i.termid);
@@ -415,35 +485,31 @@ export default {
     //整理批次(事件)列表
     getBatchList() {
       let events = this.resetEvents();
-      this.$set(this, `termList`, events);
-      // let arr = _.toPairs(_.groupBy(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);
+      //计算每批次人数上限
+      let res = events.map(i => {
+        i.batchnum = i.batchnum.map(b => {
+          b.bpt = b.number * 1 * (b.class * 1);
+          b.remaining = b.number * 1 * (b.class * 1);
+          return b;
+        });
+        return i; //bpt:该批次总人数 ,remaining:剩余人数
+      });
+      this.$set(this, `termList`, res);
       this.already = true;
     },
     //整理计划=>和日历的 events 一样
     resetEvents() {
-      let events = _.get(this.plan, 'termnum', []);
+      let events = _.cloneDeep(_.get(this.plan, 'termnum', []));
+      events = events.map(i => {
+        let tobj = { term: i.term, termid: i._id };
+        i.batchnum = i.batchnum.map(bat => {
+          let { startdate: start, enddate: end, ...info } = bat;
+          let bobj = { ...info, ...tobj, start, end };
+          return bobj;
+        });
+        return i;
+      });
       return events;
-      // events = events.map(i => {
-      //   let tobj = { term: i.term, termid: i._id };
-      //   return i.batchnum.map(bat => {
-      //     let { startdate: start, enddate: end, ...info } = bat;
-      //     let bobj = { ...info, ...tobj, start, end };
-      //     return bobj;
-      //   });
-      // });
-      // events = _.flatten(events);
-      // return events;
     },
     //名额统计
     getTotal() {
@@ -576,30 +642,7 @@ export default {
       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 '';
-    },
+
     //获取计划
     async toGetTrainPlan() {
       let planid = _.get(this.defaultOption, 'planid');
@@ -624,7 +667,10 @@ export default {
       if (planSchool.length <= 0) return data;
       let nl = data.map(i => {
         let r = planSchool.find(f => f.code == i.code);
-        if (r) i.number = r.num;
+        if (r) {
+          let { cynum = 0, jynum = 0, mznum = 0, num: number = 0 } = r;
+          i = { ...i, cynum: cynum * 1, jynum: jynum * 1, mznum: mznum * 1, number: number * 1 };
+        }
         return i;
       });
       nl = nl.sort((a, b) => a.code * 1 - b.code * 1);
@@ -637,6 +683,27 @@ export default {
       await this.toGetTrainTemplate();
       await this.getSchool();
     },
+    //batch分离与拼接
+    proAffix(value, affix) {
+      if (affix) return `${affix}-${value}`;
+      else {
+        let arr = value.split('-');
+        return { affix: _.head(arr), value: _.last(arr) };
+      }
+    },
+    //取出学校中,指定位置的信息
+    getDesignate(value, object) {
+      let obj = {};
+      let keys = Object.keys(object);
+      let arr = keys.filter(f => f.includes(value));
+      let termid = object[arr.find(f => f.includes('term_batch'))];
+      let term = object[this.proAffix(termid, 'term')];
+      obj.termid = termid;
+      obj.term = term;
+      obj.num = object[arr.find(f => f.includes('batch_total'))];
+      obj.batch = object[arr.find(f => f.includes('batch'))];
+      return obj;
+    },
   },
   filters: {
     getProp(data, prop) {

+ 0 - 72
src/views/new-plan/arrange/table/table-title.vue

@@ -1,72 +0,0 @@
-<template>
-  <div id="table-title">
-    <el-row type="flex" align="middle">
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-      <el-col :span="6">学校名称</el-col>
-    </el-row>
-  </div>
-</template>
-
-<script>
-import _ from 'lodash';
-import { mapState, createNamespacedHelpers } from 'vuex';
-export default {
-  name: 'table-title',
-  props: {
-    termList: { type: Array, default: () => [] },
-  },
-  components: {},
-  data: function() {
-    return {};
-  },
-  created() {},
-  methods: {},
-  computed: {
-    ...mapState(['user']),
-    pageTitle() {
-      return `${this.$route.meta.title}`;
-    },
-    tList() {
-      return _.cloneDeep(this.termList);
-    },
-  },
-  metaInfo() {
-    return { title: this.$route.meta.title };
-  },
-};
-</script>
-
-<style lang="less" scoped>
-.el-col {
-  text-align: center;
-  border-right: solid 0.5px #ccc;
-}
-</style>

+ 114 - 13
src/views/new-plan/arrange/table/table.vue

@@ -1,36 +1,137 @@
 <template>
   <div id="table-frame">
-    <el-card>
-      <div style="border:1px solid #ccc;max-width:1200px">
-        <t-title :termList="tList"></t-title>
-      </div>
-    </el-card>
+    <el-table :data="list" border stripe size="mini" max-height="650px" @cell-click="cellClick" :cell-style="cellStyle">
+      <el-table-column label="学校" fixed align="center" prop="name" width="180"></el-table-column>
+      <el-table-column label="期数" fixed align="center">
+        <el-table-column label="班级数" align="center">
+          <el-table-column label="时间" align="center" width="80">
+            <el-table-column label="备注" align="center" width="80">
+              <el-table-column label="总人数" align="center" prop="number" width="80">
+                <template v-slot="{ row }">
+                  <el-tooltip effect="dark" placement="top">
+                    <template #content>
+                      <el-row style="width:100px">
+                        <el-col :span="24">就业班人数:{{ row.jynum }}</el-col>
+                        <el-col :span="24">创业班人数:{{ row.cynum }}</el-col>
+                        <el-col :span="24">少数民族班人数:{{ row.mznum }}</el-col>
+                      </el-row>
+                    </template>
+                    <el-link type="primary" :underline="false">{{ row.number }}</el-link>
+                  </el-tooltip>
+                </template>
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+        </el-table-column>
+      </el-table-column>
+
+      <el-table-column align="center" v-for="(i, index) in tList" :key="index" :label="`${i.term}`">
+        <template v-for="(batch, bindex) in i.batchnum">
+          <el-table-column :label="batch.class" :key="bindex" align="center">
+            <el-table-column :label="getBatchDate(batch)" :key="bindex" align="center">
+              <el-table-column :key="bindex" align="center" min-width="100" :prop="`batch_total-${batch._id}`">
+                <!-- 用batch_batch.id batch_+对应_id拼成唯一数据存放在学校列表中,对应每个表格 -->
+                <template #header>
+                  <el-input v-model="remarks[batch._id]" size="mini" placeholder="备注" type="textarea"></el-input>
+                </template>
+              </el-table-column>
+            </el-table-column>
+          </el-table-column>
+        </template>
+      </el-table-column>
+    </el-table>
   </div>
 </template>
 
 <script>
 import _ from 'lodash';
-import tTitle from './table-title.vue';
+const moment = require('moment');
+moment.locale('zh-cn');
 import { mapState, createNamespacedHelpers } from 'vuex';
 export default {
   name: 'table-frame',
   props: {
-    termList: { type: Array, default: () => [] },
+    termList: { type: Array },
+    data: { type: Array, default: () => [] },
+    changeRange: { type: Function },
+    proAffix: { type: Function },
+    getDesignate: { type: Function },
   },
-  components: { tTitle },
+  components: {},
   data: function() {
-    return {};
+    return {
+      tList: [],
+      list: [],
+      remarks: {},
+    };
   },
   created() {},
-  methods: {},
+  methods: {
+    getBatchDate(batch) {
+      let { end, start } = batch;
+      let date = `${moment(start).format('M.D')} - ${moment(end).format('M.D')}`;
+      return date;
+    },
+    findBatch(termid) {
+      return this.bList.filter(f => f.termid == termid);
+    },
+    //手动更改
+    cellClick(row, column) {
+      let r = this.proAffix(column.property);
+      let batch = this.tList
+        .map(i => i.batchnum)
+        .flat()
+        .find(f => f._id == r.value);
+      let sch = _.cloneDeep(row);
+      let info = _.cloneDeep(batch);
+      let { num } = this.getDesignate(r.value, sch);
+      //获取了页面都需要的参数
+      this.$emit('cellClick', { sch, info, num });
+    },
+    //单元格样式
+    cellStyle({ row, column, rowIndex, columnIndex }) {
+      if (!column.property || column.property == 'name' || column.property == 'number') return '';
+      else if (!_.get(row, 'daterange')) return '';
+      else {
+        let r = this.proAffix(column.property);
+        let batch = this.tList
+          .map(i => i.batchnum)
+          .flat()
+          .find(f => f._id == r.value);
+        row = this.changeRange(row);
+        let { result } = this.$tqInRange(batch.start, batch.end, row.daterange);
+        if (result) return { background: '#67C23AA0' };
+      }
+    },
+  },
+  watch: {
+    termList: {
+      handler(val) {
+        if (_.isArray(val)) {
+          val.map(i => {
+            i.batchnum.map(b => {
+              if (_.get(b, 'remark')) this.remarks[b._id] = _.get(b, 'remark');
+            });
+          });
+          this.$set(this, `tList`, val);
+        }
+      },
+      immediate: true,
+      deep: true,
+    },
+    data: {
+      handler(val) {
+        if (_.get(val, 'length', 0) > 0) this.$set(this, `list`, val);
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
   computed: {
     ...mapState(['user']),
     pageTitle() {
       return `${this.$route.meta.title}`;
     },
-    tList() {
-      return _.cloneDeep(this.termList);
-    },
   },
   metaInfo() {
     return { title: this.$route.meta.title };