作者 yangfu

feat: 考勤打卡记录上报

@@ -2,8 +2,11 @@ package service @@ -2,8 +2,11 @@ package service
2 2
3 import ( 3 import (
4 "github.com/linmadan/egglib-go/core/application" 4 "github.com/linmadan/egglib-go/core/application"
  5 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
5 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/attendance/command" 6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/attendance/command"
6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
7 ) 10 )
8 11
9 func (attendanceService *AttendanceService) WorkerAttendanceReport(cmd *command.WorkerAttendanceReportCommand) (interface{}, error) { 12 func (attendanceService *AttendanceService) WorkerAttendanceReport(cmd *command.WorkerAttendanceReportCommand) (interface{}, error) {
@@ -26,7 +29,10 @@ func (attendanceService *AttendanceService) WorkerAttendanceReport(cmd *command. @@ -26,7 +29,10 @@ func (attendanceService *AttendanceService) WorkerAttendanceReport(cmd *command.
26 // log.Logger.Error(err.Error()) 29 // log.Logger.Error(err.Error())
27 // return nil, err 30 // return nil, err
28 //} 31 //}
29 - 32 + attendanceReportService, _ := domainService.NewPGWorkerAttendanceReportService(transactionContext.(*pgTransaction.TransactionContext))
  33 + if _, err := attendanceReportService.Report(constant.MANUFACTURE_WEIGH_DEFAULT_COMPANYID, constant.MANUFACTURE_WEIGH_DEFAULT_COMPANYID, cmd.DeviceZkTeco); err != nil {
  34 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  35 + }
30 if err := transactionContext.CommitTransaction(); err != nil { 36 if err := transactionContext.CommitTransaction(); err != nil {
31 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 37 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
32 } 38 }
@@ -28,17 +28,14 @@ type CreateProductPlanCommand struct { @@ -28,17 +28,14 @@ type CreateProductPlanCommand struct {
28 //PlanProductName string `cname:"计划的产品名称" json:"planProductName"` 28 //PlanProductName string `cname:"计划的产品名称" json:"planProductName"`
29 // 产品ID 29 // 产品ID
30 ProductId int `cname:"产品ID" json:"productId" valid:"Required"` 30 ProductId int `cname:"产品ID" json:"productId" valid:"Required"`
  31 + // 投入量规格 默认份
  32 + DevotedUnit string `cname:"投入量规格" json:"devotedUnit" `
31 // 数量(保留两位小数) 33 // 数量(保留两位小数)
32 Quantity float64 `cname:"数量(保留两位小数)" json:"quantity" valid:"Required"` 34 Quantity float64 `cname:"数量(保留两位小数)" json:"quantity" valid:"Required"`
33 - // 单位  
34 - //Unit string `cname:"单位" json:"unit" `  
35 - // 单份重量(原材料)  
36 - //nitWeight float64 `cname:"单份重量(原材料)" json:"unitWeight" valid:"Required"`  
37 // 重量 35 // 重量
38 Weight float64 `cname:"重量" json:"weight" valid:"Required"` 36 Weight float64 `cname:"重量" json:"weight" valid:"Required"`
39 // 备注 37 // 备注
40 Remark string `cname:"备注" json:"remark"` 38 Remark string `cname:"备注" json:"remark"`
41 -  
42 // 生产日期 39 // 生产日期
43 ProductDateTime time.Time `cname:"生产日期" json:"-" ` 40 ProductDateTime time.Time `cname:"生产日期" json:"-" `
44 } 41 }
@@ -49,8 +46,8 @@ func (createProductPlanCommand *CreateProductPlanCommand) Valid(validation *vali @@ -49,8 +46,8 @@ func (createProductPlanCommand *CreateProductPlanCommand) Valid(validation *vali
49 validation.Error(err.Error()) 46 validation.Error(err.Error())
50 return 47 return
51 } 48 }
52 - if t, err := time.Parse("2006/01/02", createProductPlanCommand.ProductDate); err != nil {  
53 - validation.Error("时间格式有误 2006/01/02") 49 + if t, err := time.Parse("2006-01-02", createProductPlanCommand.ProductDate); err != nil {
  50 + validation.Error("时间格式有误" + createProductPlanCommand.ProductDate)
54 return 51 return
55 } else { 52 } else {
56 createProductPlanCommand.ProductDateTime = t 53 createProductPlanCommand.ProductDateTime = t
@@ -49,8 +49,8 @@ func (updateProductPlanCommand *UpdateProductPlanCommand) Valid(validation *vali @@ -49,8 +49,8 @@ func (updateProductPlanCommand *UpdateProductPlanCommand) Valid(validation *vali
49 validation.Error(err.Error()) 49 validation.Error(err.Error())
50 return 50 return
51 } 51 }
52 - if t, err := time.Parse("2006/01/02", updateProductPlanCommand.ProductDate); err != nil {  
53 - validation.Error("时间格式有误 2006/01/02") 52 + if t, err := time.Parse("2006-01-02", updateProductPlanCommand.ProductDate); err != nil {
  53 + validation.Error("时间格式有误")
54 return 54 return
55 } else { 55 } else {
56 updateProductPlanCommand.ProductDateTime = t 56 updateProductPlanCommand.ProductDateTime = t
@@ -23,9 +23,11 @@ type ProductPlanDto struct { @@ -23,9 +23,11 @@ type ProductPlanDto struct {
23 // 上班班次描述 23 // 上班班次描述
24 WorkOnDescription string `json:"workOnDescription"` 24 WorkOnDescription string `json:"workOnDescription"`
25 // 机台 (A、B、C、D 区分机器大小) 25 // 机台 (A、B、C、D 区分机器大小)
26 - Machine string `json:"machine,omitempty"` 26 + Machine string `json:"machine"`
27 // 计划的产品名称 27 // 计划的产品名称
28 PlanProductName string `json:"planProductName,omitempty"` 28 PlanProductName string `json:"planProductName,omitempty"`
  29 + // 投入量规格 默认份
  30 + DevotedUnit string `json:"devotedUnit" `
29 // 计划投入 31 // 计划投入
30 *domain.UnitQuantity 32 *domain.UnitQuantity
31 // 计划状态 (1:上线 2:下线 默认下线) 33 // 计划状态 (1:上线 2:下线 默认下线)
@@ -45,12 +47,17 @@ type ProductPlanDto struct { @@ -45,12 +47,17 @@ type ProductPlanDto struct {
45 func (d *ProductPlanDto) LoadDto(m *domain.ProductPlan, orgId int) *ProductPlanDto { 47 func (d *ProductPlanDto) LoadDto(m *domain.ProductPlan, orgId int) *ProductPlanDto {
46 d.ProductPlanId = m.ProductPlanId 48 d.ProductPlanId = m.ProductPlanId
47 d.BatchNumber = m.BatchNumber 49 d.BatchNumber = m.BatchNumber
48 - d.ProductDate = m.ProductDate.Format("2006/01/02") 50 + d.ProductDate = m.ProductDate.Format("2006-01-02")
49 d.WorkshopId = m.Workshop.WorkshopId 51 d.WorkshopId = m.Workshop.WorkshopId
50 d.WorkshopName = m.Workshop.WorkshopName 52 d.WorkshopName = m.Workshop.WorkshopName
51 d.WorkOn = m.WorkOn 53 d.WorkOn = m.WorkOn
  54 + d.Machine = m.Machine
52 d.PlanProductName = m.PlanProductName 55 d.PlanProductName = m.PlanProductName
53 d.UnitQuantity = m.PlanDevoted 56 d.UnitQuantity = m.PlanDevoted
  57 + d.DevotedUnit = "份"
  58 + if m.Ext.ProductPlanExt != nil {
  59 + d.DevotedUnit = m.Ext.ProductPlanExt.DevotedUnit
  60 + }
54 d.PlanStatus = m.PlanStatus 61 d.PlanStatus = m.PlanStatus
55 d.TotalProduct = 0 62 d.TotalProduct = 0
56 d.Remark = m.Remark 63 d.Remark = m.Remark
@@ -86,6 +86,7 @@ func (productPlanService *ProductPlanService) CreateProductPlan(cmd *command.Cre @@ -86,6 +86,7 @@ func (productPlanService *ProductPlanService) CreateProductPlan(cmd *command.Cre
86 ProductCode: product.ProductCode, 86 ProductCode: product.ProductCode,
87 ProductName: product.ProductName, 87 ProductName: product.ProductName,
88 //ProductSpec: product.ProductSpec, 88 //ProductSpec: product.ProductSpec,
  89 + DevotedUnit: cmd.DevotedUnit,
89 }), 90 }),
90 } 91 }
91 if cmd.Weight > 0 { 92 if cmd.Weight > 0 {
1 package domain 1 package domain
2 2
3 -import "time" 3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
  6 + "time"
  7 +)
4 8
5 type DeviceZkTeco struct { 9 type DeviceZkTeco struct {
6 Sn string `json:"sn"` // 设备号 10 Sn string `json:"sn"` // 设备号
7 UserNo string `json:"userNo"` // 用户编码 11 UserNo string `json:"userNo"` // 用户编码
8 ActionTime time.Time `json:"actionTime"` // 操作时间 12 ActionTime time.Time `json:"actionTime"` // 操作时间
9 } 13 }
  14 +
  15 +func (m *DeviceZkTeco) Valid() error {
  16 + if len(m.Sn) == 0 {
  17 + return fmt.Errorf("设备号不能为空")
  18 + }
  19 + if len(m.UserNo) == 0 {
  20 + return fmt.Errorf("用户编码不能为空")
  21 + }
  22 + if m.ActionTime.IsZero() {
  23 + return fmt.Errorf("操作时间不能为空")
  24 + }
  25 + return nil
  26 +}
  27 +
  28 +func (m *DeviceZkTeco) String() string {
  29 + return fmt.Sprintf("设备号:%v 用户编码:%v 操作时间:%v", m.Sn, m.UserNo, m.ActionTime)
  30 +}
  31 +
  32 +func TaskDeviceZkTecoReport() string {
  33 + return fmt.Sprintf("%v:task:device-zk-teco:report", constant.CACHE_PREFIX)
  34 +}
@@ -10,4 +10,6 @@ type ProductPlanExt struct { @@ -10,4 +10,6 @@ type ProductPlanExt struct {
10 ProductName string `json:"productName,omitempty"` 10 ProductName string `json:"productName,omitempty"`
11 // 产品规格 11 // 产品规格
12 //ProductSpec *UnitQuantity `json:"productSpec,omitempty"` 12 //ProductSpec *UnitQuantity `json:"productSpec,omitempty"`
  13 + // 投入量规格 默认份
  14 + DevotedUnit string `json:"devotedUnit" `
13 } 15 }
@@ -20,4 +20,8 @@ type User struct { @@ -20,4 +20,8 @@ type User struct {
20 Avatar string `json:"avatar,omitempty"` 20 Avatar string `json:"avatar,omitempty"`
21 // 手机号码 21 // 手机号码
22 Phone string `json:"phone,omitempty"` 22 Phone string `json:"phone,omitempty"`
  23 +
  24 + // 额外扩展的参数
  25 + GroupId int `json:"-"`
  26 + GroupName string `json:"-"`
23 } 27 }
@@ -29,6 +29,16 @@ func NewHttpLibAlliedCreationUser(host string) *HttpLibAlliedCreationUser { @@ -29,6 +29,16 @@ func NewHttpLibAlliedCreationUser(host string) *HttpLibAlliedCreationUser {
29 func (gateway HttpLibAlliedCreationUser) User(userId int) (*models.User, error) { 29 func (gateway HttpLibAlliedCreationUser) User(userId int) (*models.User, error) {
30 return gateway.UserGet(ReqGetUser{UserId: userId}) 30 return gateway.UserGet(ReqGetUser{UserId: userId})
31 } 31 }
  32 +func (gateway HttpLibAlliedCreationUser) UserByCode(companyId, orgId int, userCode string) (*models.User, error) {
  33 + _, users, err := gateway.UserSearch(ReqUserSearch{CompanyId: int64(companyId), OrganizationId: int64(orgId), UserCode: userCode, Limit: 1, PullRealTime: true})
  34 + if err != nil {
  35 + return nil, err
  36 + }
  37 + if len(users) == 0 {
  38 + return nil, fmt.Errorf("用户不存在")
  39 + }
  40 + return users[0], nil
  41 +}
32 func (gateway HttpLibAlliedCreationUser) Users(userIds []int) ([]*models.User, error) { 42 func (gateway HttpLibAlliedCreationUser) Users(userIds []int) ([]*models.User, error) {
33 var list = make([]*models.User, 0) 43 var list = make([]*models.User, 0)
34 for i := range userIds { 44 for i := range userIds {
@@ -40,6 +40,8 @@ type ( @@ -40,6 +40,8 @@ type (
40 InEnableStatus []int `cname:"状态(1:启用 2:禁用 3:注销)" json:"inEnableStatus,omitempty"` 40 InEnableStatus []int `cname:"状态(1:启用 2:禁用 3:注销)" json:"inEnableStatus,omitempty"`
41 // 匹配多个公司 41 // 匹配多个公司
42 InCompanyIds []interface{} `json:"inCompanyIds,omitempty"` 42 InCompanyIds []interface{} `json:"inCompanyIds,omitempty"`
  43 + // 用户编号 企业内标识
  44 + UserCode string `cname:"用户编号" json:"userCode,omitempty"`
43 45
44 // 自定义高级查询 46 // 自定义高级查询
45 AdvancedQuery string `json:"advancedQuery"` 47 AdvancedQuery string `json:"advancedQuery"`
@@ -91,8 +91,8 @@ func (dao *AttendanceRecordDao) WorkerAttendanceRecords(companyId, orgId, worker @@ -91,8 +91,8 @@ func (dao *AttendanceRecordDao) WorkerAttendanceRecords(companyId, orgId, worker
91 query.Where("company_id =?", companyId) 91 query.Where("company_id =?", companyId)
92 query.Where("org_id =?", orgId) 92 query.Where("org_id =?", orgId)
93 query.Where("product_worker ->>'userId' = '?'", workerId) 93 query.Where("product_worker ->>'userId' = '?'", workerId)
94 - query.Where("sign_in <= ?", endTime)  
95 query.Where("sign_in >= ?", beginTime) 94 query.Where("sign_in >= ?", beginTime)
  95 + query.Where("sign_in <= ?", endTime)
96 query.Where("attendance_status = ?", domain.AttendanceNotApprove) 96 query.Where("attendance_status = ?", domain.AttendanceNotApprove)
97 query.SetOffsetAndLimit(domain.MaxQueryRow) 97 query.SetOffsetAndLimit(domain.MaxQueryRow)
98 query.SetOrderDirect("product_attendance_id", "DESC") 98 query.SetOrderDirect("product_attendance_id", "DESC")
  1 +package dao
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
  6 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/pg/transform"
  10 +)
  11 +
  12 +type DeviceDao struct {
  13 + transactionContext *pgTransaction.TransactionContext
  14 +}
  15 +
  16 +func NewDeviceDao(transactionContext *pgTransaction.TransactionContext) (*DeviceDao, error) {
  17 + if transactionContext == nil {
  18 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  19 + } else {
  20 + return &DeviceDao{
  21 + transactionContext: transactionContext,
  22 + }, nil
  23 + }
  24 +}
  25 +
  26 +func (d *DeviceDao) FindDeviceByDeviceCode(companyId, orgId int, deviceCode string) (*domain.Device, error) {
  27 + tx := d.transactionContext.PgTx
  28 + deviceModel := new(models.Device)
  29 + query := sqlbuilder.BuildQuery(tx.Model(deviceModel), map[string]interface{}{})
  30 + query.Where("company_id = ?", companyId)
  31 + query.Where("org_id = ?", orgId)
  32 + query.Where("device_code = ?", deviceCode)
  33 + //if v, ok := queryOptions["includeDeleted"]; ok && v.(bool) {
  34 + // query.AllWithDeleted()
  35 + //}
  36 + if err := query.First(); err != nil {
  37 + if err.Error() == "pg: no rows in result set" {
  38 + return nil, domain.ErrorNotFound
  39 + } else {
  40 + return nil, err
  41 + }
  42 + }
  43 + if deviceModel.DeviceId == 0 {
  44 + return nil, nil
  45 + } else {
  46 + return transform.TransformToDeviceDomainModelFromPgModels(deviceModel)
  47 + }
  48 + return nil, nil
  49 +}
@@ -19,6 +19,14 @@ func (svr *UserService) User(id int) (*domain.User, error) { @@ -19,6 +19,14 @@ func (svr *UserService) User(id int) (*domain.User, error) {
19 return svr.ToUser(rsp), nil 19 return svr.ToUser(rsp), nil
20 } 20 }
21 21
  22 +func (svr *UserService) UserByCode(companyId, orgId int, userCode string) (*domain.User, error) {
  23 + rsp, err := svr.internalUserService.UserByCode(companyId, orgId, userCode)
  24 + if err != nil {
  25 + return nil, err
  26 + }
  27 + return svr.ToUser(rsp), nil
  28 +}
  29 +
22 func (svr *UserService) Users(id []int) ([]*domain.User, error) { 30 func (svr *UserService) Users(id []int) ([]*domain.User, error) {
23 rsp, err := svr.internalUserService.Users(id) 31 rsp, err := svr.internalUserService.Users(id)
24 if err != nil { 32 if err != nil {
@@ -189,6 +189,8 @@ func FindGroupMembers(productGroupRepository domain.ProductGroupRepository, comp @@ -189,6 +189,8 @@ func FindGroupMembers(productGroupRepository domain.ProductGroupRepository, comp
189 //g:=groups[i] 189 //g:=groups[i]
190 for j := range groups[i].GroupMembers { 190 for j := range groups[i].GroupMembers {
191 u := groups[i].GroupMembers[j] 191 u := groups[i].GroupMembers[j]
  192 + u.GroupId = groups[i].ProductGroupId
  193 + u.GroupName = groups[i].GroupName
192 result[keyFunc(u.UserId)] = u 194 result[keyFunc(u.UserId)] = u
193 } 195 }
194 } 196 }
@@ -2,9 +2,11 @@ package domainService @@ -2,9 +2,11 @@ package domainService
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "github.com/linmadan/egglib-go/core/application"
5 pgTransaction "github.com/linmadan/egglib-go/transaction/pg" 6 pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/dao" 8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/dao"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository"
8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils" 10 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
9 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" 11 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
10 "time" 12 "time"
@@ -17,42 +19,85 @@ type PGWorkerAttendanceReportService struct { @@ -17,42 +19,85 @@ type PGWorkerAttendanceReportService struct {
17 // 考勤汇报 19 // 考勤汇报
18 func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.DeviceZkTeco) (interface{}, error) { 20 func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.DeviceZkTeco) (interface{}, error) {
19 var ( 21 var (
20 - attendanceRecordDao, _ = dao.NewAttendanceRecordDao(ptr.transactionContext)  
21 - isSignIn = true  
22 - record *domain.ProductAttendanceRecord  
23 - workStationId string //具体工位  
24 - workStation *domain.WorkStation  
25 - attendanceType int  
26 - worker *domain.User  
27 - org *domain.Org 22 + attendanceRecordDao, _ = dao.NewAttendanceRecordDao(ptr.transactionContext)
  23 + attendanceRecordRepository, _ = repository.NewProductAttendanceRecordRepository(ptr.transactionContext)
  24 + isSignIn = true
  25 + record *domain.ProductAttendanceRecord
  26 + workStationId string //具体工位
  27 + workStation *domain.WorkStation
  28 + attendanceType int = domain.ParticipateNormal
  29 + worker *domain.User
  30 + org *domain.Org
28 ) 31 )
29 32
30 - beginTime := utils.GetZeroTime(time.Now())  
31 - _, records, _ := attendanceRecordDao.WorkerAttendanceRecords(cid, oid, worker.UserId, workStationId, beginTime, time.Now()) 33 + if err := report.Valid(); err != nil {
  34 + return nil, err
  35 + }
  36 +
  37 + var (
  38 + device *domain.Device
  39 + err error
  40 + productGroupRepository, _ = repository.NewProductGroupRepository(ptr.transactionContext)
  41 + groupId = 0
  42 + groupName = ""
  43 + )
  44 + deviceRepository, _ := dao.NewDeviceDao(ptr.transactionContext)
  45 + if device, err = deviceRepository.FindDeviceByDeviceCode(cid, oid, report.Sn); err != nil {
  46 + return nil, err
  47 + }
  48 + workStation = device.WorkStation
  49 +
  50 + var userService = NewUserService()
  51 + org, err = userService.Organization(oid)
  52 + if err != nil {
  53 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  54 + }
  55 +
  56 + worker, err = userService.UserByCode(cid, oid, report.UserNo)
  57 + if err != nil {
  58 + return nil, err
  59 + }
  60 +
  61 + groupMembers, groupMembersKeyFunc := FindGroupMembers(productGroupRepository, cid, oid, workStation.WorkStationId)
  62 + if v, ok := groupMembers[groupMembersKeyFunc(worker.UserId)]; !ok {
  63 + attendanceType = domain.ParticipateSupport
  64 + } else {
  65 + groupId = v.GroupId
  66 + groupName = v.GroupName
  67 + }
  68 +
  69 + beginTime := utils.GetZeroTime(report.ActionTime)
  70 + endTime := report.ActionTime
  71 + _, records, _ := attendanceRecordDao.WorkerAttendanceRecords(cid, oid, worker.UserId, workStationId, beginTime, endTime)
32 for i := 0; i < len(records); i++ { 72 for i := 0; i < len(records); i++ {
33 r := records[i] 73 r := records[i]
34 - // 操作时间 < 签到时间 签退时间 < 操作时间  
35 - if (!r.SignIn.IsZero() && r.SignIn.After(report.ActionTime)) || (!r.SignOut.IsZero() && r.SignOut.Before(report.ActionTime)) {  
36 - continue 74 + // 操作时间 < 签到时间
  75 + if utils.TimeAfterEqual(r.SignIn, report.ActionTime) {
  76 + log.Logger.Info(fmt.Sprintf("【考勤汇报】 考勤记录不合法,操作时间小于签到时间 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime))
  77 + return struct{}{}, nil
37 } 78 }
38 -  
39 - if !r.SignIn.IsZero() && !r.SignOut.IsZero() {  
40 - if r.SignIn.Before(report.ActionTime) && r.SignOut.After(report.ActionTime) {  
41 - log.Logger.Info(fmt.Sprintf("【考勤汇报】 已存在同一时间段的考勤记录 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime)) 79 + // 存在完整打卡记录
  80 + // 1. 如果在区间内,退出
  81 + if !utils.TimeIsZero(r.SignIn) && !utils.TimeIsZero(r.SignOut) {
  82 + if utils.TimeBeforeEqual(r.SignIn, report.ActionTime) && utils.TimeAfterEqual(r.SignOut, report.ActionTime) {
  83 + log.Logger.Info(fmt.Sprintf("【考勤汇报】 已存在同一时间段的考勤记录 考勤ID:%v 用户:%v 打卡时间:%v", r.ProductAttendanceId, worker.UserId, report.ActionTime))
42 return struct{}{}, nil 84 return struct{}{}, nil
43 } 85 }
44 continue 86 continue
45 } 87 }
46 - if !r.SignIn.IsZero() && r.SignOut.IsZero() && r.SignIn.Before(report.ActionTime) {  
47 - isSignIn = false  
48 - record = r  
49 - break 88 + // 存在未结束的打卡记录
  89 + // 1.满足条件-签退
  90 + if !utils.TimeIsZero(r.SignIn) && utils.TimeIsZero(r.SignOut) {
  91 + if utils.TimeBeforeEqual(r.SignIn, report.ActionTime) {
  92 + isSignIn = false
  93 + record = r
  94 + break
  95 + }
50 } 96 }
51 } 97 }
52 98
53 - if isSignIn { 99 + if isSignIn || record == nil {
54 record = &domain.ProductAttendanceRecord{ 100 record = &domain.ProductAttendanceRecord{
55 - //ProductAttendanceId: cmd.ProductAttendanceId,  
56 CompanyId: cid, 101 CompanyId: cid,
57 OrgId: oid, 102 OrgId: oid,
58 AttendanceType: attendanceType, 103 AttendanceType: attendanceType,
@@ -65,13 +110,20 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain. @@ -65,13 +110,20 @@ func (ptr *PGWorkerAttendanceReportService) Report(cid, oid int, report *domain.
65 WorkTimeAfter: 0, 110 WorkTimeAfter: 0,
66 CreatedAt: time.Now(), 111 CreatedAt: time.Now(),
67 UpdatedAt: time.Now(), 112 UpdatedAt: time.Now(),
68 - Ext: domain.NewExt(org.OrgName).WithAttendanceExt(&domain.ProductAttendanceRecordExt{  
69 - //GroupName: productGroup.GroupName,  
70 - //ProductGroupId: productGroup.ProductGroupId, 113 + Ext: domain.NewExt(org.OrgName).WithAttendanceExt(&domain.ProductAttendanceRecordExt{
  114 + GroupName: groupName,
  115 + ProductGroupId: groupId,
71 }), 116 }),
72 } 117 }
  118 + log.Logger.Info(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签到 %v", worker.UserName, worker.UserId, report))
73 } else { 119 } else {
  120 + record.SignOut = report.ActionTime
74 record.WorkTimeBefore = record.ComputeWorkTimeBefore() 121 record.WorkTimeBefore = record.ComputeWorkTimeBefore()
  122 + log.Logger.Info(fmt.Sprintf("【考勤汇报】 用户:%v(%v) 签退 %v", worker.UserName, worker.UserId, report))
  123 + }
  124 +
  125 + if _, err = attendanceRecordRepository.Save(record); err != nil {
  126 + return nil, err
75 } 127 }
76 128
77 return struct{}{}, nil 129 return struct{}{}, nil
1 -package domainService  
2 -  
3 -//import (  
4 -// "fmt"  
5 -// pgTransaction "github.com/linmadan/egglib-go/transaction/pg"  
6 -// "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"  
7 -// "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/repository"  
8 -//)  
9 -//  
10 -//type PGWorkshopService struct {  
11 -// transactionContext *pgTransaction.TransactionContext  
12 -//}  
13 -//  
14 -//func(ptr *PGWorkshopService)CompanyWorkshops(companyId int)(domain.Workshops,error){  
15 -// workshopRepository,_:= repository.NewWorkshopRepository(ptr.transactionContext)  
16 -// _,workshops,err:= workshopRepository.Find(map[string]interface{}{"companyId":companyId})  
17 -// if err!=nil{  
18 -// return nil,err  
19 -// }  
20 -// if len(workshops)==0{  
21 -// workshops = make([]*domain.Workshop,0)  
22 -// }  
23 -// return workshops,nil  
24 -//}  
25 -//  
26 -//func NewPGWorkshopService(transactionContext *pgTransaction.TransactionContext) (*PGWorkshopService, error) {  
27 -// if transactionContext == nil {  
28 -// return nil, fmt.Errorf("transactionContext参数不能为nil")  
29 -// } else {  
30 -// return &PGWorkshopService{  
31 -// transactionContext: transactionContext,  
32 -// }, nil  
33 -// }  
34 -//}  
@@ -59,7 +59,15 @@ func (ptr *PGWorkshopWorkTimeStaticService) WorkshopWorkTimeStatic(productRecord @@ -59,7 +59,15 @@ func (ptr *PGWorkshopWorkTimeStaticService) WorkshopWorkTimeStatic(productRecord
59 } 59 }
60 60
61 func SendWorkshopWorkTimeStaticJob(productRecord *domain.ProductAttendanceRecord) error { 61 func SendWorkshopWorkTimeStaticJob(productRecord *domain.ProductAttendanceRecord) error {
62 - task := asynq.NewTask(domain.TaskKeyWorkshopWorkTimeRecordStatics(), []byte(json.MarshalToString(productRecord))) 62 + return SendAsyncJob(domain.TaskKeyWorkshopWorkTimeRecordStatics(), productRecord)
  63 +}
  64 +
  65 +func SenDeviceZkTecoReportJob(productRecord *domain.DeviceZkTeco) error {
  66 + return SendAsyncJob(domain.TaskDeviceZkTecoReport(), productRecord)
  67 +}
  68 +
  69 +func SendAsyncJob(queueName string, job interface{}) error {
  70 + task := asynq.NewTask(queueName, []byte(json.MarshalToString(job)))
63 71
64 client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS}) 72 client := asynq.NewClient(asynq.RedisClientOpt{Addr: constant.REDIS_ADDRESS})
65 _, err := client.Enqueue(task) 73 _, err := client.Enqueue(task)
@@ -50,3 +50,33 @@ func TransformTimestampToTime(timeStamp int64) time.Time { @@ -50,3 +50,33 @@ func TransformTimestampToTime(timeStamp int64) time.Time {
50 //(myTime) 50 //(myTime)
51 return time.Date(myTime.Year(), myTime.Month(), myTime.Day(), myTime.Hour(), myTime.Minute(), myTime.Second(), 0, time.Local) 51 return time.Date(myTime.Year(), myTime.Month(), myTime.Day(), myTime.Hour(), myTime.Minute(), myTime.Second(), 0, time.Local)
52 } 52 }
  53 +
  54 +func TimeIsZero(d time.Time) bool {
  55 + if d.IsZero() {
  56 + return true
  57 + }
  58 + if d.Equal(time.Date(1, 1, 1, 0, 0, 0, 0, time.Local)) {
  59 + return true
  60 + }
  61 + return false
  62 +}
  63 +
  64 +func TimeAfterEqual(t1, t2 time.Time) bool {
  65 + if t1.After(t2) {
  66 + return true
  67 + }
  68 + if t1.Equal(t2) {
  69 + return true
  70 + }
  71 + return false
  72 +}
  73 +
  74 +func TimeBeforeEqual(t1, t2 time.Time) bool {
  75 + if t1.Before(t2) {
  76 + return true
  77 + }
  78 + if t1.Equal(t2) {
  79 + return true
  80 + }
  81 + return false
  82 +}
1 package controllers 1 package controllers
2 2
3 import ( 3 import (
4 - "encoding/json"  
5 "github.com/linmadan/egglib-go/web/beego" 4 "github.com/linmadan/egglib-go/web/beego"
6 - "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"  
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" 5 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
8 - "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis" 6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
9 "strings" 7 "strings"
10 "time" 8 "time"
11 ) 9 )
@@ -28,8 +26,9 @@ func (controller *DeviceZKTecoController) PostCdata() { @@ -28,8 +26,9 @@ func (controller *DeviceZKTecoController) PostCdata() {
28 mTime, err := time.ParseInLocation("2006-01-02 15:04:05", bodyList[1], time.Local) 26 mTime, err := time.ParseInLocation("2006-01-02 15:04:05", bodyList[1], time.Local)
29 if err == nil { 27 if err == nil {
30 data.ActionTime = mTime 28 data.ActionTime = mTime
31 - mBytes, _ := json.Marshal(data)  
32 - redis.GetRedis().LPush(constant.REDIS_ZKTECO_KEY, mBytes) 29 + //mBytes, _ := json.Marshal(data)
  30 + //redis.GetRedis().LPush(domain.TaskDeviceZkTecoReport(), mBytes)
  31 + domainService.SenDeviceZkTecoReportJob(data)
33 } 32 }
34 } 33 }
35 controller.Response(data, nil) 34 controller.Response(data, nil)
1 package task 1 package task
2 2
3 import ( 3 import (
4 - "context"  
5 - "encoding/json"  
6 - "fmt"  
7 "github.com/hibiken/asynq" 4 "github.com/hibiken/asynq"
8 - "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productRecord/command"  
9 - "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productRecord/service"  
10 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant" 5 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
11 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" 6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
12 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
@@ -25,6 +20,7 @@ func Run() { @@ -25,6 +20,7 @@ func Run() {
25 // ... Register handlers 20 // ... Register handlers
26 h.HandleFunc(domain.TaskKeyPatternProductRecordStatics(), HandlerProductRecordStatics) 21 h.HandleFunc(domain.TaskKeyPatternProductRecordStatics(), HandlerProductRecordStatics)
27 h.HandleFunc(domain.TaskKeyWorkshopWorkTimeRecordStatics(), WorkshopWorkTimeRecordStatics) 22 h.HandleFunc(domain.TaskKeyWorkshopWorkTimeRecordStatics(), WorkshopWorkTimeRecordStatics)
  23 + h.HandleFunc(domain.TaskDeviceZkTecoReport(), WorkerAttendanceReport)
28 log.Logger.Info("aysnq task running ...") 24 log.Logger.Info("aysnq task running ...")
29 // Run blocks and waits for os signal to terminate the program. 25 // Run blocks and waits for os signal to terminate the program.
30 if err := srv.Run(h); err != nil { 26 if err := srv.Run(h); err != nil {
@@ -36,19 +32,3 @@ func Run() { @@ -36,19 +32,3 @@ func Run() {
36 log.Logger.Info("aysnq task stopping ...") 32 log.Logger.Info("aysnq task stopping ...")
37 srv.Shutdown() 33 srv.Shutdown()
38 } 34 }
39 -  
40 -// 生产记录统计  
41 -func HandlerProductRecordStatics(c context.Context, t *asynq.Task) error {  
42 - productPlanService := service.NewProductRecordService(nil)  
43 - cmd := &command.ProductRecordStaticsCommand{}  
44 - if err := json.Unmarshal(t.Payload(), cmd); err != nil {  
45 - return err  
46 - }  
47 - log.Logger.Debug(fmt.Sprintf("【生产记录统计】 消费 生产记录ID:%v 类型:%v 工段:%v(%v) 重量:%v", cmd.ProductRecordId, cmd.ProductRecordType,  
48 - cmd.WorkStation.SectionName, cmd.WorkStation.WorkStationId, cmd.ProductRecordInfo.Weigh))  
49 - _, err := productPlanService.ProductRecordStatics(cmd)  
50 - if err != nil {  
51 - log.Logger.Error(err.Error())  
52 - }  
53 - return err  
54 -}  
  1 +package task
  2 +
  3 +import (
  4 + "context"
  5 + "encoding/json"
  6 + "fmt"
  7 + "github.com/hibiken/asynq"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productRecord/command"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productRecord/service"
  10 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
  11 +)
  12 +
  13 +// 生产记录统计
  14 +func HandlerProductRecordStatics(c context.Context, t *asynq.Task) error {
  15 + productPlanService := service.NewProductRecordService(nil)
  16 + cmd := &command.ProductRecordStaticsCommand{}
  17 + if err := json.Unmarshal(t.Payload(), cmd); err != nil {
  18 + return err
  19 + }
  20 + log.Logger.Debug(fmt.Sprintf("【生产记录统计】 消费 生产记录ID:%v 类型:%v 工段:%v(%v) 重量:%v", cmd.ProductRecordId, cmd.ProductRecordType,
  21 + cmd.WorkStation.SectionName, cmd.WorkStation.WorkStationId, cmd.ProductRecordInfo.Weigh))
  22 + _, err := productPlanService.ProductRecordStatics(cmd)
  23 + if err != nil {
  24 + log.Logger.Error(err.Error())
  25 + }
  26 + return err
  27 +}