liujiandao
2024-04-30 a5435e6664093cd4b2ead49409cb41e301e46514
薪资计算2
2个文件已添加
14个文件已修改
678 ■■■■■ 已修改文件
controllers/report_forms_controller.go 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/request/report_forms_request.go 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/response/report_forms_response.go 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/salary_plan_controller.go 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/db.go 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/lock.go 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/salary_details.go 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/salary_report_form.go 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
task/salary_statistics.go 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
task/task_init.go 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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(&params)
    //if err != nil {
    //    util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误")
    //    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(&params)
    if err != nil {
        util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误")
        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)
}
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"`
}
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"`       //工资值
}
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 {
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": {
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": {
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:
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
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=
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())
}
models/db.go
@@ -91,6 +91,9 @@
        AttendanceManage{},
        WorkerPosition{},
        AttendanceRule{},
        SalaryReportForm{},
        SalaryDetails{},
        Lock{},
    )
    return err
}
models/lock.go
New file
@@ -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
}
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 {
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
}
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
task/task_init.go
New file
@@ -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()
}