From 1479002f3a57e29a62d0677e5cb7535b7ffadb25 Mon Sep 17 00:00:00 2001 From: jiangyong27 Date: Tue, 8 Apr 2025 19:21:48 +0800 Subject: [PATCH] salary person --- base/util/util.go | 35 ++++++++++++++++++++++++++++++++++ base/util/xlsx.go | 32 +++++++++++++++++++++++++++++++ common/dao/staff_user.go | 16 ++++++++++++++++ go.mod | 4 +--- server/controller/salary.go | 4 ++-- server/service/staff_salary.go | 34 ++++++++++++++++++++++++++++++--- 6 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 base/util/xlsx.go diff --git a/base/util/util.go b/base/util/util.go index 94d1fa0..b6796c6 100644 --- a/base/util/util.go +++ b/base/util/util.go @@ -6,6 +6,8 @@ import ( qrcode "github.com/skip2/go-qrcode" "github.com/spf13/cast" "math/rand" + "regexp" + "strconv" "time" ) @@ -42,3 +44,36 @@ func CreateQrcodeBase64V2(content string, level qrcode.RecoveryLevel, size int) //文件流需要使用base64编码后才可使用 return base64.StdEncoding.EncodeToString(png), nil } + +// ValidateIDCard 校验 18 位身份证号码 +func ValidateIDCard(idCard string) bool { + // 检查长度是否为 18 位 + if len(idCard) != 18 { + return false + } + // 检查前 17 位是否为数字 + pattern := `^\d{17}[0-9Xx]$` + match, _ := regexp.MatchString(pattern, idCard) + if !match { + return false + } + // 加权因子 + weight := []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2} + // 校验码对应值 + checkCodeList := []string{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"} + // 计算前 17 位加权和 + sum := 0 + for i := 0; i < 17; i++ { + num, _ := strconv.Atoi(string(idCard[i])) + sum += num * weight[i] + } + // 计算校验码 + index := sum % 11 + checkCode := checkCodeList[index] + // 比较校验码 + lastChar := string(idCard[17]) + if lastChar == "x" { + lastChar = "X" + } + return lastChar == checkCode +} diff --git a/base/util/xlsx.go b/base/util/xlsx.go new file mode 100644 index 0000000..846cb95 --- /dev/null +++ b/base/util/xlsx.go @@ -0,0 +1,32 @@ +package util + +import ( + "github.com/spf13/cast" + "github.com/tealeg/xlsx" +) + +func ParsePersonXlsx(fileName string) (map[string]float64, error) { + // 打开Excel文件 + xlFile, err := xlsx.OpenFile(fileName) + if err != nil { + return nil, err + } + + result := make(map[string]float64) + + // 遍历所有的sheet + for _, sheet := range xlFile.Sheets { + // 遍历sheet中的行 + for _, row := range sheet.Rows { + if len(row.Cells) < 41 || !ValidateIDCard(row.Cells[3].Value) { + continue + } + value := cast.ToFloat64(row.Cells[40].Value) + if value == 0 { + continue + } + result[row.Cells[3].Value] = value + } + } + return result, nil +} diff --git a/common/dao/staff_user.go b/common/dao/staff_user.go index af9b40e..c524927 100644 --- a/common/dao/staff_user.go +++ b/common/dao/staff_user.go @@ -83,6 +83,22 @@ func (d *StaffUserDao) GetByPhone(corpId int64, phone string) (*model.StaffUser, return &u, nil } +func (d *StaffUserDao) GetByIdNo(corpId int64, idno string) (*model.StaffUser, error) { + var u model.StaffUser + tx := GetDB().Table(d.TableName()) + tx.Where("corp_id = ?", corpId) + tx = tx.Where("idno = ?", idno) + res := tx.First(&u) + if res.Error == gorm.ErrRecordNotFound { + return nil, nil + } + + if res.Error != nil { + return nil, res.Error + } + return &u, nil +} + func (d *StaffUserDao) Query(page, size int, corpId int64, status int, username, realname, phone, idno string) ([]*model.StaffUser, int64, error) { var u []*model.StaffUser tx := GetDB().Table(d.TableName()) diff --git a/go.mod b/go.mod index 8c5690e..5530859 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( git.u8t.cn/open/gosdk v0.0.0-20250407110540-d45ac685eb45 github.com/ArtisanCloud/PowerWeChat/v3 v3.2.27 github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 - github.com/fogleman/gg v1.3.0 github.com/gin-gonic/gin v1.10.0 github.com/go-co-op/gocron v1.37.0 github.com/gogap/errors v0.0.0-20210818113853-edfbba0ddea9 @@ -24,6 +23,7 @@ require ( github.com/smbrave/goutil v0.0.0-20250312151244-845a8a40e8aa github.com/spf13/cast v1.7.0 github.com/spf13/viper v1.19.0 + github.com/tealeg/xlsx v1.0.5 github.com/xuri/excelize/v2 v2.8.1 golang.org/x/crypto v0.26.0 gorm.io/driver/mysql v1.5.7 @@ -50,7 +50,6 @@ require ( github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gogap/stack v0.0.0-20150131034635-fef68dddd4f8 // indirect - github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect @@ -94,7 +93,6 @@ require ( go.uber.org/zap v1.21.0 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/image v0.14.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect diff --git a/server/controller/salary.go b/server/controller/salary.go index 4ae1f95..77da488 100644 --- a/server/controller/salary.go +++ b/server/controller/salary.go @@ -56,8 +56,8 @@ func (s *Salary) Update(ctx *gin.Context) { } func (s *Salary) Upload(ctx *gin.Context) { - - rsp := service.NewStaffSalary().Upload(ctx) + sess := ctx.Keys[session.ContextSession].(*session.AdminSession) + rsp := service.NewStaffSalary().Upload(sess, ctx) ctx.Keys[session.ContextResponse] = rsp ctx.JSON(http.StatusOK, session.NewRsp(rsp)) } diff --git a/server/service/staff_salary.go b/server/service/staff_salary.go index e7c90e2..cde4f93 100644 --- a/server/service/staff_salary.go +++ b/server/service/staff_salary.go @@ -33,7 +33,7 @@ func NewStaffSalary() *StaffSalary { return &StaffSalary{} } -func (s *StaffSalary) Upload(ctx *gin.Context) interface{} { +func (s *StaffSalary) Upload(sess *session.AdminSession, ctx *gin.Context) interface{} { var err error saveFile := "/tmp/" @@ -52,10 +52,38 @@ func (s *StaffSalary) Upload(ctx *gin.Context) interface{} { panic(config.ErrInternal.New().Append(err)) } + result, err := butil.ParsePersonXlsx(saveFile) + if err != nil { + panic(config.ErrInternal.New().Append(err)) + } + month := time.Now().AddDate(0, -1, 0).Format("200601") + sumAmount := float64(0) + for k, v := range result { + staffUser, err := dao.NewStaffUserDao().GetByIdNo(sess.GetCorpId(), k) + session.CheckDBError(err) + if staffUser == nil { + continue + } + + salary, err := dao.NewStaffSalaryDao().GetBy(sess.GetCorpId(), staffUser.Id, month) + session.CheckDBError(err) + if salary == nil { + continue + } + if salary.Status == model.StaffSalaryStatusPayed { + log.Errorf("user idno[%s] username[%s] salary is payed", staffUser.Idno, staffUser.Username) + continue + } + salary.PersonalDeduct = v + + err = dao.NewStaffSalaryDao().Update(salary) + session.CheckDBError(err) + sumAmount += v + } defer os.Remove(saveFile) data := make(map[string]interface{}) - data["count"] = 10 - data["amount"] = "12.34" + data["count"] = len(result) + data["amount"] = cast.ToString(sumAmount) return data }