| | |
| | | import { Provide } from '@midwayjs/core'; |
| | | import { BaseService } from '@cool-midway/core'; |
| | | import { BaseService, CoolCommException } from '@cool-midway/core'; |
| | | import { InjectEntityModel } from '@midwayjs/typeorm'; |
| | | import { Repository } from 'typeorm'; |
| | | import * as moment from 'moment'; |
| | | import { PushSorterAttendanceEntity } from '../entity/sorterattendance'; |
| | | import { BasicdataSorterEntity } from '../../basicdata/entity/sorter'; |
| | | |
| | | /** |
| | | * 分拣员健康告警服务 |
| | | * 分拣员签到签退 |
| | | */ |
| | | @Provide() |
| | | export class PushSorterAttendanceService extends BaseService { |
| | | @InjectEntityModel(PushSorterAttendanceEntity) |
| | | pushSorterAttendanceEntity: Repository<PushSorterAttendanceEntity>; |
| | | } |
| | | |
| | | @InjectEntityModel(BasicdataSorterEntity) |
| | | basicdataSorterEntity: Repository<BasicdataSorterEntity>; |
| | | |
| | | async getSorter(sorterId: string) { |
| | | const sorter = await this.basicdataSorterEntity.findOneBy({ |
| | | businessId: String(sorterId || '').trim(), |
| | | }); |
| | | if (!sorter || sorter.status !== 0) { |
| | | throw new CoolCommException('分拣员账号不可用'); |
| | | } |
| | | return sorter; |
| | | } |
| | | |
| | | private locationOf(param: any) { |
| | | if (param.longitude == null || param.latitude == null) { |
| | | throw new CoolCommException('缺少定位信息'); |
| | | } |
| | | return `${Number(param.longitude)},${Number(param.latitude)}`; |
| | | } |
| | | |
| | | private today() { |
| | | return moment().format('YYYY-MM-DD'); |
| | | } |
| | | |
| | | private async todayRow(idCard: string) { |
| | | return this.pushSorterAttendanceEntity |
| | | .createQueryBuilder('a') |
| | | .where('a.idCard = :idCard', { idCard }) |
| | | .andWhere('a.workDate = :workDate', { workDate: this.today() }) |
| | | .getOne(); |
| | | } |
| | | |
| | | async checkIn(param: any) { |
| | | const sorter = await this.getSorter(param.sorterId); |
| | | const loc = this.locationOf(param); |
| | | const now = new Date(); |
| | | const workDate = this.today(); |
| | | let row = await this.todayRow(sorter.businessId); |
| | | if (row?.checkInTime) { |
| | | throw new CoolCommException('今日已签到'); |
| | | } |
| | | if (!row) { |
| | | row = this.pushSorterAttendanceEntity.create({ |
| | | idCard: sorter.businessId, |
| | | departmentId: sorter.departmentId, |
| | | uploadTime: now, |
| | | workDate: workDate as any, |
| | | checkInTime: now, |
| | | checkInLocation: loc, |
| | | workHours: 0, |
| | | status: '缺卡', |
| | | }); |
| | | } else { |
| | | row.departmentId = sorter.departmentId; |
| | | row.uploadTime = now; |
| | | row.checkInTime = now; |
| | | row.checkInLocation = loc; |
| | | } |
| | | await this.pushSorterAttendanceEntity.save(row); |
| | | return { |
| | | message: '签到成功', |
| | | workDate, |
| | | checkInTime: now, |
| | | checkInLocation: loc, |
| | | }; |
| | | } |
| | | |
| | | async checkOut(param: any) { |
| | | const sorter = await this.getSorter(param.sorterId); |
| | | const loc = this.locationOf(param); |
| | | const now = new Date(); |
| | | const workDate = this.today(); |
| | | const row = await this.todayRow(sorter.businessId); |
| | | if (!row?.checkInTime) { |
| | | throw new CoolCommException('请先上班签到'); |
| | | } |
| | | if (row.checkOutTime) { |
| | | throw new CoolCommException('今日已签退'); |
| | | } |
| | | const start = new Date(row.checkInTime).getTime(); |
| | | const hours = Math.max(0, (now.getTime() - start) / 3600000); |
| | | row.uploadTime = now; |
| | | row.checkOutTime = now; |
| | | row.checkOutLocation = loc; |
| | | row.workHours = Math.round(hours * 100) / 100; |
| | | row.status = '正常'; |
| | | await this.pushSorterAttendanceEntity.save(row); |
| | | return { |
| | | message: '签退成功', |
| | | workDate, |
| | | checkOutTime: now, |
| | | checkOutLocation: loc, |
| | | workHours: row.workHours, |
| | | }; |
| | | } |
| | | } |