liuyu 4 년 전
부모
커밋
6adaed0a94

+ 46 - 0
app/controller/.question.js

@@ -0,0 +1,46 @@
+module.exports = {
+  create: {
+    requestBody: [
+      '!type',
+      '!topic',
+      'status',
+      'option'
+    ]
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete'
+  },
+  update: {
+    params: ['!id'],
+    requestBody: [
+      'type',
+      'topic',
+      'status',
+      'option'
+    ]
+  },
+  show: {
+    parameters: {
+      params: ['!id']
+    },
+    service: 'fetch'
+  },
+  index: {
+    parameters: {
+      query: {
+        type:'type',
+        topic:'topic',
+        status :'status',
+        option :'option'
+      }
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true
+    }
+  },
+};

+ 45 - 0
app/controller/.uploadquestion.js

@@ -0,0 +1,45 @@
+module.exports = {
+  create: {
+    requestBody: [
+      "roomid",
+      "!userid",
+      "!questionnaireid",
+      "answers",
+    ],
+  },
+  destroy: {
+    params: ["!id"],
+    service: "delete",
+  },
+  update: {
+    params: ["!id"],
+    requestBody: [
+      "roomid",
+      "userid",
+      "questionnaireid",
+      "answers",
+    ],
+  },
+  show: {
+    parameters: {
+      params: ["!id"],
+    },
+    service: "fetch",
+  },
+  index: {
+    parameters: {
+      query: {
+        roomid: "roomid",
+        userid: "userid",
+        questionnaireid:"questionnaireid"
+      },
+    },
+    service: "query",
+    options: {
+      query: ["skip", "limit"],
+      sort: ["meta.createdAt"],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 19 - 0
app/controller/question.js

@@ -0,0 +1,19 @@
+'use strict';
+
+const _ = require('lodash');
+const Controller = require('egg').Controller;
+const meta = require('./.question.js');
+const { CrudController } = require('naf-framework-mongoose/lib/controller');
+
+// 科目管理
+class QusetionController extends Controller {
+
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.question;
+  }
+
+
+}
+
+module.exports = CrudController(QusetionController, meta);

+ 53 - 0
app/controller/questionnaire.js

@@ -0,0 +1,53 @@
+'use strict';
+
+const _ = require('lodash');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose/lib/controller');
+
+// 科目管理
+class QuestionnaireController extends Controller {
+
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.questionnaire;
+  }
+
+  // POST
+  // 新建问卷
+  async create() {
+    const res = await this.service.create(this.ctx.request.body);
+    this.ctx.ok({ msg: 'created', data: res });
+  }
+
+  // POST
+  // 根据id删除问卷
+  async delete() {
+    const { id } = this.ctx.params;
+    await this.service.delete({ id });
+    this.ctx.ok({ msg: 'deleted' });
+  }
+
+  // POST
+  // 根据id更新信息
+  async update() {
+    await this.service.update(this.ctx.params, this.ctx.request.body);
+    this.ctx.ok({ msg: 'accepted' });
+  }
+
+  // GET
+  // 查询
+  async query() {
+    const res = await this.service.query(this.ctx.query);
+    this.ctx.ok({ ...res });
+  }
+
+  // GET
+  // 查询详情
+  async show() {
+    const res = await this.service.show(this.ctx.params);
+    this.ctx.ok({ msg: 'queried', data: res });
+  }
+
+}
+
+module.exports = QuestionnaireController;

+ 29 - 0
app/controller/uploadquestion.js

@@ -0,0 +1,29 @@
+'use strict';
+
+const _ = require('lodash');
+const meta = require('./.uploadquestion.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose/lib/controller');
+
+// 学生上传问卷管理
+class UploadquestionController extends Controller {
+
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.uploadquestion;
+  }
+
+  // 完成度查询
+  async completion() {
+    const res = await this.service.completion(this.ctx.query);
+    this.ctx.ok({ ...res });
+  }
+
+  async index() {
+    const res = await this.service.query(this.ctx.query);
+    this.ctx.ok({ ...res });
+  }
+
+}
+
+module.exports = CrudController(UploadquestionController, meta);

+ 26 - 0
app/model/question.js

@@ -0,0 +1,26 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+
+// 选项详情
+const optionInfo = new Schema({
+  number: { type: String, required: false, maxLength: 200 }, // 序号
+  opname: { type: String, required: false, maxLength: 200 }, // 名称
+});
+
+// 问卷题库表
+const questionSchema = {
+  type: { type: String, required: true, maxLength: 200 }, // 类型,0-单选,1-多选,2-问答
+  topic: { type: String, required: true, maxLength: 500 }, // 题目
+  status: { type: String, required: false, maxLength: 200 }, // 状态,0-弃用,1-正常
+  option: { type: [ optionInfo ], select: true }, // 选项
+};
+
+const schema = new Schema(questionSchema, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.plugin(metaPlugin);
+
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Question', schema, 'question');
+};

+ 38 - 0
app/model/questionnaire.js

