|
@@ -0,0 +1,278 @@
|
|
|
+<template>
|
|
|
+ <div id="arrange">
|
|
|
+ <detail-frame :title="pageTitle" returns="./index">
|
|
|
+ <el-row :gutter="10" type="flex">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-card header="全年计划信息">
|
|
|
+ <el-form :model="info" :rules="rules" :isNew="isNew" label-width="60px" size="small" @submit.native.prevent>
|
|
|
+ <el-form-item label="年份" required>
|
|
|
+ {{ info.year }}
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="标题" prop="title" required>
|
|
|
+ {{ info.title }}
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-collapse v-model="collapse" accordion>
|
|
|
+ <el-collapse-item title="计划简表" name="1">
|
|
|
+ <data-table :fields="fields" :data="selectList" :opera="opera" @edit="toEdit" @delete="toDelete" :height="heights"></data-table>
|
|
|
+ </el-collapse-item>
|
|
|
+ </el-collapse>
|
|
|
+ <el-form-item>
|
|
|
+ <el-row type="flex" align="middle" justify="space-around" style="margin-top:20px">
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-button type="primary" @click="savePlan">保存全年计划</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="16" :style="`width:${widths}px`">
|
|
|
+ <el-card ref="card" v-if="info.year">
|
|
|
+ <calendar :year="`${info.year}`" :selfBtn="selfBtn" @draft="selectDate" @eventClick="eventClick" :vacation="vacation" :events="events"></calendar>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </detail-frame>
|
|
|
+ <el-dialog :visible.sync="dialog" title="模板计划" width="30%" :close-on-click-modal="false">
|
|
|
+ <el-form>
|
|
|
+ <el-form-item label="请输入您要生成的期数">
|
|
|
+ <el-input v-model="input.term"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="请选择开始日期">
|
|
|
+ <el-date-picker v-model="input.start" type="date" placeholder="请选择开始日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd"> </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </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 detailFrame from '@frame/layout/admin/detail-frame';
|
|
|
+import calendar from '@frame/components/calendar';
|
|
|
+import dataTable from '@frame/components/data-table';
|
|
|
+import { mapState, createNamespacedHelpers } from 'vuex';
|
|
|
+const { mapActions } = createNamespacedHelpers('trainplan');
|
|
|
+const { mapActions: trainTemplate } = createNamespacedHelpers('trainTemplate');
|
|
|
+export default {
|
|
|
+ name: 'arrange',
|
|
|
+ props: {},
|
|
|
+ components: { detailFrame, calendar, dataTable },
|
|
|
+ data: function() {
|
|
|
+ var that = this;
|
|
|
+ return {
|
|
|
+ template: {},
|
|
|
+ info: {},
|
|
|
+ selectList: [],
|
|
|
+ events: [],
|
|
|
+ vacation: [],
|
|
|
+ fields: [
|
|
|
+ { label: '开始时间', prop: 'start' },
|
|
|
+ { label: '结束时间', prop: 'end' },
|
|
|
+ { label: '期数', prop: 'term' },
|
|
|
+ { label: '班级类型', prop: 'type', format: item => (item === '0' ? '正常班级' : '特殊班级') },
|
|
|
+ ],
|
|
|
+ opera: [
|
|
|
+ {
|
|
|
+ label: '编辑',
|
|
|
+ icon: 'el-icon-edit',
|
|
|
+ method: 'edit',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '删除',
|
|
|
+ icon: 'el-icon-delete',
|
|
|
+ method: 'delete',
|
|
|
+ confirm: true,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ rules: {
|
|
|
+ title: [{ required: true, message: '请输入标题' }],
|
|
|
+ },
|
|
|
+ formRules: {
|
|
|
+ start: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
|
|
|
+ end: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
|
|
|
+ term: [{ required: true, message: '请输入期数' }],
|
|
|
+ number: [{ required: true, message: '请输入每班人数' }],
|
|
|
+ type: [{ required: true, message: '请选择班级类型' }],
|
|
|
+ },
|
|
|
+ dialog: false,
|
|
|
+ selfBtn: {
|
|
|
+ term: {
|
|
|
+ text: '生成模板计划',
|
|
|
+ //设置假期
|
|
|
+ click: () => (that.dialog = true),
|
|
|
+ position: 'left',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ input: {
|
|
|
+ term: 50,
|
|
|
+ start: '2020-01-01',
|
|
|
+ },
|
|
|
+ heights: 250,
|
|
|
+ collapse: '',
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.search();
|
|
|
+ this.searchTemplate();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ ...mapActions(['fetch', 'update']),
|
|
|
+ ...trainTemplate({ trainTemplate: 'query' }),
|
|
|
+ async search() {
|
|
|
+ const res = await this.fetch(this.id);
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ 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);
|
|
|
+ this.$set(this, `info`, res.data);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setDefaultPlan() {
|
|
|
+ this.dialog = false;
|
|
|
+ let { term, start } = this.input;
|
|
|
+ let { day, batchnum, classnum } = this.template;
|
|
|
+ let event = []; //处理成功事件的存储
|
|
|
+ let qb = 0; //剩余没有满足之前的批数
|
|
|
+ let qt = 0; //剩余没有满足之前的期数
|
|
|
+ //第一次正常安排
|
|
|
+ let arrange = (t, v) => {
|
|
|
+ let arr = [];
|
|
|
+ for (let it = 1; it <= t; it++) {
|
|
|
+ for (let ib = 1; ib <= v; ib++) {
|
|
|
+ let end = this.$plusDay(start, day - 1);
|
|
|
+ let object = { startStr: start, endStr: end, vacation: this.vacation };
|
|
|
+ let res = this.$checkDate(object);
|
|
|
+ if (res == true) {
|
|
|
+ let batch = {
|
|
|
+ term: it - qt,
|
|
|
+ batch: ib,
|
|
|
+ class: classnum,
|
|
|
+ start,
|
|
|
+ end,
|
|
|
+ type: '0',
|
|
|
+ title: `第${it - qt}期第${ib}批次`,
|
|
|
+ color: this.getColor(it, ib),
|
|
|
+ };
|
|
|
+ start = this.$plusDay(start);
|
|
|
+ arr.push(batch);
|
|
|
+ } else {
|
|
|
+ if (ib == 1) qt += 1;
|
|
|
+ else qb += batchnum - ib + 1;
|
|
|
+ start = this.$plusDay(res.end);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ };
|
|
|
+ event = arrange(term, batchnum);
|
|
|
+ while (qb > 0) {
|
|
|
+ qt = qt + Math.ceil(qb / batchnum);
|
|
|
+ let sb = qb % batchnum;
|
|
|
+ let lessArr = arrange(qt, batchnum);
|
|
|
+ let last = _.last(event);
|
|
|
+ let lessNArr = _.chunk(lessArr, 3).map((i, index) => {
|
|
|
+ i.map(ii => {
|
|
|
+ ii.term = last.term + index + 1;
|
|
|
+ ii.title = `第${ii.term}期第${ii.batch}批次`;
|
|
|
+ return ii;
|
|
|
+ });
|
|
|
+ return i;
|
|
|
+ });
|
|
|
+ lessArr = _.flatten(lessNArr);
|
|
|
+ //TODO需要判断是否还有剩余的批次,有的话还需要处理
|
|
|
+ }
|
|
|
+
|
|
|
+ //最后赋值回去
|
|
|
+ this.$set(this, `events`, event);
|
|
|
+ this.$set(this, `selectList`, event);
|
|
|
+ },
|
|
|
+ setHeight() {
|
|
|
+ let heights = this.$refs.card.$el.clientHeight * 0.63;
|
|
|
+ this.$set(this, `heights`, heights);
|
|
|
+ },
|
|
|
+ //列表编辑事件
|
|
|
+ toEdit({ data, index }) {
|
|
|
+ this.$set(this, `form`, JSON.parse(JSON.stringify(data)));
|
|
|
+ this.formIsNew = false;
|
|
|
+ this.drawer = true;
|
|
|
+ },
|
|
|
+ //列表删除事件
|
|
|
+ toDelete({ data, index }) {
|
|
|
+ this.$set(
|
|
|
+ this,
|
|
|
+ `events`,
|
|
|
+ this.events.filter(f => f.id !== data.id)
|
|
|
+ );
|
|
|
+ // this.events.splice(index, 1);
|
|
|
+ this.selectList.splice(index, 1);
|
|
|
+ },
|
|
|
+ //计划保存
|
|
|
+ savePlan() {},
|
|
|
+ //
|
|
|
+ selectDate() {},
|
|
|
+ //
|
|
|
+ eventClick() {},
|
|
|
+ //
|
|
|
+ async searchTemplate() {
|
|
|
+ let res = await this.trainTemplate();
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ if (res.data.length > 0) {
|
|
|
+ this.$set(this, `template`, res.data[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getColor(it, ib) {
|
|
|
+ let { color, batchnum } = this.template;
|
|
|
+ if (color.length > 0) {
|
|
|
+ let num = ((it - 1) * batchnum + ib) % color.length;
|
|
|
+ return color[num];
|
|
|
+ } else return '#004499';
|
|
|
+ },
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState(['user']),
|
|
|
+ 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.5;
|
|
|
+ return width > 400 ? width : 400;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ metaInfo() {
|
|
|
+ return { title: this.$route.meta.title };
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped></style>
|