北斗应用技术培训考试管理系统

This commit is contained in:
2026-03-27 17:54:10 +08:00
commit 359dff3cad
106 changed files with 9510 additions and 0 deletions

260
app/service/Admin.js Normal file
View File

@@ -0,0 +1,260 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "Admin";
class AdminService extends Service {
// 管理系统新增普通管理员账号信息
async addAdmin(form) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "addAdmin";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看普通管理员账号信息
async showAdmin(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['uid', 'account_name', 'role', 'status', 'created_at', 'updated_at', 'login_status'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['uid', 'account_name'],
key = ['role', 'status', 'login_status'],
between = ['created_at', 'updated_at'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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.model.Manager.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showAdmin";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑普通管理员账号信息
async editAdmin(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { uid, account_name, role, status } = requestMsg;
where = { uid, account_name, role, status };
} else if (modelType == "multiple") {
let uid = [], account_name = [], role = [], status = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
uid.push(element.uid);
account_name.push(element.account_name);
role.push(element.role);
status.push(element.status);
});
}
where = { uid, account_name, role, status };
}
updateMsg.updated_at = new Date();
const resultList = await ctx.model.Manager.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editAdmin";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除普通管理员账号信息
async deleteAdmin(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除用户账号信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { uid, account_name, role, status } = requestMsg;
where = { uid, account_name, role, status };
} else if (modelType == "multiple") {
let uid = [], account_name = [], role = [], status = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
uid.push(element.uid);
account_name.push(element.account_name);
role.push(element.role);
status.push(element.status);
});
}
where = { uid, account_name, role, status };
}
const resultList = await ctx.model.Manager.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteAdmin";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出普通管理员账号信息数据
async downloadAdminData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['uid', 'account_name', 'role', 'status', 'created_at', 'updated_at', 'login_status'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['uid', 'account_name'],
key = ['role', 'status', 'login_status'],
between = ['created_at', 'updated_at'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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, where, order };
const result = await ctx.model.Manager.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const roleOptions = [
{
value: "9",
label: "系统管理员"
},
{
value: "0",
label: "临时管理员"
},
{
value: "1",
label: "普通管理员"
},
{
value: "2",
label: "高级管理员"
},
];
const statusOptions = [
{
value: "0",
label: "默认状态"
},
{
value: "1",
label: "正常使用"
},
{
value: "2",
label: "已被弃用"
},
];
result.forEach(element => {
roleOptions.forEach((item) => {
if (item.value == element.dataValues["role"]) {
element.dataValues["role"] = item.label;
}
});
statusOptions.forEach((item) => {
if (item.value == element.dataValues["status"]) {
element.dataValues["status"] = item.label;
}
});
element.dataValues.created_at = moment
.utc(element.dataValues.created_at)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
element.dataValues.updated_at = moment
.utc(element.dataValues.updated_at)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
delete element.dataValues.login_status;
data.push(element.dataValues);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadAdminData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = AdminService;

483
app/service/Application.js Normal file
View File

@@ -0,0 +1,483 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "Application";
class ApplicationService extends Service {
// 管理系统新增用户报名信息
async addApplication(userMsgObj, form) {
const { ctx } = this;
try {
let attributes = ['uid', 'user_name', 'identity_card'],
where = userMsgObj,
dbOptions = { attributes, where };
const userUid = await ctx.model.Examinee.findAll(dbOptions);
if(userUid.length == 0) {
let errorForm = [];
form.forEach(item => {
errorForm.push({
user_name: item.user_name,
identity_card: item.identity_card,
exam_uid: item.exam_uid,
type: 0,
status: 0,
created_at: new Date()
});
});
await ctx.model.Importerror.bulkCreate(errorForm);
return { code: 400 };
};
let errorMark = false;
form.forEach(async item => {
item.user_uid = 'none';
userUid.forEach(element => {
if (item.user_name == element.dataValues.user_name && item.identity_card == element.dataValues.identity_card) {
item.user_uid = element.dataValues.uid;
}
});
delete item.user_name;
delete item.identity_card;
if(item.user_uid == 'none') {
let errorForm = {
user_name: item.user_name,
identity_card: item.identity_card,
exam_uid: item.exam_uid,
type: 0,
status: 0,
created_at: new Date()
};
errorMark = true;
await ctx.model.Importerror.create(errorForm);
}
});
const result = await ctx.model.Application.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : errorMark ? { code: 300, data: result } : { code: 200, data: result };
} catch (error) {
const blockName = fileName + "--" + "addApplication";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看用户报名信息
async showApplication(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['user_uid', 'exam_uid', 'source', 'status', 'pay_status', 'result', 'created_at'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['user_uid', 'exam_uid', 'source', 'result'],
key = ['status', 'pay_status'],
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 (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let examination = ['exam_name', 'application_start', 'application_end'],
examinationWhere = {},
examinationOrder = [],
examinationJoinSubstring = [],
examinationSubstring = ['exam_name'],
examinationKey = [],
examinationBetween = ['application_start', 'application_end'];
examination.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examinationJoinSubstring.includes(item)) {
examinationWhere[item] = null;
} else {
examinationWhere[item] = [null, ''];
}
} else if (examinationSubstring.includes(item)) {
examinationWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examinationKey.includes(item)) {
examinationWhere[item] = searchOptions[item];
} else if (examinationBetween.includes(item)) {
examinationWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examinationOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examinationOrder.push([item, 'DESC']);
}
});
let examinee = ['user_name', 'identity_card', 'workplace', 'phone'],
examineeWhere = {},
examineeOrder = [],
examineeJoinSubstring = [],
examineeSubstring = ['user_name', 'identity_card', 'workplace', 'phone'],
examineeKey = [],
examineeBetween = [];
examinee.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examineeJoinSubstring.includes(item)) {
examineeWhere[item] = null;
} else {
examineeWhere[item] = [null, ''];
}
} else if (examineeSubstring.includes(item)) {
examineeWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examineeKey.includes(item)) {
examineeWhere[item] = searchOptions[item];
} else if (examineeBetween.includes(item)) {
examineeWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examineeOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examineeOrder.push([item, 'DESC']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card', 'workplace', 'phone'],
where: examineeWhere,
order: examineeOrder
},
{
model: ctx.model.Examination,
attributes: ['exam_name', 'application_start', 'application_end'],
where: examinationWhere,
order: examinationOrder
}
];
ctx.model.Application.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
ctx.model.Application.belongsTo(ctx.model.Examination, { foreignKey: 'exam_uid', targetKey: 'uid' });
dbOptions = { attributes, offset, limit, where, order, include };
const result = await ctx.model.Application.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showApplication";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑用户报名信息
async editApplication(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { user_uid, exam_uid, source, status, pay_status, result } = requestMsg;
where = { user_uid, exam_uid, source, status, pay_status, result };
} else if (modelType == "multiple") {
let user_uid = [], exam_uid = [], source = [], status = [], pay_status = [], result = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
user_uid.push(element.user_uid);
exam_uid.push(element.exam_uid);
source.push(element.source);
status.push(element.status);
pay_status.push(element.pay_status);
result.push(element.result);
});
}
where = { user_uid, exam_uid, source, status, pay_status, result };
}
const resultList = await ctx.model.Application.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editApplication";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除用户报名信息
async deleteApplication(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除用户账号信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { user_uid, exam_uid, source, status, pay_status, result } = requestMsg;
where = { user_uid, exam_uid, source, status, pay_status, result };
} else if (modelType == "multiple") {
let user_uid = [], exam_uid = [], source = [], status = [], pay_status = [], result = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
user_uid.push(element.user_uid);
exam_uid.push(element.exam_uid);
source.push(element.source);
status.push(element.status);
pay_status.push(element.pay_status);
result.push(element.result);
});
}
where = { user_uid, exam_uid, source, status, pay_status, result };
}
const resultList = await ctx.model.Application.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteApplication";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出考生报名信息数据
async downloadApplicationData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['user_uid', 'exam_uid', 'source', 'status', 'pay_status', 'result', 'created_at'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['user_uid', 'exam_uid', 'source', 'result'],
key = ['status', 'pay_status'],
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 (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let examination = ['exam_name', 'application_start', 'application_end'],
examinationWhere = {},
examinationOrder = [],
examinationJoinSubstring = [],
examinationSubstring = ['exam_name'],
examinationKey = [],
examinationBetween = ['application_start', 'application_end'];
examination.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examinationJoinSubstring.includes(item)) {
examinationWhere[item] = null;
} else {
examinationWhere[item] = [null, ''];
}
} else if (examinationSubstring.includes(item)) {
examinationWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examinationKey.includes(item)) {
examinationWhere[item] = searchOptions[item];
} else if (examinationBetween.includes(item)) {
examinationWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examinationOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examinationOrder.push([item, 'DESC']);
}
});
let examinee = ['user_name', 'identity_card', 'workplace', 'phone'],
examineeWhere = {},
examineeOrder = [],
examineeJoinSubstring = [],
examineeSubstring = ['user_name', 'identity_card', 'workplace', 'phone'],
examineeKey = [],
examineeBetween = [];
examinee.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examineeJoinSubstring.includes(item)) {
examineeWhere[item] = null;
} else {
examineeWhere[item] = [null, ''];
}
} else if (examineeSubstring.includes(item)) {
examineeWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examineeKey.includes(item)) {
examineeWhere[item] = searchOptions[item];
} else if (examineeBetween.includes(item)) {
examineeWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examineeOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examineeOrder.push([item, 'DESC']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card', 'workplace', 'phone'],
where: examineeWhere,
order: examineeOrder
},
{
model: ctx.model.Examination,
attributes: ['exam_name', 'application_start', 'application_end'],
where: examinationWhere,
order: examinationOrder
}
];
ctx.model.Application.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
ctx.model.Application.belongsTo(ctx.model.Examination, { foreignKey: 'exam_uid', targetKey: 'uid' });
dbOptions = { attributes, where, order, include };
const result = await ctx.model.Application.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const statusOptions = [
{
value: "0",
label: "审核中"
},
{
value: "1",
label: "报名成功"
},
{
value: "2",
label: "报名失败"
},
{
value: "3",
label: "取消报名"
},
];
const payStatusOptions = [
{
value: "0",
label: "未缴费"
},
{
value: "1",
label: "缴费成功"
},
{
value: "2",
label: "缴费失败"
},
];
result.forEach(element => {
statusOptions.forEach((item) => {
if (item.value == element.dataValues["status"]) {
element.dataValues["status"] = item.label;
}
});
payStatusOptions.forEach((item) => {
if (item.value == element.dataValues["pay_status"]) {
element.dataValues["pay_status"] = item.label;
}
});
element.dataValues.user_name = element.dataValues.examinee.dataValues.user_name;
element.dataValues.identity_card = element.dataValues.examinee.dataValues.identity_card;
element.dataValues.exam_name = element.dataValues.examination.dataValues.exam_name;
element.dataValues.created_at = moment
.utc(element.dataValues.created_at)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
element.dataValues.application_start = moment
.utc(element.dataValues.examination.dataValues.application_start)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
element.dataValues.application_end = moment
.utc(element.dataValues.examination.dataValues.application_end)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
delete element.dataValues.examinee;
delete element.dataValues.examination;
let elementClone = {
user_uid: element.dataValues.user_uid,
user_name: element.dataValues.user_name,
identity_card: element.dataValues.identity_card,
exam_uid: element.dataValues.exam_uid,
exam_name: element.dataValues.exam_name,
source: element.dataValues.source,
status: element.dataValues.status,
pay_status: element.dataValues.pay_status,
result: element.dataValues.result,
created_at: element.dataValues.created_at,
application_start: element.dataValues.application_start,
application_end: element.dataValues.application_end,
}
data.push(elementClone);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadApplicationData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = ApplicationService;

89
app/service/Audit.js Normal file
View File

@@ -0,0 +1,89 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const fileName = "Audit";
class AuditService extends Service {
// 管理系统查看用户关键信息变更
async auditList(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['uid', 'user_name', 'identity_card', 'real_check', 'workplace', 'address', 'phone', 'email', 'status', 'created_at', 'updated_at', 'login_status'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['uid', 'user_name', 'identity_card', 'workplace', 'address', 'phone', 'email'],
key = ['real_check', 'status', 'login_status'],
between = ['created_at', 'updated_at'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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 };
// 默认查询的 status 为 0,管理员可以请求其他状态的审核列表
// let status = 0;
const result = await ctx.model.Audit.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "auditList";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统审核用户关键信息变更
async userMsgAudit(uid, body) {
const { ctx } = this;
try {
console.log(uid);
console.log(body);
// const result = await ctx.model.Audit.update({ status: 1 }, { where: { status: 0, body } });
// console.log(result);
// return result[0] == 0 ? false : true;
return true;
} catch (error) {
const blockName = fileName + "--" + "userMsgAudit";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 保存导入考生报名信息和考生成绩时存在错误的数据,方便管理员查找问题
async importerror(form) {
const { ctx } = this;
try {
await ctx.model.Importerror.bulkCreate(form);
} catch (error) {
const blockName = fileName + "--" + "importerror";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = AuditService;

57
app/service/Cntev.js Normal file
View File

@@ -0,0 +1,57 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const fileName = "Cntev";
class CntevService extends Service {
// 筛选核验失败的数据
async siftFailedList(finishedList) {
const { ctx } = this;
try {
let attributes = ['user_name', 'identity_card', 'real_check'],
where = { identity_card: { [Op.notIn]: finishedList }, real_check: 2 },
dbOptions = { attributes, where };
const result = await ctx.model.Examinee.findAll(dbOptions);
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "siftFailedList";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 筛选未核验的数据
async validateList(finishedList) {
const { ctx } = this;
try {
let attributes = ['user_name', 'identity_card', 'real_check'],
where = { identity_card: { [Op.notIn]: finishedList }, real_check: 0 },
dbOptions = { attributes, where };
const result = await ctx.model.Examinee.findAll(dbOptions);
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "validateList";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 身份证二要素核验状态更新
async updateCNTEV(user_name, identity_card, real_check) {
const { ctx } = this;
try {
const where = { user_name, identity_card };
await ctx.model.Examinee.update({ real_check }, { where });
await ctx.model.Audit.update({ status: real_check }, { where });
} catch (error) {
const blockName = fileName + "--" + "CNTEV";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = CntevService;

80
app/service/Diff.js Normal file
View File

@@ -0,0 +1,80 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const fileName = "Diff";
class DiffService extends Service {
// 比较身份证号
async diffIdentityCard(identity_card, type, uid) {
const { ctx } = this;
try {
let attributes = ['identity_card'],
where = { identity_card },
dbOptions = { attributes, where };
const search = await ctx.model.Examinee.findAll(dbOptions);
if (type == 'register') {
return search.length == 0;
} else if (type == 'edit') {
where = { uid };
dbOptions = { attributes, where };
const result = await ctx.model.Examinee.findOne(dbOptions);
return result == null ? true : result.dataValues.identity_card == identity_card ? true : search.length == 0;
}
} catch (error) {
const blockName = fileName + "--" + "diffIdentityCard";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 比较邮箱
async diffEmail(email, type, uid) {
const { ctx } = this;
try {
let attributes = ['email'],
where = { email },
dbOptions = { attributes, where };
const search = await ctx.model.Examinee.findAll(dbOptions);
if (type == 'register') {
return search.length == 0;
} else if (type == 'edit') {
where = { uid };
dbOptions = { attributes, where };
const result = await ctx.model.Examinee.findOne(dbOptions);
return result == null ? true : result.dataValues.email == email ? true : search.length == 0;
}
} catch (error) {
const blockName = fileName + "--" + "diffEmail";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 比较电话号码
async diffPhone(phone, type, uid) {
const { ctx } = this;
try {
let attributes = ['phone'],
where = { phone },
dbOptions = { attributes, where };
const search = await ctx.model.Examinee.findAll(dbOptions);
if (type == 'register') {
return search.length == 0;
} else if (type == 'edit') {
where = { uid };
dbOptions = { attributes, where };
const result = await ctx.model.Examinee.findOne(dbOptions);
return result == null ? true : result.dataValues.phone == phone ? true : search.length == 0;
}
} catch (error) {
const blockName = fileName + "--" + "diffPhone";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = DiffService;

493
app/service/Download.js Normal file
View File

@@ -0,0 +1,493 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const fileName = "Download";
class DownloadService extends Service {
// 导出小鹅通导入用户
async importXiaoeTech(uid, searchMsg, importForm) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['user_uid', 'exam_uid', 'status', 'result'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['exam_uid', 'result'],
key = ['status'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card', 'workplace', 'address', 'phone', 'email'],
}
];
ctx.model.Application.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
dbOptions = { attributes, where, order, include };
const result = await ctx.model.Application.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
result.forEach(element => {
let identity_card = element.dataValues.examinee.dataValues.identity_card,
gender = parseInt(identity_card[16], 10) % 2 == 0 ? '女' : '男',
birthday = new Date(identity_card.substring(6, 14).substring(0, 4), identity_card.substring(6, 14).substring(4, 6) - 1, identity_card.substring(6, 14).substring(6, 8)),
age = new Date().getFullYear() - birthday.getFullYear();
const m = new Date().getMonth() - birthday.getMonth();
if (m < 0 || (m === 0 && new Date().getDate() < birthday.getDate())) {
age--;
}
data.push({
phone: element.dataValues.examinee.dataValues.phone,
user_name: element.dataValues.examinee.dataValues.user_name,
remark: "",
gender,
age,
birthday,
province: "",
city: "",
address: element.dataValues.examinee.dataValues.address,
email: element.dataValues.examinee.dataValues.email,
industry: "",
company: element.dataValues.examinee.dataValues.workplace,
position: "",
description: "",
tags: "",
});
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "importXiaoeTech";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 导出小鹅通开课学员
async commencementXiaoeTech(uid, searchMsg, importForm) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['user_uid', 'exam_uid', 'status', 'result'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['exam_uid', 'result'],
key = ['status'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['phone'],
}
];
ctx.model.Application.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
dbOptions = { attributes, where, order, include };
const result = await ctx.model.Application.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
result.forEach(element => {
data.push({
phone: element.dataValues.examinee.dataValues.phone,
expired_at: importForm.expired_at.replace(/_/g, ' ').replace(/:/g, ':'),
});
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "commencementXiaoeTech";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 导出批量报名导入 excel 表
async importApplicationData(uid, searchMsg, importForm) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['user_name', 'identity_card', 'workplace', 'created_at'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['workplace'],
key = [],
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 (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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, where, order };
const result = await ctx.model.Examinee.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
result.forEach(element => {
data.push({
identity_card: element.dataValues.identity_card,
user_name: element.dataValues.user_name,
exam_uid: importForm.exam_uid,
source: importForm.source,
status: "1",
pay_status: "1",
result: importForm.result
});
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "importApplicationData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 导出考试星学员导入 excel 表
async importExamStars(uid, searchMsg, importForm) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['exam_uid', 'status'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['exam_uid'],
key = ['status'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card'],
}
];
ctx.model.Application.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
dbOptions = { attributes, where, order, include };
const result = await ctx.model.Application.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
result.forEach(element => {
data.push({
account: element.dataValues.examinee.dataValues.identity_card,
password: element.dataValues.examinee.dataValues.identity_card.substr(-6),
name: element.dataValues.examinee.dataValues.user_name,
department: "",
});
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "importExamStars";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 导出培训证书发放用户导入 excel 表
async importIssuance(uid, searchMsg, importForm) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['exam_uid', 'status'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['exam_uid'],
key = ['status'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card', 'workplace', 'address', 'phone'],
}
];
ctx.model.Application.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
dbOptions = { attributes, where, order, include };
const result = await ctx.model.Application.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
result.forEach((element, index) => {
data.push({
id: index + 1,
user_name: element.dataValues.examinee.dataValues.user_name,
identity_card: element.dataValues.examinee.dataValues.identity_card,
workplace: element.dataValues.examinee.dataValues.workplace,
address: element.dataValues.examinee.dataValues.address,
phone: element.dataValues.examinee.dataValues.phone,
start: "",
end: "",
place: "",
way: "",
score: "",
certificate_name: "",
level: "",
});
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "importIssuance";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 导出培训证书发放用户照片文件夹
async importUserPhoto(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['exam_uid', 'status'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['exam_uid'],
key = ['status'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['identity_card'],
}
];
ctx.model.Application.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
dbOptions = { attributes, where, order, include };
const result = await ctx.model.Application.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
result.forEach(element => {
data.push({
identity_card: element.dataValues.examinee.dataValues.identity_card,
});
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "importUserPhoto";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 导出考试成绩导入 excel 表
async importGradesData(uid, formClone, dataType, passingScore, gradesType) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
const data = formClone.map(item => ({
user_name: item.user_name,
identity_card: item.identity_card,
exam_uid: "",
status: "",
grades: item.grades,
pass_type: "",
}));
const identityCards = data.map(item => item.identity_card);
const userNames = data.map(item => item.user_name);
const examineeUid = await ctx.model.Examinee.findAll({ attributes: ['uid', 'identity_card', 'user_name'], where: { identity_card: identityCards, user_name: userNames } });
if (examineeUid.length == 0) return { code: false };
const uidMap = new Map();
const userUids = [];
examineeUid.forEach(element => {
uidMap.set(`${element.dataValues.identity_card}_${element.dataValues.user_name}`, element.dataValues.uid);
userUids.push(element.dataValues.uid);
});
data.forEach(item => {
const key = `${item.identity_card}_${item.user_name}`;
if (uidMap.has(key)) {
item.user_uid = uidMap.get(key);
}
});
const applicationUid = await ctx.model.Application.findAll({ attributes: ['user_uid', 'exam_uid'], where: { user_uid: userUids, status: 1 }, order: [['created_at', 'DESC']], limit: userUids.length });
if (applicationUid.length == 0) return { code: false };
const applicationUidMap = new Map(applicationUid.map(item => [item.dataValues.user_uid, item.dataValues.exam_uid]));
data.forEach(item => {
if (applicationUidMap.has(item.user_uid)) {
item.exam_uid = applicationUidMap.get(item.user_uid);
}
});
const examUids = [...new Set(applicationUid.map(item => item.dataValues.exam_uid))];
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card'],
},
];
if (gradesType == '0') {
ctx.model.Application.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
const application = await ctx.model.Application.findAll({ attributes: ['user_uid', 'exam_uid'], where: { user_uid: { [Op.notIn]: userUids }, exam_uid: examUids, status: 1 }, include });
application.forEach(element => {
data.push({
identity_card: element.dataValues.examinee.dataValues.identity_card,
user_name: element.dataValues.examinee.dataValues.user_name,
user_uid: element.dataValues.user_uid,
exam_uid: element.dataValues.exam_uid,
grades: null,
});
});
}
data.forEach(item => {
delete item.user_uid;
item.status = dataType == '0' ? 1 : (item.grades == null ? 0 : 1);
item.pass_type = item.grades == null
? (dataType == '0' ? 0 : 2)
: (dataType == '1' && item.grades < passingScore ? 0 : 1);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "importGradesData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = DownloadService;

247
app/service/Exam.js Normal file
View File

@@ -0,0 +1,247 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "Exam";
class ExamService extends Service {
// 管理系统新增考试信息
async addExam(form) {
const { ctx } = this;
try {
const result = await ctx.model.Examination.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "addExam";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看考试信息
async showExam(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['uid', 'exam_name', 'status', 'application_start', 'application_end', 'exam_start', 'exam_end'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['uid', 'exam_name'],
key = ['status'],
between = ['application_start', 'application_end', 'exam_start', 'exam_end'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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.model.Examination.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showExam";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑考试信息
async editExam(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { exam_name, status, application_start, application_end, exam_start, exam_end } = requestMsg;
where = { exam_name, status, application_start, application_end, exam_start, exam_end };
} else if (modelType == "multiple") {
let exam_name = [], status = [], application_start = [], application_end = [], exam_start = [], exam_end = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
exam_name.push(element.exam_name);
status.push(element.status);
application_start.push(element.application_start);
application_end.push(element.application_end);
exam_start.push(element.exam_start);
exam_end.push(element.exam_end);
});
}
where = { exam_name, status, application_start, application_end, exam_start, exam_end };
}
const resultList = await ctx.model.Examination.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editExam";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除考试信息
async deleteExam(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除用户账号信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { exam_name, status, application_start, application_end, exam_start, exam_end } = requestMsg;
where = { exam_name, status, application_start, application_end, exam_start, exam_end };
} else if (modelType == "multiple") {
let exam_name = [], status = [], application_start = [], application_end = [], exam_start = [], exam_end = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
exam_name.push(element.exam_name);
status.push(element.status);
application_start.push(element.application_start);
application_end.push(element.application_end);
exam_start.push(element.exam_start);
exam_end.push(element.exam_end);
});
}
where = { exam_name, status, application_start, application_end, exam_start, exam_end };
}
const resultList = await ctx.model.Examination.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteExam";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出考试信息数据
async downloadExamData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['uid', 'exam_name', 'status', 'application_start', 'application_end', 'exam_start', 'exam_end'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['uid', 'exam_name'],
key = ['status'],
between = ['application_start', 'application_end', 'exam_start', 'exam_end'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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, where, order };
const result = await ctx.model.Examination.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const statusOptions = [
{
value: "0",
label: "即将进行"
},
{
value: "1",
label: "正在进行"
},
{
value: "2",
label: "已经结束"
},
];
result.forEach(element => {
statusOptions.forEach((item) => {
if (item.value == element.dataValues["status"]) {
element.dataValues["status"] = item.label;
}
});
element.dataValues.application_start = moment
.utc(element.dataValues.application_start)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
element.dataValues.application_end = moment
.utc(element.dataValues.application_end)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
element.dataValues.exam_start = moment
.utc(element.dataValues.exam_start)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
element.dataValues.exam_end = moment
.utc(element.dataValues.exam_end)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
data.push(element.dataValues);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadExamData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = ExamService;

82
app/service/Find.js Normal file
View File

@@ -0,0 +1,82 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const fileName = "Find";
class FindService extends Service {
// 管理系统检索考生姓名
async findUserName(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Examinee.findOne({ where: { user_name: body.user_name } });
return result || false;
} catch (error) {
const blockName = fileName + "--" + "findUserName";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统检索考生身份证号
async findIdentityCard(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Examinee.findOne({ where: { identity_card: body.identity_card } });
if (!result) return { code: 404 };
const user = await ctx.model.Examinee.findOne({ where: { user_name: body.user_name, identity_card: body.identity_card } });
if (!user) return { code: 303 };
return { code: 200 };
} catch (error) {
const blockName = fileName + "--" + "findIdentityCard";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统检索考生 uid
async findUserUid(identity_card, user_name) {
const { ctx } = this;
try {
let attributes = ['uid'],
where = { identity_card, user_name },
dbOptions = { attributes, where };
const result = await ctx.model.Examinee.findOne(dbOptions);
return result || false;
} catch (error) {
const blockName = fileName + "--" + "findUserUid";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统检索考试 uid
async findExamUid(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Examination.findOne({ where: { uid: body.exam_uid } });
return result || false;
} catch (error) {
const blockName = fileName + "--" + "findExamUid";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查找指定工作单位
async findWorkplace(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Examinee.findOne({ where: { workplace: body.workplace } });
return result || false;
} catch (error) {
const blockName = fileName + "--" + "findWorkplace";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = FindService;

468
app/service/Grades.js Normal file
View File

@@ -0,0 +1,468 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "Grades";
class GradesService extends Service {
// 管理系统新增用户考试结果
async addGrades(userMsgObj, form) {
const { ctx } = this;
try {
let attributes = ['uid', 'user_name', 'identity_card'],
where = userMsgObj,
dbOptions = { attributes, where };
const userUid = await ctx.model.Examinee.findAll(dbOptions);
if(userUid.length == 0) {
let errorForm = [];
form.forEach(item => {
errorForm.push({
user_name: item.user_name,
identity_card: item.identity_card,
exam_uid: item.exam_uid,
type: 1,
status: 0,
created_at: new Date()
});
});
await ctx.model.Importerror.bulkCreate(errorForm);
return { code: 400 };
};
let errorMark = false;
form.forEach(async item => {
item.user_uid = 'none';
userUid.forEach(element => {
if (item.user_name == element.dataValues.user_name && item.identity_card == element.dataValues.identity_card) {
item.user_uid = element.dataValues.uid;
}
});
delete item.user_name;
delete item.identity_card;
if (item.user_uid == 'none') {
let errorForm = {
user_name: item.user_name,
identity_card: item.identity_card,
exam_uid: item.exam_uid,
type: 1,
status: 0,
created_at: new Date()
};
errorMark = true;
await ctx.model.Importerror.create(errorForm);
}
});
const result = await ctx.model.Grades.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : errorMark ? { code: 300, data: result } : { code: 200, data: result };
} catch (error) {
const blockName = fileName + "--" + "addGrades";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看用户考试结果
async showGrades(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['user_uid', 'exam_uid', 'status', 'grades', 'pass_type'],
where = {}, order = [], dbOptions,
joinSubstring = ['grades'],
substring = ['user_uid', 'exam_uid'],
key = ['status', 'pass_type'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let examination = ['exam_name', 'exam_start', 'exam_end'],
examinationWhere = {},
examinationOrder = [],
examinationJoinSubstring = [],
examinationSubstring = ['exam_name'],
examinationKey = [],
examinationBetween = ['exam_start', 'exam_end'];
examination.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examinationJoinSubstring.includes(item)) {
examinationWhere[item] = null;
} else {
examinationWhere[item] = [null, ''];
}
} else if (examinationSubstring.includes(item)) {
examinationWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examinationKey.includes(item)) {
examinationWhere[item] = searchOptions[item];
} else if (examinationBetween.includes(item)) {
examinationWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examinationOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examinationOrder.push([item, 'DESC']);
}
});
let examinee = ['user_name', 'identity_card', 'workplace', 'phone'],
examineeWhere = {},
examineeOrder = [],
examineeJoinSubstring = [],
examineeSubstring = ['user_name', 'identity_card', 'workplace', 'phone'],
examineeKey = [],
examineeBetween = [];
examinee.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examineeJoinSubstring.includes(item)) {
examineeWhere[item] = null;
} else {
examineeWhere[item] = [null, ''];
}
} else if (examineeSubstring.includes(item)) {
examineeWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examineeKey.includes(item)) {
examineeWhere[item] = searchOptions[item];
} else if (examineeBetween.includes(item)) {
examineeWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examineeOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examineeOrder.push([item, 'DESC']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card', 'workplace', 'phone'],
where: examineeWhere,
order: examineeOrder
},
{
model: ctx.model.Examination,
attributes: ['exam_name', 'exam_start', 'exam_end'],
where: examinationWhere,
order: examinationOrder
}
];
ctx.model.Grades.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
ctx.model.Grades.belongsTo(ctx.model.Examination, { foreignKey: 'exam_uid', targetKey: 'uid' });
dbOptions = { attributes, offset, limit, where, order, include };
const result = await ctx.model.Grades.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showGrades";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑用户考试结果
async editGrades(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { user_uid, exam_uid, status, grades, pass_type } = requestMsg;
where = { user_uid, exam_uid, status, grades, pass_type };
} else if (modelType == "multiple") {
let user_uid = [], exam_uid = [], status = [], pass_type = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
user_uid.push(element.user_uid);
exam_uid.push(element.exam_uid);
status.push(element.status);
pass_type.push(element.pass_type);
});
}
where = { user_uid, exam_uid, status, pass_type };
}
const resultList = await ctx.model.Grades.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editGrades";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除考生考试成绩
async deleteGrades(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除考生考试成绩信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { user_uid, exam_uid, status, grades, pass_type } = requestMsg;
where = { user_uid, exam_uid, status, grades, pass_type };
} else if (modelType == "multiple") {
let user_uid = [], exam_uid = [], status = [], grades = [], pass_type = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
user_uid.push(element.user_uid);
exam_uid.push(element.exam_uid);
status.push(element.status);
grades.push(element.grades);
pass_type.push(element.pass_type);
});
}
where = { user_uid, exam_uid, status, grades, pass_type };
}
const resultList = await ctx.model.Grades.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteGrades";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出考生考试结果数据
async downloadGradesData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['user_uid', 'exam_uid', 'status', 'grades', 'pass_type'],
where = {}, order = [], dbOptions,
joinSubstring = ['grades'],
substring = ['user_uid', 'exam_uid'],
key = ['status', 'pass_type'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let examination = ['exam_name', 'exam_start', 'exam_end'],
examinationWhere = {},
examinationOrder = [],
examinationJoinSubstring = [],
examinationSubstring = ['exam_name'],
examinationKey = [],
examinationBetween = ['exam_start', 'exam_end'];
examination.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examinationJoinSubstring.includes(item)) {
examinationWhere[item] = null;
} else {
examinationWhere[item] = [null, ''];
}
} else if (examinationSubstring.includes(item)) {
examinationWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examinationKey.includes(item)) {
examinationWhere[item] = searchOptions[item];
} else if (examinationBetween.includes(item)) {
examinationWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examinationOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examinationOrder.push([item, 'DESC']);
}
});
let examinee = ['user_name', 'identity_card', 'workplace', 'phone'],
examineeWhere = {},
examineeOrder = [],
examineeJoinSubstring = [],
examineeSubstring = ['user_name', 'identity_card', 'workplace', 'phone'],
examineeKey = [],
examineeBetween = [];
examinee.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examineeJoinSubstring.includes(item)) {
examineeWhere[item] = null;
} else {
examineeWhere[item] = [null, ''];
}
} else if (examineeSubstring.includes(item)) {
examineeWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examineeKey.includes(item)) {
examineeWhere[item] = searchOptions[item];
} else if (examineeBetween.includes(item)) {
examineeWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examineeOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examineeOrder.push([item, 'DESC']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card', 'workplace', 'phone'],
where: examineeWhere,
order: examineeOrder
},
{
model: ctx.model.Examination,
attributes: ['exam_name', 'exam_start', 'exam_end'],
where: examinationWhere,
order: examinationOrder
}
];
ctx.model.Grades.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
ctx.model.Grades.belongsTo(ctx.model.Examination, { foreignKey: 'exam_uid', targetKey: 'uid' });
dbOptions = { attributes, where, order, include };
const result = await ctx.model.Grades.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const statusOptions = [
{
value: "0",
label: "旷考"
},
{
value: "1",
label: "正常参与"
},
{
value: "2",
label: "考试作弊"
},
];
const passTypeOptions = [
{
value: "0",
label: "成绩不及格"
},
{
value: "1",
label: "成绩及格"
},
{
value: "2",
label: "无成绩"
},
];
result.forEach(element => {
statusOptions.forEach((item) => {
if (item.value == element.dataValues["status"]) {
element.dataValues["status"] = item.label;
}
});
passTypeOptions.forEach((item) => {
if (item.value == element.dataValues["pass_type"]) {
element.dataValues["pass_type"] = item.label;
}
});
element.dataValues.user_name = element.dataValues.examinee.dataValues.user_name;
element.dataValues.identity_card = element.dataValues.examinee.dataValues.identity_card;
element.dataValues.exam_name = element.dataValues.examination.dataValues.exam_name;
element.dataValues.exam_start = moment
.utc(element.dataValues.examination.dataValues.exam_start)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
element.dataValues.exam_end = moment
.utc(element.dataValues.examination.dataValues.exam_end)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
delete element.dataValues.examinee;
delete element.dataValues.examination;
let elementClone = {
user_uid: element.dataValues.user_uid,
user_name: element.dataValues.user_name,
identity_card: element.dataValues.identity_card,
exam_uid: element.dataValues.exam_uid,
exam_name: element.dataValues.exam_name,
status: element.dataValues.status,
grades: element.dataValues.grades,
pass_type: element.dataValues.pass_type,
exam_start: element.dataValues.exam_start,
exam_end: element.dataValues.exam_end,
}
data.push(elementClone);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadGradesData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = GradesService;

145
app/service/Importerror.js Normal file
View File

@@ -0,0 +1,145 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const fileName = "Importerror";
class ImporterrorService extends Service {
// 查看导入错误记录
async showImporterror(body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['user_name', 'identity_card', 'exam_uid', 'type', 'status', 'created_at'],
where = {}, order = [], dbOptions, joinSubstring = [],
substring = ['user_name', 'identity_card', 'exam_uid'],
key = ['type', 'status'],
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];
} 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']);
}
});
let examination = ['exam_name'],
examinationWhere = {},
examinationOrder = [],
examinationJoinSubstring = [],
examinationSubstring = ['exam_name'],
examinationKey = [],
examinationBetween = [];
examination.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examinationJoinSubstring.includes(item)) {
examinationWhere[item] = null;
} else {
examinationWhere[item] = [null, ''];
}
} else if (examinationSubstring.includes(item)) {
examinationWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examinationKey.includes(item)) {
examinationWhere[item] = searchOptions[item];
} else if (examinationBetween.includes(item)) {
examinationWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examinationOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examinationOrder.push([item, 'DESC']);
}
});
let include = [
{
model: ctx.model.Examination,
attributes: ['exam_name'],
where: examinationWhere,
order: examinationOrder
}
];
ctx.model.Importerror.belongsTo(ctx.model.Examination, { foreignKey: 'exam_uid', targetKey: 'uid' });
dbOptions = { attributes, offset, limit, where, order, include };
const result = await ctx.model.Importerror.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showImporterror";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 删除导入错误记录
async deleteImporterror(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemImporterror = {
operate: 2,
operate_msg: '删除导入错误记录',
type: 2,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemImporterror.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemImporterror.status = 1;
else if (result.dataValues.role < 2) systemImporterror.status = 2;
await ctx.model.Importerror.create(systemImporterror);
return false;
};
let where = {};
if (modelType == "single") {
const { identity_card, exam_uid, created_at } = requestMsg;
where = { identity_card, exam_uid, created_at };
} else if (modelType == "multiple") {
let identity_card = [], exam_uid = [], created_at = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
identity_card.push(element.identity_card),
exam_uid.push(element.exam_uid),
created_at.push(element.created_at)
});
}
where = { identity_card, exam_uid, created_at };
}
const resultList = await ctx.model.Importerror.destroy({ where });
systemImporterror.status = resultList == 0 ? 3 : 4;
systemImporterror.affect_entries = resultList;
await ctx.model.Importerror.create(systemImporterror);
return resultList == 0 ? false : true;
} catch (error) {
systemImporterror.status = 5;
await ctx.model.Importerror.create(systemImporterror);
const blockName = fileName + "--" + "deleteImporterror";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = ImporterrorService;

View File

@@ -0,0 +1,225 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "Interlocution";
class InterlocutionService extends Service {
// 管理系统新增问答题
async addInterlocution(form) {
const { ctx } = this;
try {
const result = await ctx.model2.Interlocution.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "addInterlocution";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看问答题
async showInterlocution(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['stem', 'answer', 'difficulty'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['stem', 'answer'],
key = ['difficulty'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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.model2.Interlocution.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showInterlocution";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑问答题
async editInterlocution(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { stem, answer, difficulty } = requestMsg;
where = { stem, answer, difficulty };
} else if (modelType == "multiple") {
let stem = [], answer = [], difficulty = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
stem.push(element.stem);
answer.push(element.answer);
difficulty.push(element.difficulty);
});
}
where = { stem, answer, difficulty };
}
const resultList = await ctx.model2.Interlocution.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editInterlocution";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除问答题
async deleteInterlocution(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除用户账号信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { stem, answer, difficulty } = requestMsg;
where = { stem, answer, difficulty };
} else if (modelType == "multiple") {
let stem = [], answer = [], difficulty = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
stem.push(element.stem);
answer.push(element.answer);
difficulty.push(element.difficulty);
});
}
where = { stem, answer, difficulty };
}
const resultList = await ctx.model2.Interlocution.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteInterlocution";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出问答题数据
async downloadInterlocutionData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return { code: false };
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['stem', 'answer', 'difficulty'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['stem', 'answer', 'difficulty'],
key = [],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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, where, order };
const result = await ctx.model2.Interlocution.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const difficultyOptions = [
{
value: "0",
label: "简单"
},
{
value: "1",
label: "普通"
},
{
value: "2",
label: "困难"
},
];
result.forEach(element => {
difficultyOptions.forEach((item) => {
if (item.value == element.dataValues["difficulty"]) {
element.dataValues["difficulty"] = item.label;
}
});
data.push(element.dataValues);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadInterlocutionData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = InterlocutionService;

240
app/service/Judgment.js Normal file
View File

@@ -0,0 +1,240 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "Judgment";
class JudgmentService extends Service {
// 管理系统新增判断题
async addJudgment(form) {
const { ctx } = this;
try {
const result = await ctx.model2.Judgment.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "addJudgment";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看判断题
async showJudgment(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['stem', 'answer', 'difficulty'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['stem'],
key = ['answer', 'difficulty'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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.model2.Judgment.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showJudgment";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑判断题
async editJudgment(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { stem, answer, difficulty } = requestMsg;
where = { stem, answer, difficulty };
} else if (modelType == "multiple") {
let stem = [], answer = [], difficulty = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
stem.push(element.stem);
answer.push(element.answer);
difficulty.push(element.difficulty);
});
}
where = { stem, answer, difficulty };
}
const resultList = await ctx.model2.Judgment.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editJudgment";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除判断题
async deleteJudgment(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除用户账号信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { stem, answer, difficulty } = requestMsg;
where = { stem, answer, difficulty };
} else if (modelType == "multiple") {
let stem = [], answer = [], difficulty = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
stem.push(element.stem);
answer.push(element.answer);
difficulty.push(element.difficulty);
});
}
where = { stem, answer, difficulty };
}
const resultList = await ctx.model2.Judgment.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteJudgment";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出判断题数据
async downloadJudgmentData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return { code: false };
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['stem', 'answer', 'difficulty'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['stem', 'answer', 'difficulty'],
key = [],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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, where, order };
const result = await ctx.model2.Judgment.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const answerOptions = [
{
value: "0",
label: "错误"
},
{
value: "1",
label: "正确"
},
];
const difficultyOptions = [
{
value: "0",
label: "简单"
},
{
value: "1",
label: "普通"
},
{
value: "2",
label: "困难"
},
];
result.forEach(element => {
answerOptions.forEach((item) => {
if (item.value == element.dataValues["answer"]) {
element.dataValues["answer"] = item.label;
}
});
difficultyOptions.forEach((item) => {
if (item.value == element.dataValues["difficulty"]) {
element.dataValues["difficulty"] = item.label;
}
});
data.push(element.dataValues);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadJudgmentData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = JudgmentService;

136
app/service/Monitoring.js Normal file
View File

@@ -0,0 +1,136 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const fileName = "Monitoring";
class MonitoringService extends Service {
// 查看危险操作记录
async showMonitoring(body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['operate', 'operate_msg', 'type', 'status', 'affect_entries', 'user', 'created_at'],
where = {}, order = [], dbOptions, joinSubstring = [],
substring = ['operate_msg', 'user'],
key = ['type', 'status', 'operate'],
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];
} 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']);
}
});
const manager = await ctx.model.Manager.findAll({ attributes: ['uid', 'account_name', 'role'] });
if (searchOptions.account_name) {
if (searchOptions.account_name == '*空') {
where.user = [null, ''];
} else {
let uidArr = [];
manager.filter(item => {
if (item.dataValues.account_name.includes(searchOptions.account_name)) {
uidArr.push(item.dataValues.uid);
}
});
where.user = [...uidArr];
}
}
if (searchOptions.role) {
let uidArr = [];
manager.filter(item => {
if (item.dataValues.role == searchOptions.role) {
uidArr.push(item.dataValues.uid);
}
});
where.user = [...uidArr];
}
dbOptions = { attributes, offset, limit, where, order };
const result = await ctx.model.Monitoring.findAndCountAll(dbOptions);
result.rows.forEach(element => {
element.dataValues.account_name = '';
element.dataValues.role = '';
manager.filter(item => {
if (item.dataValues.uid == element.dataValues.user) {
element.dataValues.account_name = item.dataValues.account_name;
element.dataValues.role = item.dataValues.role;
}
});
});
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showMonitoring";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 删除危险操作记录
async deleteMonitoring(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除危险操作记录',
type: 2,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { user, created_at } = requestMsg;
where = { user, created_at };
} else if (modelType == "multiple") {
let user = [], created_at = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
user.push(element.user),
created_at.push(element.created_at)
});
}
where = { user, created_at };
}
const resultList = await ctx.model.Monitoring.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteMonitoring";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = MonitoringService;

235
app/service/Multiple.js Normal file
View File

@@ -0,0 +1,235 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "Multiple";
class MultipleService extends Service {
// 管理系统新增多选题
async addMultiple(form) {
const { ctx } = this;
try {
const result = await ctx.model2.Multiple.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "addMultiple";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看多选题
async showMultiple(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['stem', 'options_a', 'options_b', 'options_c', 'options_d', 'options_e', 'answer', 'difficulty'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['stem', 'options_a', 'options_b', 'options_c', 'options_d', 'options_e', 'answer'],
key = ['difficulty'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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.model2.Multiple.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showMultiple";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑多选题
async editMultiple(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { stem, options_a, options_b, options_c, options_d, options_e, answer, difficulty } = requestMsg;
where = { stem, options_a, options_b, options_c, options_d, options_e, answer, difficulty };
} else if (modelType == "multiple") {
let stem = [], options_a = [], options_b = [], options_c = [], options_d = [], options_e = [], answer = [], difficulty = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
stem.push(element.stem);
options_a.push(element.options_a);
options_b.push(element.options_b);
options_c.push(element.options_c);
options_d.push(element.options_d);
options_e.push(element.options_e);
answer.push(element.answer);
difficulty.push(element.difficulty);
});
}
where = { stem, options_a, options_b, options_c, options_d, options_e, answer, difficulty };
}
const resultList = await ctx.model2.Multiple.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editMultiple";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除多选题
async deleteMultiple(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除用户账号信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { stem, options_a, options_b, options_c, options_d, options_e, answer, difficulty } = requestMsg;
where = { stem, options_a, options_b, options_c, options_d, options_e, answer, difficulty };
} else if (modelType == "multiple") {
let stem = [], options_a = [], options_b = [], options_c = [], options_d = [], options_e = [], answer = [], difficulty = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
stem.push(element.stem);
options_a.push(element.options_a);
options_b.push(element.options_b);
options_c.push(element.options_c);
options_d.push(element.options_d);
options_e.push(element.options_e);
answer.push(element.answer);
difficulty.push(element.difficulty);
});
}
where = { stem, options_a, options_b, options_c, options_d, options_e, answer, difficulty };
}
const resultList = await ctx.model2.Multiple.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteMultiple";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出多选题数据
async downloadMultipleData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return { code: false };
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['stem', 'options_a', 'options_b', 'options_c', 'options_d', 'options_e', 'answer', 'difficulty'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['stem', 'options_a', 'options_b', 'options_c', 'options_d', 'options_e', 'answer', 'difficulty'],
key = [],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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, where, order };
const result = await ctx.model2.Multiple.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const difficultyOptions = [
{
value: "0",
label: "简单"
},
{
value: "1",
label: "普通"
},
{
value: "2",
label: "困难"
},
];
result.forEach(element => {
difficultyOptions.forEach((item) => {
if (item.value == element.dataValues["difficulty"]) {
element.dataValues["difficulty"] = item.label;
}
});
data.push(element.dataValues);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadMultipleData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = MultipleService;

233
app/service/Radio.js Normal file
View File

@@ -0,0 +1,233 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "Radio";
class RadioService extends Service {
// 管理系统新增单选题
async addRadio(form) {
const { ctx } = this;
try {
const result = await ctx.model2.Radio.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "addRadio";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看单选题
async showRadio(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['stem', 'options_a', 'options_b', 'options_c', 'options_d', 'answer', 'difficulty'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['stem', 'options_a', 'options_b', 'options_c', 'options_d', 'answer'],
key = ['difficulty'],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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.model2.Radio.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showRadio";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑单选题
async editRadio(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { stem, options_a, options_b, options_c, options_d, answer, difficulty } = requestMsg;
where = { stem, options_a, options_b, options_c, options_d, answer, difficulty };
} else if (modelType == "multiple") {
let stem = [], options_a = [], options_b = [], options_c = [], options_d = [], answer = [], difficulty = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
stem.push(element.stem);
options_a.push(element.options_a);
options_b.push(element.options_b);
options_c.push(element.options_c);
options_d.push(element.options_d);
answer.push(element.answer);
difficulty.push(element.difficulty);
});
}
where = { stem, options_a, options_b, options_c, options_d, answer, difficulty };
}
const resultList = await ctx.model2.Radio.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editRadio";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除单选题
async deleteRadio(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除用户账号信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { stem, options_a, options_b, options_c, options_d, answer, difficulty } = requestMsg;
where = { stem, options_a, options_b, options_c, options_d, answer, difficulty };
} else if (modelType == "multiple") {
let stem = [], options_a = [], options_b = [], options_c = [], options_d = [], answer = [], difficulty = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
stem.push(element.stem);
options_a.push(element.options_a);
options_b.push(element.options_b);
options_c.push(element.options_c);
options_d.push(element.options_d);
answer.push(element.answer);
difficulty.push(element.difficulty);
});
}
where = { stem, options_a, options_b, options_c, options_d, answer, difficulty };
}
const resultList = await ctx.model2.Radio.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteRadio";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出单选题数据
async downloadRadioData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return { code: false };
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['stem', 'options_a', 'options_b', 'options_c', 'options_d', 'answer', 'difficulty'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['stem', 'options_a', 'options_b', 'options_c', 'options_d', 'answer', 'difficulty'],
key = [],
between = [];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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, where, order };
const result = await ctx.model2.Radio.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const difficultyOptions = [
{
value: "0",
label: "简单"
},
{
value: "1",
label: "普通"
},
{
value: "2",
label: "困难"
},
];
result.forEach(element => {
difficultyOptions.forEach((item) => {
if (item.value == element.dataValues["difficulty"]) {
element.dataValues["difficulty"] = item.label;
}
});
data.push(element.dataValues);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadRadioData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = RadioService;

131
app/service/Search.js Normal file
View File

@@ -0,0 +1,131 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const fs = require('fs');
const path = require('path');
const fileName = "Search";
class SearchService extends Service {
// 管理系统检索考生姓名
async searchUserName(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Examinee.findAll({ where: { user_name: { [Op.substring]: body.user_name } } });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "searchUserName";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统检索考生身份证号
async searchIdentityCard(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Examinee.findAll({ where: { identity_card: { [Op.substring]: body.identity_card } } });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "searchIdentityCard";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统检索考生 uid
async searchUserUid(identity_card, user_name) {
const { ctx } = this;
try {
let attributes = ['uid'],
where = { identity_card, user_name },
dbOptions = { attributes, where };
const result = await ctx.model.Examinee.findOne(dbOptions);
return result || false;
} catch (error) {
const blockName = fileName + "--" + "searchUserUid";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统检索考试 uid
async searchExamUid(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Examination.findAll({ where: { uid: { [Op.substring]: body.exam_uid } } });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "searchExamUid";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统检索工作单位
async searchWorkplace(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Examinee.findAll({ where: { workplace: { [Op.substring]: body.workplace } } });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "searchWorkplace";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统检索报名结果说明
async searchResult(uid, body) {
const { ctx } = this;
try {
const result = await ctx.model.Application.findAll({ where: { result: { [Op.substring]: body.result } } });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "searchResult";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 用户照片是否存在判断
async checkPhoto(idCardArr) {
const { ctx } = this;
try {
let attributes = ['uid', 'identity_card'],
where = { identity_card: idCardArr },
dbOptions = { attributes, where };
const result = await ctx.model.Examinee.findAll(dbOptions);
if (result.length == 0) return false;
let photoUrlArr = [];
result.forEach(element => {
const filePath = path.join(__dirname.replace(/\bbd-training-exam-manager\b/g, "bd-training-exam"), `../public/userPhoto/${element.dataValues.identity_card}.jpg`);
// const filePath = `/disk/a/userPhoto/${element.dataValues.identity_card}.jpg`;
const fileExists = fs.existsSync(filePath);
if (fileExists) {
// 文件存在
// 本机服务器地址
// 'http://127.0.0.1:8019'
// 'http://192.168.31.28:8019'
// 公司服务器地址
// 'http://123.57.205.46:8019'
// 'http://certlogin.hwasmart.com//bdTrainingExam'
photoUrlArr.push({ identity_card: element.dataValues.identity_card, photoUrl: 'http://127.0.0.1:8019' + `/public/userPhoto/${element.dataValues.identity_card}.jpg?time=${new Date().getTime()}` });
} else {
// 文件不存在
photoUrlArr.push({ identity_card: element.dataValues.identity_card, photoUrl: '#' });
}
});
return photoUrlArr;
} catch (error) {
const blockName = fileName + "--" + "checkPhoto";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = SearchService;

View File

@@ -0,0 +1,334 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "TopicWhitelist";
class TopicWhitelistService extends Service {
// 管理系统新增题库白名单
async addTopicWhitelist(userMsgObj, form) {
const { ctx } = this;
try {
let attributes = ['uid', 'phone'],
where = userMsgObj,
dbOptions = { attributes, where };
const userUid = await ctx.model.Examinee.findAll(dbOptions);
form.forEach(async item => {
item.user_uid = 'none';
userUid.forEach(element => {
if (item.phone == element.dataValues.phone) {
item.user_uid = element.dataValues.uid;
}
});
delete item.phone;
});
const result = await ctx.model.Whitelist.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "addTopicWhitelist";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看题库白名单
async showTopicWhitelist(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['user_uid', 'type', 'expired_at'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['user_uid', 'user_name', 'identity_card'],
key = ['type'],
between = ['expired_at'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let examinee = ['user_name', 'identity_card'],
examineeWhere = {},
examineeOrder = [],
examineeJoinSubstring = [],
examineeSubstring = ['user_name', 'identity_card'],
examineeKey = [],
examineeBetween = [];
examinee.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examineeJoinSubstring.includes(item)) {
examineeWhere[item] = null;
} else {
examineeWhere[item] = [null, ''];
}
} else if (examineeSubstring.includes(item)) {
examineeWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examineeKey.includes(item)) {
examineeWhere[item] = searchOptions[item];
} else if (examineeBetween.includes(item)) {
examineeWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examineeOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examineeOrder.push([item, 'DESC']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card'],
where: examineeWhere,
order: examineeOrder
}
];
ctx.model.Whitelist.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
dbOptions = { attributes, offset, limit, where, order, include };
const result = await ctx.model.Whitelist.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showTopicWhitelist";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑题库白名单
async editTopicWhitelist(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { user_uid, type, expired_at } = requestMsg;
where = { user_uid, type, expired_at };
} else if (modelType == "multiple") {
let user_uid = [], type = [], expired_at = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
user_uid.push(element.user_uid);
type.push(element.type);
expired_at.push(element.expired_at);
});
}
where = { user_uid, type, expired_at };
}
updateMsg.type = Number(updateMsg.type);
if (updateMsg.expired_at) {
updateMsg.expired_at = new Date(updateMsg.expired_at);
} else {
updateMsg.expired_at = null;
}
const resultList = await ctx.model.Whitelist.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editTopicWhitelist";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除题库白名单
async deleteTopicWhitelist(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除题库白名单',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { type, expired_at } = requestMsg;
where = { type, expired_at };
} else if (modelType == "multiple") {
let type = [], expired_at = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
type.push(element.type);
expired_at.push(element.expired_at);
});
}
where = { type, expired_at };
}
const resultList = await ctx.model.Whitelist.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteTopicWhitelist";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出题库白名单
async downloadTopicWhitelistData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['user_uid', 'type', 'expired_at'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['user_uid'],
key = ['type'],
between = ['expired_at'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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']);
}
});
let examinee = ['user_name', 'identity_card'],
examineeWhere = {},
examineeOrder = [],
examineeJoinSubstring = [],
examineeSubstring = ['user_name', 'identity_card'],
examineeKey = [],
examineeBetween = [];
examinee.forEach(item => {
if (searchOptions[item]) {
if (searchOptions[item] == '*空') {
if (examineeJoinSubstring.includes(item)) {
examineeWhere[item] = null;
} else {
examineeWhere[item] = [null, ''];
}
} else if (examineeSubstring.includes(item)) {
examineeWhere[item] = { [Op.substring]: searchOptions[item] };
} else if (examineeKey.includes(item)) {
examineeWhere[item] = searchOptions[item];
} else if (examineeBetween.includes(item)) {
examineeWhere[item] = { [Op.between]: [searchOptions[item][0], searchOptions[item][1]] };
}
}
if (sortOptions[item] == true) {
examineeOrder.push([item, 'ASC']);
} else if (sortOptions[item] == false) {
examineeOrder.push([item, 'DESC']);
}
});
let include = [
{
model: ctx.model.Examinee,
attributes: ['user_name', 'identity_card'],
where: examineeWhere,
order: examineeOrder
}
];
ctx.model.Whitelist.belongsTo(ctx.model.Examinee, { foreignKey: 'user_uid', targetKey: 'uid' });
dbOptions = { attributes, where, order, include };
const result = await ctx.model.Whitelist.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const typeOptions = [
{
value: "0",
label: "永久白名单"
},
{
value: "1",
label: "临时白名单"
},
];
result.forEach(element => {
typeOptions.forEach((item) => {
if (item.value == element.dataValues["type"]) {
element.dataValues["type"] = item.label;
}
});
element.dataValues.user_name = element.dataValues.examinee.dataValues.user_name;
element.dataValues.identity_card = element.dataValues.examinee.dataValues.identity_card;
element.dataValues.expired_at = moment
.utc(element.dataValues.examination.dataValues.expired_at)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
delete element.dataValues.examinee;
let elementClone = {
user_uid: element.dataValues.user_uid,
user_name: element.dataValues.user_name,
identity_card: element.dataValues.identity_card,
type: element.dataValues.type,
expired_at: element.dataValues.expired_at,
}
data.push(elementClone);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadTopicWhitelistData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = TopicWhitelistService;

272
app/service/User.js Normal file
View File

@@ -0,0 +1,272 @@
'use strict';
const Service = require('../core/base_service');
const { Op } = require('sequelize');
const moment = require('moment');
const fileName = "User";
class UserService extends Service {
// 管理系统新增用户账号信息
async addUser(form) {
const { ctx } = this;
try {
const result = await ctx.model.Examinee.bulkCreate(form, { ignoreDuplicates: true });
return result.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "addUser";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统查看用户账号信息
async showUser(uid, body) {
const { ctx } = this;
try {
let { offset, limit, searchOptions, sortOptions } = body;
offset = (offset - 1) * limit;
let attributes = ['uid', 'user_name', 'identity_card', 'real_check', 'workplace', 'address', 'phone', 'email', 'referrers', 'status', 'created_at', 'updated_at', 'login_status'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['uid', 'user_name', 'identity_card', 'workplace', 'address', 'phone', 'email', 'referrers'],
key = ['real_check', 'status', 'login_status'],
between = ['created_at', 'updated_at'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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.model.Examinee.findAndCountAll(dbOptions);
return result.rows.length == 0 ? false : result;
} catch (error) {
const blockName = fileName + "--" + "showUser";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统编辑用户账号信息
async editUser(uid, modelType, updateMsg, requestMsg) {
const { ctx } = this;
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.role < 1) return false;
let where = {};
if (modelType == "single") {
const { uid, user_name, identity_card, real_check, workplace, address, phone, email, status } = requestMsg;
where = { uid, user_name, identity_card, real_check, workplace, address, phone, email, status };
} else if (modelType == "multiple") {
let uid = [], user_name = [], identity_card = [], real_check = [], workplace = [], address = [], phone = [], email = [], status = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
uid.push(element.uid);
user_name.push(element.user_name);
identity_card.push(element.identity_card);
real_check.push(element.real_check);
workplace.push(element.workplace);
address.push(element.address);
phone.push(element.phone);
email.push(element.email);
status.push(element.status);
});
}
where = { uid, user_name, identity_card, real_check, workplace, address, phone, email, status };
}
updateMsg.updated_at = new Date();
const resultList = await ctx.model.Examinee.update(updateMsg, { where });
return resultList[0] == 0 ? false : resultList;
} catch (error) {
const blockName = fileName + "--" + "editUser";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统删除用户账号信息
async deleteUser(uid, modelType, password, requestMsg) {
const { ctx } = this;
const systemMonitoring = {
operate: 2,
operate_msg: '删除用户账号信息',
type: 0,
status: 0,
affect_entries: 0,
user: uid,
created_at: new Date()
};
try {
const result = await ctx.model.Manager.findOne({ where: { uid } });
if (!result || result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt)) || result.dataValues.role < 2) {
if (!result) systemMonitoring.status = 0;
else if (result.dataValues.password !== this.shaForm(password, this.decryptRequest(result.dataValues.salt))) systemMonitoring.status = 1;
else if (result.dataValues.role < 2) systemMonitoring.status = 2;
await ctx.model.Monitoring.create(systemMonitoring);
return false;
};
let where = {};
if (modelType == "single") {
const { uid, user_name, identity_card, real_check, workplace, address, phone, email, status } = requestMsg;
where = { uid, user_name, identity_card, real_check, workplace, address, phone, email, status };
await ctx.model.Audit.destroy({ where : { user_uid: uid } });
await ctx.model.Application.destroy({ where : { user_uid: uid } });
await ctx.model.Grades.destroy({ where: { user_uid: uid } });
} else if (modelType == "multiple") {
let uid = [], user_name = [], identity_card = [], real_check = [], workplace = [], address = [], phone = [], email = [], status = [];
for (const key in requestMsg) {
requestMsg[key].forEach(element => {
uid.push(element.uid);
user_name.push(element.user_name);
identity_card.push(element.identity_card);
real_check.push(element.real_check);
workplace.push(element.workplace);
address.push(element.address);
phone.push(element.phone);
email.push(element.email);
status.push(element.status);
});
}
where = { uid, user_name, identity_card, real_check, workplace, address, phone, email, status };
await ctx.model.Audit.destroy({ where : { user_uid: uid } });
await ctx.model.Application.destroy({ where : { user_uid: uid } });
await ctx.model.Grades.destroy({ where: { user_uid: uid } });
}
const resultList = await ctx.model.Examinee.destroy({ where });
systemMonitoring.status = resultList == 0 ? 3 : 4;
systemMonitoring.affect_entries = resultList;
await ctx.model.Monitoring.create(systemMonitoring);
return resultList == 0 ? false : true;
} catch (error) {
systemMonitoring.status = 5;
await ctx.model.Monitoring.create(systemMonitoring);
const blockName = fileName + "--" + "deleteUser";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
// 管理系统导出用户账号信息数据
async downloadUserData(uid, searchMsg) {
const { ctx } = this;
try {
const user = await ctx.model.Manager.findOne({ where: { uid } });
if (!user || user.dataValues.role < 1) return false;
let { searchOptions, sortOptions } = searchMsg;
let attributes = ['uid', 'user_name', 'identity_card', 'real_check', 'workplace', 'address', 'phone', 'email', 'status', 'created_at', 'updated_at', 'login_status'],
where = {}, order = [], dbOptions,
joinSubstring = [],
substring = ['uid', 'user_name', 'identity_card', 'workplace', 'address', 'phone', 'email'],
key = ['real_check', 'status', 'login_status'],
between = ['created_at', 'updated_at'];
attributes.forEach(element => {
if (searchOptions[element]) {
if (searchOptions[element] == '*空') {
if (joinSubstring.includes(element)) {
where[element] = null;
} else {
where[element] = [null, ''];
}
} else if (joinSubstring.includes(element)) {
let targetKeyArr = [];
where[element] = targetKeyArr.length > 0 ? targetKeyArr : 'null';
} else if (substring.includes(element)) {
where[element] = { [Op.substring]: searchOptions[element] };
} else if (key.includes(element)) {
where[element] = searchOptions[element];
} 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, where, order };
const result = await ctx.model.Examinee.findAll(dbOptions);
if (result.length == 0) return { code: false };
let data = [];
const realCheckOptions = [
{
value: "0",
label: "未核验"
},
{
value: "1",
label: "核验通过"
},
{
value: "2",
label: "核验失败"
},
];
const statusOptions = [
{
value: "0",
label: "默认状态"
},
{
value: "1",
label: "正常使用"
},
{
value: "2",
label: "已被封禁"
},
];
result.forEach(element => {
realCheckOptions.forEach((item) => {
if (item.value == element.dataValues["real_check"]) {
element.dataValues["real_check"] = item.label;
}
});
statusOptions.forEach((item) => {
if (item.value == element.dataValues["status"]) {
element.dataValues["status"] = item.label;
}
});
element.dataValues.created_at = moment
.utc(element.dataValues.created_at)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
element.dataValues.updated_at = moment
.utc(element.dataValues.updated_at)
.add(8, "hours")
.format("YYYY年MM月DD日HH时mm分ss秒");
delete element.dataValues.login_status;
data.push(element.dataValues);
});
return { code: true, data };
} catch (error) {
const blockName = fileName + "--" + "downloadUserData";
ctx.app.middleware.log('../../serviceLog', blockName + ">>>>" + error);
return 'error';
}
}
}
module.exports = UserService;