123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- 'use strict';
- const assert = require('assert');
- const _ = require('lodash');
- const moment = require('moment');
- const XLSX = require('xlsx');
- const { CrudService } = require('naf-framework-mongoose/lib/service');
- const { BusinessError, ErrorCode } = require('naf-core').Error;
- const stringRandom = require('string-random');
- const { ObjectId } = require('mongoose').Types;
- class TeacherService extends CrudService {
- constructor(ctx) {
- super(ctx, 'teacher');
- this.model = this.ctx.model.Teacher;
- this.umodel = this.ctx.model.User;
- const { baseUrl } = _.get(this.ctx.app.config, 'mission');
- if (baseUrl) this.missionBase = baseUrl;
- this.yjy = this.ctx.model.Yjyconnect;
- this.export_limit = 50;
- }
- async query({ name, ...info } = {}, { skip = 0, limit = 0 } = {}) {
- const query = { ...info };
- if (name) {
- query.name = { $regex: name };
- }
- let rs = await this.model.find(query, null, { skip, limit }).exec();
- if (rs.length > 0) rs = JSON.parse(JSON.stringify(rs));
- const ids = rs.map((i) => ObjectId(i._id).toString());
- const users = await this.umodel.find({ uid: ids }).lean();
- const uids = users.map((i) => ObjectId(i._id).toString());
- const yjyUsers = await this.yjy.find({ suid: uids }).lean();
- for (const i of rs) {
- const { _id: did } = i;
- const user = users.find((f) => ObjectId(did).equals(f.uid));
- if (!user) {
- i.is_bind = false;
- continue;
- }
- const yjyUser = yjyUsers.find((f) => ObjectId(user._id).equals(f.suid));
- if (yjyUser) i.is_bind = true;
- else i.is_bind = false;
- }
- return rs;
- }
- async count({ name, ...info } = {}) {
- const query = { ...info };
- if (name) {
- query.name = { $regex: name };
- }
- const res = await this.model.count(query);
- return res;
- }
- // 根据状态删除教师信息
- async deleteByStatus({ status }) {
- await this.model.deleteMany({ status });
- return 'deleted';
- }
- // 查询详情
- async fetchTeacher({ id }) {
- // 将文件拼到查询到的数据后
- return await this.model.findById(id, '+file');
- }
- async create(data) {
- const { name, phone: mobile } = data;
- const user = await this.umodel.findOne({ mobile });
- if (user) {
- throw new BusinessError(ErrorCode.DATA_EXIST, '电话已经存在');
- }
- // 创建教师信息
- const res = await this.model.create(data);
- // 再创建教师用户
- const passwd = stringRandom();
- const newdata = {
- name,
- mobile,
- type: '3',
- uid: ObjectId(res.id || res._id).toString(),
- passwd: { secret: passwd },
- };
- await this.umodel.create(newdata);
- // 返回教师信息
- return this.model.findById(res._id || res.id);
- }
- async delete({ id }) {
- await this.model.findByIdAndDelete(id);
- await this.umodel.deleteOne({ uid: id, type: '3' });
- return 'deleted';
- }
- // 批量查询教师
- async fetchteachers({ ids }) {
- return await this.model.find({ _id: { $in: ids } });
- }
- // 检查教师
- async checkarrange({ id, date }) {}
- async status(data) {
- const { teachersid, zlscore, msscore, status, remark } = data;
- for (const teacherid of teachersid) {
- const teacher = await this.model.findById(teacherid);
- console.log(status);
- teacher.status = status;
- if (zlscore) {
- teacher.zlscore = zlscore;
- }
- if (msscore) {
- teacher.msscore = msscore;
- }
- await teacher.save();
- let detail = '';
- if (status === '1') {
- const userInfo = await this.umodel.findOne({ uid: teacherid }, '+passwd');
- if (!userInfo) continue;
- const passwd = _.get(userInfo, 'passwd.secret');
- detail = '您的账号身份已确认,密码为:' + passwd + '请尽快登录账号上传课件资料附件';
- } else if (status === '4') {
- detail = '您已通过审核被正式录入教师库';
- }
- const date = await this.ctx.service.util.updatedate();
- const user = await this.umodel.findOne({ uid: teacher.id, type: '3' });
- if (user && user.openid) {
- await this.ctx.service.weixin.sendTemplateMsg(this.ctx.app.config.REVIEW_TEMPLATE_ID, user.openid, '您有一个新的通知', detail, date, remark);
- } else {
- await this.ctx.service.util.sendMail(teacher.email, '账号审核', detail, '');
- }
- }
- }
- // 教室分数上传
- async teaimport(data) {
- const { filepath } = data;
- assert(filepath, 'filepath不能为空');
- // 取得excle中数据
- const _filepath = this.ctx.app.config.baseUrl + filepath;
- const teadatas = await this.getImportXLSXData(_filepath);
- // 将得到的数据校验
- const datacheck = await this.datacheck(teadatas);
- if (datacheck.errorcode === '1') {
- return datacheck;
- }
- // 将数据存入数据库中
- for (const tea of teadatas) {
- const res = await this.model.findOne({
- idnumber: tea.idnumber,
- name: tea.name,
- });
- if (res) {
- res.beforescore = tea.xsscore;
- await res.save();
- }
- }
- return datacheck;
- }
- // 获取导入的XLSX文件中的数据
- async getImportXLSXData(filepath) {
- const file = await this.ctx.curl(filepath);
- const workbook = XLSX.read(file.data);
- // 读取内容
- let exceldata = [];
- const sheetNames = workbook.SheetNames; // 获取表名
- const sheet = workbook.Sheets[sheetNames[0]]; // 通过表名得到表对象
- // 遍历26个字母
- const theadRule = [];
- const range = XLSX.utils.decode_range(sheet['!ref']);
- const col_start = range.s.c;
- const col_end = range.e.c;
- for (let i = col_start; i <= col_end; i++) {
- const addr = XLSX.utils.encode_col(i) + XLSX.utils.encode_row(0);
- theadRule.push(sheet[addr].v);
- }
- const params = XLSX.utils.sheet_to_json(sheet); // 通过工具将表对象的数据读出来并转成json
- if (!params) return [];
- const length = params.length;
- const _datas = [];
- let data = {};
- for (let i = 0; i < length; i++) {
- data = params[i];
- _datas.push({
- idnumber: data[theadRule[1]],
- name: data[theadRule[2]],
- xsscore: data[theadRule[3]],
- });
- }
- exceldata = [...exceldata, ..._datas];
- return exceldata;
- }
- // 获取导入的XLSX文件中的数据
- async datacheck(studatas) {
- let errorcode = '0';
- const errormsg = [];
- for (const data of studatas) {
- // 判断是否为空
- if (!data.idnumber) {
- errorcode = '1';
- data.msg = data.msg + '身份证号不允许为空,';
- }
- if (!data.name) {
- errorcode = '1';
- data.msg = data.msg + '姓名不允许为空,';
- }
- if (!data.xsscore) {
- errorcode = '1';
- data.msg = data.msg + '评分不允许为空,';
- }
- if (errorcode === '1') {
- errormsg.push(data);
- }
- }
- return { errorcode, errormsg };
- }
- // 建立任务
- async toExport(body) {
- const fn = `教师导出 ${moment().format('YYYY-MM-DD HH:SS:mm')}`;
- const data = {
- title: fn,
- params: {
- project: 'center',
- service: 'teacher',
- method: 'export',
- body,
- },
- };
- if (this.missionBase) {
- const url = `${this.missionBase}/api/mission`;
- const res = await this.ctx.curl(url, {
- method: 'post',
- headers: {
- 'content-type': 'application/json',
- },
- data,
- dataType: 'json',
- });
- if (res.status !== 200 || res.data.errcode !== 0) {
- throw new BusinessError(ErrorCode.SERVICE_FAULT, '创建任务失败');
- }
- } else {
- throw new BusinessError(ErrorCode.SERVICE_FAULT, '未找到任务项目设置');
- }
- }
- // 导出
- async export({ missionid, model }) {
- assert(missionid, '缺少任务信息,无法执行任务');
- try {
- const head = model.map((i) => {
- // const { zh, model } = i;
- // const headObj = { header: zh };
- // if (model) headObj.key = model;
- // headObj.width = 20;
- // return headObj;
- return i.zh;
- });
- let fn = '教师导出';
- let skip = 0;
- const total = await this.count({});
- const times = Math.ceil(total / this.export_limit);
- let dp = null;
- const { downloadPath, fn: nfn } = await this.ctx.service.util.toAsyncExcel([head], fn, dp);
- dp = downloadPath;
- fn = nfn;
- for (let i = 0; i < times; i++) {
- const data = await this.query({}, { skip, limit: this.export_limit });
- if (data.length <= 0) break;
- const dataList = data.map((i) => {
- const obj = [];
- for (const m of model) {
- obj.push(i[m.model]);
- }
- return obj;
- });
- await this.ctx.service.util.toAsyncExcel(dataList, fn, dp);
- skip = skip + this.export_limit;
- const per = Math.ceil(((i + 1) / times) * 100);
- this.ctx.service.util.updateProcess(missionid, per);
- }
- this.ctx.service.util.updateProcess(missionid, '100', '2', {
- uri: dp,
- });
- } catch (error) {
- console.log('in function:error');
- this.ctx.service.util.updateProcess(missionid, undefined, '3');
- }
- }
- }
- module.exports = TeacherService;
|