attendance.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. 'use strict';
  2. const assert = require('assert');
  3. const _ = require('lodash');
  4. const sd = require('silly-datetime');
  5. const moment = require('moment');
  6. const { ObjectId } = require('mongoose').Types;
  7. const { CrudService } = require('naf-framework-mongoose/lib/service');
  8. const student = require('../model/student');
  9. const { BusinessError, ErrorCode } = require('naf-core').Error;
  10. class AttendanceService extends CrudService {
  11. constructor(ctx) {
  12. super(ctx, 'attendance');
  13. this.model = this.ctx.model.Attendance;
  14. this.stumodel = this.ctx.model.Student;
  15. this.umodel = this.ctx.model.User;
  16. this.clamodel = this.ctx.model.Class;
  17. this.lomodel = this.ctx.model.Location;
  18. this.bmodel = this.ctx.model.Bedroom;
  19. this.setmodel = this.ctx.model.Setting;
  20. }
  21. async attendancecreate(data) {
  22. // 修改ibeacon=>[],存有 limit 范围内的所有蓝牙设备号
  23. const { openid, type, ibeacon } = data;
  24. assert(openid && type && ibeacon, '缺少信息项');
  25. // 通过openid取得学生信息
  26. const user = await this.umodel.findOne({ appopenid: openid });
  27. if (!user) {
  28. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '用户不存在');
  29. }
  30. const student = await this.stumodel.findById(user.uid);
  31. if (!student) {
  32. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '学生信息不存在');
  33. }
  34. // 取得设置表内考勤时间
  35. const setting = await this.setmodel.findOne();
  36. if (!setting) {
  37. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '考勤设置信息不存在');
  38. }
  39. // type为0是上课考勤
  40. if (type === '0') {
  41. const classes = await this.clamodel.findById(student.classid);
  42. if (!classes) {
  43. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '班级信息不存在');
  44. }
  45. const location = await this.lomodel.findById(classes.jslocationid);
  46. if (!location) {
  47. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '位置信息不存在');
  48. }
  49. // 判断,location的蓝牙号在不在ibeacon中
  50. const r = ibeacon.find(f => `${f}` === `${location.ibeacon}`);
  51. if (!r) {
  52. throw new BusinessError(ErrorCode.BUSINESS, '考勤位置不正确');
  53. }
  54. const attendance = await this.model.findOne({
  55. termid: student.termid,
  56. batchid: student.batchid,
  57. classid: student.classid,
  58. studentid: student.id,
  59. });
  60. const datetime = sd.format(new Date(), 'YYYY-MM-DD HH:mm');
  61. // TODO 考勤时间没有处理
  62. const diffres = await this.islate(datetime, setting, type);
  63. if (diffres === 0) {
  64. throw new BusinessError(
  65. ErrorCode.BUSINESS,
  66. '考勤时间不正确,请稍后在签到'
  67. );
  68. }
  69. const newData = {
  70. date: datetime.substr(0, 10),
  71. time: datetime.substr(11, 5),
  72. type,
  73. status: diffres + '',
  74. };
  75. if (attendance) {
  76. // TODO: 保存数据
  77. const attends = attendance.attend;
  78. let result = false;
  79. for (const elm of attends) {
  80. if (
  81. elm.date === datetime.substr(0, 10) &&
  82. elm.type === '0' &&
  83. elm.time.substr(0, 2) === datetime.substr(11, 2)
  84. ) {
  85. result = true;
  86. break;
  87. }
  88. }
  89. if (!result) {
  90. const newattend = await attendance.attend.create(newData);
  91. attendance.attend.push(newattend);
  92. await attendance.save();
  93. }
  94. } else {
  95. const newdatastu = {
  96. termid: student.termid,
  97. batchid: student.batchid,
  98. classid: student.classid,
  99. planyearid: student.planyearid,
  100. planid: student.planid,
  101. studentid: student.id,
  102. stuname: student.name,
  103. schname: student.school_name,
  104. schid: student.schid,
  105. attend: [ newData ],
  106. };
  107. await this.model.create(newdatastu);
  108. }
  109. } else if (type === '1') {
  110. const beedroom = await this.bmodel.findOne({ code: student.bedroom });
  111. if (!beedroom) {
  112. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '寝室信息不存在');
  113. }
  114. const r = ibeacon.find(f => `${f}` === `${beedroom.ibeacon}`);
  115. if (!r) {
  116. throw new BusinessError(ErrorCode.BUSINESS, '考勤位置不正确');
  117. }
  118. const attendance = await this.model.findOne({
  119. termid: student.termid,
  120. batchid: student.batchid,
  121. classid: student.classid,
  122. studentid: student.id,
  123. });
  124. const datetime = sd.format(new Date(), 'YYYY-MM-DD HH:mm');
  125. // TODO 考勤时间没有处理
  126. const diffres = await this.islate(datetime, setting, type);
  127. if (diffres === 0) {
  128. throw new BusinessError(
  129. ErrorCode.BUSINESS,
  130. '考勤时间不正确,请稍后在签到'
  131. );
  132. }
  133. const newData = {
  134. date: datetime.substr(0, 10),
  135. time: datetime.substr(11, 5),
  136. type,
  137. status: diffres + '',
  138. };
  139. if (attendance) {
  140. // TODO: 保存数据
  141. const attends = attendance.attend;
  142. let result = false;
  143. for (const elm of attends) {
  144. if (elm.date === datetime.substr(0, 10) && elm.type === '1') {
  145. result = true;
  146. break;
  147. }
  148. }
  149. if (!result) {
  150. const newattend = await attendance.attend.create(newData);
  151. attendance.attend.push(newattend);
  152. await attendance.save();
  153. }
  154. } else {
  155. const newdatastu = {
  156. termid: student.termid,
  157. batchid: student.batchid,
  158. classid: student.classid,
  159. studentid: student.id,
  160. schid: student.schid,
  161. stuname: student.name,
  162. schname: student.school_name,
  163. attend: [ newData ],
  164. };
  165. await this.model.create(newdatastu);
  166. }
  167. }
  168. }
  169. async test() {
  170. const setting = await this.setmodel.findOne();
  171. if (!setting) {
  172. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '考勤设置信息不存在');
  173. }
  174. const datetime = sd.format(new Date(), 'YYYY-MM-DD HH:mm');
  175. // TODO 考勤时间没有处理
  176. const diffres = await this.islate(datetime, setting, '0');
  177. }
  178. // 判断上课考勤是否迟到和开始
  179. async islate(nowdata, setting, type) {
  180. nowdata = nowdata + ':00';
  181. let res = 0;
  182. if (type === '0') {
  183. const am_start = nowdata.substr(0, 10) + ' ' + setting.am_start + ':00';
  184. const am_end = nowdata.substr(0, 10) + ' ' + setting.am_end + ':00';
  185. const pm_start = nowdata.substr(0, 10) + ' ' + setting.pm_start + ':00';
  186. const pm_end = nowdata.substr(0, 10) + ' ' + setting.pm_end + ':00';
  187. const resamstart = moment(nowdata).diff(moment(am_start), 'minutes');
  188. const resamend = moment(nowdata).diff(moment(am_end), 'minutes');
  189. const respmstart = moment(nowdata).diff(moment(pm_start), 'minutes');
  190. const respmend = moment(nowdata).diff(moment(pm_end), 'minutes');
  191. // 当前时间大于am开始时间
  192. if (resamstart > 0) {
  193. // 当前时间小于pm开始时间
  194. if (respmstart < 0) {
  195. // 判断上午考勤是否迟到
  196. if (resamend > 0) {
  197. res = 2;
  198. } else {
  199. res = 1;
  200. }
  201. } else {
  202. // 判断下午考勤是否迟到
  203. if (respmend > 0) {
  204. res = 2;
  205. } else {
  206. res = 1;
  207. }
  208. }
  209. }
  210. } else if (type === '1') {
  211. const bd_start = nowdata.substr(0, 10) + ' ' + setting.bd_start + ':00';
  212. const bd_end = nowdata.substr(0, 10) + ' ' + setting.bd_end + ':00';
  213. const resstart = moment(nowdata).diff(moment(bd_start), 'minutes');
  214. const resend = moment(nowdata).diff(moment(bd_end), 'minutes');
  215. if (resstart > 0) {
  216. if (resend > 0) {
  217. res = 2;
  218. } else {
  219. res = 1;
  220. }
  221. }
  222. }
  223. return res;
  224. }
  225. async attendancecreateList({ studentIds }) {
  226. for (const studentId of studentIds) {
  227. // 查出这个学生,更新这个学生的签到并签到
  228. const student = await this.stumodel.findById(studentId);
  229. if (!student) {
  230. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '学生信息不存在');
  231. }
  232. // 签到学生是否来了
  233. student.isComming = '1';
  234. await student.save();
  235. const attendInfo = {
  236. date: new Date().getDate(),
  237. time: new Date().getHours(),
  238. type: '0',
  239. status: '1',
  240. };
  241. const data = {
  242. planyearid: student.planyearid,
  243. planid: student.planid,
  244. termid: student.termid,
  245. batchid: student.batchid,
  246. classid: student.classid,
  247. schid: student.schid,
  248. schname: student.school_name,
  249. studentid: student.id,
  250. stuname: student.name,
  251. attendInfo,
  252. };
  253. await this.model.create(data);
  254. }
  255. }
  256. }
  257. module.exports = AttendanceService;