@@ -0,0 +1,38 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+
+
+// 选项详情
+const optionInfo = new Schema({
+  number: { type: String, required: false, maxLength: 200 }, // 序号
+  opname: { type: String, required: false, maxLength: 200 }, // 名称
+});
+
+// 问卷题
+const questionInfo = {
+  type: { type: String, required: true, maxLength: 200 }, // 类型,0-单选,1-多选,2-问答
+  topic: { type: String, required: true, maxLength: 500 }, // 题目
+  status: { type: String, required: false, maxLength: 200 }, // 状态,0-弃用,1-正常
+  option: { type: [ optionInfo ], select: true }, // 选项
+};
+
+// 问卷表
+const QuestionnaireSchema = {
+  name: { type: String, required: true, maxLength: 200 }, // 问卷名称
+  num: { type: String, required: true, maxLength: 200 }, // 序号
+  type: { type: String, required: true, maxLength: 200 }, // 类型,0-常用问卷,1-非常用问卷,2-教师问卷
+  status: { type: String, required: true, maxLength: 200, default: '0' }, // 状态,0-草稿,1-发布,2-禁用
+  question: { type: [ questionInfo ], required: false, select: true }, // 问卷
+};
+
+
+const schema = new Schema(QuestionnaireSchema, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ type: 1 });
+schema.plugin(metaPlugin);
+
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Questionnaire', schema, 'questionnaire');
+};

+ 29 - 0
app/model/uploadquestion.js

@@ -0,0 +1,29 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+
+// 答案详情
+const answerInfo = new Schema({
+  questionid: { type: String, required: false, maxLength: 200 }, // 问题id
+  answer: { type: String, required: false, maxLength: 200 }, // 答案
+});
+
+// 学生上传问卷表
+const UploadquestionSchema = {
+  roomid: { type: String, required: true, maxLength: 200 }, // 计划id
+  userid: { type: String, required: true, maxLength: 200 }, // 学生id
+  questionnaireid: { type: String, required: false, maxLength: 200 }, // 问卷id
+  answers: { type: [ answerInfo ], select: true }, // 选项
+};
+
+
+const schema = new Schema(UploadquestionSchema, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ roomid: 1 });
+schema.index({ userid: 1 });
+schema.plugin(metaPlugin);
+
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Uploadquestion', schema, 'uploadquestion');
+};

+ 15 - 0
app/router.js

@@ -41,6 +41,21 @@ module.exports = app => {
   router.resources('lookrecord', '/api/onlive/lookrecord', controller.lookrecord); // index、create、show、destroy
   router.post('lookrecord', '/api/onlive/lookrecord/update/:id', controller.lookrecord.update);
 
+  // 问卷题库表配置路由
+  router.resources('question', '/api/onlive/question', controller.question); // index、create、show、destroy
+  router.post('question', '/api/onlive/question/update/:id', controller.question.update);
+
+  // 问卷表配置路由
+  router.post('questionnaire', '/api/onlive/questionnaire', controller.questionnaire.create);
+  router.delete('questionnaire', '/api/onlive/questionnaire/:id', controller.questionnaire.delete);
+  router.post('questionnaire', '/api/onlive/questionnaire/update/:id', controller.questionnaire.update);
+  router.get('questionnaire', '/api/onlive/questionnaire', controller.questionnaire.query);
+  router.get('questionnaire', '/api/onlive/questionnaire/show/:id', controller.questionnaire.show);
+
+  // 学生上传问卷表设置路由
+  router.get('/api/onlive/uploadquestion/completion', controller.uploadquestion.completion); // 统计完成度
+  router.resources('uploadquestion', '/api/onlive/uploadquestion', controller.uploadquestion); // index、create、show、destroy
+  router.post('uploadquestion', '/api/onlive/uploadquestion/update/:id', controller.uploadquestion.update);
 
   // 用户登录
   router.post('/api/onlive/login', controller.login.login);

+ 18 - 0
app/service/question.js

@@ -0,0 +1,18 @@
+'use strict';
+
+
+const assert = require('assert');
+const _ = require('lodash');
+const { ObjectId } = require('mongoose').Types;
+const { CrudService } = require('naf-framework-mongoose/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+class QuestionService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'question');
+    this.model = this.ctx.model.Question;
+  }
+
+}
+
+module.exports = QuestionService;

+ 75 - 0
app/service/questionnaire.js

