From a5435e6664093cd4b2ead49409cb41e301e46514 Mon Sep 17 00:00:00 2001 From: liujiandao <274878379@qq.com> Date: 星期二, 30 四月 2024 14:07:04 +0800 Subject: [PATCH] 薪资计算2 --- task/salary_statistics.go | 52 +++- controllers/response/report_forms_response.go | 19 + controllers/report_forms_controller.go | 50 +++- controllers/salary_plan_controller.go | 1 task/task_init.go | 17 + go.mod | 4 docs/swagger.yaml | 87 +++++++ docs/docs.go | 132 ++++++++++ docs/swagger.json | 132 ++++++++++ controllers/request/report_forms_request.go | 3 models/salary_report_form.go | 29 + go.sum | 19 + models/db.go | 3 main.go | 5 models/salary_details.go | 10 models/lock.go | 115 +++++++++ 16 files changed, 625 insertions(+), 53 deletions(-) diff --git a/controllers/report_forms_controller.go b/controllers/report_forms_controller.go index b00be87..42d20ff 100644 --- a/controllers/report_forms_controller.go +++ b/controllers/report_forms_controller.go @@ -2,6 +2,11 @@ import ( "github.com/gin-gonic/gin" + "silkserver/controllers/request" + "silkserver/controllers/response" + "silkserver/extend/code" + "silkserver/extend/util" + "silkserver/models" ) type ReportFormsController struct { @@ -14,19 +19,38 @@ // @Produce application/json // @Param object body request.SalaryReportForms true "鍙傛暟" // @Param Authorization header string true "token" -// @Success 200 {object} util.ResponseList{data=[]models.WorkTypeManage} "鎴愬姛" +// @Success 200 {object} util.ResponseList{data=[]response.SalaryReportForms} "鎴愬姛" // @Router /api-jl/v1/forms/salaryReportForms [post] func (slf ReportFormsController) SalaryReportForms(c *gin.Context) { - //var params request.SalaryReportForms - //err := c.BindJSON(¶ms) - //if err != nil { - // util.ResponseFormat(c, code.RequestParamError, "鍙傛暟瑙f瀽澶辫触锛屾暟鎹被鍨嬮敊璇�") - // return - //} - //workers, err := models.NewWorkerSearch().SetPage(params.Page, params.PageSize).FindNotTotal() - //if err != nil { - // util.ResponseFormat(c, code.RequestParamError, err) - // return - //} - + var params request.SalaryReportForms + err := c.BindJSON(¶ms) + if err != nil { + util.ResponseFormat(c, code.RequestParamError, "鍙傛暟瑙f瀽澶辫触锛屾暟鎹被鍨嬮敊璇�") + return + } + reportForms, total, err := models.NewSalaryReportFormSearch().SetPage(params.Page, params.PageSize).SetKeyword(params.Keyword).SetPreload(true).Find() + if err != nil { + util.ResponseFormat(c, code.RequestParamError, err) + return + } + data := make([]response.SalaryReportForms, 0) + for _, form := range reportForms { + var srf response.SalaryReportForms + srf.WorkerId = form.WorkerId + srf.WorkerName = form.WorkerName + srf.Phone = form.Phone + srf.IssueSalary = form.IssueSalary + srf.Remark = form.Remark + srf.WorkType = form.WorkType.WorkName + salaryDetails := make([]response.SalaryDetail, 0) + for _, detail := range form.Details { + var sd response.SalaryDetail + sd.SalaryTypeId = detail.SalaryTypeId + sd.SalaryType = detail.SalaryType.Name + sd.Amount = detail.Amount + salaryDetails = append(salaryDetails, sd) + } + srf.Details = salaryDetails + } + util.ResponseFormatList(c, code.Success, data, total) } diff --git a/controllers/request/report_forms_request.go b/controllers/request/report_forms_request.go index 6ce2f3d..399ade5 100644 --- a/controllers/request/report_forms_request.go +++ b/controllers/request/report_forms_request.go @@ -2,5 +2,6 @@ type SalaryReportForms struct { PageInfo - Month string `json:"month"` + Month string `json:"month"` + Keyword string `json:"keyword"` } diff --git a/controllers/response/report_forms_response.go b/controllers/response/report_forms_response.go index 598df6e..3c4b8bc 100644 --- a/controllers/response/report_forms_response.go +++ b/controllers/response/report_forms_response.go @@ -1,8 +1,19 @@ package response +import "github.com/shopspring/decimal" + type SalaryReportForms struct { - WorkerName string `json:"workerName"` - WorkerId string `json:"workerId"` - Phone string `json:"phone"` - WorkType string `json:"workType"` + WorkerName string `json:"workerName"` + WorkerId string `json:"workerId"` + Phone string `json:"phone"` + WorkType string `json:"workType"` //宸ョ + IssueSalary decimal.Decimal `json:"issueSalary"` //搴斿彂宸ヨ祫 + Remark string `json:"remark"` //澶囨敞 + Details []SalaryDetail `json:"details"` +} + +type SalaryDetail struct { + SalaryTypeId uint `json:"salaryTypeId"` //钖祫绫诲瀷id + SalaryType string `json:"salaryType"` //钖祫绫诲瀷 + Amount decimal.Decimal `json:"amount"` //宸ヨ祫鍊� } diff --git a/controllers/salary_plan_controller.go b/controllers/salary_plan_controller.go index 02109c9..0212979 100644 --- a/controllers/salary_plan_controller.go +++ b/controllers/salary_plan_controller.go @@ -153,6 +153,7 @@ } break } else if value.Id == mini.ID { + dict.ID = mini.ID update = append(update, &dict) flag = false if i < len(dicts)-1 { diff --git a/docs/docs.go b/docs/docs.go index 2a40518..e1824a3 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -800,6 +800,58 @@ } } }, + "/api-jl/v1/forms/salaryReportForms": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "鎶ヨ〃绠$悊" + ], + "summary": "钖祫鎶ヨ〃", + "parameters": [ + { + "description": "鍙傛暟", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SalaryReportForms" + } + }, + { + "type": "string", + "description": "token", + "name": "Authorization", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "鎴愬姛", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/util.ResponseList" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/response.SalaryReportForms" + } + } + } + } + ] + } + } + } + } + }, "/api-jl/v1/mentor/createMentorInfo": { "post": { "produces": [ @@ -2474,6 +2526,9 @@ "overTimeDuration": { "type": "number" }, + "phoneNum": { + "type": "string" + }, "startWorkTime": { "type": "string" }, @@ -2936,10 +2991,14 @@ "type": "string" }, "salaryFormula": { + "description": "SalaryType string ` + "`" + `json:\"salaryType\" gorm:\"type:varchar(255);comment:钖祫绫诲瀷\"` + "`" + `", "type": "string" }, "salaryType": { - "type": "string" + "$ref": "#/definitions/models.MiniDict" + }, + "salaryTypeId": { + "type": "integer" }, "updatedAt": { "type": "string" @@ -3748,6 +3807,25 @@ } } }, + "request.SalaryReportForms": { + "type": "object", + "properties": { + "keyword": { + "type": "string" + }, + "month": { + "type": "string" + }, + "page": { + "description": "椤电爜", + "type": "integer" + }, + "pageSize": { + "description": "姣忛〉澶у皬", + "type": "integer" + } + } + }, "request.SalaryType": { "type": "object", "properties": { @@ -3770,6 +3848,9 @@ "request.SalaryTypeValue": { "type": "object", "properties": { + "id": { + "type": "integer" + }, "isDefault": { "description": "鏄惁鍙紪杈�", "type": "boolean" @@ -4338,6 +4419,55 @@ } } }, + "response.SalaryDetail": { + "type": "object", + "properties": { + "amount": { + "description": "宸ヨ祫鍊�", + "type": "number" + }, + "salaryType": { + "description": "钖祫绫诲瀷", + "type": "string" + }, + "salaryTypeId": { + "description": "钖祫绫诲瀷id", + "type": "integer" + } + } + }, + "response.SalaryReportForms": { + "type": "object", + "properties": { + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/response.SalaryDetail" + } + }, + "issueSalary": { + "description": "搴斿彂宸ヨ祫", + "type": "number" + }, + "phone": { + "type": "string" + }, + "remark": { + "description": "澶囨敞", + "type": "string" + }, + "workType": { + "description": "宸ョ", + "type": "string" + }, + "workerId": { + "type": "string" + }, + "workerName": { + "type": "string" + } + } + }, "util.Response": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index 60235c7..4fd364b 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -788,6 +788,58 @@ } } }, + "/api-jl/v1/forms/salaryReportForms": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "鎶ヨ〃绠$悊" + ], + "summary": "钖祫鎶ヨ〃", + "parameters": [ + { + "description": "鍙傛暟", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SalaryReportForms" + } + }, + { + "type": "string", + "description": "token", + "name": "Authorization", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "鎴愬姛", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/util.ResponseList" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/response.SalaryReportForms" + } + } + } + } + ] + } + } + } + } + }, "/api-jl/v1/mentor/createMentorInfo": { "post": { "produces": [ @@ -2462,6 +2514,9 @@ "overTimeDuration": { "type": "number" }, + "phoneNum": { + "type": "string" + }, "startWorkTime": { "type": "string" }, @@ -2924,10 +2979,14 @@ "type": "string" }, "salaryFormula": { + "description": "SalaryType string `json:\"salaryType\" gorm:\"type:varchar(255);comment:钖祫绫诲瀷\"`", "type": "string" }, "salaryType": { - "type": "string" + "$ref": "#/definitions/models.MiniDict" + }, + "salaryTypeId": { + "type": "integer" }, "updatedAt": { "type": "string" @@ -3736,6 +3795,25 @@ } } }, + "request.SalaryReportForms": { + "type": "object", + "properties": { + "keyword": { + "type": "string" + }, + "month": { + "type": "string" + }, + "page": { + "description": "椤电爜", + "type": "integer" + }, + "pageSize": { + "description": "姣忛〉澶у皬", + "type": "integer" + } + } + }, "request.SalaryType": { "type": "object", "properties": { @@ -3758,6 +3836,9 @@ "request.SalaryTypeValue": { "type": "object", "properties": { + "id": { + "type": "integer" + }, "isDefault": { "description": "鏄惁鍙紪杈�", "type": "boolean" @@ -4326,6 +4407,55 @@ } } }, + "response.SalaryDetail": { + "type": "object", + "properties": { + "amount": { + "description": "宸ヨ祫鍊�", + "type": "number" + }, + "salaryType": { + "description": "钖祫绫诲瀷", + "type": "string" + }, + "salaryTypeId": { + "description": "钖祫绫诲瀷id", + "type": "integer" + } + } + }, + "response.SalaryReportForms": { + "type": "object", + "properties": { + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/response.SalaryDetail" + } + }, + "issueSalary": { + "description": "搴斿彂宸ヨ祫", + "type": "number" + }, + "phone": { + "type": "string" + }, + "remark": { + "description": "澶囨敞", + "type": "string" + }, + "workType": { + "description": "宸ョ", + "type": "string" + }, + "workerId": { + "type": "string" + }, + "workerName": { + "type": "string" + } + } + }, "util.Response": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 7d4e568..da4f0f1 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -162,6 +162,8 @@ type: integer overTimeDuration: type: number + phoneNum: + type: string startWorkTime: type: string status: @@ -477,9 +479,12 @@ name: type: string salaryFormula: + description: SalaryType string `json:"salaryType" gorm:"type:varchar(255);comment:钖祫绫诲瀷"` type: string salaryType: - type: string + $ref: '#/definitions/models.MiniDict' + salaryTypeId: + type: integer updatedAt: type: string workTypes: @@ -1032,6 +1037,19 @@ description: 寮�濮嬬氦搴� type: number type: object + request.SalaryReportForms: + properties: + keyword: + type: string + month: + type: string + page: + description: 椤电爜 + type: integer + pageSize: + description: 姣忛〉澶у皬 + type: integer + type: object request.SalaryType: properties: type: @@ -1045,6 +1063,8 @@ type: object request.SalaryTypeValue: properties: + id: + type: integer isDefault: description: 鏄惁鍙紪杈� type: boolean @@ -1445,6 +1465,40 @@ startFineness: description: 寮�濮嬬氦搴� type: number + type: object + response.SalaryDetail: + properties: + amount: + description: 宸ヨ祫鍊� + type: number + salaryType: + description: 钖祫绫诲瀷 + type: string + salaryTypeId: + description: 钖祫绫诲瀷id + type: integer + type: object + response.SalaryReportForms: + properties: + details: + items: + $ref: '#/definitions/response.SalaryDetail' + type: array + issueSalary: + description: 搴斿彂宸ヨ祫 + type: number + phone: + type: string + remark: + description: 澶囨敞 + type: string + workType: + description: 宸ョ + type: string + workerId: + type: string + workerName: + type: string type: object util.Response: properties: @@ -1950,6 +2004,37 @@ summary: 淇濆瓨浜ч噺鐧昏琛� tags: - 鐢熶骇绠$悊/浜ч噺鐧昏琛� + /api-jl/v1/forms/salaryReportForms: + post: + parameters: + - description: 鍙傛暟 + in: body + name: object + required: true + schema: + $ref: '#/definitions/request.SalaryReportForms' + - description: token + in: header + name: Authorization + required: true + type: string + produces: + - application/json + responses: + "200": + description: 鎴愬姛 + schema: + allOf: + - $ref: '#/definitions/util.ResponseList' + - properties: + data: + items: + $ref: '#/definitions/response.SalaryReportForms' + type: array + type: object + summary: 钖祫鎶ヨ〃 + tags: + - 鎶ヨ〃绠$悊 /api-jl/v1/mentor/createMentorInfo: post: parameters: diff --git a/go.mod b/go.mod index 0b283cf..ed23f5b 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ github.com/Knetic/govaluate v3.0.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-gonic/gin v1.9.1 + github.com/go-co-op/gocron v1.37.0 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/nsqio/go-nsq v1.1.0 github.com/shopspring/decimal v1.3.1 @@ -45,6 +46,7 @@ github.com/goccy/go-json v0.10.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.1 // indirect + github.com/google/uuid v1.6.0 // 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 @@ -62,6 +64,7 @@ github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.3 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -72,6 +75,7 @@ github.com/ugorji/go/codec v1.2.11 // indirect github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect + go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect diff --git a/go.sum b/go.sum index f0f9548..0bf724b 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0= +github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -62,6 +64,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -77,6 +82,8 @@ github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -101,12 +108,12 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nsqio/go-nsq v1.1.0 h1:PQg+xxiUjA7V+TLdXw7nVrJ5Jbl3sN86EhGCQj4+FYE= github.com/nsqio/go-nsq v1.1.0/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQTuDEY= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= @@ -115,6 +122,10 @@ github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= @@ -165,6 +176,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -247,8 +260,10 @@ google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= diff --git a/main.go b/main.go index b195719..9ff533d 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ "silkserver/models" "silkserver/pkg/logx" "silkserver/router" + "silkserver/task" "syscall" "time" ) @@ -36,6 +37,10 @@ ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second, } + + //瀹氭椂浠诲姟鍒濆鍖� + task.Init() + go shutdown(server) logx.Error(server.ListenAndServe().Error()) } diff --git a/models/db.go b/models/db.go index 9609b84..4226418 100644 --- a/models/db.go +++ b/models/db.go @@ -91,6 +91,9 @@ AttendanceManage{}, WorkerPosition{}, AttendanceRule{}, + SalaryReportForm{}, + SalaryDetails{}, + Lock{}, ) return err } diff --git a/models/lock.go b/models/lock.go new file mode 100644 index 0000000..5a26fdc --- /dev/null +++ b/models/lock.go @@ -0,0 +1,115 @@ +package models + +import ( + "fmt" + "gorm.io/gorm" + "silkserver/pkg/mysqlx" + "time" +) + +type ( + // Lock 鍒嗗竷寮忛攣 + Lock struct { + LockName string `gorm:"primaryKey"` + LockedBy string + LockedAt time.Time + } + + LockSearch struct { + Lock + Orm *gorm.DB + } +) + +func (slf *Lock) TableName() string { + return "distributed_lock" +} + +func NewLockSearch() *LockSearch { + return &LockSearch{Orm: mysqlx.GetDB()} +} + +func (slf *LockSearch) SetOrm(tx *gorm.DB) *LockSearch { + slf.Orm = tx + + return slf +} + +func (slf *LockSearch) SetLockName(lockName string) *LockSearch { + slf.LockName = lockName + return slf +} + +func (slf *LockSearch) SetLockedBy(lockedBy string) *LockSearch { + slf.LockedBy = lockedBy + return slf +} + +func (slf *LockSearch) build() *gorm.DB { + var db = slf.Orm.Model(&Lock{}) + + if slf.LockName != "" { + db = db.Where("lock_name = ?", slf.LockName) + } + + if slf.LockedBy != "" { + db = db.Where("locked_by = ?", slf.LockedBy) + } + + return db +} + +// Create 鍗曟潯鎻掑叆 +func (slf *LockSearch) Create(record *Lock) error { + var db = slf.build() + + if err := db.Create(record).Error; err != nil { + return err + } + + return nil +} + +func (slf *LockSearch) Delete() error { + var db = slf.build() + return db.Delete(&Lock{}).Error +} + +func (slf *LockSearch) First() (*Lock, error) { + var ( + record = new(Lock) + db = slf.build() + ) + + if err := db.First(record).Error; err != nil { + return record, err + } + + return record, nil +} + +func (slf *LockSearch) AcquireLock(lockName, serviceID string) error { + err := WithTransaction(func(db *gorm.DB) error { + lock, err := slf.SetLockName(lockName).SetLockedBy(serviceID).First() + if err != nil && err != gorm.ErrRecordNotFound { + return err + } + if lock.LockedBy != "" { + return fmt.Errorf("AcquireLock failed, lockName: %s, serviceID: %+v", lockName, serviceID) + } + return slf.Create(&Lock{ + LockName: lockName, + LockedBy: serviceID, + LockedAt: time.Now(), + }) + }) + return err +} + +func (slf *LockSearch) ReleaseLock(lockName, serviceID string) error { + err := slf.SetLockName(lockName).SetLockedBy(serviceID).Delete() + if err != nil { + return fmt.Errorf("AcquireLock err: %v, lockName: %s, serviceID: %+v", err, lockName, serviceID) + } + return nil +} diff --git a/models/salary_details.go b/models/salary_details.go index eec1e11..9427d3c 100644 --- a/models/salary_details.go +++ b/models/salary_details.go @@ -11,10 +11,10 @@ //SalaryDetails 钖祫鏄庣粏琛� SalaryDetails struct { gorm.Model - SalaryDetailsId uint `json:"SalaryDetailsId" gorm:"type:int(11);comment:钖祫鎶ヨ〃id"` - SalaryTypeId uint `json:"salaryTypeId" gorm:"type:int(11);comment:钖祫绫诲瀷id"` - SalaryType MiniDict `json:"salaryType" gorm:"foreignKey:SalaryTypeId;references:ID"` - Amount decimal.Decimal `json:"amount" gorm:"type:decimal(20,3);comment:宸ヨ祫鍊�"` + SalaryReportFormId uint `json:"salaryReportFormId" gorm:"type:int(11);not null;comment:钖祫鎶ヨ〃id"` + SalaryTypeId uint `json:"salaryTypeId" gorm:"type:int(11);comment:钖祫绫诲瀷id"` + SalaryType MiniDict `json:"salaryType" gorm:"foreignKey:SalaryTypeId;references:ID"` + Amount decimal.Decimal `json:"amount" gorm:"type:decimal(20,3);comment:宸ヨ祫鍊�"` } SalaryDetailsSearch struct { SalaryDetails @@ -26,7 +26,7 @@ ) func (slf SalaryDetails) TableName() string { - return "salary_details" + return "silk_salary_details" } func NewSalaryDetailsSearch() *SalaryDetailsSearch { diff --git a/models/salary_report_form.go b/models/salary_report_form.go index 67aa59f..a03738b 100644 --- a/models/salary_report_form.go +++ b/models/salary_report_form.go @@ -11,27 +11,28 @@ // SalaryReportForm 钖祫鎶ヨ〃 SalaryReportForm struct { gorm.Model - WorkerId string `json:"workerId" gorm:"type:varchar(255);comment:浜哄憳id"` - WorkerName string `json:"workerName" gorm:"type:varchar(255);comment:浜哄憳濮撳悕"` - Phone string `json:"phone" gorm:"type:varchar(255);comment:鐢佃瘽"` - WorkTypeId uint `json:"workTypeId" gorm:"type:int(11);comment:宸ョ绫诲瀷id"` - WorkType WorkTypeManage `json:"workType" gorm:"foreignKey:WorkTypeId;references:ID"` - Month string `json:"month" gorm:"type:varchar(255);comment:鏈堜唤"` - IssueSalary decimal.Decimal `json:"issueSalary" gorm:"type:decimal(20,3);comment:搴斿彂宸ヨ祫"` - Remark string `json:"remark" gorm:"type:varchar(255);comment:澶囨敞"` - Details []SalaryDetails `json:"details" gorm:"foreignKey:SalaryReportFormId;references:Id"` + WorkerId string `json:"workerId" gorm:"type:varchar(255);comment:浜哄憳id"` + WorkerName string `json:"workerName" gorm:"type:varchar(255);comment:浜哄憳濮撳悕"` + Phone string `json:"phone" gorm:"type:varchar(255);comment:鐢佃瘽"` + WorkTypeId uint `json:"workTypeId" gorm:"type:int(11);comment:宸ョ绫诲瀷id"` + WorkType WorkTypeManage `json:"workType" gorm:"foreignKey:WorkTypeId;references:ID"` + Month string `json:"month" gorm:"type:varchar(255);comment:鏈堜唤"` + IssueSalary decimal.Decimal `json:"issueSalary" gorm:"type:decimal(20,3);comment:搴斿彂宸ヨ祫"` + Remark string `json:"remark" gorm:"type:varchar(255);comment:澶囨敞"` + Details []*SalaryDetails `json:"details" gorm:"foreignKey:SalaryReportFormId"` } SalaryReportFormSearch struct { SalaryReportForm PageNum int PageSize int Preload bool + Keyword string Orm *gorm.DB } ) func (slf SalaryReportForm) TableName() string { - return "salary_report_form" + return "silk_salary_report_form" } func NewSalaryReportFormSearch() *SalaryReportFormSearch { @@ -53,12 +54,20 @@ return slf } +func (slf *SalaryReportFormSearch) SetKeyword(keyword string) *SalaryReportFormSearch { + slf.Keyword = keyword + return slf +} + func (slf *SalaryReportFormSearch) build() *gorm.DB { var db = slf.Orm.Table(slf.TableName()) if slf.Preload { db = db.Model(SalaryReportForm{}).Preload("Details").Preload("WorkType") } + if slf.Keyword != "" { + db = db.Where("worker_name like ? or worker_id like ?", "%"+slf.Keyword+"%", "%"+slf.Keyword+"%") + } return db } diff --git a/task/salary_statistics.go b/task/salary_statistics.go index 07e1a1e..254e306 100644 --- a/task/salary_statistics.go +++ b/task/salary_statistics.go @@ -11,6 +11,23 @@ ) func SalaryStatistics() { + //鍔犻攣锛屽彧闇�瑕佷竴涓繘绋嬭繍琛屾浠诲姟 + var ( + lockName = "SalaryStatistics" + serviceID = "silkServer" + ) + err := models.NewLockSearch().AcquireLock(lockName, serviceID) + if err != nil { + logx.Errorf("MonthStats AcquireLock err:%v", err) + return + } + defer func() { + err := models.NewLockSearch().ReleaseLock(lockName, serviceID) + if err != nil { + logx.Errorf("MonthStats ReleaseLock err:%v", err) + } + }() + lastMonthStart, lastMonthEnd := GetLastMonthPeriod() month := lastMonthStart.Format("2006-01") @@ -24,19 +41,23 @@ } var reportForms []*models.SalaryReportForm + reportMap := make(map[string]*models.SalaryReportForm) workTypeIdMap := make(map[uint]uint) dataMap := make(map[string]utils.SalaryCalculateData) for _, attendance := range attendances { - var rf models.SalaryReportForm + if _, ok := reportMap[attendance.WorkerId]; !ok { + var rf models.SalaryReportForm + rf.WorkerId = attendance.WorkerId + rf.WorkerName = attendance.WorkerName + rf.WorkTypeId = attendance.WorkTypeId + rf.Month = month + rf.Phone = attendance.PhoneNum + reportMap[attendance.WorkerId] = &rf + } var data utils.SalaryCalculateData if _, ok := dataMap[attendance.WorkerId]; ok { data = dataMap[attendance.WorkerId] } - rf.WorkerId = attendance.WorkerId - rf.WorkerName = attendance.WorkerName - rf.WorkTypeId = attendance.WorkTypeId - rf.Month = month - rf.Phone = attendance.PhoneNum if attendance.WorkTypeId > 0 { workTypeIdMap[attendance.WorkTypeId] = attendance.WorkTypeId } @@ -47,7 +68,9 @@ data.TotalAttendanceDays = data.TotalAttendanceDays + 1 } dataMap[attendance.WorkerId] = data - reportForms = append(reportForms, &rf) + } + for _, v := range reportMap { + reportForms = append(reportForms, v) } workTypeIds := make([]uint, 0) for _, v := range workTypeIdMap { @@ -61,7 +84,7 @@ return } for _, form := range reportForms { - details := make([]models.SalaryDetails, 0) + details := make([]*models.SalaryDetails, 0) issueSalary := decimal.NewFromInt(0) for _, manage := range workTypeManages { if form.WorkTypeId == manage.ID { @@ -76,16 +99,15 @@ data, err = GetDailySilkProduction(startStr, endStr, form.WorkerId, data) if err != nil { logx.Error("SalaryStatistics 缁熻钖祫鍑洪敊 err: " + err.Error()) - } else { - amount, err = utils.CalculateSalary(data, formula) - if err != nil { - logx.Error("SalaryStatistics 璁$畻钖祫鍑洪敊 err: " + err.Error()) - } } + } + amount, err = utils.CalculateSalary(data, formula) + if err != nil { + logx.Error("SalaryStatistics 璁$畻钖祫鍑洪敊 err: " + err.Error()) } detail.Amount = amount issueSalary = issueSalary.Add(amount) - details = append(details, detail) + details = append(details, &detail) } } } @@ -155,7 +177,7 @@ //鏌ヨ绾ゅ害鐧昏琛� var fineness []models.FinenessRegister markets := make([]string, 0) - err = models.NewFinenessRegisterSearch().Orm.Table("silk_fineness_register").Where("workshop in (?) and workshop_group "+ + err = models.NewFinenessRegisterSearch().Orm.Table("silk_fineness_register").Where("workshop_number in (?) and workshop_group "+ "in (?) and finish_date >= ? and finish_date <= ?", workshops, groups, start, end).Find(&fineness).Error if err != nil { return data, err diff --git a/task/task_init.go b/task/task_init.go new file mode 100644 index 0000000..284d37b --- /dev/null +++ b/task/task_init.go @@ -0,0 +1,17 @@ +package task + +import ( + "github.com/go-co-op/gocron" + "time" +) + +var s *gocron.Scheduler + +func init() { + s = gocron.NewScheduler(time.UTC) +} +func Init() { + s.Every(1).Month().Do(SalaryStatistics) //姣忔湀鍒濇墽琛屼竴娆� + + s.StartAsync() +} -- Gitblit v1.8.0