|
@@ -0,0 +1,583 @@
|
|
|
|
+<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 } = createNamespacedHelpers('trainplan');
|
|
|
|
+const { mapActions: trainTemplate } = createNamespacedHelpers('trainTemplate');
|
|
|
|
+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>
|