attendance.js 8.7 KB

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