lrf402788946 5 år sedan
förälder
incheckning
a399dbc2ab

+ 4 - 3
config/menu-config.js

@@ -1,4 +1,4 @@
-export const school = [
+const school = [
   // {
   // {
   //   path: '',
   //   path: '',
   //   name: '测试',
   //   name: '测试',
@@ -41,7 +41,7 @@ export const school = [
     module: 'school',
     module: 'school',
   },
   },
 ];
 ];
-export const director = [
+const director = [
   {
   {
     path: '/newPlan/index',
     path: '/newPlan/index',
     name: '计划管理', //上报名单
     name: '计划管理', //上报名单
@@ -53,7 +53,7 @@ export const director = [
   //   module: 'director',
   //   module: 'director',
   // },
   // },
 ];
 ];
-export const teacher = [
+const teacher = [
   {
   {
     path: '/plan/index',
     path: '/plan/index',
     name: '查看计划', //上报名单
     name: '查看计划', //上报名单
@@ -188,6 +188,7 @@ export const menu = [
     ],
     ],
   },
   },
   ...director,
   ...director,
+  ...teacher,
   {
   {
     //班主任只有这个
     //班主任只有这个
     path: '',
     path: '',

+ 79 - 0
parts/print/certCard.vue

@@ -0,0 +1,79 @@
+<template>
+  <div id="certCard">
+    <el-row>
+      <el-col :span="24">
+        <el-col :span="24">
+          <el-button type="primary" size="mini" @click="toTest()">打印证书</el-button>
+        </el-col>
+        <test :list="list"></test>
+        <!-- <el-col :span="24" ref="print">
+          <el-col :span="24" class="list" v-for="(item, index) in list" :key="index">
+            <p>
+              <span>学校(院):</span>
+              <span>{{ item.school_name }}</span>
+              <span>,</span>
+              <span>{{ item.entry_year }}</span>
+              <span>级</span>
+              <span>{{ item.major }}</span>
+              <span>专业</span>
+              <span>学生:</span>
+              <span>{{ item.name }}</span>
+              <span>于</span>
+              <span>2020年11月参加吉林省大学生就业能力扩展训练</span>
+              <span>第</span>
+              <span>{{ item.termname }}</span>
+              <span>期培训班。培训合格,特发此证</span>
+            </p>
+            <p>
+              <span>证书编号:2020{{ item.termname }}{{ item.classname }}</span>
+              <span>2020年11月22日</span>
+            </p>
+          </el-col>
+        </el-col> -->
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import printTemplate from 'print-template';
+import test from './test';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'certCard',
+  props: {
+    list: null,
+  },
+  components: { test },
+  data: function() {
+    return {
+      zhengshu: require('@/assets/zhengshu.jpg'),
+    };
+  },
+  created() {},
+  methods: {
+    toPrint() {
+      this.$print(this.$refs.print);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  height: 710px;
+  background-image: url(/img/zhengshu.bc829b8f.jpg);
+  background-size: 100% 100%;
+  background-repeat: no-repeat;
+  width: 100%;
+}
+</style>

+ 115 - 0
parts/print/namCard.vue

@@ -0,0 +1,115 @@
+<template>
+  <div id="namCard">
+    <el-row type="flex" align="middle" justify="end" class="btn_bar">
+      <!-- <el-col :span="4" class="printingBtn">
+        <el-button type="primary" size="mini" icon="el-icon-arrow-left" @click="now--" :disabled="now == 0">上一班</el-button>
+      </el-col> -->
+      <el-col :span="4" class="printingBtn">
+        <el-button type="primary" size="mini" @click="toPrint()">打印名牌</el-button>
+      </el-col>
+      <!-- <el-col :span="4" class="printingBtn">
+        <el-button type="primary" size="mini" icon="el-icon-arrow-right" @click="now++" :disabled="now == csList.length - 1">下一班</el-button>
+      </el-col> -->
+    </el-row>
+
+    <!-- <el-col :span="24" class="info" ref="print">
+      <el-col :span="6" class="list" v-for="(item, index) in list" :key="index">
+        <p>
+          <span>吉林省高校学生就业能力扩展训练</span><span>第{{ item.termname }}期</span><span>{{ item.classname }}</span>
+        </p>
+        <p>{{ item.name }}</p>
+      </el-col>
+    </el-col> -->
+    <el-col :span="24" class="info" ref="print">
+      <el-col :span="6" class="list" v-for="(item, index) in csList[now]" :key="index">
+        <p>
+          <span>吉林省高校学生就业能力扩展训练</span><span>第{{ item.termname }}期</span><span>{{ item.classname }}</span>
+        </p>
+        <p>{{ item.name }}</p>
+      </el-col>
+    </el-col>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions } = createNamespacedHelpers('student');
+export default {
+  metaInfo: { title: '学生名单' },
+  name: 'name-list',
+  props: { list: { type: Array, default: () => [] } },
+  components: {},
+  data: function() {
+    return {
+      csList: [],
+      now: 0,
+      nowList: [],
+    };
+  },
+  created() {},
+  methods: {
+    ...mapActions(['query']),
+    groupByClass() {
+      let duplicate = _.cloneDeep(this.list);
+      let group = _.flatten(_.toPairs(_.groupBy(duplicate, 'classid'))).filter(f => _.isArray(f));
+      this.$set(this, `csList`, group);
+    },
+    toPrint() {
+      this.$print(this.$refs.print);
+    },
+    toreturn() {
+      window.history.go(-1);
+    },
+  },
+  computed: {
+    id() {
+      return this.$route.query.id;
+    },
+    mainTitle() {
+      let meta = this.$route.meta;
+      let main = meta.title || '';
+      let sub = meta.sub || '';
+      let title = main + sub;
+      return title;
+    },
+  },
+  watch: {
+    list: {
+      handler(val) {
+        if (val) this.groupByClass();
+      },
+      immediate: true,
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+// .info {
+//   width: 714px;
+// }
+.list {
+  width: 171px;
+  height: 140px;
+  border: 1px dashed #333;
+  margin: 0 8px 10px 0;
+  padding: 5px 5px;
+  p {
+    float: left;
+    width: 100%;
+    text-align: center;
+    font-size: 12px;
+    padding: 0 0 10px 0;
+  }
+  p:last-child {
+    font-size: 25px;
+    letter-spacing: 5px;
+    padding: 0;
+  }
+}
+.printingBtn {
+  text-align: center;
+  padding: 10px 0;
+}
+</style>

+ 53 - 0
parts/print/print-sign.vue

@@ -0,0 +1,53 @@
+<template>
+  <div id="print-sign">
+    <el-row type="flex" align="middle" justify="end" class="btn_bar">
+      <el-col :span="4" class="printingBtn">
+        <el-button type="primary" size="mini" @click="toPrint()">打印报到表</el-button>
+      </el-col>
+    </el-row>
+    <el-row type="flex" align="middle" justify="center" style="text-align:center">
+      <el-col :span="24" style="width:1060px;border: solid #cecece;">
+        <el-table border stripe :data="list" ref="print" size="small" style="border: solid #cecece;">
+          <el-table-column align="center" label="姓名" prop="name" width="170"></el-table-column>
+          <el-table-column align="center" label="学校" prop="school_name" width="150"></el-table-column>
+          <el-table-column align="center" label="性别" prop="gender" width="80"></el-table-column>
+          <el-table-column align="center" label="民族" prop="nation" width="150"></el-table-column>
+          <el-table-column align="center" label="班级" prop="classname" width="80"></el-table-column>
+          <el-table-column align="center" label="手机号" prop="phone" width="150"></el-table-column>
+          <el-table-column align="center" label="签名"></el-table-column>
+        </el-table>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'print-sign',
+  props: {
+    list: { type: Array, default: () => [] },
+  },
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {
+    toPrint() {
+      this.$print(this.$refs.print);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 111 - 0
parts/print/test.vue

@@ -0,0 +1,111 @@
+<template>
+  <div id="test">
+    <el-row :gutter="12">
+      <el-col :offset="8" :span="8">
+        <el-card shadow="always">
+          <div slot="header" class="clearfix">
+            <span>简单实例</span>
+          </div>
+
+          <div>
+            <el-form label-width="80px">
+              <el-form-item label="名字">
+                <el-input v-model="from.name"></el-input>
+              </el-form-item>
+              <el-form-item label="条形码">
+                <el-input v-model="from.code"></el-input>
+              </el-form-item>
+              <el-form-item label="页数">
+                <el-input-number v-model="from.num" controls-position="right" :min="1" :max="10"> </el-input-number>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" @click="print">生成打印文件</el-button>
+                <el-button v-if="url" type="success" @click="openPdf">
+                  打开生成文件
+                </el-button>
+              </el-form-item>
+            </el-form>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import printTemplate from 'print-template';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'test',
+  props: {
+    list: { type: Array, default: () => [] },
+  },
+  components: {},
+  data: function() {
+    return {
+      url: '',
+      template: null,
+      from: { num: 1, name: '张三', code: 'YT121212323' },
+      zhengshu: require('@/assets/zhengshu.jpg'),
+    };
+  },
+  created() {
+    this.init();
+  },
+  methods: {
+    init() {
+      this.template = new printTemplate();
+      this.template.push({
+        name: 'expressDelivery1',
+        unit: 'mm',
+        size: [210, 297],
+        fixed: [{ type: 'image', x: 0, y: 0, default: this.zhengshu, width: 210, height: 297 }],
+
+        data: {
+          school_name: { type: 'text', x: 15, y: 15, fontSize: 3.5 },
+          entry_year: { type: 'text', x: 56, y: 55, fontSize: 3.5 },
+          major: { type: 'text', x: 107, y: 105, fontSize: 3.5 },
+          name: { type: 'text', x: 158, y: 155, fontSize: 3.5 },
+          termname: { type: 'text', x: 15, y: 255, fontSize: 3.5 },
+          cernum: { type: 'text', x: 100, y: 250, fontSize: 3.5 },
+        },
+      });
+    },
+    openPdf() {
+      let link = document.createElement('a');
+      link.href = this.url;
+      link.target = '_blank';
+      link.click();
+    },
+    print() {
+      let data = [];
+      this.url = null;
+      let duplicate = _.cloneDeep(this.list);
+      duplicate = duplicate.map(i => {
+        i.cernum = `2020${i.termname}${i.classname}`;
+        return i;
+      });
+      this.template.print('expressDelivery1', [duplicate[0]]).then(pdf => {
+        if (pdf) {
+          this.$message.success('生成成功');
+          this.url = pdf.output('bloburi', { filename: '证书' });
+        } else {
+          this.$message.warring('生成失败');
+        }
+      });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 112 - 0
parts/statistics/bar.vue

@@ -0,0 +1,112 @@
+<template>
+  <div id="bar">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { Bar } from '@antv/g2plot';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'bar',
+  props: {
+    data: { type: [Object, Array], default: () => [] },
+    axis: { type: Object, default: () => {} },
+    gid: { type: String, default: `${new Date().getTime()}` },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: [],
+    };
+  },
+  created() {},
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let { x, y, xAlias, yAlias } = this.axis;
+      let meta = {};
+      meta[x] = { alias: xAlias };
+      meta[y] = { alias: yAlias };
+      this.chart = new Bar(this.gid, {
+        pixelRatio: 1,
+        data: this.list,
+        //条形和柱状的x,y轴需要互换
+        xField: y,
+        yField: x,
+        meta: meta,
+        point: {
+          visible: true,
+        },
+        label: {
+          visible: true,
+        },
+        //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+        stackField: x,
+        legend: {
+          visible: true,
+          position: 'right-top',
+        },
+        xAxis: {
+          nice: true,
+          visible: true,
+          line: {
+            visible: true,
+          },
+          grid: {
+            visible: true,
+          },
+          max: _.max(this.list.map(i => i.value)),
+          min: 0,
+          tickLine: {
+            visible: true,
+          },
+        },
+        yAxis: {
+          nice: true,
+          visible: true,
+          grid: {
+            visible: true,
+          },
+          line: {
+            visible: true,
+          },
+        },
+
+        events: {
+          onColumnClick: e => this.gclick(e),
+        },
+      });
+      this.chart.render();
+    },
+    gclick(data) {
+      console.log('in function:gclick');
+      console.log(data);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  watch: {
+    data: {
+      immediate: true,
+      deep: true,
+      handler(val) {
+        if (val) this.$set(this, `list`, val);
+      },
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 84 - 0
parts/statistics/column.vue

@@ -0,0 +1,84 @@
+<template>
+  <div id="column">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { Column } from '@antv/g2plot';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'column',
+  props: {
+    data: { type: [Object, Array], default: () => [] },
+    axis: { type: Object, default: () => {} },
+    gid: { type: String, default: `${new Date().getTime()}` },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: [],
+    };
+  },
+  created() {},
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let { x, y, xAlias, yAlias } = this.axis;
+      let meta = {};
+      meta[x] = { alias: xAlias };
+      meta[y] = { alias: yAlias };
+      this.chart = new Column(this.gid, {
+        pixelRatio: 4,
+        data: this.list,
+        xField: x,
+        yField: y,
+        meta: meta,
+        point: {
+          visible: true,
+        },
+        label: {
+          visible: true,
+        },
+        //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+        stackField: x,
+        legend: {
+          visible: true,
+          position: 'right-top',
+        },
+        events: {
+          onColumnClick: e => this.gclick(e),
+        },
+      });
+      this.chart.render();
+    },
+    gclick(data) {
+      console.log('in function:gclick');
+      console.log(data);
+    },
+  },
+  watch: {
+    data: {
+      immediate: true,
+      deep: true,
+      handler(val) {
+        if (val) this.$set(this, `list`, val);
+      },
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 90 - 0
parts/statistics/donut.vue

@@ -0,0 +1,90 @@
+<template>
+  <div id="donut">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { Donut } from '@antv/g2plot';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'donut',
+  props: {
+    data: { type: [Object, Array], default: () => [] },
+    axis: { type: Object, default: () => {} },
+    gid: { type: String, default: `${new Date().getTime()}` },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: [],
+    };
+  },
+  created() {},
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let { x, y, xAlias, yAlias } = this.axis;
+      let meta = {};
+      meta[x] = { alias: xAlias };
+      meta[y] = { alias: yAlias };
+      this.chart = new Donut(this.gid, {
+        pixelRatio: 4,
+        data: this.list,
+        colorField: x,
+        angleField: y,
+        // meta: meta,
+        point: {
+          visible: true,
+        },
+        label: {
+          visible: true,
+          type: 'spider',
+          formatter: (text, item) => `${item._origin[x]}: ${item._origin[y]}`,
+        },
+        //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+        stackField: x,
+        legend: {
+          visible: true,
+          position: 'right-top',
+        },
+        //环形中间部分设置
+        statistic: {
+          visible: true,
+        },
+        events: {
+          onPieClick: e => this.gclick(e),
+        },
+      });
+      this.chart.render();
+    },
+    gclick(data) {
+      console.log('in function:gclick');
+      console.log(data);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  watch: {
+    data: {
+      immediate: true,
+      deep: true,
+      handler(val) {
+        if (val) this.$set(this, `list`, val);
+      },
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 86 - 0
parts/statistics/pie.vue

@@ -0,0 +1,86 @@
+<template>
+  <div id="pie">
+    <div :id="gid"></div>
+  </div>
+</template>
+
+<script>
+import { Pie } from '@antv/g2plot';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'pie',
+  props: {
+    data: { type: [Object, Array], default: () => [] },
+    axis: { type: Object, default: () => {} },
+    gid: { type: String, default: `${new Date().getTime()}` },
+  },
+  components: {},
+  data: function() {
+    return {
+      chart: null,
+      list: [],
+    };
+  },
+  created() {},
+  mounted() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      let { x, y, xAlias, yAlias } = this.axis;
+      let meta = {};
+      meta[x] = { alias: xAlias };
+      meta[y] = { alias: yAlias };
+      this.chart = new Pie(this.gid, {
+        pixelRatio: 4,
+        data: this.list,
+        colorField: x,
+        angleField: y,
+        // meta: meta,
+        point: {
+          visible: true,
+        },
+        label: {
+          visible: true,
+          type: 'spider',
+          formatter: (text, item) => `${item._origin[x]}: ${item._origin[y]}`,
+        },
+        //stackField + legend 一起使用,前者确定以哪个字段作为选项,后者是显示与否,位置
+        stackField: x,
+        legend: {
+          visible: true,
+          position: 'right-top',
+        },
+        events: {
+          onPieClick: e => this.gclick(e),
+        },
+      });
+      this.chart.render();
+    },
+    gclick(data) {
+      console.log('in function:gclick');
+      console.log(data);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  watch: {
+    data: {
+      immediate: true,
+      deep: true,
+      handler(val) {
+        if (val) this.$set(this, `list`, val);
+      },
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 132 - 0
parts/statistics/quest-chart.vue

@@ -0,0 +1,132 @@
+<template>
+  <div id="quest-chart">
+    <el-row type="flex" align="middle" justify="start" class="btn_bar">
+      <el-col :span="10"> {{ data.topic }} [{{ data.type | topicType }}] </el-col>
+    </el-row>
+    <template v-if="data.type != 2">
+      <el-row type="flex" align="middle" justify="center" v-if="btnModel.table">
+        <el-col :span="16">
+          <el-table :data="data.option" size="mini" border stripe>
+            <el-table-column align="center" label="选项" prop="opname"></el-table-column>
+            <el-table-column align="center" label="小计" prop="value"></el-table-column>
+            <el-table-column align="center" label="比例">
+              <template v-slot="{ row, $index }">
+                <el-progress :text-inside="true" :stroke-width="20" :percentage="getPercent(row.value)" :color="getPS(getPercent(row.value))"></el-progress>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-col>
+      </el-row>
+      <el-row type="flex" align="middle" justify="center" class="btn_bar" :gutter="10" v-if="!nodata">
+        <el-col :span="3" v-for="(i, index) in btnList" :key="index">
+          <el-button :type="btnModel[i.model] ? 'primary' : ''" size="mini" @click="changeModel(i.model)">
+            {{ i.text }}
+          </el-button>
+        </el-col>
+      </el-row>
+      <el-row type="flex" align="middle" justify="center">
+        <el-col :span="16" v-if="btnModel.column">
+          <g2column :data="data.option" :axis="axis" :gid="data._id"></g2column>
+        </el-col>
+        <el-col :span="16" v-if="btnModel.pie">
+          <g2pie :data="data.option" :axis="axis" :gid="data._id"></g2pie>
+        </el-col>
+        <el-col :span="16" v-if="btnModel.donut">
+          <g2donut :data="data.option" :axis="axis" :gid="data._id"></g2donut>
+        </el-col>
+        <el-col :span="16" v-if="btnModel.bar">
+          <g2bar :data="data.option" :axis="axis" :gid="data._id"></g2bar>
+        </el-col>
+      </el-row>
+    </template>
+    <template v-else>
+      <div style="margin:10px">见详情</div>
+    </template>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import g2column from '@frame/parts/statistics/column.vue';
+import g2pie from '@frame/parts/statistics/pie.vue';
+import g2donut from '@frame/parts/statistics/donut.vue';
+import g2bar from '@frame/parts/statistics/bar.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'quest-chart',
+  props: {
+    data: { type: [Object, Array], default: () => [] },
+    nodata: { type: Boolean, default: false },
+  },
+  components: { g2column, g2pie, g2donut, g2bar },
+  data: function() {
+    return {
+      axis: {
+        x: 'opname',
+        xAlias: '选项',
+        y: 'value',
+        yAlias: '数量',
+      },
+      btnModel: {
+        table: true,
+        pie: false,
+        dount: false,
+        column: false,
+        bar: false,
+      },
+      btnList: [
+        { text: '表格', model: 'table' },
+        { text: '饼状图', model: 'pie' },
+        { text: '圆环图', model: 'donut' },
+        { text: '柱状图', model: 'column' },
+        { text: '条形图', model: 'bar' },
+      ],
+    };
+  },
+  created() {},
+  methods: {
+    changeModel(model) {
+      if (model !== 'table') {
+        let keys = Object.keys(this.btnModel);
+        for (const key of keys) {
+          if (key != 'table' && key != model) {
+            this.btnModel[key] = false;
+          }
+        }
+      }
+      this.btnModel[model] = !this.btnModel[model];
+      this.$forceUpdate();
+    },
+    getPercent(num) {
+      let all = this.data.option.reduce((prev, next) => prev + next.value * 1 || 0, 0);
+      if (all == 0) return 0;
+      let percent = (num * 1) / all;
+      percent = _.round(percent, 4) * 100;
+      return percent;
+    },
+    getPS(percent) {
+      if (percent >= 70) return 'red';
+      if (_.inRange(percent, 30, 70)) return 'blue';
+      if (percent <= 30) return 'gray';
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  filters: {
+    topicType(val) {
+      if (val == 0) return '单选题';
+      if (val == 1) return '多选题';
+      if (val == 2) return '简答题';
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 48 - 0
parts/statistics/report.vue

@@ -0,0 +1,48 @@
+<template>
+  <div id="report">
+    <template v-for="(answer, index) in report.answers">
+      <div :key="`${index}${new Date().getTime()}`" style="border-bottom: 1px solid #EBEEF5;">
+        <el-row type="flex" align="middle" justify="center" class="btn_bar">
+          <el-col :span="18"> {{ answer.topic }} [{{ answer.type | topicType }}] </el-col>
+        </el-row>
+        <el-row type="flex" align="middle" justify="center" class="btn_bar">
+          <el-col :span="18" v-if="answer.type == 0">{{ answer.answer }}</el-col>
+        </el-row>
+      </div>
+    </template>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'report',
+  props: {
+    report: { type: Object, default: () => [] },
+  },
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  filters: {
+    topicType(val) {
+      if (val == 0) return '单选题';
+      if (val == 1) return '多选题';
+      if (val == 2) return '简答题';
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>