From 0f8093693d0cd3b8da71abac95c617aa850f4819 Mon Sep 17 00:00:00 2001
From: liujiandao <274878379@qq.com>
Date: 星期一, 22 四月 2024 15:44:55 +0800
Subject: [PATCH] 考勤管理
---
constvar/const.go | 9 +
controllers/attendance_controller.go | 83 ++++++++++++++++
models/attendance_rule.go | 105 +++++++++++++++++++++
models/db.go | 5
models/worker.go | 10 ++
controllers/request/attendance_request.go | 2
models/attendance_manage.go | 36 +++++--
router/router.go | 2
8 files changed, 240 insertions(+), 12 deletions(-)
diff --git a/constvar/const.go b/constvar/const.go
index 1a2f576..d6c296e 100644
--- a/constvar/const.go
+++ b/constvar/const.go
@@ -86,3 +86,12 @@
ResourceTypeDevice ResourceType = iota + 1 // 璁惧
ResourceTypeWorker // 浜哄憳
)
+
+type AttendanceStatus int
+
+const (
+ Normal AttendanceStatus = iota + 1 //姝e父
+ Overtime //鍔犵彮
+ Vacation //浼戝亣
+ Abnormal //寮傚父
+)
diff --git a/controllers/attendance_controller.go b/controllers/attendance_controller.go
index 117131c..6a88958 100644
--- a/controllers/attendance_controller.go
+++ b/controllers/attendance_controller.go
@@ -2,6 +2,7 @@
import (
"github.com/gin-gonic/gin"
+ "github.com/shopspring/decimal"
"github.com/xuri/excelize/v2"
"silkserver/constvar"
"silkserver/controllers/request"
@@ -71,12 +72,31 @@
}
am.AddPeople = info.NickName
am.CreateTime = timex.TimeToString2(time.Now())
+ am.Status = constvar.Normal
attendances = append(attendances, &am)
}
for K, _ := range idMap {
workerIds = append(workerIds, K)
}
+ //鏌ヨ浜哄憳宸ョ
+ workers, err := models.NewWorkerSearch().SetIds(workerIds).FindNotTotal()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, err)
+ return
+ }
+ for _, attendance := range attendances {
+ for _, worker := range workers {
+ if attendance.WorkerId == worker.ID {
+ attendance.WorkTypeId = worker.WorkTypeId
+ break
+ }
+ }
+ }
+
+ //鏌ヨ鍔犵彮瑙勫垯
+ rule, _ := models.NewAttendanceRuleSearch().First()
+
//鏌ヨ鐝淇℃伅
schedules, err := models.NewShiftScheduleSearch().SetResourceIDs(workerIds).SetResourceType(constvar.ResourceTypeWorker).FindNotTotal()
if err != nil {
@@ -95,6 +115,11 @@
}
}
}
+ var overTime int64 = 0
+ hour := decimal.NewFromInt(3600)
+ if rule.WeekdayRule == 2 {
+ overTime = rule.OverTimeStart.Mul(hour).IntPart()
+ }
for _, attendance := range attendances {
for _, schedule := range schedules {
if attendance.WorkerId == schedule.ResourceID {
@@ -104,6 +129,23 @@
t := schedule.Shift[0].ShiftTime[0]
attendance.ClassesStartTime = t.StartTime
attendance.ClassesEndTime = t.EndTime
+ //鍒ゆ柇鎵撳崱鏃堕棿
+ t1, _ := timex.StringToClock(attendance.EndWorkTime)
+ t2, _ := timex.StringToClock(t.EndTime)
+ endWork := t1.Unix()
+ endClasses := t2.Unix()
+ if endWork < endClasses {
+ attendance.Status = constvar.Abnormal
+ } else if endWork > endClasses {
+ //鍒ゆ柇鍔犵彮
+ if rule.WeekdayRule == 2 {
+ ot := endWork - endClasses
+ if ot > overTime {
+ attendance.OverTimeDuration = decimal.NewFromInt(ot).DivRound(hour, 2)
+ attendance.Status = constvar.Overtime
+ }
+ }
+ }
}
}
break
@@ -166,3 +208,44 @@
}
util.ResponseFormat(c, code.Success, "鍒犻櫎鎴愬姛")
}
+
+// GetAttendanceRule
+//
+// @Tags 鑰冨嫟绠$悊
+// @Summary 鑾峰彇鍔犵彮瑙勫垯
+// @Produce application/json
+// @Param Authorization header string true "token"
+// @Success 200 {object} util.Response "鎴愬姛"
+// @Router /api-jl/v1/attendance/getAttendanceRule [get]
+func (slf AttendanceController) GetAttendanceRule(c *gin.Context) {
+ rule, err := models.NewAttendanceRuleSearch().First()
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, err)
+ return
+ }
+ util.ResponseFormat(c, code.Success, rule)
+}
+
+// SaveAttendanceRule
+//
+// @Tags 鑰冨嫟绠$悊
+// @Summary 淇濆瓨鍔犵彮瑙勫垯
+// @Produce application/json
+// @Param object body models.AttendanceRule true "鍙傛暟"
+// @Param Authorization header string true "token"
+// @Success 200 {object} util.Response "鎴愬姛"
+// @Router /api-jl/v1/attendance/saveAttendanceRule [post]
+func (slf AttendanceController) SaveAttendanceRule(c *gin.Context) {
+ var rule models.AttendanceRule
+ err := c.BindJSON(&rule)
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, "鍙傛暟瑙f瀽澶辫触锛屾暟鎹被鍨嬮敊璇�")
+ return
+ }
+ err = models.NewAttendanceRuleSearch().Save(&rule)
+ if err != nil {
+ util.ResponseFormat(c, code.RequestParamError, err)
+ return
+ }
+ util.ResponseFormat(c, code.Success, "淇濆瓨鎴愬姛")
+}
diff --git a/controllers/request/attendance_request.go b/controllers/request/attendance_request.go
index a79e381..e28e379 100644
--- a/controllers/request/attendance_request.go
+++ b/controllers/request/attendance_request.go
@@ -6,5 +6,5 @@
}
type DeleteAttendanceInfo struct {
- Ids []uint `json:"ids"`
+ Ids []uint `json:"ids"` //璁板綍id
}
diff --git a/models/attendance_manage.go b/models/attendance_manage.go
index dac4b23..9a9f49e 100644
--- a/models/attendance_manage.go
+++ b/models/attendance_manage.go
@@ -2,7 +2,9 @@
import (
"fmt"
+ "github.com/shopspring/decimal"
"gorm.io/gorm"
+ "silkserver/constvar"
"silkserver/pkg/mysqlx"
)
@@ -10,21 +12,26 @@
//AttendanceManage 鑰冨嫟绠$悊琛�
AttendanceManage struct {
gorm.Model
- Date string `json:"date" gorm:"type:varchar(255);comment:鑰冨嫟鏃堕棿"`
- WorkerId string `json:"workerId" gorm:"type:varchar(255);comment:浜哄憳id"`
- WorkerName string `json:"workerName" gorm:"type:varchar(255);comment:浜哄憳濮撳悕"`
- StartWorkTime string `json:"startWorkTime" gorm:"type:varchar(255);comment:涓婄彮鎵撳崱鏃堕棿"`
- EndWorkTime string `json:"endWorkTime" gorm:"type:varchar(255);comment:涓嬬彮鎵撳崱鏃堕棿"`
- Classes string `json:"classes" gorm:"type:varchar(255);comment:鐝"`
- ClassesStartTime string `json:"classesStartTime" gorm:"type:varchar(255);comment:鐝寮�濮嬫椂闂�"`
- ClassesEndTime string `json:"classesEndTime" gorm:"type:varchar(255);comment:鐝涓嬬彮鏃堕棿"`
- CreateTime string `json:"createTime" gorm:"type:varchar(255);comment:娣诲姞鏃堕棿"`
- AddPeople string `json:"addPeople" gorm:"type:varchar(255);comment:娣诲姞浜�"`
+ Date string `json:"date" gorm:"type:varchar(255);comment:鑰冨嫟鏃堕棿"`
+ WorkerId string `json:"workerId" gorm:"type:varchar(255);comment:浜哄憳id"`
+ WorkerName string `json:"workerName" gorm:"type:varchar(255);comment:浜哄憳濮撳悕"`
+ StartWorkTime string `json:"startWorkTime" gorm:"type:varchar(255);comment:涓婄彮鎵撳崱鏃堕棿"`
+ EndWorkTime string `json:"endWorkTime" gorm:"type:varchar(255);comment:涓嬬彮鎵撳崱鏃堕棿"`
+ Classes string `json:"classes" gorm:"type:varchar(255);comment:鐝"`
+ ClassesStartTime string `json:"classesStartTime" gorm:"type:varchar(255);comment:鐝寮�濮嬫椂闂�"`
+ ClassesEndTime string `json:"classesEndTime" gorm:"type:varchar(255);comment:鐝涓嬬彮鏃堕棿"`
+ CreateTime string `json:"createTime" gorm:"type:varchar(255);comment:娣诲姞鏃堕棿"`
+ AddPeople string `json:"addPeople" gorm:"type:varchar(255);comment:娣诲姞浜�"`
+ WorkTypeId uint `json:"workTypeId" gorm:"type:int(11);comment:宸ョid"`
+ WorkType WorkTypeManage `json:"workType" gorm:"foreignKey:WorkTypeId"`
+ Status constvar.AttendanceStatus `json:"status" gorm:"type:int(11);comment:鐘舵��"`
+ OverTimeDuration decimal.Decimal `json:"overTimeDuration" gorm:"type:decimal(20,2);comment:鍔犵彮鏃堕暱"`
}
AttendanceManageSearch struct {
AttendanceManage
PageNum int
PageSize int
+ Preload bool
Ids []uint
Orm *gorm.DB
}
@@ -53,6 +60,11 @@
return slf
}
+func (slf *AttendanceManageSearch) SetPreload(preload bool) *AttendanceManageSearch {
+ slf.Preload = preload
+ return slf
+}
+
func (slf *AttendanceManageSearch) build() *gorm.DB {
var db = slf.Orm.Table(slf.TableName())
@@ -60,6 +72,10 @@
db = db.Where("id in (?)", slf.Ids)
}
+ if slf.Preload {
+ db = db.Model(&AttendanceManage{}).Preload("WorkType")
+ }
+
return db
}
diff --git a/models/attendance_rule.go b/models/attendance_rule.go
new file mode 100644
index 0000000..b653609
--- /dev/null
+++ b/models/attendance_rule.go
@@ -0,0 +1,105 @@
+package models
+
+import (
+ "fmt"
+ "github.com/shopspring/decimal"
+ "gorm.io/gorm"
+ "silkserver/pkg/mysqlx"
+)
+
+type (
+ AttendanceRule struct {
+ gorm.Model
+ WeekdayRule int `json:"weekdayRule" gorm:"type:int(1);default:1;comment:宸ヤ綔鏃ュ姞鐝鍒�,1涓嶅惎鐢�,2鍚敤"`
+ OverTimeStart decimal.Decimal `json:"overTimeStart" gorm:"type:decimal(20,3);comment:宸ヤ綔鏃ュ姞鐝捣绠楁椂闀�"`
+ RestDayRule int `json:"restDayRule" gorm:"type:int(1);default:1;comment:浼戞伅鏃ュ姞鐝鍒�,1涓嶅惎鐢�,2鍚敤"`
+ RestDayStart decimal.Decimal `json:"restDayStart" gorm:"type:decimal(20,3);comment:浼戞伅鏃ュ姞鐝捣绠楁椂闀�"`
+ }
+ AttendanceRuleSearch struct {
+ AttendanceRule
+ Orm *gorm.DB
+ }
+)
+
+func (slf AttendanceRule) TableName() string {
+ return "silk_attendance_rule"
+}
+
+func NewAttendanceRuleSearch() *AttendanceRuleSearch {
+ return &AttendanceRuleSearch{Orm: mysqlx.GetDB()}
+}
+
+func (slf *AttendanceRuleSearch) SetOrm(tx *gorm.DB) *AttendanceRuleSearch {
+ slf.Orm = tx
+ return slf
+}
+
+func (slf *AttendanceRuleSearch) build() *gorm.DB {
+ var db = slf.Orm.Table(slf.TableName())
+
+ return db
+}
+
+// Create 鍗曟潯鎻掑叆
+func (slf *AttendanceRuleSearch) Create(record *AttendanceRule) error {
+ var db = slf.build()
+
+ if err := db.Create(record).Error; err != nil {
+ return fmt.Errorf("create err: %v, record: %+v", err, record)
+ }
+
+ return nil
+}
+
+func (slf *AttendanceRuleSearch) Save(record *AttendanceRule) error {
+ var db = slf.build()
+
+ if err := db.Omit("CreatedAt").Save(record).Error; err != nil {
+ return fmt.Errorf("save err: %v, record: %+v", err, record)
+ }
+
+ return nil
+}
+
+func (slf *AttendanceRuleSearch) Delete() error {
+ var db = slf.build()
+
+ if err := db.Unscoped().Delete(&AttendanceRule{}).Error; err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (slf *AttendanceRuleSearch) First() (*AttendanceRule, error) {
+ var (
+ record = new(AttendanceRule)
+ db = slf.build()
+ )
+
+ if err := db.First(record).Error; err != nil {
+ return record, err
+ }
+
+ return record, nil
+}
+
+// InitDefaultData 鍒濆鍖栨暟鎹�
+func (slf *AttendanceRuleSearch) InitDefaultData() error {
+ var (
+ rule AttendanceRule
+ total int64
+ )
+ db := slf.Orm.Table(slf.TableName())
+ err := db.Count(&total).Error
+ if err != nil {
+ return err
+ }
+ if total > 0 {
+ return nil
+ }
+ rule.WeekdayRule = 1
+ rule.RestDayRule = 1
+ err = db.Create(&rule).Error
+ return err
+}
diff --git a/models/db.go b/models/db.go
index d96e5be..f1655cf 100644
--- a/models/db.go
+++ b/models/db.go
@@ -89,6 +89,7 @@
SalaryPlan{},
Mentor{},
AttendanceManage{},
+ AttendanceRule{},
)
return err
}
@@ -98,7 +99,9 @@
}
func InsertDefaultData() {
- models := []interface{}{}
+ models := []interface{}{
+ NewAttendanceRuleSearch(),
+ }
for _, model := range models {
if id, ok := model.(InitDefaultData); ok {
if err := id.InitDefaultData(); err != nil {
diff --git a/models/worker.go b/models/worker.go
index 07640e0..678a213 100644
--- a/models/worker.go
+++ b/models/worker.go
@@ -32,6 +32,7 @@
PageSize int
Orm *gorm.DB
Fields string
+ Ids []string
}
)
@@ -93,6 +94,11 @@
return slf
}
+func (slf *WorkerSearch) SetIds(ids []string) *WorkerSearch {
+ slf.Ids = ids
+ return slf
+}
+
func (slf *WorkerSearch) build() *gorm.DB {
var db = slf.Orm.Table(slf.TableName())
@@ -129,6 +135,10 @@
db = db.Select(slf.Fields)
}
+ if len(slf.Ids) > 0 {
+ db = db.Where("id in (?)", slf.Ids)
+ }
+
return db
}
diff --git a/router/router.go b/router/router.go
index 98fa0f0..7f60839 100644
--- a/router/router.go
+++ b/router/router.go
@@ -108,6 +108,8 @@
attendanceApi.POST("attendanceInput", attendanceController.AttendanceInput) //鑰冨嫟瀵煎叆
attendanceApi.POST("getAttendanceList", attendanceController.GetAttendanceList) //鑾峰彇鑰冨嫟鍒楄〃
attendanceApi.DELETE("deleteAttendanceInfo", attendanceController.DeleteAttendanceInfo) //鍒犻櫎鑰冨嫟淇℃伅
+ attendanceApi.GET("getAttendanceRule", attendanceController.GetAttendanceRule) //鑾峰彇鍔犵彮瑙勫垯
+ attendanceApi.POST("saveAttendanceRule", attendanceController.SaveAttendanceRule) //淇濆瓨鍔犵彮瑙勫垯
}
mentorApi := r.Group(urlPrefix + "/mentor")
--
Gitblit v1.8.0