Browse Source

Merge branch 'master' of http://git.cc-lotus.info/new_train/service-center

cheny 4 năm trước cách đây
mục cha
commit
b238a9e448

+ 6 - 3
app/controller/.location.js

@@ -2,7 +2,8 @@ module.exports = {
   create: {
     requestBody: [
       '!name',
-      'ibeacon'
+      'ibeacon',
+      'type',
     ]
   },
   destroy: {
@@ -13,7 +14,8 @@ module.exports = {
     params: ['!id'],
     requestBody: [
       'name',
-      'ibeacon'
+      'ibeacon',
+      'type',
     ]
   },
   show: {
@@ -25,7 +27,8 @@ module.exports = {
   index: {
     parameters: {
       query: {
-        name: 'name'
+        name: 'name',
+        type: 'type',
       }
     },
     service: 'query',

+ 2 - 0
app/controller/.student.js

@@ -35,6 +35,7 @@ module.exports = {
       "diy",
       "isComming",
       "type",
+      "status",
     ],
   },
   destroy: {
@@ -78,6 +79,7 @@ module.exports = {
       "diy",
       "isComming",
       "type",
+      "status",
     ],
   },
   show: {

+ 6 - 4
app/controller/.teacher.js

@@ -7,8 +7,8 @@ module.exports = {
       '!gender',
       '!zynumber',
       '!zynumberfile',
-      '!schid',
-      '!schname',
+      'schid',
+      'schname',
       '!email',
       'openid',
       '!age',
@@ -32,7 +32,8 @@ module.exports = {
       'msscore',
       'xsscore',
       'file',
-      'status'
+      'status',
+      'jobaddress'
     ]
   },
   destroy: {
@@ -73,7 +74,8 @@ module.exports = {
       'msscore',
       'xsscore',
       'file',
-      'status'
+      'status',
+      'jobaddress'
     ]
   },
   show: {

+ 6 - 0
app/controller/teacher.js

@@ -25,6 +25,12 @@ class TeacherController extends Controller {
     this.ctx.ok({ data: res });
   }
 
+  // 教师评分上报
+  async teaimport() {
+    const res = await this.service.teaimport(this.ctx.request.body);
+    this.ctx.ok({ msg: 'created', data: res });
+  }
+
 }
 
 module.exports = CrudController(TeacherController, meta);

+ 3 - 0
app/controller/weixin.js

@@ -80,10 +80,13 @@ class WeixinController extends Controller {
       const { redirect_uri, type, uid, qrcode } = JSON.parse(val);
       console.log('redirect_uri-->' + redirect_uri);
       const user = await this.ctx.service.user.findByOpenid(openid);
+      console.log('type-->' + type);
       if (type === '0') {
         // 通过openid取得用户信息
         if (user) {
           const token = await this.ctx.service.login.createJwt(user);
+          console.log('token-->' + token);
+          console.log('user.type-->' + user.type);
           if (user.type === '4') {
             const to_uri = urljoin(redirect_uri, `?token=${token}`);
             // TODO: 重定性页面

+ 1 - 0
app/model/lesson.js

@@ -11,6 +11,7 @@ const lessonInfo = new Schema({
   date: { type: String, required: false, maxLength: 500 }, // 日期
   time: { type: String, required: false, maxLength: 500 }, // 时间
   day: { type: String, required: false, maxLength: 500 }, // 课程天数,半天或一天
+  reason: { type: String, required: false, maxLength: 500 }, // 原因
 });
 
 // 课程表

+ 1 - 0
app/model/location.js

@@ -5,6 +5,7 @@ const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
 // 位置表
 const LocationSchema = {
   name: { type: String, required: true, maxLength: 500 }, // 名称
+  type: { type: String, required: true, maxLength: 10 }, // 0、教室位置 1、开班仪式地点 2、拓展计划地点 3、用餐地点
   ibeacon: { type: String, required: true, maxLength: 500 }, // 蓝牙设备号
 };
 

+ 1 - 0
app/model/student.js

@@ -38,6 +38,7 @@ const StudentSchema = {
   diy: { type: { Object }, required: false, zh: '自定义' }, // 自定义
   isComming: { type: String, default: '0', zh: '签到' }, // 是否签到0否,1是
   type: { type: String, required: false, maxLength: 200, default: '0' }, // 类型:0-正常,1-特殊
+  status: { type: String, required: false, maxLength: 200, default: '1' }, // 0:待确定。1:确定,2:失败
 };
 
 

+ 20 - 5
app/model/teacher.js

@@ -22,6 +22,20 @@ const FileInfo = new Schema({
   type: { type: String, required: false, maxLength: 200 }, // 资料类别,教案(Word)、PPT、视频(Mp4)、其他(zip)
 });
 
+// 教育培训经历
+const experienceInfo = new Schema({
+  startDate: { type: String, required: false, maxLength: 200 }, // 开始日期
+  endDate: { type: String, required: false, maxLength: 200 }, // 结束日期
+  content: { type: String, required: false }, // 内容
+});
+
+// 主要学术成果及获奖情况
+const academicInfo = new Schema({
+  startDate: { type: String, required: false, maxLength: 200 }, // 开始日期
+  endDate: { type: String, required: false, maxLength: 200 }, // 结束日期
+  content: { type: String, required: false }, // 内容
+});
+
 // 教师表
 const TeacherSchema = {
   name: { type: String, required: true, maxLength: 200 }, // 教师姓名
@@ -29,9 +43,9 @@ const TeacherSchema = {
   idnumber: { type: String, required: true, maxLength: 200 }, // 身份证号
   gender: { type: String, required: true, maxLength: 200 }, // 教师性别
   zynumber: { type: String, required: true, maxLength: 200 }, // 职业资格证号
-  zynumberfile: { type: [ zynumberfileInfo ], required: true, maxLength: 200 }, // 职业资格证图片
-  schid: { type: String, required: true, maxLength: 200 }, // 学校id
-  schname: { type: String, required: true, maxLength: 200 }, // 学校名称
+  zynumberfile: { type: [ zynumberfileInfo ], select: true }, // 职业资格证图片
+  schid: { type: String, required: false, maxLength: 200 }, // 学校id
+  schname: { type: String, required: false, maxLength: 200 }, // 学校名称
   email: { type: String, required: true, maxLength: 200 }, // 邮箱
   openid: { type: String, required: false, maxLength: 200 }, // 微信openid
   age: { type: String, required: true, maxLength: 200 }, // 年龄
@@ -45,10 +59,11 @@ const TeacherSchema = {
   degree: { type: String, required: true, maxLength: 200 }, // 最后学位
   major: { type: String, required: true, maxLength: 200 }, // 教师所学专业
   schlesson: { type: String, required: true, maxLength: 200 }, // 教师在校所教课程
-  experience: { type: String, required: true, maxLength: 200 }, // 教育培训经历(从大学开始)
+  experience: { type: [ experienceInfo ], select: true }, // 教育培训经历(从大学开始)
   courses: { type: String, required: true, maxLength: 200 }, // 主讲课程
-  academic: { type: String, required: true, maxLength: 200 }, // 主要学术成果及获奖情况
+  academic: { type: [ academicInfo ], select: true }, // 主要学术成果及获奖情况
   jobyear: { type: String, required: true, maxLength: 200 }, // 从事就业创业教学工作年限
+  jobaddress: { type: String, required: false, maxLength: 500 }, // 工作地点
   subid: { type: String, required: true, maxLength: 200 }, // 科目id
   islyteacher: { type: String, required: true, maxLength: 200 }, // 是否可讲礼仪课,0-否,1-是
   zlscore: { type: String, required: false, maxLength: 200 }, // 资料评分

+ 1 - 0
app/router.js

@@ -46,6 +46,7 @@ module.exports = app => {
     '/api/train/teacher/status',
     controller.teacher.status
   );
+  router.post('/api/train/teacher/teaimport', controller.teacher.teaimport);
 
   // 作业表配置路由
   router.resources('task', '/api/train/task', controller.task); // index、create、show、destroy

+ 28 - 1
app/service/class.js

@@ -100,10 +100,37 @@ class ClassService extends CrudService {
     }
     // 循环出所有班级进行添加操作
     const term = await res.termnum.id(termid);
+    let yclocationid = ''; // 用餐地点
+    let kzjhlocationid = ''; // 拓展计划地点
+    let kbyslocationid = ''; // 开班仪式地点
+    let jslocationid = ''; // 教室位置
+    const locations = await this.locamodel.find();
+    const jslocationids = _.filter(locations, { type: '0' });
+    const kbyslocationids = _.filter(locations, { type: '1' });
+    const kzjhlocationids = _.filter(locations, { type: '2' });
+    const yclocationids = _.filter(locations, { type: '3' });
     for (const batch of term.batchnum) {
       const classs = await batch.class;
       for (const cla of classs) {
-        const newdata = { name: cla.name, number: cla.number, batchid: batch.id, termid: term.id, planid: res.id, type: cla.type, headteacherid: cla.headteacherid };
+        // 取得班级各个地点
+        // 同一地点同期只能使用一次
+        if (jslocationids.length > 0) {
+          jslocationid = jslocationids[0].id;
+          _.remove(jslocationids, { id: jslocationid });
+        }
+        if (kbyslocationids.length > 0) {
+          kbyslocationid = kbyslocationids[0].id;
+          _.remove(kbyslocationids, { id: kbyslocationid });
+        }
+        if (kzjhlocationids.length > 0) {
+          kzjhlocationid = kzjhlocationids[0].id;
+          _.remove(kzjhlocationids, { id: kzjhlocationid });
+        }
+        if (yclocationids.length > 0) {
+          yclocationid = yclocationids[0].id;
+          _.remove(yclocationids, { id: yclocationid });
+        }
+        const newdata = { name: cla.name, number: cla.number, batchid: batch.id, termid: term.id, planid: res.id, type: cla.type, headteacherid: cla.headteacherid, jslocationid, kbyslocationid, kzjhlocationid, yclocationid };
         await this.model.create(newdata);
       }
     }

+ 47 - 1
app/service/lesson.js

@@ -15,6 +15,10 @@ class LessonService extends CrudService {
     this.tmodel = this.ctx.model.Trainplan;
     this.clamodel = this.ctx.model.Class;
     this.lmodel = this.ctx.model.Lessonmode;
+    this.teamodel = this.ctx.model.Teacher;
+    this.stumodel = this.ctx.model.Student;
+    this.schmodel = this.ctx.model.School;
+
   }
 
   // 自动排课私有方法
@@ -59,6 +63,7 @@ class LessonService extends CrudService {
           const newlesson = [];
           for (const day of sedays) {
             // 循环课程模板,将模板信息排入班级课程表中
+            const teachids = [];
             for (const lessm of lessons_) {
               // 循环插入模板信息
               if (lessm['day' + i] !== '--') {
@@ -70,8 +75,13 @@ class LessonService extends CrudService {
                 }
                 let allday = 0;
                 if (i === 6) {
-                  allday = _lessonmode.allday;
+                  // 判断是否有外市的学生有的时候 将其设置为半天
+                  const ishalfday = await this.ishalfday(cla.id);
+                  if (ishalfday) {
+                    allday = 1;
+                  }
                 }
+
                 const data = {
                   subid: _subid,
                   subname: lessm['day' + i],
@@ -79,6 +89,13 @@ class LessonService extends CrudService {
                   time: lessm.time,
                   day: allday,
                 };
+                // 将教师按照分数的综合成绩排序,上报时间,安排教师.
+                const teacher_ = await this.autoteacher(_subid, teachids);
+                if (teacher_) {
+                  data.teaid = teacher_.id;
+                  data.teaname = teacher_.name;
+                  teachids.push(teacher_.id);
+                }
                 newlesson.push(data);
               }
             }
@@ -97,6 +114,35 @@ class LessonService extends CrudService {
     }
   }
 
+  // 自动排教师,按照分数的综合成绩排序,上报时间,安排教师
+  async autoteacher(subid, teachids) {
+    // 按照上报时间取得所有老师,进行正序排列
+    const teachers = await this.teamodel.find({ subid, status: '4' }).sort({ zlscore: '-1', msscore: '-1', xsscore: '-1' });
+    for (const teaid of teachids) {
+      _.remove(teachers, item => item.id === teaid);
+    }
+    let teacher = {};
+    if (teachers.length > 0) {
+      teacher = teachers[0];
+    }
+    return teacher;
+  }
+
+  // 判断是否为半天
+  async ishalfday(classid) {
+    // 通过班级id取得所有学生
+    const students = await this.stumodel.find({ classid });
+    let res = false;
+    for (const stu of students) {
+      const sch = await this.schmodel.findOne({ code: stu.schid });
+      if (sch && sch.hascar === '0') {
+        res = true;
+        break;
+      }
+    }
+    return res;
+  }
+
   // 取得日期间所有日期
   async getAllDays(begin_date, end_date) {
     const errArr = [],

+ 3 - 1
app/service/login.js

@@ -59,8 +59,10 @@ class LoginService extends CrudService {
       const result = await this.tModel.findById(_userid);
       res = { userid: _userid, schid: result.schid, schname: result.schname, name, subid: result.subid, type, id: _id, status };
     } else if (type === '4') {
-      _userid = uid.toString();
+      _userid = uid;
+      console.log('进入查询--' + _userid);
       const result = await this.stuModel.findById(_userid);
+      console.log(result);
       res = { userid: _userid, schid: result.schid, schname: result.school_name, termid: result.termid, batchid: result.batchid, classid: result.classid, bedroomid: result.bedroomid, bedroom: result.bedroom, job: result.job, name, type, id: _id, status, planid: result.planid };
     }
     const token = await jwt.sign(res, secret, { expiresIn, issuer, subject });

+ 105 - 2
app/service/notice.js

@@ -17,17 +17,24 @@ class NoticeService extends CrudService {
     this.schmodel = this.ctx.model.School;
     this.heamodel = this.ctx.model.Headteacher;
     this.teamodel = this.ctx.model.Teacher;
+    this.lmodel = this.ctx.model.Lesson;
+    this.clsmodel = this.ctx.model.Class;
   }
 
   async create(data) {
-    const { planyearid, planid, termid, classid, noticeid, content, notified } = data;
+    const { planyearid, planid, termid, classid, noticeid, content, notified, type } = data;
     assert(planyearid, '年度计划id为必填项');
     assert(planid, '计划id为必填项');
     assert(noticeid, '通知人id为必填项');
     assert(content, '通知内容为必填项');
     const res = await this.model.create(data);
     if (res) {
-      for (const elm of res.notified) {
+      // 判断班级id是否为空
+      // 不为空时被通知人:当前期,班下的学生,教师,班主任,并使用type判断
+      const notified_ = await this.getnotified(termid, classid, type);
+      res.notified = notified_;
+      await res.save();
+      for (const elm of notified_) {
         const user = await this.umodel.findOne({ uid: elm.notifiedid });
         if (!user) {
           continue;
@@ -44,6 +51,102 @@ class NoticeService extends CrudService {
     }
   }
 
+  // 取得要通知的人
+  async getnotified(termid, classid, type) {
+    const notified_ = [];
+    if (classid) {
+      if (type === '1') {
+        const students = await this.stumodel.find({ classid });
+        for (const stu of students) {
+          const newdata = { notifiedid: stu.id, username: stu.name };
+          notified_.push(newdata);
+        }
+      } else if (type === '2') {
+        const lesson = await this.lmodel.findOne({ classid });
+        for (const elm of lesson.lessons) {
+          const newdata = { notifiedid: elm.teaid, username: elm.teaname };
+          notified_.push(newdata);
+        }
+      } else if (type === '3') {
+        const class_ = await this.clsmodel.findById(classid);
+        if (class_) {
+          const htea = await this.heamodel.findById(class_.headteacherid);
+          if (htea) {
+            const newdata = { notifiedid: htea.id, username: htea.name };
+            notified_.push(newdata);
+          }
+        }
+      } else if (type === '0') {
+        const students = await this.stumodel.find({ classid });
+        for (const stu of students) {
+          const newdata = { notifiedid: stu.id, username: stu.name };
+          notified_.push(newdata);
+        }
+        const lesson = await this.lmodel.findOne({ classid });
+        for (const elm of lesson.lessons) {
+          const newdata = { notifiedid: elm.teaid, username: elm.teaname };
+          notified_.push(newdata);
+        }
+        const class_ = await this.clsmodel.findById(classid);
+        if (class_) {
+          const htea = await this.heamodel.findById(class_.headteacherid);
+          if (htea) {
+            const newdata = { notifiedid: htea.id, username: htea.name };
+            notified_.push(newdata);
+          }
+        }
+      }
+    } else {
+      // 没输入班级的时候
+      if (type === '1') {
+        const students = await this.stumodel.find({ termid });
+        for (const stu of students) {
+          const newdata = { notifiedid: stu.id, username: stu.name };
+          notified_.push(newdata);
+        }
+      } else if (type === '2') {
+        const lessons = await this.lmodel.find({ termid });
+        for (const les of lessons) {
+          for (const elm of les.lessons) {
+            const newdata = { notifiedid: elm.teaid, username: elm.teaname };
+            notified_.push(newdata);
+          }
+        }
+      } else if (type === '3') {
+        const class_ = await this.clsmodel.find({ termid });
+        for (const cla of class_) {
+          const htea = await this.heamodel.findById(cla.headteacherid);
+          if (htea) {
+            const newdata = { notifiedid: htea.id, username: htea.name };
+            notified_.push(newdata);
+          }
+        }
+      } else if (type === '0') {
+        const students = await this.stumodel.find({ termid });
+        for (const stu of students) {
+          const newdata = { notifiedid: stu.id, username: stu.name };
+          notified_.push(newdata);
+        }
+        const lessons = await this.lmodel.find({ termid });
+        for (const les of lessons) {
+          for (const elm of les.lessons) {
+            const newdata = { notifiedid: elm.teaid, username: elm.teaname };
+            notified_.push(newdata);
+          }
+        }
+        const class_ = await this.clsmodel.find({ termid });
+        for (const cla of class_) {
+          const htea = await this.heamodel.findById(cla.headteacherid);
+          if (htea) {
+            const newdata = { notifiedid: htea.id, username: htea.name };
+            notified_.push(newdata);
+          }
+        }
+      }
+    }
+    return notified_;
+  }
+
   async look(data) {
     const { noticeid, uid } = data;
     const notice = await this.model.findById(noticeid);

+ 40 - 0
app/service/school.js

@@ -233,6 +233,10 @@ class SchoolService extends CrudService {
         errorcode = '1';
         data.msg = data.msg + '性别不允许为空,';
       }
+      if (!data.nation) {
+        errorcode = '1';
+        data.msg = data.msg + '民族不允许为空,';
+      }
       if (!data.id_number) {
         errorcode = '1';
         data.msg = data.msg + '身份证号不允许为空,';
@@ -245,6 +249,42 @@ class SchoolService extends CrudService {
         errorcode = '1';
         data.msg = data.msg + '手机号不允许为空,';
       }
+      if (!data.faculty) {
+        errorcode = '1';
+        data.msg = data.msg + '院系不允许为空,';
+      }
+      if (!data.major) {
+        errorcode = '1';
+        data.msg = data.msg + '专业不允许为空,';
+      }
+      if (!data.entry_year) {
+        errorcode = '1';
+        data.msg = data.msg + '入学年份不允许为空,';
+      }
+      if (!data.finish_year) {
+        errorcode = '1';
+        data.msg = data.msg + '毕业年份不允许为空,';
+      }
+      if (!data.school_job) {
+        errorcode = '1';
+        data.msg = data.msg + '职务不允许为空,';
+      }
+      if (!data.qq) {
+        errorcode = '1';
+        data.msg = data.msg + 'QQ号不允许为空,';
+      }
+      if (!data.family_place) {
+        errorcode = '1';
+        data.msg = data.msg + '家庭所在地不允许为空,';
+      }
+      if (!data.family_is_hard) {
+        errorcode = '1';
+        data.msg = data.msg + '家庭是否困难不允许为空,';
+      }
+      if (!data.have_grant) {
+        errorcode = '1';
+        data.msg = data.msg + '是否获得过助学金不允许为空,';
+      }
       if (!/^\d{11}$/i.test(data.phone)) {
         errorcode = '1';
         data.msg = data.msg + '手机号不正确,';

+ 87 - 0
app/service/teacher.js

@@ -3,6 +3,7 @@
 
 const assert = require('assert');
 const _ = require('lodash');
+const XLSX = require('xlsx');
 const { CrudService } = require('naf-framework-mongoose/lib/service');
 const { BusinessError, ErrorCode } = require('naf-core').Error;
 const stringRandom = require('string-random');
@@ -63,6 +64,92 @@ class TeacherService extends CrudService {
     }
   }
 
+  // 教室分数上传
+  async teaimport(data) {
+    const { filepath } = data;
+    assert(filepath, 'filepath不能为空');
+    // 取得excle中数据
+    const _filepath = this.ctx.app.config.baseUrl + filepath;
+    console.log(_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.xsscore = tea.xsscore;
+        await res.save();
+      }
+    }
+    return datacheck;
+  }
+
+  // 获取导入的XLSX文件中的数据
+  async getImportXLSXData(filepath) {
+    console.log(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 };
+  }
+
 }
 
 module.exports = TeacherService;