detail.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <template>
  2. <div id="detail">
  3. <detail-frame :title="mainTitle" returns="/plan/index">
  4. <el-row :gutter="10" type="flex">
  5. <el-col :span="12">
  6. <el-card header="全年计划信息">
  7. <el-form :model="info" label-width="60px" size="small" @submit.native.prevent>
  8. <el-form-item label="年份">
  9. {{ info.year }}
  10. </el-form-item>
  11. <el-form-item label="标题" prop="title">
  12. {{ info.title }}
  13. </el-form-item>
  14. <!-- <el-form-item label="备注" prop="remark">
  15. <el-input v-model="info.remark" type="textarea" :autosize="{ minRows: 3, maxRows: 5 }"></el-input>
  16. </el-form-item> -->
  17. <el-collapse v-model="collapse" accordion>
  18. <el-collapse-item title="上报可行时间列表" name="1">
  19. <data-table :fields="fields" :data="selected" :opera="opera" @delete="toDelete" :height="heights"></data-table>
  20. </el-collapse-item>
  21. </el-collapse>
  22. <el-form-item>
  23. <el-row type="flex" align="middle" justify="space-around" style="margin-top:20px">
  24. <el-col :span="6">
  25. <el-button type="primary" @click="savePlan">上报选择时间</el-button>
  26. </el-col>
  27. </el-row>
  28. </el-form-item>
  29. </el-form>
  30. </el-card>
  31. </el-col>
  32. <el-col :span="16" :style="`width:${widths}px`">
  33. <el-card ref="card" v-if="info.year">
  34. <calendar :year="info.year" :useDraft="false" @eventClick="eventClick" :events="events"></calendar>
  35. </el-card>
  36. </el-col>
  37. </el-row>
  38. </detail-frame>
  39. </div>
  40. </template>
  41. <script>
  42. import detailFrame from '@frame/layout/admin/detail-frame';
  43. import calendar from '@frame/components/calendar';
  44. import dataTable from '@frame/components/data-table';
  45. import _ from 'lodash';
  46. import { mapState, createNamespacedHelpers } from 'vuex';
  47. const { mapActions } = createNamespacedHelpers('trainplan');
  48. const { mapActions: schPlan } = createNamespacedHelpers('schPlan');
  49. export default {
  50. metaInfo: { title: '计划详情' },
  51. name: 'detail',
  52. props: {},
  53. components: { detailFrame, calendar, dataTable },
  54. data: () => ({
  55. info: {},
  56. form: {},
  57. events: [],
  58. collapse: '1',
  59. fields: [
  60. // { label: '期数', prop: 'termnum' },
  61. { label: '名称', prop: 'name' },
  62. { label: '总人数', prop: 'number', format: item => `${item}人` },
  63. ],
  64. opera: [
  65. {
  66. label: '删除',
  67. icon: 'el-icon-delete',
  68. method: 'delete',
  69. confirm: true,
  70. },
  71. ],
  72. heights: 250,
  73. selected: [],
  74. }),
  75. created() {
  76. this.search();
  77. this.searchSch();
  78. },
  79. mounted() {},
  80. methods: {
  81. ...mapActions(['fetch', 'create', 'update']),
  82. ...schPlan({
  83. schQuery: 'query',
  84. schPlanCreate: 'create',
  85. schPlanUpdate: 'update',
  86. }),
  87. async searchSch() {
  88. let res = await this.schQuery({ planid: this.id, schid: _.get(this.user, 'schid', '99991') });
  89. if (this.$checkRes(res)) {
  90. let data = JSON.parse(JSON.stringify(res.data));
  91. if (res.data.length > 0) {
  92. this.$set(this.info, `schplanid`, data[0]._id);
  93. let list = _.flatten(data.map(i => i.term));
  94. list = list.map(i => {
  95. if (i.type === '0') i.name = `第${i.termnum}期`;
  96. else if (i.type) {
  97. let fRes = _.find(this.events, f => f.termid === i.termid && f.type === i.type);
  98. i.name = fRes.name || fRes.title;
  99. } else return {};
  100. return i;
  101. });
  102. this.$set(this, `selected`, list);
  103. }
  104. }
  105. },
  106. //查询计划
  107. async search() {
  108. const res = await this.fetch(this.id);
  109. if (this.$checkRes(res)) this.$set(this, `info`, res.data);
  110. let midArr = JSON.parse(JSON.stringify(res.data));
  111. let events = [];
  112. events = _.flatten(
  113. midArr.termnum.map(item => {
  114. item.batchnum.map(i => {
  115. i.term = item.term;
  116. i.termid = item._id; //需要使用期id
  117. i.id = i._id;
  118. i.start = JSON.parse(JSON.stringify(i.startdate));
  119. i.end = JSON.parse(JSON.stringify(i.enddate));
  120. i.title = JSON.parse(JSON.stringify(i.name));
  121. delete i.startdate, delete i.enddate, delete i.name;
  122. return i;
  123. });
  124. return item.batchnum;
  125. })
  126. );
  127. let vac = midArr.festivals.map(i => {
  128. let object = {};
  129. object.id = i._id;
  130. object.start = i.begindate;
  131. object.end = i.finishdate;
  132. object.rendering = 'background';
  133. object.color = 'red';
  134. object.editable = false;
  135. return object;
  136. });
  137. this.$set(this, `events`, events.concat(vac));
  138. },
  139. //日历事件点击事件
  140. eventClick({ event }) {
  141. let arr = this.events.filter(fil => fil.id == event.id);
  142. let object = {};
  143. if (arr.length > 0) {
  144. //有这个事件
  145. object = arr[0];
  146. if (!_.get(object, 'editable', true)) {
  147. this.$message.warning('不能上报假期的时间');
  148. return;
  149. }
  150. } else {
  151. console.warn(`无对应id事件`);
  152. return;
  153. }
  154. let { type, termid, id } = object;
  155. //查重,先查期数一致,再查类型
  156. //期数没有,则加入;期数有,则看类型,如果是普通班级,则不加入;如果是特殊班级,则查该期是否有特殊班级的id,没有就加入
  157. let re = () => {
  158. this.$notify({
  159. title: '重复添加该期',
  160. });
  161. };
  162. let push = data => {
  163. this.selected.push(data);
  164. this.$notify({
  165. title: '已添加',
  166. });
  167. };
  168. // 需要判断期id和期类型
  169. let isSelected = this.selected.filter(i => i.termid === termid && i.type == type);
  170. if (isSelected.length > 0) {
  171. //因为特殊班一期有一个班,按上面条件过滤后,能确定是否有该期该种班
  172. re();
  173. // //普通班=>重复加入
  174. // if (type === '0') re();
  175. // else {
  176. // // 特殊班=>使用id(batchid,批的id)判断
  177. // let res = this.selected.filter(f => f.id === id);
  178. // //特殊班重复加入
  179. // if (res.length > 0) re();
  180. // else push(this.setSchoolDate(object)); //加入
  181. // }
  182. } else {
  183. if (type === '0') {
  184. let nextArr = this.events.filter(f => f.termid === object.termid && f.type === '0');
  185. push(this.setSchoolDate(nextArr));
  186. } else push(this.setSchoolDate(object)); //加入
  187. }
  188. },
  189. //列表删除事件
  190. toDelete({ data, index }) {
  191. this.selected.splice(index, 1);
  192. },
  193. //保存计划事件
  194. savePlan() {
  195. // 获取已选择的时间
  196. let arr = JSON.parse(JSON.stringify(this.selected));
  197. //整理数据
  198. let { year, _id, remark, schplanid } = JSON.parse(JSON.stringify(this.info));
  199. arr = arr.map(i => {
  200. let obj = { termnum: i.termnum, termid: i.termid, number: i.number, type: i.type };
  201. i._id ? (obj.id = i._id) : '';
  202. return obj;
  203. });
  204. let object = { year, planid: _id, remark, term: arr, schid: _.get(this.user, 'schid', '99991') };
  205. let res;
  206. let msg;
  207. //需要找到条件判断是修改还是添加,默认先修改看看出现什么情况
  208. if (!schplanid) {
  209. res = this.schPlanCreate(object);
  210. msg = `时间上报成功`;
  211. } else {
  212. object.id = schplanid;
  213. res = this.schPlanUpdate(object);
  214. msg = `时间修改成功`;
  215. }
  216. if (this.$checkRes(res, msg)) this.$router.push({ path: '/plan/index' });
  217. },
  218. setHeight() {
  219. let heights = this.$refs.card.$el.clientHeight * 0.63;
  220. this.$set(this, `heights`, heights);
  221. },
  222. //添加上报时间
  223. setSchoolDate(object) {
  224. let data = JSON.parse(JSON.stringify(object));
  225. //整合出的数据需要有 期数 termnum;期id termid; 人数 number
  226. //因为点击普通类型,就会将这一期的所有普通类型添加进去,所以需要用data数组去计算筛选出来的所有事件的人数,期数和期id随意提取一个就好
  227. //特殊类型就是data是object
  228. //所以直接判断,如果_.isArray(data) => 是普通类型的,按普通类型处理;反之为特殊类型,按特殊类型处理
  229. let res = {};
  230. if (_.isArray(data)) {
  231. res.number = data.reduce((pre, cur) => pre + parseInt(cur.class) * parseInt(cur.number), 0);
  232. res.termnum = JSON.parse(JSON.stringify(data[0].term));
  233. res.termid = JSON.parse(JSON.stringify(data[0].termid));
  234. res.type = JSON.parse(JSON.stringify(data[0].type));
  235. res.name = `第${res.termnum}期`;
  236. } else {
  237. res.number = JSON.parse(JSON.stringify(data.number));
  238. res.termnum = JSON.parse(JSON.stringify(data.term));
  239. res.termid = JSON.parse(JSON.stringify(data.termid));
  240. res.type = JSON.parse(JSON.stringify(data.type));
  241. res.name = JSON.parse(JSON.stringify(data.title));
  242. }
  243. return res;
  244. },
  245. },
  246. computed: {
  247. ...mapState(['user']),
  248. widths() {
  249. let width = (document.body.clientWidth - 200) * 0.5;
  250. return width > 400 ? width : 400;
  251. },
  252. id() {
  253. return this.$route.query.id;
  254. },
  255. mainTitle() {
  256. let meta = this.$route.meta;
  257. let main = meta.title || '';
  258. let sub = meta.sub || '';
  259. return `${main}${sub}`;
  260. },
  261. keyWord() {
  262. let meta = this.$route.meta;
  263. let main = meta.title || '';
  264. return main;
  265. },
  266. },
  267. };
  268. </script>
  269. <style lang="less" scoped>
  270. /deep/.el-divider--horizontal {
  271. margin: 5px 0;
  272. }
  273. </style>