|
@@ -0,0 +1,573 @@
|
|
|
+<template>
|
|
|
+ <div id="plan-arrange">
|
|
|
+ <el-row type="flex" align="middle" style="padding:10px">
|
|
|
+ <el-col :span="2">
|
|
|
+ <el-button type="primary" size="mini" @click="toBack">返回</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="2">
|
|
|
+ <el-button type="primary" size="mini" @click="toTemplateView()">查看计划模板</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="2">
|
|
|
+ <el-button type="primary" size="mini" @click="() => (dialog = true)">生成模板计划</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="2">
|
|
|
+ <el-button type="success" size="mini" @click="savePlan">保存计划</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="14" style="text-align:right">
|
|
|
+ <el-tooltip placement="bottom" effect="light">
|
|
|
+ <el-button type="warning" size="mini">场地颜色对应</el-button>
|
|
|
+ <template #content>
|
|
|
+ <el-row v-for="i in placeList" :key="i._id" style="padding-bottom:5px;line-height:18px">
|
|
|
+ <el-col :span="24">{{ i.name }}: <el-color-picker v-model="i.color" size="mini" :predefine="colors"></el-color-picker></el-col>
|
|
|
+ </el-row>
|
|
|
+ </template>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+
|
|
|
+ <table-cal v-if="dataReady" :year="info.year" :events="events" :vacation="vacation" :remark="remark"
|
|
|
+ :placeList="placeList" @cellClick="eventClick"></table-cal>
|
|
|
+ <div style="height:800px" v-else v-loading="!dataReady" element-loading-text="加载中,请稍后..."
|
|
|
+ element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)"></div>
|
|
|
+ <el-drawer :visible.sync="drawer" direction="rtl" title="安排计划" @close="toClose">
|
|
|
+ <event :data="form" :year="info.year" :vacation="vacation" :isNew="formIsNew" :predefineColors="template.color"
|
|
|
+ :classTypeList="classTypeList" :loading.sync="eventLoading" :placeList="placeList" @save="setEvent"
|
|
|
+ @delete="toDelete"></event>
|
|
|
+ </el-drawer>
|
|
|
+ <el-dialog :visible.sync="dialog" title="模板计划" width="40%" :close-on-click-modal="false">
|
|
|
+ <el-form>
|
|
|
+ <el-row type="flex">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="自动生成预估数据">
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="24"> 至少 {{ template.term }} 期 </el-col>
|
|
|
+ <el-col :span="24">至少需要 {{ template.leastDay }} 天 <span>(无假期等任何影响安排的因素)</span></el-col>
|
|
|
+ <el-col :span="24">
|
|
|
+ <span>每期有 {{ template | getBatchNum }} 批</span>
|
|
|
+ <span>;每批需要 {{ template.day }} 天</span>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="24" v-for="(b, index) in template.batchnum" :key="index">
|
|
|
+ 第{{ b.batch }}批:<el-col style="padding-left:20px" :span="24" v-for="(c, cindex) in b.classnum"
|
|
|
+ :key="cindex">{{ c.class }}班:{{ c.number }}人</el-col>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="请输入开始的期数">
|
|
|
+ <el-tooltip content="第X期 此处为填写X" placement="right">
|
|
|
+ <el-input-number v-model="input.termnum"></el-input-number>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="请选择班级类型">
|
|
|
+ <el-select v-model="input.classType">
|
|
|
+ <el-option v-for="(i, index) in classTypeList" :key="index" :label="i.name" :value="i.code"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="请选择开始日期">
|
|
|
+ <el-date-picker :picker-options="pickerOptions" v-model="input.start" type="date" placeholder="请选择开始日期"
|
|
|
+ format="yyyy-MM-dd" value-format="yyyy-MM-dd">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="请选择结束日期">
|
|
|
+ <el-date-picker :picker-options="pickerOptions" v-model="input.end" type="date" placeholder="请选择结束日期"
|
|
|
+ format="yyyy-MM-dd" value-format="yyyy-MM-dd">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-row :gutter="20" type="flex" justify="center" align="middle">
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button @click="dialog = false">取消</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button type="primary" @click="setDefaultPlan">确定</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import _ from 'lodash';
|
|
|
+var moment = require('moment');
|
|
|
+import event from './parts/event';
|
|
|
+import tableCal from './arrange/new-table';
|
|
|
+import { mapState, createNamespacedHelpers } from 'vuex';
|
|
|
+const { mapActions } = createNamespacedHelpers('trainplan');
|
|
|
+const { mapActions: trainTemplate } = createNamespacedHelpers('trainTemplate');
|
|
|
+const { mapActions: schPlan } = createNamespacedHelpers('schPlan');
|
|
|
+const { mapActions: util } = createNamespacedHelpers('util');
|
|
|
+const { mapActions: classtype } = createNamespacedHelpers('classtype');
|
|
|
+const { mapActions: location } = createNamespacedHelpers('location');
|
|
|
+export default {
|
|
|
+ name: 'plan-arrange',
|
|
|
+ props: {},
|
|
|
+ components: {
|
|
|
+ event,
|
|
|
+ tableCal,
|
|
|
+ },
|
|
|
+ data: function () {
|
|
|
+ var that = this;
|
|
|
+ return {
|
|
|
+ colors: ['#E60000', '#FF7300', '#996B1F', '#FFD700', '#AFA4E0', '#74868A', '#09A343', '#E9F1F4'],
|
|
|
+ dataReady: false,
|
|
|
+ template: {},
|
|
|
+ info: {
|
|
|
+ year: '2020',
|
|
|
+ },
|
|
|
+ form: {},
|
|
|
+ events: [],
|
|
|
+ vacation: undefined,
|
|
|
+ dialog: false,
|
|
|
+ input: {
|
|
|
+ termnum: 1,
|
|
|
+ classType: '0',
|
|
|
+ },
|
|
|
+ pickerOptions: {
|
|
|
+ disabledDate: time => that.checkDate(time),
|
|
|
+ },
|
|
|
+ collapse: '',
|
|
|
+ drawer: false,
|
|
|
+ formIsNew: true,
|
|
|
+ options: {},
|
|
|
+ classTypeList: [],
|
|
|
+ eventLoading: false,
|
|
|
+ remark: [],
|
|
|
+ placeList: [],
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ async created() {
|
|
|
+ this.getOtherList();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ ...mapActions(['fetch', 'update']),
|
|
|
+ ...trainTemplate({ trainTemplate: 'query' }),
|
|
|
+ ...schPlan({ setSchPlan: 'schArrange' }),
|
|
|
+ ...util({ modelFetch: 'fetch' }),
|
|
|
+ ...classtype({ getClassType: 'query' }),
|
|
|
+ ...location({ getLocation: 'query' }),
|
|
|
+ async search() {
|
|
|
+ let planid = _.get(this.defaultOption, 'planid');
|
|
|
+ if (!planid) return;
|
|
|
+ const res = await this.fetch(planid);
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ this.$set(this, `info`, res.data);
|
|
|
+ let data = _.cloneDeep(res.data);
|
|
|
+ this.$set(this, `events`, _.cloneDeep(data.termnum));
|
|
|
+ let fest = _.get(res.data, 'festivals', []);
|
|
|
+ let vac = fest.map(i => {
|
|
|
+ let object = {};
|
|
|
+ object.id = i._id;
|
|
|
+ object.start = i.begindate;
|
|
|
+ object.end = i.finishdate;
|
|
|
+ object.title = i.name;
|
|
|
+ object.rendering = 'background';
|
|
|
+ object.color = 'red';
|
|
|
+ object.editable = false;
|
|
|
+ return object;
|
|
|
+ });
|
|
|
+ this.$set(this, `vacation`, vac);
|
|
|
+ }
|
|
|
+ await this.searchTemplate();
|
|
|
+ await this.toResetRemark();
|
|
|
+ this.dataReady = true;
|
|
|
+ },
|
|
|
+ //模板事件开始
|
|
|
+ //生成默认模板
|
|
|
+ async setDefaultPlan() {
|
|
|
+ // this.$set(this, `events`, []);
|
|
|
+ this.$message('正在自动生成计划,请稍后...');
|
|
|
+ this.dialog = false;
|
|
|
+ let isOk = false;
|
|
|
+ let { start, end, termnum, classType } = this.input;
|
|
|
+ let { batchnum, term, total } = this.template;
|
|
|
+ let event = []; //处理成功事件的存储
|
|
|
+ let wtotal = 0,
|
|
|
+ wtermnum = 0;
|
|
|
+ let { total: newTotal, termnum: newTerm, events, isInRange } = this.toArrange(start, end, termnum, term, classType, total);
|
|
|
+ if (newTotal == 0) isOk = true;
|
|
|
+ else if (!isInRange) isOk = true;
|
|
|
+ wtotal = newTotal;
|
|
|
+ wtermnum = newTerm;
|
|
|
+ event = events;
|
|
|
+ while (!isOk) {
|
|
|
+ let nt = this.computedTerm(batchnum, wtotal);
|
|
|
+ let res = this.toArrange(start, end, wtermnum, nt, classType, wtotal, event);
|
|
|
+ // console.log(res);
|
|
|
+ // isOk = true;
|
|
|
+ if (res.total == 0) isOk = true;
|
|
|
+ else if (!res.isInRange) isOk = true;
|
|
|
+ wtotal = res.total;
|
|
|
+ wtermnum = res.termnum;
|
|
|
+ event = events;
|
|
|
+ }
|
|
|
+ this.$set(this, `events`, event);
|
|
|
+ this.toResetRemark();
|
|
|
+ },
|
|
|
+ //安排
|
|
|
+ // start:选择的开始时间
|
|
|
+ // end:选择打的结束时间
|
|
|
+ // termnum:手动输入开始的期数
|
|
|
+ // total:剩余人数
|
|
|
+ // events:已有安排,第一次不用传,再安排需要
|
|
|
+ toArrange(start, end, termnum, term, classType, total, events = []) {
|
|
|
+ let { day, batchnum } = this.template;
|
|
|
+ let iirr = true;
|
|
|
+ for (let i = 0; i < term; i++) {
|
|
|
+ if (total == 0) break;
|
|
|
+ if (!iirr) break;
|
|
|
+ let bnum = [];
|
|
|
+ for (const b of batchnum) {
|
|
|
+ if (total == 0) break;
|
|
|
+ let startdate;
|
|
|
+ let enddate;
|
|
|
+ //先查看是否是这期的批次正在排
|
|
|
+ if (bnum.length > 0) {
|
|
|
+ let last = _.last(bnum);
|
|
|
+ startdate = this.dayPlus(last.startdate, 1);
|
|
|
+ } else if (events.length == 0) {
|
|
|
+ //是第一期处理
|
|
|
+ startdate = start;
|
|
|
+ //此处应该处理startdate,如果startdate在假期中,就应该把时间约过假期再做
|
|
|
+ let res = this.getDateNotInVac(startdate, this.dayPlus(startdate, day - 1), day - 1);
|
|
|
+ startdate = res.start;
|
|
|
+ } else {
|
|
|
+ //不是第一期处理
|
|
|
+ //找到最后一期
|
|
|
+ let lastTerm = _.last(events);
|
|
|
+ //找到对应的批次(其实就是第一批次,因为第二批次已经走了if)
|
|
|
+ let fb = _.head(lastTerm.batchnum);
|
|
|
+ startdate = this.dayPlus(fb.enddate, 1);
|
|
|
+ //此处应该处理startdate,如果startdate在假期中,就应该把时间约过假期再做
|
|
|
+ let res = this.getDateNotInVac(startdate, this.dayPlus(startdate, day - 1), day - 1);
|
|
|
+ startdate = res.start;
|
|
|
+ }
|
|
|
+ enddate = this.dayPlus(startdate, day - 1);
|
|
|
+ let r = this.isInVac(startdate, enddate, day - 1);
|
|
|
+ //判断在不在假期
|
|
|
+ if (r) break;
|
|
|
+ let isInRange = this.isInRange(startdate, enddate, start, end);
|
|
|
+ let classes = [];
|
|
|
+ //判断不在手选的时间范围内
|
|
|
+ if (!isInRange) {
|
|
|
+ iirr = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ let bobj = { startdate, enddate, batch: b.batch };
|
|
|
+ for (const c of b.classnum) {
|
|
|
+ let { class: name, number } = c;
|
|
|
+ let type = classType;
|
|
|
+ if (total * 1 - c.number * 1 >= 0) {
|
|
|
+ total = total * 1 - c.number * 1;
|
|
|
+ classes.push({ name, number, type });
|
|
|
+ } else {
|
|
|
+ number = total;
|
|
|
+ total = 0;
|
|
|
+ classes.push({ name, number, type });
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bobj.class = classes;
|
|
|
+ bnum.push(bobj);
|
|
|
+ }
|
|
|
+ //最后处理成期的数据
|
|
|
+ if (bnum.length > 0) {
|
|
|
+ let color = this.getColor(termnum);
|
|
|
+ bnum = bnum.map(i => ({ ...i, color }));
|
|
|
+ let classnum = bnum.reduce((p, n) => p + n.class.length, 0);
|
|
|
+ let obj = { term: termnum, batchnum: bnum, classnum: classnum };
|
|
|
+ termnum = termnum * 1 + 1;
|
|
|
+ events.push(obj);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let obj = { total, termnum, events, isInRange: iirr };
|
|
|
+ return obj;
|
|
|
+ },
|
|
|
+ //默认事件排序
|
|
|
+ sortOtherData(last, data) {
|
|
|
+ let arr = _.chunk(data, 3).map((i, index) => {
|
|
|
+ i.map(ii => {
|
|
|
+ ii.term = last.term + index + 1;
|
|
|
+ ii.title = `第${ii.term}期第${ii.batch}批次`;
|
|
|
+ return ii;
|
|
|
+ });
|
|
|
+ return i;
|
|
|
+ });
|
|
|
+ return _.flatten(arr);
|
|
|
+ },
|
|
|
+ //手动操作事件开始
|
|
|
+ async setEvent({ data, isNew }) {
|
|
|
+ console.log(data);
|
|
|
+ data = JSON.parse(JSON.stringify(data));
|
|
|
+ if (isNew) {
|
|
|
+ let { term, ...info } = data;
|
|
|
+ //新添,找是不是在已知 期 中添加的信息
|
|
|
+ let res = this.events.find(f => f.term == term);
|
|
|
+ if (res) {
|
|
|
+ //找:是不是修改已知 批次 中信息
|
|
|
+ let termIndex = this.events.findIndex(f => f.term == term);
|
|
|
+ let batchIndex = res.batchnum.findIndex(f => f.batch == info.batch);
|
|
|
+ //是修改已知批次,就将信息放进去
|
|
|
+ if (batchIndex >= 0) this.$set(this.events[termIndex].batchnum, batchIndex, info);
|
|
|
+ else {
|
|
|
+ //新添批次,取出来=>复制=>赋回去,保证刷新视图
|
|
|
+ let duplicate = _.cloneDeep(this.events[termIndex].batchnum);
|
|
|
+ duplicate.push(info);
|
|
|
+ this.$set(this.events[termIndex], `batchnum`, duplicate);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //需要处理该数据为期[批次[班级的形式]]
|
|
|
+ let { term, batch, class: cl, ...info } = data;
|
|
|
+ let ta = { term, classnum: cl.length };
|
|
|
+ let tb = { batch, ...info, class: cl };
|
|
|
+ ta.batchnum = [tb];
|
|
|
+ console.log(ta);
|
|
|
+ this.events.push(ta);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let { term, ...info } = data;
|
|
|
+ let res = this.events.find(f => f.term == term);
|
|
|
+ if (res) {
|
|
|
+ let termIndex = this.events.findIndex(f => f.term == term);
|
|
|
+ let batchIndex = res.batchnum.findIndex(f => f.batch == info.batch);
|
|
|
+ if (batchIndex >= 0) this.$set(this.events[termIndex].batchnum, batchIndex, info);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.toClose();
|
|
|
+ this.toResetRemark();
|
|
|
+ },
|
|
|
+ //列表删除事件,一定是删除批次,班级属于内部信息,期需要自己把批次都删了
|
|
|
+ toDelete(data) {
|
|
|
+ let { term, batch } = data;
|
|
|
+ let res = this.events.find(f => f.term == term);
|
|
|
+ if (res) {
|
|
|
+ let termIndex = this.events.findIndex(f => f.term == term);
|
|
|
+ let batchIndex = res.batchnum.findIndex(f => f.batch == batch);
|
|
|
+ if (batchIndex >= 0) this.events[termIndex].batchnum.splice(batchIndex, 1);
|
|
|
+ }
|
|
|
+ this.toClose();
|
|
|
+ },
|
|
|
+ //计划保存
|
|
|
+ savePlan() {
|
|
|
+ let data = JSON.parse(JSON.stringify(this.info));
|
|
|
+ let plan = JSON.parse(JSON.stringify(this.events));
|
|
|
+ data.termnum = plan;
|
|
|
+ let res;
|
|
|
+ let msg;
|
|
|
+ res = this.update(data);
|
|
|
+ msg = `计划保存成功`;
|
|
|
+ this.$checkRes(res, msg);
|
|
|
+ },
|
|
|
+ //添加/修改事件
|
|
|
+ eventClick(event) {
|
|
|
+ if (_.isObject(event)) {
|
|
|
+ this.formIsNew = false;
|
|
|
+ let res = this.events.find(f => f.term == event.term);
|
|
|
+ if (res) {
|
|
|
+ let { term } = res;
|
|
|
+ res = res.batchnum.find(f => f.batch == event.batch);
|
|
|
+ let obj = { ...res, term };
|
|
|
+ this.$set(this, `form`, obj);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //新添只允许添加一个批次,一个批次一个批次添加
|
|
|
+ this.$set(this, `form`, { startdate: event, class: [] });
|
|
|
+ }
|
|
|
+ this.drawer = true;
|
|
|
+ // this.formIsNew = false;
|
|
|
+ },
|
|
|
+ //寻找最开始安排的计划日历作为模板
|
|
|
+ async searchTemplate() {
|
|
|
+ let planid = _.get(this.defaultOption, 'planid');
|
|
|
+ let planyearid = _.get(this.defaultOption, 'planyearid');
|
|
|
+ let res = await this.modelFetch({ model: 'trainmodel', planyearid, planid });
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ if (res.data !== null) {
|
|
|
+ let template = _.cloneDeep(res.data);
|
|
|
+ let { total, batchnum, day } = template;
|
|
|
+ template.term = this.computedTerm(batchnum, total);
|
|
|
+ let bn = _.get(batchnum, 'length', 0) - 1 >= 0 ? _.get(batchnum, 'length', 0) - 1 : 0;
|
|
|
+ template.leastDay = template.term * day + bn;
|
|
|
+ this.$set(this, `template`, template);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //人数计算无假期的剩余期
|
|
|
+ // batchnum:模板的批次设置
|
|
|
+ // total:剩余人数(可用来重复计算)
|
|
|
+ computedTerm(batchnum, total) {
|
|
|
+ let termTotal = batchnum.reduce((p, n) => p + n.classnum.reduce((np, nn) => np + nn.number * 1, 0), 0);
|
|
|
+ let term = 0;
|
|
|
+ if (termTotal !== 0) term = Math.ceil(total / termTotal);
|
|
|
+ return term;
|
|
|
+ },
|
|
|
+ //其他事件(无关紧要)
|
|
|
+ //关闭抽屉函数
|
|
|
+ toClose() {
|
|
|
+ this.drawer = false;
|
|
|
+ this.formIsNew = true;
|
|
|
+ },
|
|
|
+ //设置事件颜色
|
|
|
+ getColor(it) {
|
|
|
+ let { color, batchnum } = this.template;
|
|
|
+ if (color.length > 0) {
|
|
|
+ // let num = ((it - 1) * batchnum + ib) % color.length;
|
|
|
+ let num = (it - 1) % color.length;
|
|
|
+ return color[num];
|
|
|
+ } else return '#004499';
|
|
|
+ },
|
|
|
+
|
|
|
+ checkDate(date) {
|
|
|
+ let year = JSON.parse(JSON.stringify(this.info.year));
|
|
|
+ let res = moment(date).isBetween(`${year}-01-01`, `${year}-12-31`, null, '[]');
|
|
|
+ // console.log(res);
|
|
|
+ // let dv = _.cloneDeep(this.vacation);
|
|
|
+ // let vres = dv.find(f => moment(date).isBetween(f.start, f.end, null, '[]'));
|
|
|
+ // console.log(vres);&& !vres
|
|
|
+ return !res;
|
|
|
+ },
|
|
|
+ dayPlus(date, num) {
|
|
|
+ return moment(date)
|
|
|
+ .add(num, 'days')
|
|
|
+ .format('YYYY-MM-DD');
|
|
|
+ },
|
|
|
+ //若遇到假期,返回假期后的日期
|
|
|
+ getDateNotInVac(start, end, day) {
|
|
|
+ let res = false;
|
|
|
+ res = this.isInVac(start, end);
|
|
|
+ if (res) {
|
|
|
+ let ns = this.dayPlus(res.end, 1);
|
|
|
+ let ne = this.dayPlus(ns, day);
|
|
|
+ res = this.getDateNotInVac(ns, ne, day);
|
|
|
+ } else res = { start, end };
|
|
|
+
|
|
|
+ return res;
|
|
|
+ },
|
|
|
+ //如果在假期,就返回这个假期;不在假期,就
|
|
|
+ isInVac(start, end) {
|
|
|
+ let res = false;
|
|
|
+ for (const vac of this.vacation) {
|
|
|
+ let { start: vs, end: ve } = vac;
|
|
|
+ let sr = moment(start).isBetween(vs, ve, null, '[]');
|
|
|
+ let er = moment(end).isBetween(vs, ve, null, '[]');
|
|
|
+ let vsr = moment(vs).isBetween(start, end, null, '[]');
|
|
|
+ let ver = moment(ve).isBetween(start, end, null, '[]');
|
|
|
+ if (sr || er || vsr || ver) {
|
|
|
+ //返回这个假期
|
|
|
+ res = vac;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ },
|
|
|
+ //查看是否在要求的事件范围内
|
|
|
+ //start:当前开始时间;end:当前结束时间;rs:范围开始时间;re:范围结束时间
|
|
|
+ isInRange(start, end, rs, re) {
|
|
|
+ let sr = moment(start).isBetween(rs, re, null, '[]');
|
|
|
+ let er = moment(end).isBetween(rs, re, null, '[]');
|
|
|
+ return sr && er;
|
|
|
+ },
|
|
|
+ //整理remark
|
|
|
+ toResetRemark() {
|
|
|
+ let des = _.cloneDeep(this.events);
|
|
|
+ des = des.map(i => i.batchnum).flat();
|
|
|
+ // 根据结束日期来决定这些班级和人数归到哪个月份
|
|
|
+ des = des.map(i => {
|
|
|
+ i.month = moment(i.enddate).month() + 1;
|
|
|
+ return i;
|
|
|
+ });
|
|
|
+ let r = _.groupBy(des, 'month');
|
|
|
+ let remark = [];
|
|
|
+ for (let i = 1; i <= 12; i++) {
|
|
|
+ let mdata = _.get(r, i);
|
|
|
+ if (mdata) {
|
|
|
+ let obj = {};
|
|
|
+ let cn = mdata.reduce((p, n) => p + _.get(n.class, 'length', 0), 0);
|
|
|
+ obj.class = mdata.reduce((p, n) => p + _.get(n.class, 'length', 0), 0);
|
|
|
+ let num = mdata.reduce((p, n) => p + _.get(n, 'class', []).reduce((pc, nc) => pc + nc.number * 1, 0), 0);
|
|
|
+ obj.number = mdata.reduce((p, n) => p + _.get(n, 'class', []).reduce((pc, nc) => pc + nc.number * 1, 0), 0);
|
|
|
+ obj.month = i;
|
|
|
+ remark.push(obj);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.$set(this, `remark`, remark);
|
|
|
+ },
|
|
|
+ async getOtherList() {
|
|
|
+ let res = await this.getClassType();
|
|
|
+ if (this.$checkRes(res)) this.$set(this, `classTypeList`, res.data);
|
|
|
+ res = await this.getLocation({ type: '4' })
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ // 为每个地点随机生成颜色
|
|
|
+ let list = res.data;
|
|
|
+ if (res.data && res.data.length > 0) {
|
|
|
+ list = list.map(i => {
|
|
|
+ const color = '#' + (parseInt(Math.random() * 0xffffff)).toString(16)
|
|
|
+ return { ...i, color }
|
|
|
+ })
|
|
|
+ this.$set(this, `placeList`, list);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ toBack() {
|
|
|
+ this.$router.go(-1);
|
|
|
+ },
|
|
|
+ toTemplateView() {
|
|
|
+ this.$emit('changeView', 'template')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ filters: {
|
|
|
+ getBatchNum: template => _.get(template.batchnum, 'length', 0),
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ defaultOption: {
|
|
|
+ handler(val) {
|
|
|
+ if (!_.get(this, 'options')) {
|
|
|
+ this.$set(this, `options`, _.cloneDeep(val));
|
|
|
+ this.search();
|
|
|
+ } else {
|
|
|
+ let nplanid = _.get(val, 'planid');
|
|
|
+ let oplanid = _.get(this.options, 'planid');
|
|
|
+ if (nplanid && !_.isEqual(nplanid, oplanid)) {
|
|
|
+ this.$set(this, `options`, _.cloneDeep(val));
|
|
|
+ this.search();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ deep: true,
|
|
|
+ immediate: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState(['user', 'defaultOption']),
|
|
|
+ id() {
|
|
|
+ return this.$route.query.id;
|
|
|
+ },
|
|
|
+ isNew() {
|
|
|
+ return this.$route.query.id ? false : true; //false : true;
|
|
|
+ },
|
|
|
+ pageTitle() {
|
|
|
+ return `${this.$route.meta.title}`;
|
|
|
+ },
|
|
|
+ widths() {
|
|
|
+ let width = (document.body.clientWidth - 200) * 0.65;
|
|
|
+ return width > 400 ? width : 400;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ metaInfo() {
|
|
|
+ return { title: this.$route.meta.title };
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+/deep/.el-card__body {
|
|
|
+ overflow: auto;
|
|
|
+ padding: 10px;
|
|
|
+}
|
|
|
+</style>
|