'use strict'; const Service = require('../core/base_service'); const { Op } = require('sequelize'); const fileName = "Exam"; class ExamService extends Service { // 学生获取历史消息 async getHistoryMsg(uid, body) { const { ctx } = this; try { let { offset, limit, searchOptions, sortOptions } = body; offset = (offset - 1) * limit; let attributes = ['id', 'card_id', 'encode_type', 'msg_data', 'created_at'], where = { user_uid: uid }, order = [], dbOptions, joinSubstring = [], substring = ['card_id', 'msg_data'], key = ['encode_type'], between = ['created_at']; attributes.forEach(element => { if (searchOptions[element]) { if (searchOptions[element] == '*空') { if (joinSubstring.includes(element)) { where[element] = null; } else { where[element] = [null, '']; } } else if (substring.includes(element)) { where[element] = { [Op.substring]: searchOptions[element] }; } else if (key.includes(element)) { where[element] = searchOptions[element] == "1" ? true : false; } else if (between.includes(element)) { where[element] = { [Op.between]: [searchOptions[element][0], searchOptions[element][1]] }; } } if (sortOptions[element] == true) { order.push([element, 'ASC']); } else if (sortOptions[element] == false) { order.push([element, 'DESC']); } }); dbOptions = { attributes, offset, limit, where, order }; const result = await ctx.model4.TShortMsg.findAndCountAll(dbOptions); return result.rows.length == 0 ? false : result; } catch (error) { const blockName = fileName + "--" + "getHistoryMsg"; ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error); return 'error'; } } // 学生删除历史消息 async delHistoryMsg(uid, modelType, password, requestMsg) { const { ctx } = this; try { const result = await ctx.model4.Account.findOne({ where: { uid } }); if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) return false; let where = {}; if (modelType == "single") { const { card_id, encode_type, msg_data, origin_time } = requestMsg; where = { user_uid: uid, card_id, encode_type, msg_data, created_at: origin_time }; } else if (modelType == "multiple") { let card_id = [], encode_type = [], msg_data = [], created_at = []; for (const key in requestMsg) { requestMsg[key].forEach(element => { card_id.push(element.card_id), encode_type.push(element.encode_type), msg_data.push(element.msg_data), created_at.push(element.origin_time) }); } where = { user_uid: uid, card_id, encode_type, msg_data, created_at }; } else if (modelType == "all") { where = { user_uid: uid }; } const resetList = await ctx.model4.TShortMsg.destroy({ where }); return resetList.length == 0 ? false : resetList; } catch (error) { const blockName = fileName + "--" + "delHistoryMsg"; ctx.app.middleware.utils.log('../../../serviceLog', blockName + ">>>>" + error); return 'error'; } } // 学生完成答题 async answer(uid, body) { const { ctx } = this; try { // 根据 updated_at 来判断是否已经完成过答题,确保只能提交一次答题,如果已经完成答题则不允许再次提交答案 const userExam = await ctx.model4.Examination.findOne({ attributes: ['topic1', 'topic2', 'topic3', 'topic5'], where: { user_uid: uid, updated_at: null } }); if (!userExam) return false; // 根据答案进行评分 const shortMsg = await ctx.model4.TShortMsg.findAll({ attributes: ['id', 'msg_data'], where: { user_uid: uid } }); if (shortMsg.length == 0) return false; const { answer1, answer2, answer3, answer4, answer5 } = body; const answerObj = {}; const answerArr = [answer1, answer2, answer3, answer4, answer5]; shortMsg.forEach(element => { if (element.dataValues.id == answer1) { if (element.dataValues.msg_data.length > 2) { answerObj.answer1 = element.dataValues.msg_data.slice(0, 2); } else { answerObj.answer1 = element.dataValues.msg_data; } } if (element.dataValues.id == answer2) { if (element.dataValues.msg_data.length > 2) { answerObj.answer2 = element.dataValues.msg_data.slice(0, 2); } else { answerObj.answer2 = element.dataValues.msg_data; } } if (element.dataValues.id == answer3) { if (element.dataValues.msg_data.length > 10) { answerObj.answer3 = element.dataValues.msg_data.slice(0, 10); } else { answerObj.answer3 = element.dataValues.msg_data; } } if (element.dataValues.id == answer4) { if (element.dataValues.msg_data.length > 20) { answerObj.answer4 = element.dataValues.msg_data.slice(0, 20); } else { answerObj.answer4 = element.dataValues.msg_data; } } if (element.dataValues.id == answer5) { if (element.dataValues.msg_data.length > 10) { answerObj.answer5 = element.dataValues.msg_data.slice(0, 10); } else { answerObj.answer5 = element.dataValues.msg_data; } } }); let score = 0; let scoreCollection = []; if (this.toHalfWidth(answerObj.answer1) == userExam.dataValues.topic1) { score = score + 1; scoreCollection.push(1); } else { scoreCollection.push(0); } if (this.toHalfWidth(answerObj.answer2) == userExam.dataValues.topic2) { score = score + 1; scoreCollection.push(1); } else{ scoreCollection.push(0); } let topic3Arr = userExam.dataValues.topic3.split(","); const radioAnswer = await ctx.model4.ChoiceTopic.findAll({ attributes: ['id', 'answer'], where: { id: topic3Arr } }); if (radioAnswer.length == 0) return false; let answer3Str = ""; const radioAnswerObj = {}; radioAnswer.forEach(item => { radioAnswerObj[item.dataValues.id] = item.dataValues.answer; }); topic3Arr.forEach(element => { answer3Str = answer3Str + radioAnswerObj[element]; }); if (this.toHalfWidth(answerObj.answer3) == answer3Str) { score = score + 3; scoreCollection.push(1); } else { scoreCollection.push(0); } if (this.toHalfWidth(answerObj.answer4).length == 17) { const longitude = parseFloat(this.toHalfWidth(answerObj.answer4).slice(0, 3) + "." + this.toHalfWidth(answerObj.answer4).slice(3, 9)); const latitude = parseFloat(this.toHalfWidth(answerObj.answer4).slice(9, 11) + "." + this.toHalfWidth(answerObj.answer4).slice(11)); if (-180 <= longitude && longitude <= 180 && -90 <= latitude && latitude <= 90) { score = score + 3; scoreCollection.push(1); } else { scoreCollection.push(0); } } if (this.toHalfWidth(answerObj.answer5) == userExam.dataValues.topic5) { score = score + 2; scoreCollection.push(1); } else { scoreCollection.push(0); } const updateMsg = { answer: answerArr.join(","), answer1: answerObj.answer1, answer2: answerObj.answer2, answer3: answerObj.answer3, answer4: answerObj.answer4, answer5: answerObj.answer5, score, score_collection: scoreCollection.join(","), updated_at: new Date(), }; const result = await ctx.model4.Examination.update(updateMsg, { where: { user_uid: uid, updated_at: null } }); return !result[0] == 0; } catch (error) { const blockName = fileName + "--" + "answer"; ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error); return 'error'; } } // 学生查看成绩信息 async grades(uid) { const { ctx } = this; try { let include = [{ model: ctx.model4.Account, attributes: ['account_name'], }]; ctx.model4.Examination.belongsTo(ctx.model4.Account, { foreignKey: 'user_uid', targetKey: 'uid' }); const userExam = await ctx.model4.Examination.findOne({ attributes: ['score', 'score_collection', 'created_at', 'updated_at'], where: { user_uid: uid, updated_at: { [Op.ne]: null } }, include }); if (!userExam) return false; // 查找得分比当前得分高的数据数目 const higherScoresCount = await ctx.model4.Examination.findAndCountAll({ where: { score: { [Op.gt]: userExam.dataValues.score }, updated_at: { [Op.ne]: null } } }); // 查找相同得分的所有数据 const sameScores = await ctx.model4.Examination.findAndCountAll({ where: { score: userExam.dataValues.score, created_at: { [Op.lt]: userExam.dataValues.created_at }, updated_at: { [Op.ne]: null } } }); // 计算总排名(比当前得分高的数目 + 相同得分的数目 + 1(当前用户自己)) const totalRank = higherScoresCount.count + sameScores.count + 1; userExam.dataValues.totalRank = totalRank; return userExam; } catch (error) { const blockName = fileName + "--" + "grades"; ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error); return 'error'; } } } module.exports = ExamService;