lrf402788946 4 anni fa
parent
commit
4c046a0248

+ 2 - 0
package.json

@@ -8,6 +8,7 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@antv/g2plot": "^1.1.7",
     "@fullcalendar/core": "^4.3.1",
     "@fullcalendar/daygrid": "^4.3.0",
     "@fullcalendar/interaction": "^4.3.0",
@@ -20,6 +21,7 @@
     "lodash": "^4.17.15",
     "moment": "^2.24.0",
     "naf-core": "^0.1.2",
+    "print-template": "^1.2.2",
     "qrcode": "^1.4.4",
     "vue": "^2.6.10",
     "vue-meta": "^2.3.2",

BIN
src/assets/zhengshu.jpg


+ 1 - 1
src/main.js

@@ -10,7 +10,7 @@ import '@/plugins/element';
 import InitStomp from '@/plugins/stomp';
 import '@frame/icon/iconfont.css';
 Vue.config.productionTip = false;
-import Print from '@/util/print';
+import Print from '@frame/utils/print';
 Vue.use(Print); //注册
 
 new Vue({

+ 16 - 40
src/router/index.js

@@ -21,18 +21,6 @@ const routes = [
     component: () => import('@/views/index.vue'),
     children: [
       ...newPlan,
-      // {
-      //   path: '/classes/index',
-      //   name: 'classes_index',
-      //   meta: { title: '班级管理' },
-      //   component: () => import('@/views/classes/index.vue'),
-      // },
-      // {
-      //   path: '/classes/index',
-      //   name: 'classes_list',
-      //   meta: { title: '班级列表' },
-      //   component: () => import('@/views/classes/classes.vue'),
-      // },
       {
         path: '/train/plan/remind',
         name: 'remind_index',
@@ -48,8 +36,8 @@ const routes = [
       {
         path: '/train/plan/print',
         name: 'print_index',
-        meta: { title: '班级列表', act: '打印' },
-        component: () => import('@/views/classes/classes.vue'),
+        meta: { title: '打印' },
+        component: () => import('@/views/classes/print.vue'),
       },
       {
         path: '/train/plan/leave',
@@ -67,33 +55,21 @@ const routes = [
         path: '/train/plan/score',
         name: 'score_index',
         meta: { title: '班级列表', act: '学生成绩' },
-        component: () => import('@/views/classes/classes.vue'),
+        component: () => import('@/views/classes/score.vue'),
       },
       {
         path: '/statistics/question/index',
         name: 'statistics_index',
-        meta: { title: '班级列表', act: '问卷统计' },
-        component: () => import('@/views/classes/classes.vue'),
+        meta: { title: '问卷统计' },
+        component: () => import('@/views/classes/completion.vue'),
       },
-      // {
-      //   path: '/classes/leave',
-      //   name: 'classes_leave',
-      //   meta: { title: '请假管理' },
-      //   component: () => import('@/views/classes/leave.vue'),
-      // },
-
       {
-        path: '/train/plan/leave',
-        name: 'leave_index',
-        meta: { title: '班级列表' },
-        component: () => import('@/views/classes/classes.vue'),
+        path: '/statistics/question/detail',
+        name: 'statistics_detail',
+        meta: { title: '问卷统计详情' },
+        component: () => import('@/views/classes/completion-detail.vue'),
       },
-      // {
-      //   path: '/student/index',
-      //   name: 'student_index',
-      //   meta: { title: '班级', sub: '名单' },
-      //   component: () => import('@/views/classes/name-list.vue'),
-      // },
+
       {
         path: '/classes/lesson',
         name: 'classes_lesson',
@@ -108,12 +84,12 @@ const routes = [
       },
       // 新增-打印名单
 
-      {
-        path: '/classes/namCard',
-        name: 'classes_namCard',
-        meta: { title: '班级', sub: '学生名单' },
-        component: () => import('@/views/classes/namCard.vue'),
-      },
+      // {
+      //   path: '/classes/namCard',
+      //   name: 'classes_namCard',
+      //   meta: { title: '班级', sub: '学生名单' },
+      //   component: () => import('@/views/classes/namCard.vue'),
+      // },
       // {
       //   path: '/classes/attendance',
       //   name: 'classes_attendance',

+ 2 - 0
src/store/index.js

@@ -16,6 +16,7 @@ import lesson from '@frame/store/lesson';
 import director from '@frame/store/director';
 import termquest from '@frame/store/termquest';
 import questionnaire from '@frame/store/questionnaire';
+import questionanswer from '@frame/store/question-answer';
 import bedroom from '@frame/store/bedroom';
 import login from '@frame/store/login';
 import util from '@frame/store/util';
@@ -54,6 +55,7 @@ export default new Vuex.Store({
     leave,
     setting,
     trainBatch,
+    questionanswer,
   },
   state: { ...ustate, ...dostate },
   mutations: { ...umutations, ...domutations },

+ 23 - 2
src/views/classes/attendance.vue

@@ -1,7 +1,25 @@
 <template>
   <div id="attendance">
     <listFrame :title="pageTitle" @query="skipsearch" :total="total" :needFilter="false" :returns="toreturn" :needAdd="false">
-      <attendanceInfo :tableData="tableData" :options="options" @filterDate="filterDate"></attendanceInfo>
+      <!-- <attendanceInfo :tableData="tableData" :options="options" @filterDate="filterDate"></attendanceInfo> -->
+      <el-select v-model="value" placeholder="请选择" @change="filterDate">
+        <el-option v-for="(item, index) in options" :key="index" :label="item" :value="item"> </el-option>
+      </el-select>
+      <el-table :data="tableData" border style="width: 100%">
+        <el-table-column align="center" prop="date" label="日期"> </el-table-column>
+        <el-table-column align="center" prop="time" label="时间"> </el-table-column>
+        <el-table-column align="center" prop="name" label="姓名"> </el-table-column>
+        <el-table-column align="center" label="类型">
+          <template slot-scope="scope">
+            <span>{{ scope.row.type === '0' ? '上课考勤' : scope.row.type === '1' ? '寝室考勤' : '' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" label="状态">
+          <template slot-scope="scope">
+            <span>{{ scope.row.status === '0' ? '未签到' : scope.row.status === '1' ? '已签到' : scope.row.status === '2' ? '迟到' : '' }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
     </listFrame>
   </div>
 </template>
@@ -17,13 +35,14 @@ const { mapActions: classes } = createNamespacedHelpers('classes');
 export default {
   name: 'attendance',
   props: {},
-  components: { attendanceInfo, listFrame },
+  components: { listFrame }, //attendanceInfo
   data: () => ({
     total: 0,
     attendList: [],
     tableData: [],
     options: [],
     dataList: [],
+    value: '',
   }),
   created() {},
   computed: {
@@ -122,6 +141,8 @@ export default {
   watch: {
     id: {
       handler(val) {
+        this.$set(this, `options`, []);
+        this.$set(this, `value`, '');
         if (val) this.search();
         else this.$set(this, `tableData`, []);
       },

+ 167 - 0
src/views/classes/completion-detail.vue

@@ -0,0 +1,167 @@
+<template>
+  <div id="detail">
+    <detail-frame :title="pageTitle" :returns="toReturns">
+      <el-card :header="quest.name">
+        <el-tabs v-model="tabs" :stretch="true" type="card">
+          <el-tab-pane label="图表分析" name="chart">
+            <el-row
+              v-for="(quest, qi) in quest.question"
+              :key="qi"
+              type="flex"
+              align="middle"
+              justify="center"
+              style="text-align:center;border-bottom: 1px solid #EBEEF5;"
+            >
+              <el-col :span="24">
+                <charts :data="quest" :nodata="nodata"></charts>
+              </el-col>
+            </el-row>
+          </el-tab-pane>
+          <el-tab-pane label="具体数据" name="data">
+            <el-collapse v-model="collapse" accordion>
+              <el-collapse-item v-for="(data, qi) in cdata" :key="qi" :title="data.studentname" :name="`${qi}`">
+                <el-row type="flex" align="middle" justify="center" style="border-bottom: 1px solid #EBEEF5;">
+                  <el-col :span="24">
+                    <reports :report="data"></reports>
+                  </el-col>
+                </el-row>
+              </el-collapse-item>
+            </el-collapse>
+          </el-tab-pane>
+        </el-tabs>
+      </el-card>
+    </detail-frame>
+  </div>
+</template>
+
+<script>
+//组件全部转移到frame中,和班主任端共用
+import _ from 'lodash';
+import charts from '@frame/parts/statistics/quest-chart.vue';
+import reports from '@frame/parts/statistics/report.vue';
+import detailFrame from '@frame/layout/admin/detail-frame';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: questionnaire } = createNamespacedHelpers('questionnaire');
+const { mapActions: questionanswer } = createNamespacedHelpers('questionanswer');
+
+export default {
+  name: 'detail',
+  props: {},
+  components: { detailFrame, charts, reports },
+  data: function() {
+    return {
+      mylb: null,
+      tabs: 'chart',
+      collapse: '',
+      quest: {},
+      cdata: [], //具体数据
+      nodata: false,
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    ...questionnaire(['fetch']),
+    ...questionanswer(['query']),
+    async search() {
+      let res = await this.fetch(this.querys.questionnaireid);
+      if (!this.$checkRes(res)) return;
+      let ansres = await this.query(this.querys); //{ questionnaireid: this.id, termid: this.termid, batchid: this.batchid, classid: this.classid }
+      if (this.$checkRes(ansres)) {
+        if (_.get(ansres.data, 'length', 0) <= 0) {
+          this.$set(this, `nodata`, true);
+        }
+        let data = _.cloneDeep(_.get(res, 'data'));
+        let quests = _.cloneDeep(_.get(res.data, `question`, []));
+        let allAnswer = _.cloneDeep(ansres.data);
+        let naa = _.flatten(allAnswer.map(i => i.answers)).map(i => {
+          i.answer = JSON.parse(i.answer);
+          return i;
+        });
+        //统计
+        let nq = this.getStatistics(naa, quests);
+        let sta = _.cloneDeep(data);
+        sta.question = nq;
+        this.$set(this, `quest`, sta);
+        //具体数据
+        let concreteData = this.getConcreteData(quests, allAnswer);
+        this.$set(this, `cdata`, concreteData);
+      }
+    },
+    //获取图表分析部分
+    getStatistics(answer, quests) {
+      let allAnswer = _.cloneDeep(answer);
+      let questList = _.cloneDeep(quests);
+      let newquest = questList.map(i => {
+        //单选题
+        if (i.type == 0) i = this.dealRadio(i, allAnswer);
+
+        //多选题
+        if (i.type == 1) i = this.dealCheckBox(i, allAnswer);
+        //简答,应该不需要了
+
+        return i;
+      });
+      return newquest;
+    },
+    dealRadio(quest, answers) {
+      let rl = answers.filter(f => f.questionid == quest._id);
+      let ga = _.groupBy(rl, 'answer');
+      quest.option.map(i => {
+        let r = _.get(ga[i.opname], 'length', 0);
+        i.value = r || 0;
+        return i;
+      });
+      return quest;
+    },
+    dealCheckBox(quest, answers) {
+      let rl = answers.filter(f => f.questionid == quest._id);
+      let mid = _.flatten(rl.map(i => i.answer));
+      quest.option.map(i => {
+        let r = mid.filter(f => f == i.opname);
+        i.value = r.length || 0;
+        return i;
+      });
+      return quest;
+    },
+    //具体数据部分
+    getConcreteData(quests, answers) {
+      let dquests = _.cloneDeep(quests);
+      let danswers = _.cloneDeep(answers);
+      danswers.map(i => {
+        i.answers = i.answers.map(answer => {
+          let r = quests.find(f => f._id == answer.questionid);
+          if (r) {
+            answer.topic = r.topic;
+            answer.type = r.type;
+          }
+          return answer;
+        });
+        return i;
+      });
+      return danswers;
+    },
+    toReturns() {
+      window.history.go(-1);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    id() {
+      return this.$route.query.id;
+    },
+    querys() {
+      return this.$route.query;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 58 - 75
src/views/classes/completion.vue

@@ -1,24 +1,19 @@
 <template>
   <div id="completion">
-    <detail-frame :title="mainTitle" :returns="toreturn">
-      <!-- <el-alert :title="`进度:${student.answertotal || 0}/${student.alltotal || 0}`" :closable="false"></el-alert> -->
-      <self-cards title="问卷列表" v-if="views === `quest`">
-        <dataTable :fields="questFields" :data="questList" :opera="opera" @view="data => toView(data, 'term')"></dataTable>
-      </self-cards>
-      <self-cards title="班级进度" :returns="toReturns" v-else>
-        <el-alert :title="`进度:${student.answertotal || 0}/${student.alltotal || 0}`" :closable="false"></el-alert>
-        <dataTable :fields="fields" :data="student.list" :opera="[]"></dataTable>
+    <detail-frame :title="pageTitle" :returns="toreturn">
+      <self-cards title="问卷列表">
+        <data-table :fields="fields" :data="list" :opera="opera" @data="toData" :usePage="false"></data-table>
       </self-cards>
     </detail-frame>
   </div>
 </template>
 
 <script>
-import dataTable from '@frame/components/data-table';
+import dataTable from '@frame/components/filter-page-table';
 import detailFrame from '@frame/layout/admin/detail-frame';
 import selfCards from '@frame/parts/cards';
 import _ from 'lodash';
-import { createNamespacedHelpers } from 'vuex';
+import { mapState, createNamespacedHelpers } from 'vuex';
 const { mapActions: completion } = createNamespacedHelpers('completion');
 const { mapActions: classes } = createNamespacedHelpers('classes');
 const { mapActions: termquest } = createNamespacedHelpers('termquest');
@@ -26,81 +21,52 @@ const { mapActions: questionnaire } = createNamespacedHelpers('questionnaire');
 const { mapActions: util } = createNamespacedHelpers('util');
 
 export default {
-  metaInfo: { title: '问卷进度查看' },
+  metaInfo: { title: '问卷统计' },
   name: 'completion',
   props: {},
   components: { detailFrame, dataTable, selfCards },
   data: () => ({
-    views: 'quest',
-    fields: [
-      { label: '姓名', prop: 'name' },
-      { label: '进度', prop: 'completion' },
-    ],
-    classes: {},
-    questFields: [
-      { label: '标题', prop: 'name' },
-      { label: '类型', prop: 'type', format: i => (i == 0 ? '常用问卷' : '非常用问卷') },
-    ],
-    questList: [],
-    quest: [],
     opera: [
       {
-        label: '查看',
-        icon: 'el-icon-view',
-        method: 'view',
+        label: '查看结果',
+        method: 'data',
       },
     ],
-    student: {
-      list: [],
-    },
+    fields: [
+      { label: '问卷标题', prop: 'name' },
+      { label: '问卷类型', prop: 'type', format: i => (i == '0' ? '常用问卷' : i == '1' ? '非常用问题' : '教师问卷') },
+    ],
+    filFields: [
+      { label: '问卷名', model: 'name' },
+      { label: '问卷序号', model: 'id' },
+    ],
+    list: [],
+    options: undefined,
+    total: 0,
   }),
 
-  created() {
-    this.search();
-  },
+  created() {},
   methods: {
-    ...completion({ getCompletion: 'query' }),
-    ...classes({ getClass: 'fetch' }),
-    ...termquest({ getTermQuestList: 'query' }),
-    ...questionnaire({ getQuestionnaireList: 'query', allFetch: 'mergeRequest' }),
     ...util({ modelFetch: 'fetch' }),
-    async search() {
-      //查询班级信息,获得期,批次
-      let res = await this.getClass(this.id);
+    ...questionnaire(['query', 'delete']),
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      let termid = _.get(this.defaultOption, 'termid');
+      if (!termid) return;
+      let unusaul = await this.modelFetch({ model: 'termquest', termid });
+      let uqlist = []; //非常用问卷
+      let usual = []; //常用问卷
+      if (this.$checkRes(unusaul)) uqlist = unusaul.data.questionnaireid;
+      let res = await this.query({ ...info });
       if (this.$checkRes(res)) {
-        this.$set(this, `classes`, res.data);
+        usual = res.data.filter(i => i.type == 0 && i.status == 1);
+        let nqulist = res.data.filter(i => i.status == 1 && _.includes(uqlist, i._id));
+        let rlist = [...nqulist, ...usual];
+        this.$set(this, `list`, rlist);
       }
-      let ql = [];
-      //查询所有问卷
-      const quest = await this.getQuestionnaireList({ type: 0 });
-      if (this.$checkRes(quest)) {
-        ql = ql.concat(quest.data);
-        // this.$set(this, `quest`, quest.data);
-      }
-      //查询这期的所有问卷,id=>数据
-      let rql = await this.modelFetch({ model: 'termquest', termid: this.classes.termid });
-      if (this.$checkRes(rql)) {
-        let ids = _.get(rql.data, `questionnaireid`);
-        if (ids) {
-          let questList = await this.allFetch({ method: 'fetch', data: ids });
-          ql = ql.concat(questList);
-        }
-      }
-      this.$set(this, `questList`, ql);
     },
-    async toView({ data }, type) {
-      this.views = type;
-      let { id: questionnaireid } = data;
-      let { id: batch } = this.classes;
-      let res = await this.getCompletion({ type: '2', typeid: batch, questionnaireid });
-      if (this.$checkRes(res)) {
-        let { data: completion, answertotal, alltotal, completiontotal } = res;
-        completion = completion.map(i => {
-          i.completion.includes('NaN') ? (i.completion = '-') : '';
-          return i;
-        });
-        this.$set(this, `student`, { list: completion, answertotal, alltotal, completiontotal });
-      }
+    toData({ data }) {
+      let classid = _.get(this.defaultOption, 'classid');
+      this.$router.push({ path: './detail', query: { questionnaireid: data.id, classid } });
     },
     toReturns() {
       this.views = 'quest';
@@ -110,14 +76,31 @@ export default {
     },
   },
   computed: {
+    ...mapState(['user', 'defaultOption']),
     id() {
       return this.$route.query.id;
     },
-    mainTitle() {
-      let meta = this.$route.meta;
-      let main = meta.title || '';
-      let sub = meta.sub || '';
-      return `${main}${sub}`;
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  watch: {
+    defaultOption: {
+      immediate: true,
+      deep: true,
+      handler(val) {
+        if (!_.get(this, 'options')) {
+          this.$set(this, `options`, _.cloneDeep(val));
+          this.search();
+        } else {
+          let ntermid = _.get(val, 'termid');
+          let otermid = _.get(this.options, 'termid');
+          if (ntermid && !_.isEqual(ntermid, otermid)) {
+            this.$set(this, `options`, _.cloneDeep(val));
+            this.search();
+          }
+        }
+      },
     },
   },
 };

+ 1 - 1
src/views/classes/leave.vue

@@ -1,6 +1,6 @@
 <template>
   <div id="leave">
-    <listFrame :title="pageTitle" @query="search" :total="total" :needFilter="false" :returns="toreturn" :needAdd="false">
+    <listFrame :title="pageTitle" @query="search" :total="total" :needFilter="false" :needAdd="false">
       <leaveInfo :tableData="tableData"></leaveInfo>
     </listFrame>
   </div>

+ 165 - 0
src/views/classes/print.vue

@@ -0,0 +1,165 @@
+<template>
+  <div id="print">
+    <listFrame :title="pageTitle" :needFilter="false" :needPag="false" :needAdd="false">
+      <el-tabs v-model="active" type="border-card" stretch @tab-click="tabChange">
+        <el-tab-pane label="打印名签" name="name" :lazy="true">
+          <el-row type="flex" align="middle" justify="center" v-loading="loading">
+            <el-col :span="18" style="padding-left:100px; min-height:500px">
+              <name-card :list="studList"></name-card>
+            </el-col>
+          </el-row>
+        </el-tab-pane>
+        <el-tab-pane label="打印证书" name="cert" :lazy="true">配置管理</el-tab-pane>
+        <el-tab-pane label="打印报道表" name="sign" :lazy="true">
+          <sign-card v-loading="loading" :list="studList"></sign-card>
+        </el-tab-pane>
+        <el-tab-pane label="打印班级课表" name="lesson" :lazy="true">
+          <lesson-table v-loading="loading" :data="classInfo" :th="lth" :tr="ltr" :lessons="lessons"></lesson-table>
+        </el-tab-pane>
+      </el-tabs>
+    </listFrame>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import axios from 'axios';
+import listFrame from '@frame/layout/admin/list-frame';
+import signCard from '@frame/parts/print/print-sign';
+import nameCard from '@frame/parts/print/namCard.vue';
+import certCard from '@frame/parts/print/certCard.vue';
+import lessonTable from '@frame/parts/time-table.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: classes } = createNamespacedHelpers('classes');
+const { mapActions: trainplan } = createNamespacedHelpers('trainplan');
+const { mapActions: student } = createNamespacedHelpers('student');
+const { mapActions: util } = createNamespacedHelpers('util');
+const { mapActions: location } = createNamespacedHelpers('location'); //地点
+const { mapActions: teacher } = createNamespacedHelpers('teacher'); //教师
+const { mapActions: director } = createNamespacedHelpers('director'); //教师
+export default {
+  name: 'print',
+  props: {},
+  components: { listFrame, nameCard, signCard, lessonTable },
+  data: function() {
+    return {
+      active: 'name',
+      loading: false,
+      studList: [],
+      classInfo: {},
+      lth: [], //table表头
+      ltr: [], //table y轴
+      lessons: [], //原始课表,取出来什么样就什么样
+    };
+  },
+  created() {},
+  methods: {
+    ...trainplan({ planfetch: 'fetch' }),
+    ...classes({ classesquery: 'query', getClass: 'fetch' }),
+    ...student({ getStudentList: 'query' }),
+    ...util({ modelFetch: 'fetch' }),
+    ...location({ getLocation: 'fetch' }),
+    ...teacher({ getTeacher: 'fetch' }),
+    ...director({ getDirector: 'fetch' }),
+    tabChange() {
+      if (this.active == 'name') this.nameList();
+      if (this.active == 'sign') this.signList();
+      if (this.active == 'lesson') this.classLesson();
+    },
+    async nameList() {
+      this.loading = true;
+      let res = await this.getStudentList({ classid: this.id });
+      if (this.$checkRes(res)) this.$set(this, `studList`, res.data);
+      this.loading = false;
+    },
+    async signList() {
+      this.loading = true;
+      let res = await this.getStudentList({ classid: this.id });
+      if (this.$checkRes(res)) this.$set(this, `studList`, res.data);
+      this.loading = false;
+    },
+    async classLesson() {
+      this.loading = true;
+      let classInfo = {};
+      let cir = await this.getClass(this.id);
+      if (!this.$checkRes(cir)) return;
+      classInfo = cir.data;
+      let res = await this.modelFetch({ model: 'lesson', classid: this.id });
+      if (this.$checkRes(res)) {
+        let { lessons } = res.data;
+        let { x, y } = this.proLesson(lessons);
+        this.$set(this, `lth`, x);
+        this.$set(this, `ltr`, y);
+        this.$set(this, `lessons`, lessons);
+        classInfo = await this.getRemarkParts(classInfo);
+        this.$set(this, `classInfo`, classInfo);
+      }
+      this.loading = false;
+    },
+
+    proLesson(data) {
+      let duplicate = _.cloneDeep(data);
+      let x = _.uniq(_.orderBy(duplicate, 'date', 'asc').map(i => i.date));
+      let y = _.uniq(_.orderBy(duplicate, 'time', 'asc').map(i => i.time));
+      return { x, y };
+    },
+    async getRemarkParts(data) {
+      let { headteacherid, jslocationid, lyteacherid } = data;
+      let aArr = [];
+      aArr.push(this.getDirector(headteacherid));
+      aArr.push(this.getLocation(jslocationid));
+      axios.all(aArr).then(
+        axios.spread((r1, r2) => {
+          if (r1 && r1.errcode == 0) data.headteacher = r1.data.name;
+          if (r2 && r2.errcode == 0) data.jslocation = r2.data.name;
+        })
+      );
+      let check = data => {
+        if (!data || data.errcode != 0) return false;
+        let obj = _.get(data, `data`);
+        if (!obj) return false;
+        return obj.name;
+      };
+      //单独处理礼仪教师,因为数据可能从2个表来
+      let res = await this.getDirector(lyteacherid);
+      let name = check(res);
+      if (name) data.lyteacher = name;
+      else res = await this.getTeacher(lyteacherid);
+      name = check(res);
+      if (name) data.lyteacher = name;
+      return data;
+    },
+  },
+  computed: {
+    ...mapState(['user', 'defaultOption']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    id() {
+      return this.defaultOption.classid;
+    },
+  },
+  watch: {
+    id: {
+      handler(val) {
+        if (val) {
+          this.tabChange();
+        } else {
+          this.studList = [];
+          this.classInfo = [];
+          this.lth = [];
+          this.ltr = [];
+          this.lessons = [];
+        }
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 93 - 0
src/views/classes/score.vue

@@ -0,0 +1,93 @@
+<template>
+  <div id="score">
+    <list-frame title="学生成绩查看" @query="search" :total="total" :needFilter="false" :needAdd="false">
+      <data-table :fields="fields" :data="list" :opera="opera" @viewtask="viewtask"> </data-table>
+    </list-frame>
+    <el-dialog title="学生作业" :visible.sync="dialog">
+      <data-table :fields="taskfields" :data="tasklist"> </data-table>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import listFrame from '@frame/layout/admin/list-frame';
+import dataTable from '@frame/components/data-table';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: student } = createNamespacedHelpers('student');
+const { mapActions: trainplan } = createNamespacedHelpers('trainplan');
+const { mapActions: classes } = createNamespacedHelpers('classes');
+const { mapActions: group } = createNamespacedHelpers('group');
+const { mapActions: uploadtask } = createNamespacedHelpers('uploadtask');
+export default {
+  name: 'score',
+  props: {},
+  components: { listFrame, dataTable },
+  data: function() {
+    return {
+      fields: [
+        { label: '学生姓名', prop: 'name' },
+        { label: '个人分', prop: 'selfscore' },
+        { label: '总分', prop: 'score' },
+        { label: '小组分', prop: 'groupscore' },
+      ],
+      opera: [
+        {
+          label: '查看学生作业',
+          icon: 'el-icon-view',
+          method: 'viewtask',
+        },
+      ],
+      form: {},
+      list: [],
+      total: 0,
+      dialog: false,
+      taskfields: [
+        { label: '科目名称', prop: 'lessonname' },
+        { label: '科目成绩', prop: 'score' },
+      ],
+      tasklist: [],
+    };
+  },
+  created() {},
+  methods: {
+    ...trainplan({ planfetch: 'fetch' }),
+    ...classes({ classesquery: 'query' }),
+    ...student({ stuquery: 'query', findscore: 'findscore' }),
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      const res = await this.findscore({ skip, limit, termid: this.form.termid, classid: this.form.classid, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `total`, res.total);
+        this.$set(this, `list`, res.data);
+      }
+    },
+    async viewtask({ data }) {
+      this.dialog = true;
+      this.$set(this, `tasklist`, data.tasks);
+    },
+  },
+  computed: {
+    ...mapState(['user', 'defaultOption']),
+    id() {
+      return this.defaultOption.classid;
+    },
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  watch: {
+    id: {
+      handler(val) {
+        if (val) this.search();
+        else this.$set(this, `list`, []);
+      },
+      immediate: true,
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>