attendance.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. const { openid, type, ibeacon } = data;
  23. assert(openid && type && ibeacon, '缺少信息项');
  24. // 通过openid取得学生信息
  25. const user = await this.umodel.findOne({ appopenid: openid });
  26. if (!user) {
  27. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '用户不存在');
  28. }
  29. console.log(user);
  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. if (location.ibeacon !== ibeacon) {
  50. throw new BusinessError(ErrorCode.BUSINESS, '考勤位置不正确');
  51. }
  52. const attendance = await this.model.findOne({
  53. termid: student.termid,
  54. batchid: student.batchid,
  55. classid: student.classid,
  56. studentid: student.id,
  57. });
  58. const datetime = sd.format(new Date(), 'YYYY-MM-DD HH:mm');
  59. // TODO 考勤时间没有处理
  60. const diffres = await this.islate(datetime, setting, type);
  61. if (diffres === 0) {
  62. throw new BusinessError(
  63. ErrorCode.BUSINESS,
  64. '考勤时间不正确,请稍后在签到'
  65. );
  66. }
  67. const newData = {
  68. date: datetime.substr(0, 10),
  69. time: datetime.substr(11, 5),
  70. type,
  71. status: diffres + '',
  72. };
  73. if (attendance) {
  74. // TODO: 保存数据
  75. const attends = attendance.attend;
  76. let result = false;
  77. for (const elm of attends) {
  78. if (
  79. elm.date === datetime.substr(0, 10) &&
  80. elm.type === '0' &&
  81. elm.time.substr(0, 2) === datetime.substr(11, 2)
  82. ) {
  83. result = true;
  84. break;
  85. }
  86. }
  87. if (!result) {
  88. const newattend = await attendance.attend.create(newData);
  89. console.log('newattend:', newattend);
  90. attendance.attend.push(newattend);
  91. await attendance.save();
  92. }
  93. } else {
  94. const newdatastu = {
  95. termid: student.termid,
  96. batchid: student.batchid,
  97. classid: student.classid,
  98. planyearid: student.planyearid,
  99. planid: student.planid,
  100. studentid: student.id,
  101. stuname: student.name,
  102. schname: student.school_name,
  103. schid: student.schid,
  104. attend: [ newData ],
  105. };
  106. await this.model.create(newdatastu);
  107. }
  108. } else if (type === '1') {
  109. console.log('寝室考勤');
  110. const beedroom = await this.bmodel.findOne({ code: student.bedroom });
  111. if (!beedroom) {
  112. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '寝室信息不存在');
  113. }
  114. if (beedroom.ibeacon !== ibeacon) {
  115. throw new BusinessError(ErrorCode.BUSINESS, '考勤位置不正确');
  116. }
  117. const attendance = await this.model.findOne({
  118. termid: student.termid,
  119. batchid: student.batchid,
  120. classid: student.classid,
  121. studentid: student.id,
  122. });
  123. const datetime = sd.format(new Date(), 'YYYY-MM-DD HH:mm');
  124. // TODO 考勤时间没有处理
  125. const diffres = await this.islate(datetime, setting, type);
  126. if (diffres === 0) {
  127. throw new BusinessError(
  128. ErrorCode.BUSINESS,
  129. '考勤时间不正确,请稍后在签到'
  130. );
  131. }
  132. const newData = {
  133. date: datetime.substr(0, 10),
  134. time: datetime.substr(11, 5),
  135. type,
  136. status: diffres + '',
  137. };
  138. if (attendance) {
  139. // TODO: 保存数据
  140. const attends = attendance.attend;
  141. let result = false;
  142. for (const elm of attends) {
  143. if (elm.date === datetime.substr(0, 10) && elm.type === '1') {
  144. result = true;
  145. break;
  146. }
  147. }
  148. if (!result) {
  149. const newattend = await attendance.attend.create(newData);
  150. console.log('newattend:', newattend);
  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. console.log(diffres);
  178. }
  179. // 判断上课考勤是否迟到和开始
  180. async islate(nowdata, setting, type) {
  181. nowdata = nowdata + ':00';
  182. let res = 0;
  183. if (type === '0') {
  184. const am_start = nowdata.substr(0, 10) + ' ' + setting.am_start + ':00';
  185. const am_end = nowdata.substr(0, 10) + ' ' + setting.am_end + ':00';
  186. const pm_start = nowdata.substr(0, 10) + ' ' + setting.pm_start + ':00';
  187. const pm_end = nowdata.substr(0, 10) + ' ' + setting.pm_end + ':00';
  188. const resamstart = moment(nowdata).diff(moment(am_start), 'minutes');
  189. const resamend = moment(nowdata).diff(moment(am_end), 'minutes');
  190. const respmstart = moment(nowdata).diff(moment(pm_start), 'minutes');
  191. const respmend = moment(nowdata).diff(moment(pm_end), 'minutes');
  192. // 当前时间大于am开始时间
  193. if (resamstart > 0) {
  194. // 当前时间小于pm开始时间
  195. if (respmstart < 0) {
  196. // 判断上午考勤是否迟到
  197. if (resamend > 0) {
  198. res = 2;
  199. } else {
  200. res = 1;
  201. }
  202. } else {
  203. // 判断下午考勤是否迟到
  204. if (respmend > 0) {
  205. res = 2;
  206. } else {
  207. res = 1;
  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. }
  224. return res;
  225. }
  226. async attendancecreateList({ studentIds }) {
  227. for (const studentId of studentIds) {
  228. // 查出这个学生,更新这个学生的签到并签到
  229. const student = await this.stumodel.findById(studentId);
  230. if (!student) {
  231. throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '学生信息不存在');
  232. }
  233. // 签到学生是否来了
  234. student.isComming = '1';
  235. await student.save();
  236. const attendInfo = {
  237. date: new Date().getDate(),
  238. time: new Date().getHours(),
  239. type: '0',
  240. status: '1',
  241. };
  242. const data = {
  243. planyearid: student.planyearid,
  244. planid: student.planid,
  245. termid: student.termid,
  246. batchid: student.batchid,
  247. classid: student.classid,
  248. schid: student.schid,
  249. schname: student.school_name,
  250. studentid: student.id,
  251. stuname: student.name,
  252. attendInfo,
  253. };
  254. await this.model.create(data);
  255. }
  256. }
  257. }
  258. module.exports = AttendanceService;