@@ -0,0 +1,75 @@
+'use strict';
+
+
+const assert = require('assert');
+const _ = require('lodash');
+const { ObjectId } = require('mongoose').Types;
+const { CrudService } = require('naf-framework-mongoose/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+class QuestionnaireService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'qusetionnaire');
+    this.questionnairemodel = this.ctx.model.Questionnaire;
+    this.questionmodel = this.ctx.model.Question;
+  }
+
+  // 插入问卷
+  async create(data) {
+    const { name, num, type, question } = data;
+    assert(name, '问卷名称不能为空');
+    assert(num, '问卷序号不能为空');
+    assert(type, '问卷类型不能为空');
+    const quedata = [];
+    for (const elm of question) {
+      const ques = await this.questionmodel.findById(elm);
+      if (ques) {
+        quedata.push(ques);
+      }
+    }
+    data.question = quedata;
+    return await this.questionnairemodel.create(data);
+  }
+
+  // 根据id删除问卷
+  async delete({ id }) {
+    await this.questionnairemodel.findByIdAndDelete(id);
+    return 'deleted';
+  }
+
+  // 根据id更新问卷信息
+  async update({ id }, data) {
+    const { name, num, type, question } = data;
+    const questionnaire = await this.questionnairemodel.findById(id);
+    if (name) {
+      questionnaire.name = name;
+    }
+    if (num) {
+      questionnaire.num = num;
+    }
+    if (type) {
+      questionnaire.type = type;
+    }
+    if (question) {
+      questionnaire.question = question;
+    }
+    return await questionnaire.save();
+  }
+
+  // 查询
+  async query({ skip, limit, ...num }) {
+    const total = await this.questionnairemodel.count(num);
+    const data = await this.questionnairemodel.find(num).skip(Number(skip)).limit(Number(limit));
+    const result = { total, data };
+    return result;
+  }
+
+  // 查询详情
+  async show({ id }) {
+    const questionnaire = await this.questionnairemodel.findById(id);
+    return questionnaire;
+  }
+
+}
+
+module.exports = QuestionnaireService;

+ 101 - 0
app/service/uploadquestion.js

@@ -0,0 +1,101 @@
+'use strict';
+
+
+const assert = require('assert');
+const _ = require('lodash');
+const { ObjectId } = require('mongoose').Types;
+const { CrudService } = require('naf-framework-mongoose/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+class UploadquestionService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'uploadquestion');
+    this.model = this.ctx.model.Uploadquestion;
+    this.umodel = this.ctx.model.Roomuser;
+  }
+
+  // 完成度查询
+  async completion(data) {
+    const { type, typeid, trainplanid, questionnaireid } = data;
+    assert(type && typeid && questionnaireid, '缺少部分信息项');
+    const datas = [];
+    let answertotal = '';
+    let alltotal = '';
+    // 如果是期查询
+    if (type === '0') {
+      const trainplan = await this.tmodel.findById(trainplanid);
+      const term = await trainplan.termnum.id(typeid);
+      const batchs = await term.batchnum;
+      for (const batch of batchs) {
+        // 取得当前期学生总数
+        const allcount = await this.smodel.count({ batchid: batch.id });
+        // 取得当前期学生答问卷数
+        const answercount = await this.model.count({ batchid: batch.id, questionnaireid });
+        let completion = (answercount / allcount * 100).toFixed(2);
+        completion = completion + '%';
+        const newdata = { id: batch.id, name: batch.name, allcount, answercount, completion };
+        datas.push(newdata);
+      }
+      // 取得当前期学生总数
+      alltotal = await this.smodel.count({ termid: typeid });
+      // 取得当前期学生答问卷数
+      answertotal = await this.model.count({ termid: typeid, questionnaireid });
+    } else if (type === '1') {
+      const classs = await this.cmodel.find({ batchid: typeid });
+      for (const elm of classs) {
+        // 取得当前期学生总数
+        const allcount = await this.smodel.count({ classid: elm.id });
+        // 取得当前期学生答问卷数
+        const answercount = await this.model.count({ classid: elm.id, questionnaireid });
+        let completion = (answercount / allcount * 100).toFixed(2);
+        completion = completion + '%';
+        const newdata = { id: elm.id, name: elm.name, allcount, answercount, completion };
+        datas.push(newdata);
+      }
+      // 取得当前期学生总数
+      alltotal = await this.smodel.count({ batchid: typeid });
+      // 取得当前期学生答问卷数
+      answertotal = await this.model.count({ batchid: typeid, questionnaireid });
+    } else if (type === '2') {
+      // 取得当前期学生总数
+      const stus = await this.smodel.find({ classid: typeid });
+      for (const elm of stus) {
+        // 取得当前期学生答问卷数
+        const answer = await this.model.findOne({ studentid: elm.id, questionnaireid });
+        let completion = '';
+        if (answer) {
+          completion = '100%';
+        } else {
+          completion = '0%';
+        }
+        const newdata = { id: elm.id, name: elm.name, completion };
+        datas.push(newdata);
+      }
+      // 取得当前期学生总数
+      alltotal = await this.smodel.count({ classid: typeid });
+      // 取得当前期学生答问卷数
+      answertotal = await this.model.count({ classid: typeid, questionnaireid });
+
+    }
+    let completiontotal = (answertotal / alltotal * 100).toFixed(2);
+    completiontotal = completiontotal + '%';
+    const newdata = { data: datas, answertotal, alltotal, completiontotal };
+    return newdata;
+  }
+
+  async query({ skip, limit, ...info }) {
+    const total = await this.model.count(info);
+    const res = await this.model.find(info).skip(Number(skip)).limit(Number(limit));
+    const data = [];
+    for (const _res of res) {
+      const elm = _.cloneDeep(JSON.parse(JSON.stringify(_res)));
+      const stu = await this.umodel.findById(elm.userid);
+      elm.username = stu.name;
+      data.push(elm);
+    }
+    return { data, total };
+  }
+
+}
+
+module.exports = UploadquestionService;