Jelajahi Sumber

generation - table - dynamic columns

hare8999@163.com 3 tahun lalu
induk
melakukan
271335e61b

+ 339 - 5
mock/modules/elective-generation.js

@@ -1,7 +1,9 @@
 const Mock = require('mockjs')
+const Random = Mock['Random']
 
-const mockGeneration = 1 // primary
-const mockGroups = [1, 2, 3, 9, 10, 11]
+const mockGeneration = 4 // primary
+const mockGroups = [1, 2, 3, 4, 5, 6]
+const mockPreferenceCount = 3 // 1 or 3 // 1志愿/3志愿
 
 module.exports = [
   {
@@ -15,6 +17,16 @@ module.exports = [
           year: 2021,
           roundId: 1,
           roundName: '第X次选科',
+          groupIds: mockGroups.toString(),
+          roundGroups: mockGroups.map(groupId => ({
+            groupId: groupId,
+            classCount: Random.integer(2, 6),
+            personCount: function() {
+              return this.classCount * 50
+            },
+            limitPerson: false,
+            rankOut: false
+          })),
           allMatched: false,
           currentGeneration: mockGeneration
         }
@@ -25,12 +37,334 @@ module.exports = [
     url: '/mock/front/report/getElectiveSummary',
     type: 'get',
     response: config => {
+      const results = []
+      for (let generation = 1; generation <= mockGeneration; generation++) {
+        const copyGeneration = generation
+        switch (generation) {
+          case 1:
+            // primary
+            const allPreferences = []
+            for (let pref = 0; pref < mockPreferenceCount; pref++) {
+              const preferences = []
+              const groupDefines = [
+                {
+                  category: 'actualCount',
+                  displayName: '实际人数',
+                  values: mockGroups.map(groupId => ({
+                    groupId: groupId,
+                    value: Random.integer(120, 400),
+                    color: '',
+                    bold: false,
+                    star: false,
+                    queryCode: 'abc',
+                    disabled: false
+                  }))
+                }
+              ]
+              const nonGroupDefines = [
+                {
+                  category: 'unfinishedCount',
+                  displayName: '未完成人数',
+                  values: [{
+                    groupId: 0,
+                    value: Random.integer(0, 10),
+                    color: '',
+                    bold: false,
+                    star: false,
+                    queryCode: 'abc',
+                    disabled: false
+                  }]
+                }
+              ]
+              preferences.push(...groupDefines)
+              preferences.push(...nonGroupDefines)
+              allPreferences.push(preferences)
+            }
+            const primary = {
+              roundId: 1,
+              generation: copyGeneration,
+              categories: allPreferences
+            }
+            results.push(primary)
+            break
+          default:
+            const commonDefines = [
+              {
+                generations: [2],
+                factory: () => [
+                  {
+                    category: 'indicateCount',
+                    displayName: '指标',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'approvedCount',
+                    displayName: '录取人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'adjustCount',
+                    displayName: '调剂人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'matchedCount',
+                    displayName: '可调剂人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'nonmatchedCount',
+                    displayName: '不可调剂人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  }
+                ]
+              },
+              {
+                generations: [3, 5],
+                factory: () => [
+                  {
+                    category: 'matchedApproved',
+                    displayName: '可调剂已填人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'matchedRejected',
+                    displayName: '可调剂已拒绝人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'matchedNonaction',
+                    displayName: '可调剂未完成人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'nonmatchedApproved',
+                    displayName: '不可调剂已填人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'nonmatchedRejected',
+                    displayName: '不可调剂已拒绝人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'nonmatchedNonaction',
+                    displayName: '不可调剂未完成人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  }
+                ]
+              },
+              {
+                generations: [4],
+                factory: () => [
+                  {
+                    category: 'approvedCount',
+                    displayName: '补录录取人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'forcedCount',
+                    displayName: '调剂录取人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'matchedCount',
+                    displayName: '可调剂人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'nonmatchedCount',
+                    displayName: '不可调剂人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  }
+                ]
+              },
+              {
+                generations: [6],
+                factory: () => [
+                  {
+                    category: 'approvedCount',
+                    displayName: '补录录取人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  },
+                  {
+                    category: 'forcedCount',
+                    displayName: '调剂录取人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  }
+                ]
+              },
+              {
+                generations: [7],
+                factory: () => [
+                  {
+                    category: 'forcedCount',
+                    displayName: '调剂录取人数',
+                    values: mockGroups.map(groupId => ({
+                      groupId: groupId,
+                      value: Random.integer(120, 400),
+                      color: '',
+                      bold: false,
+                      star: false,
+                      queryCode: 'abc',
+                      disabled: false
+                    }))
+                  }
+                ]
+              }
+            ]
+            const defines = commonDefines.find(d => d.generations.includes(generation))
+            if (defines) {
+              results.push({
+                roundId: 1,
+                generation: copyGeneration,
+                categories: defines.factory()
+              })
+            }
+            break
+        }
+      }
+
       return {
         code: 200,
         msg: 'success',
-        'data|6': [{
-          year: 2021,
-        }]
+        data: results
       }
     }
   }

+ 30 - 3
src/common/mx-config.js

@@ -64,7 +64,7 @@ export default {
       title: '人生价值观探索',
       description: '价值观是指一个人对各类事物的意义和重要性的评价与看法,是一套判断事物是否有价值的观念体系,是指导我们选择与行动的内在指南。它指引着我们的生活。不同价值观的人会在不同的职业和专业领域实现自己的价值。下面的探索活动将帮助你了解自己在生命中所看的东西,指引你去探索属于自己专业的未来。'
     },
-    occupation:{
+    occupation: {
       title: '职业兴趣探索',
       description: '与学业和职业相关的兴趣,隐藏在生活的方方面面。探索兴趣的方法非常多样,通常人们通过思考自己在学习、生活中的表现或者对某些职业、活动的感受来确定自己的兴趣。职业研究者根据兴趣与职业世界、学业世界的关联把人的兴趣分为六种类型。下面让我们一起来看看你的兴趣代码及与之相关的专业和学科。'
     },
@@ -75,56 +75,83 @@ export default {
   },
   electiveGenerationOptions: {
     init: {
+      key: 'init',
+      value: 0,
+      decisionMaking: false,
       stepsVisible: false,
-      title: '',
+      title: '未开启',
       description: '',
       icon: ''
     },
     primary: {
+      key: 'primary',
+      value: 1,
+      decisionMaking: false,
       stepsVisible: true,
       title: '初选报名',
       description: '',
       icon: ''
     },
     primaryDM: {
+      key: 'primaryDM',
+      value: 2,
+      decisionMaking: true,
       stepsVisible: true,
       title: '初选报名决策',
       description: '',
       icon: ''
     },
     backTracking: {
+      key: 'backTracking',
+      value: 3,
+      decisionMaking: false,
       stepsVisible: true,
       title: '补录报名',
       description: '',
       icon: ''
     },
     backTrackingDM: {
+      key: 'backTrackingDM',
+      value: 4,
+      decisionMaking: true,
       stepsVisible: true,
       title: '补录报名决策',
       description: '',
       icon: ''
     },
     finalAdjust: {
+      key: 'finalAdjust',
+      value: 5,
+      decisionMaking: false,
       stepsVisible: true,
       title: '补录调剂报名',
       description: '',
       icon: ''
     },
     finalAdjustDM: {
+      key: 'finalAdjustDM',
+      value: 6,
+      decisionMaking: true,
       stepsVisible: true,
       title: '补录调剂报名决策',
       description: '',
       icon: ''
     },
     rankBalance: {
+      key: 'rankBalance',
+      value: 7,
+      decisionMaking: true,
       stepsVisible: true,
       title: '排名均衡',
       description: '',
       icon: ''
     },
     terminate: {
+      key: 'terminate',
+      value: 8,
+      decisionMaking: false,
       stepsVisible: false,
-      title: '',
+      title: '选科结束',
       description: '',
       icon: ''
     }

+ 0 - 11
src/common/mx-const.js

@@ -69,17 +69,6 @@ export default {
       philosophy: 1,  // 人生价值观
       occupation: 2,  // 职业兴趣
       knowledge: 3    // 知识兴趣
-    },
-    electiveGeneration: {
-      init: 0,
-      primary: 1,
-      primaryDM: 2,
-      backTracking: 3,
-      backTrackingDM: 4,
-      finalAdjust: 5,
-      finalAdjustDM: 6,
-      rankBalance: 7,
-      terminate: 8
     }
   }
 }

+ 3 - 0
src/common/mx-extension.js

@@ -51,6 +51,9 @@ export default {
         return this
       }
     }
+    String.prototype.tailingFix = function(fix) {
+      return this.endsWith(fix) ? this : this + fix
+    }
 
     // Global func.
     Vue.prototype.deepClone = function(obj) {

+ 6 - 2
src/components/MxTable/index.vue

@@ -1,9 +1,9 @@
 <template>
-  <el-table ref="table" :data="rows" @selection-change="$emit('selection-change', $event)">
+  <el-table ref="table" :border="border" :data="rows" @selection-change="$emit('selection-change', $event)">
     <template v-for="(prop, key) in propDefines">
       <template v-if="prop.hidden"></template>
       <el-table-column v-else-if="!prop.type" :key="key" :label="prop.label" :width="prop.width"
-                       :min-width="prop.minWidth" :align="prop.align || 'center'">
+                       :min-width="prop.minWidth" :align="prop.align || 'center'" :fixed="prop.fixed">
         <template v-if="prop.slotHeader" #header="scopeHeader">
           <slot :name="prop.slotHeader" v-bind="{
             ...scopeHeader,
@@ -34,6 +34,10 @@
 <script>
 export default {
   props: {
+    border: {
+      type: Boolean,
+      default: false
+    },
     rows: {
       type: Array,
       default: () => []

+ 1 - 2
src/filters/index.js

@@ -4,7 +4,6 @@
 export default {
   classTailing: function(name) {
     if (!name) return name
-    if (name.endsWith('班')) return name
-    return name + '班'
+    return  name.tailingFix('班')
   }
 }

+ 13 - 0
src/views/elective/generation/components/elective-generation-bar-chart.vue

@@ -0,0 +1,13 @@
+<template>
+
+</template>
+
+<script>
+export default {
+  name: 'elective-generation-bar-chart'
+}
+</script>
+
+<style scoped>
+
+</style>

+ 69 - 0
src/views/elective/generation/components/elective-generation-master.vue

@@ -0,0 +1,69 @@
+<template>
+  <div class="fx-column">
+    <evaluation-empty v-if="isUnPassedStep" :shadow="false" :title="emptyTitle"></evaluation-empty>
+    <template v-else>
+      <slot :name="activeKey+'-header'" v-bind="chartBinding"></slot>
+      <slot :name="activeKey" v-bind="chartBinding">
+        <elective-generation-table :chart-binding="chartBinding"></elective-generation-table>
+      </slot>
+      <slot :name="activeKey+'-footer'" v-bind="chartBinding"></slot>
+    </template>
+  </div>
+</template>
+
+<script>
+
+import ElectiveGenerationTable from '@/views/elective/generation/components/elective-generation-table'
+
+export default {
+  name: 'elective-generation-master',
+  components: { ElectiveGenerationTable },
+  props: {
+    generation: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      emptyTitle: ''
+    }
+  },
+  computed: {
+    activeKey() {
+      return this.generation.activeOpt?.key || ''
+    },
+    isUnPassedStep() {
+      if (!this.generation.activeOpt) return false
+      this.emptyTitle = this.generation.currentOpt == this.generation.options.init
+        ? '选科还未开启'
+        : `正在进行${this.generation.currentOpt.title || '{未知进程}'}, 还未进行至${this.generation.activeOpt.title}`
+      return this.generation.active > this.generation.current
+    },
+    categories() {
+      // summary - categories for display in table
+      debugger
+      const filterResult = this.generation.summary.filter(item => item.generation <= this.generation.active)
+      console.log('re-calculate categories', filterResult)
+      return filterResult
+    },
+    accumulates() {
+      // summary - accumulate for display in charts
+      return this.generation.summary.find(item => item.generation == this.generation.active && item.accumulates?.length)
+        || this.generation.summary.find(item => item.generation == this.generation.active - 1)
+    },
+    chartBinding() {
+      return {
+        generation: this.generation,
+        tableData: this.categories,
+        chartData: this.accumulates
+      }
+    }
+  },
+  methods: {}
+}
+</script>
+
+<style scoped>
+
+</style>

+ 13 - 0
src/views/elective/generation/components/elective-generation-pie-chart.vue

@@ -0,0 +1,13 @@
+<template>
+
+</template>
+
+<script>
+export default {
+  name: 'elective-generation-pie-chart'
+}
+</script>
+
+<style scoped>
+
+</style>

+ 125 - 0
src/views/elective/generation/components/elective-generation-steps.vue

@@ -0,0 +1,125 @@
+<template>
+  <div class="fx-column pl20 pr20">
+    <div class="fx-row fx-cen-cen f18 f-333 bold">
+      {{ title }}
+    </div>
+    <el-steps :active="activeStep" class="mt20">
+      <el-step v-for="(step,idx) in steps" :key="step.key" :title="step.title" :status="step.status">
+        <template #title>
+          <div class="rel"
+               :class="{'bold':activeStep==idx+1, 'f-333':activeStep==idx+1&&step.value>generation.current}">
+            <i v-if="activeStep==idx+1" class="el-icon-thumb current-pointer abs"></i>
+            <span class="pointer" @click="handleStepChange(step)">
+              {{ step.title }}</span>
+          </div>
+        </template>
+      </el-step>
+    </el-steps>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+
+export default {
+  name: 'elective-generation-steps',
+  model: {
+    prop: 'modelValue',
+    event: 'change'
+  },
+  props: {
+    generation: {
+      type: Object,
+      default: () => ({})
+    },
+    modelValue: {
+      type: String,
+      default: '' // active step key.
+    }
+  },
+  data() {
+    return {
+      activeStep: 0
+    }
+  },
+  computed: {
+    ...mapGetters(['school']),
+    steps() {
+      const options = this.generation.options
+      const current = this.generation.current
+      const visibleSteps = Object.keys(options)
+        .filter(key => options[key].stepsVisible)
+      return visibleSteps.map(key => {
+        const opt = options[key]
+        return {
+          key: key,
+          value: opt.value,
+          title: opt.title,
+          status: opt.value < current
+            ? 'success'
+            : opt.value > current
+              ? 'wait'
+              : 'process'
+        }
+      })
+    },
+    title() {
+      const year = (this.generation.status.year + '').tailingFix('学年')
+      const schoolName = this.school.schoolName
+      const roundName = this.generation.status.roundName
+
+      const options = this.generation.options
+      let statusTip = this.generation.currentOpt?.title + '进行中...'
+      let defaultOpt = this.generation.currentOpt
+      if (this.generation.current < options.primary.value) {
+        statusTip = '选科未开启'
+        defaultOpt = options.primary
+      } else if (this.generation.current > options.rankBalance.value) {
+        statusTip = '选科结束'
+        defaultOpt = options.rankBalance
+      }
+
+      if (!this.modelValue) {
+        this.activeStep = this.steps.findIndex(item => item.value == defaultOpt.value) + 1
+        this.$emit('change', defaultOpt.key)
+      }
+      return `${year}${schoolName}${roundName}(${statusTip})`
+    }
+  },
+  methods: {
+    handleStepChange(step) {
+      const target = this.steps.findIndex(item => item.key == step.key) + 1
+      if (target != this.activeStep) {
+        this.activeStep = target
+        this.$emit('change', step.key)
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.current-pointer {
+  left: -20px;
+  top: 10px;
+  animation: finger infinite 2s;
+}
+
+@keyframes finger {
+  0% {
+    transform: translate(-5px) rotate(90deg)
+  }
+  25% {
+    transform: translate(5px) rotate(90deg)
+  }
+  50% {
+    transform: translate(-5px) rotate(90deg)
+  }
+  75% {
+    transform: translate(5px) rotate(90deg)
+  }
+  100% {
+    transform: translate(-5px) rotate(90deg)
+  }
+}
+</style>

+ 81 - 0
src/views/elective/generation/components/elective-generation-table.vue

@@ -0,0 +1,81 @@
+<template>
+  <mx-table :prop-defines="resolvedTable.columns" :rows="resolvedTable.rows" border>
+    <template #elective-cell="{value}">
+      {{ value && value.value }}
+    </template>
+  </mx-table>
+</template>
+
+<script>
+import MxGroupTranslateMixin from '@/components/Cache/modules/mx-select-translate-mixin'
+
+export default {
+  mixins: [MxGroupTranslateMixin],
+  name: 'elective-generation-table',
+  props: ['chartBinding'],
+  computed: {
+    resolvedTable() {
+      console.log('resolvedTable called', this.listGroupsOptions, this.chartBinding)
+      if (!this.listGroupsOptions.length) return {}
+      const columns = { groupName: { label: '组合', fixed: true }, expectedCount: { label: '设置人数', fixed: true } }
+      const rows = this.chartBinding.generation.status.roundGroups.map(rg => ({
+        groupId: rg.groupId,
+        groupName: this.translateGroup(rg.groupId),
+        expectedCount: rg.personCount
+      }))
+      const mergedColumns = []
+      this.chartBinding.tableData.forEach(item => {
+        const ext = { roundId: item.roundId, generation: item.generation }
+        const isPreference = item.categories.every(item => Array.isArray(item))
+        if (isPreference) {
+          item.categories.forEach((subItem, idx) => {
+            const prefix = item.categories.length > 1 ? `第${idx + 1}志愿` : ''
+            subItem.forEach(data => this.resolveTableGeneration(ext, data, columns, rows, mergedColumns, prefix))
+          })
+        } else {
+          item.categories.forEach(data => this.resolveTableGeneration(ext, data, columns, rows, mergedColumns))
+        }
+      })
+      return {
+        mergedColumns,
+        columns,
+        rows
+      }
+    }
+  },
+  mounted() {
+    window.tableVue = this
+  },
+  methods: {
+    resolveTableGeneration(ext, data, columnsRef, rowsRef, mergedColumnsRef, prefix = '') {
+      // resolve core
+      const prop = prefix + ext.generation + '_' + data.category
+      const name = prefix + data.displayName
+      const shouldMerge = data.values.length != rowsRef.length
+        || data.values.some(v => v.groupId == 0)
+
+      columnsRef[prop] = { label: name, slot: 'elective-cell' }
+      if (!shouldMerge) {
+        data.values.forEach(val => {
+          const row = rowsRef.find(row => row.groupId == val.groupId)
+          if (row) {
+            row[prop] = val
+          }
+        })
+      } else {
+        // mark for table rows merge
+        mergedColumnsRef.push(prop)
+
+        // keep value in display row
+        const val = data.values.first()
+        const row = rowsRef.first()
+        row[prop] = val
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 77 - 8
src/views/elective/generation/index.vue

@@ -1,20 +1,89 @@
 <template>
-
+  <div class="app-container">
+    <el-card>
+      <mx-condition :query-params="queryParams" :require-fields="requireFields"
+                    @query="handleQuery" @invalid="handleInvalid"></mx-condition>
+    </el-card>
+    <el-card v-if="electiveStatus" class="mt20">
+      <template #header>
+        <elective-generation-steps v-model="activeStep" :generation="generation"></elective-generation-steps>
+      </template>
+      <elective-generation-master :generation="generation"></elective-generation-master>
+    </el-card>
+    <evaluation-empty v-else class="mt20"></evaluation-empty>
+  </div>
 </template>
 
 <script>
-import { getElectiveSummary } from '@/api/webApi/elective/generation'
+import Vue from 'vue'
+import config from '@/common/mx-config'
+import { getElectiveStatus, getElectiveSummary } from '@/api/webApi/elective/generation'
+import MxCondition from '@/components/MxCondition/mx-condition'
+import ElectiveGenerationSteps from '@/views/elective/generation/components/elective-generation-steps'
+import ElectiveGenerationMaster from '@/views/elective/generation/components/elective-generation-master'
 
 export default {
   name: 'generation-index',
-  mounted() {
-    this.loadElectiveSummary()
+  components: { ElectiveGenerationMaster, ElectiveGenerationSteps, MxCondition },
+  data() {
+    return {
+      // query
+      queryParams: {
+        year: '',
+        roundId: ''
+      },
+      requireFields: ['year', 'roundId'],
+      // api data
+      electiveStatus: null,
+      electiveSummary: [],
+      // local data
+      activeStep: '',
+      options: config.electiveGenerationOptions
+    }
+  },
+  computed: {
+    current() {
+      /// 当前进程代,可能没有值
+      return this.electiveStatus?.currentGeneration
+    },
+    currentOpt() {
+      /// 当前进程代对应的配置项,可能没有值
+      return Object.values(this.options).find(opt => opt.value == this.current)
+    },
+    activeOpt() {
+      /// 当前选中的进程代,可能没有值
+      return this.options[this.activeStep]
+    },
+    active() {
+      return this.activeOpt?.value
+    },
+    generation() {
+      return {
+        // generation key value
+        options: this.options,
+        current: this.current,
+        currentOpt: this.currentOpt,
+        active: this.active,
+        activeOpt: this.activeOpt,
+        /// root data inject
+        summary: this.electiveSummary,
+        status: this.electiveStatus
+      }
+    }
   },
   methods: {
-    loadElectiveSummary() {
-      getElectiveSummary().then(res => {
-        console.log('getElectiveSummary', res)
-      })
+    handleInvalid() {
+      this.electiveStatus = null
+      this.electiveSummary = []
+    },
+    async handleQuery() {
+      const resStatus = await getElectiveStatus(this.queryParams)
+      this.electiveStatus = resStatus.data
+      const resSummary = await getElectiveSummary(this.queryParams)
+      this.electiveSummary = resSummary.data
+      debugger
+      window.electiveVue = this
+      console.log('query completed')
     }
   }
 }