From 54e05acc91a189b06e7e05c5f9b96e819c9aea05 Mon Sep 17 00:00:00 2001 From: jiangyong27 Date: Wed, 2 Apr 2025 22:20:29 +0800 Subject: [PATCH] salarybill --- common/model/staff_salary.go | 10 +++ conf/template/salary_bill.html | 115 +++++++++++++++++++++++++++++++++ go.mod | 3 + server/controller/salary.go | 6 ++ server/server.go | 1 + server/service/staff_salary.go | 67 +++++++++++++++++++ 6 files changed, 202 insertions(+) create mode 100644 conf/template/salary_bill.html diff --git a/common/model/staff_salary.go b/common/model/staff_salary.go index d80237b..4a3341e 100644 --- a/common/model/staff_salary.go +++ b/common/model/staff_salary.go @@ -13,6 +13,16 @@ var ( StaffSalaryStatusPayed = 2 ) +type SalaryBillLine struct { + Label string + Value string +} + +type SalaryBillSection struct { + Name string + Line []*SalaryBillLine +} + type StaffSalary struct { Id int64 CorpId int64 diff --git a/conf/template/salary_bill.html b/conf/template/salary_bill.html new file mode 100644 index 0000000..b700e2b --- /dev/null +++ b/conf/template/salary_bill.html @@ -0,0 +1,115 @@ + + + + + + + 工资单 + + + + +
+

{{.title}}

+ + {{range $i, $data := .datas}} +
+

{{.Name}}

+ + {{range $j, $v := .Line}} +
+ {{ $v.Label }} + {{ $v.Value }} +
+ {{end}} +
+ {{end}} + + +
+ 实发工资 + {{ .salary }} +
+
+ + + \ No newline at end of file diff --git a/go.mod b/go.mod index 0ddf035..58b5618 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( git.u8t.cn/open/gosdk v0.0.0-20250309163531-2f47649d3dbd 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 @@ -49,6 +50,7 @@ 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 @@ -92,6 +94,7 @@ 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 a887ac0..cbb636c 100644 --- a/server/controller/salary.go +++ b/server/controller/salary.go @@ -92,3 +92,9 @@ func (s *Salary) SyncStaffSalary(ctx *gin.Context) { go new(worker.Staff).SyncStaffSalary(corp.Id, "") ctx.JSON(http.StatusOK, session.NewRspOk()) } + +func (s *Salary) Bill(ctx *gin.Context) { + id := cast.ToInt64(ctx.Query("id")) + + service.NewStaffSalary().Bill(id, ctx) +} diff --git a/server/server.go b/server/server.go index d7931fe..6786443 100644 --- a/server/server.go +++ b/server/server.go @@ -38,6 +38,7 @@ func initRoutge(engine *gin.Engine) { apiGroup.POST("/salary/pay", controller.NewSalary().Pay) apiGroup.PUT("/staff/salary", controller.NewSalary().Update) apiGroup.DELETE("/staff/salary", controller.NewSalary().Delete) + noTokenGroup.GET("/staff/salary/bill", controller.NewSalary().Bill) apiGroup.GET("/staff/suggest", controller.NewStaff().Suggest) apiGroup.POST("/staff/pay", controller.NewStaff().Pay) diff --git a/server/service/staff_salary.go b/server/service/staff_salary.go index 7391207..38eedb1 100644 --- a/server/service/staff_salary.go +++ b/server/service/staff_salary.go @@ -426,3 +426,70 @@ func (s *StaffSalary) toExcel(filePath string, header []string, datas [][]string ctx.Writer.Header().Add("Content-Type", "application/msexcel") ctx.File(filePath) } + +func (s *StaffSalary) Bill(id int64, ctx *gin.Context) { + + salary, err := dao.NewStaffSalaryDao().Get(id) + session.CheckDBError(err) + session.CheckNilError(salary, "工资单不存在") + corp, err := dao.NewCorpDao().Get(salary.CorpId) + session.CheckDBError(err) + session.CheckNilError(corp, "企业不存在") + user, err := dao.NewStaffUserDao().Get(salary.UserId) + session.CheckDBError(err) + session.CheckNilError(user, "用户不存在") + + datas := make([]*model.SalaryBillSection, 0) + + baseDetail := make([]*model.SalaryBillLine, 0) + baseDetail = append(baseDetail, &model.SalaryBillLine{Label: "员工姓名", Value: fmt.Sprintf("%s", user.Realname)}) + baseDetail = append(baseDetail, &model.SalaryBillLine{Label: "基本工资", Value: fmt.Sprintf("%s", user.GetSalary().Base)}) + baseDetail = append(baseDetail, &model.SalaryBillLine{Label: "出勤工资", Value: fmt.Sprintf("%s", user.GetSalary().Target)}) + datas = append(datas, &model.SalaryBillSection{ + Name: "基本信息", + Line: baseDetail, + }) + + salaryDetail := make([]*model.SalaryBillLine, 0) + + salaryDetail = append(salaryDetail, &model.SalaryBillLine{Label: "出勤收入", Value: fmt.Sprintf("%.2f 元", salary.AttendSalary)}) + salaryDetail = append(salaryDetail, &model.SalaryBillLine{Label: "绩效收入", Value: fmt.Sprintf("%.2f 元", salary.TargetSalary)}) + + if salary.AwardSalary != 0 { + salaryDetail = append(salaryDetail, &model.SalaryBillLine{Label: "奖金收入", Value: fmt.Sprintf("%.2f 元", salary.AwardSalary)}) + } + if salary.OtherSalary != 0 { + salaryDetail = append(salaryDetail, &model.SalaryBillLine{Label: "其他收入", Value: fmt.Sprintf("%.2f 元", salary.OtherSalary)}) + } + if salary.SocialDeduct != 0 { + salaryDetail = append(salaryDetail, &model.SalaryBillLine{Label: "社保扣除", Value: fmt.Sprintf("%.2f 元", salary.SocialDeduct)}) + } + if salary.HouseDeduct != 0 { + salaryDetail = append(salaryDetail, &model.SalaryBillLine{Label: "公积金扣除", Value: fmt.Sprintf("%.2f 元", salary.HouseDeduct)}) + } + + salaryDetail = append(salaryDetail, &model.SalaryBillLine{Label: "个税扣除", Value: fmt.Sprintf("%.2f 元", salary.PersonalDeduct)}) + if salary.OtherSalary != 0 { + salaryDetail = append(salaryDetail, &model.SalaryBillLine{Label: "其他扣除", Value: fmt.Sprintf("%.2f 元", salary.OtherSalary)}) + } + datas = append(datas, &model.SalaryBillSection{ + Name: "工资明细", + Line: salaryDetail, + }) + + attendDetail := make([]*model.SalaryBillLine, 0) + attendDetail = append(attendDetail, &model.SalaryBillLine{Label: "应出勤", Value: fmt.Sprintf("%d 天", salary.ShouldDay)}) + attendDetail = append(attendDetail, &model.SalaryBillLine{Label: "休假天数", Value: fmt.Sprintf("%.2f 天", salary.HolidayDay)}) + attendDetail = append(attendDetail, &model.SalaryBillLine{Label: "缺勤天数", Value: fmt.Sprintf("%.2f 天", float64(salary.ShouldDay)-salary.AttendDay-salary.HolidayDay)}) + attendDetail = append(attendDetail, &model.SalaryBillLine{Label: "实际出勤", Value: fmt.Sprintf("%.2f 天", salary.AttendDay)}) + datas = append(datas, &model.SalaryBillSection{ + Name: "出勤信息", + Line: attendDetail, + }) + + ctx.HTML(http.StatusOK, "salary_bill.html", gin.H{ + "title": "工资单", + "salary": fmt.Sprintf("%.2f 元", salary.GetRealSalary()), + "datas": datas, + }) +}