liujiandao
2024-04-17 67b13bb40517145cfadc05d7b22411b16f1528d7
Merge branch 'master' of http://192.168.5.5:10010/r/aps/WMS
6个文件已添加
14个文件已修改
1394 ■■■■■ 已修改文件
controllers/report_forms_controller.go 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.go 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/common.go 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/db.go 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/location_product_amount.go 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/lock.go 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/material.go 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/month_stats.go 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/operation.go 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/operation_details.go 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
request/report_forms_request.go 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
router/router.go 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/month_stats.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
task/month_stats.go 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
task/tasklist.go 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/report_forms_controller.go
@@ -370,3 +370,27 @@
    util.ResponseFormatList(c, code.Success, result, int(total))
}
// MonthStats
// @Tags      报表
// @Summary   月度统计库存报表
// @Produce   application/json
// @Param     object  body  request.GetMonthStats true  "查询参数"
// @Param     Authorization    header string true "token"
// @Success   200 {object} util.ResponseList{data=[]models.MonthStats}    "成功"
// @Router    /api-wms/v1/forms/monthStats [post]
func (slf ReportFormsController) MonthStats(c *gin.Context) {
    var params request.GetMonthStats
    if err := c.BindJSON(&params); err != nil {
        util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误")
        return
    }
    list, total, err := models.NewMonthStatsSearch().SetPage(params.Page, params.PageSize).SetKeyword(params.Keyword).SetDate(params.Date).Find()
    if err != nil {
        util.ResponseFormat(c, code.InternalError, "查询失败")
        return
    }
    util.ResponseFormatList(c, code.Success, list, int(total))
}
docs/docs.go
@@ -551,6 +551,58 @@
                }
            }
        },
        "/api-wms/v1/forms/monthStats": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "报表"
                ],
                "summary": "月度统计库存报表",
                "parameters": [
                    {
                        "description": "查询参数",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/request.GetMonthStats"
                        }
                    },
                    {
                        "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/models.MonthStats"
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        },
        "/api-wms/v1/location/addLocation": {
            "post": {
                "produces": [
@@ -3440,6 +3492,12 @@
                    "description": "客户前置时间(天)",
                    "type": "number"
                },
                "grossUnit": {
                    "type": "string"
                },
                "grossWeight": {
                    "type": "number"
                },
                "id": {
                    "type": "string"
                },
@@ -3514,9 +3572,24 @@
                        }
                    ]
                },
                "moreUnit": {
                    "type": "boolean"
                },
                "moreUnitList": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "name": {
                    "description": "物料名称",
                    "type": "string"
                },
                "netUnit": {
                    "type": "string"
                },
                "netWeight": {
                    "type": "number"
                },
                "note": {
                    "type": "string"
@@ -3612,6 +3685,84 @@
                "volume": {
                    "description": "体积",
                    "type": "number"
                },
                "weight": {
                    "description": "重量",
                    "type": "number"
                }
            }
        },
        "models.MonthStats": {
            "type": "object",
            "properties": {
                "MoreUnitsArr": {
                    "description": "期末其他单位数组",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "amount": {
                    "description": "期末结余数量",
                    "type": "number"
                },
                "beginAmount": {
                    "description": "期初数量",
                    "type": "number"
                },
                "beginMoreUnitsArr": {
                    "description": "期初其他单位数组",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "createTime": {
                    "type": "string"
                },
                "date": {
                    "description": "日期 2024-04",
                    "type": "string"
                },
                "id": {
                    "type": "integer"
                },
                "inputAmount": {
                    "description": "入库数量",
                    "type": "number"
                },
                "inputMoreUnitsArr": {
                    "description": "入库其他单位数组",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "outputAmount": {
                    "description": "出库数量",
                    "type": "number"
                },
                "outputMoreUnitsArr": {
                    "description": "出库其他单位数组",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "productId": {
                    "description": "产品id",
                    "type": "string"
                },
                "productName": {
                    "description": "产品名称",
                    "type": "string"
                },
                "unit": {
                    "description": "单位",
                    "type": "string"
                },
                "updateTime": {
                    "type": "string"
                },
                "weight": {
                    "description": "重量",
@@ -3829,6 +3980,12 @@
                    "description": "目标位置id",
                    "type": "integer"
                },
                "totalGrossWeight": {
                    "type": "number"
                },
                "totalNetWeight": {
                    "type": "number"
                },
                "updateTime": {
                    "type": "string"
                }
@@ -3958,6 +4115,20 @@
                    "type": "boolean"
                },
                "name": {
                    "type": "string"
                }
            }
        },
        "models.UnitItems": {
            "type": "object",
            "properties": {
                "amount": {
                    "type": "number"
                },
                "floating": {
                    "type": "boolean"
                },
                "unit": {
                    "type": "string"
                }
            }
@@ -4514,6 +4685,25 @@
                }
            }
        },
        "request.GetMonthStats": {
            "type": "object",
            "properties": {
                "date": {
                    "type": "string"
                },
                "keyword": {
                    "type": "string"
                },
                "page": {
                    "description": "页码",
                    "type": "integer"
                },
                "pageSize": {
                    "description": "每页大小",
                    "type": "integer"
                }
            }
        },
        "request.GetProductList": {
            "type": "object",
            "properties": {
@@ -4629,6 +4819,14 @@
                "toLocationId": {
                    "description": "目标位置id",
                    "type": "integer"
                },
                "totalGrossWeight": {
                    "description": "总毛重",
                    "type": "number"
                },
                "totalNetWeight": {
                    "description": "总净重",
                    "type": "number"
                }
            }
        },
docs/swagger.json
@@ -539,6 +539,58 @@
                }
            }
        },
        "/api-wms/v1/forms/monthStats": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "报表"
                ],
                "summary": "月度统计库存报表",
                "parameters": [
                    {
                        "description": "查询参数",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/request.GetMonthStats"
                        }
                    },
                    {
                        "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/models.MonthStats"
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        },
        "/api-wms/v1/location/addLocation": {
            "post": {
                "produces": [
@@ -3428,6 +3480,12 @@
                    "description": "客户前置时间(天)",
                    "type": "number"
                },
                "grossUnit": {
                    "type": "string"
                },
                "grossWeight": {
                    "type": "number"
                },
                "id": {
                    "type": "string"
                },
@@ -3502,9 +3560,24 @@
                        }
                    ]
                },
                "moreUnit": {
                    "type": "boolean"
                },
                "moreUnitList": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "name": {
                    "description": "物料名称",
                    "type": "string"
                },
                "netUnit": {
                    "type": "string"
                },
                "netWeight": {
                    "type": "number"
                },
                "note": {
                    "type": "string"
@@ -3600,6 +3673,84 @@
                "volume": {
                    "description": "体积",
                    "type": "number"
                },
                "weight": {
                    "description": "重量",
                    "type": "number"
                }
            }
        },
        "models.MonthStats": {
            "type": "object",
            "properties": {
                "MoreUnitsArr": {
                    "description": "期末其他单位数组",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "amount": {
                    "description": "期末结余数量",
                    "type": "number"
                },
                "beginAmount": {
                    "description": "期初数量",
                    "type": "number"
                },
                "beginMoreUnitsArr": {
                    "description": "期初其他单位数组",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "createTime": {
                    "type": "string"
                },
                "date": {
                    "description": "日期 2024-04",
                    "type": "string"
                },
                "id": {
                    "type": "integer"
                },
                "inputAmount": {
                    "description": "入库数量",
                    "type": "number"
                },
                "inputMoreUnitsArr": {
                    "description": "入库其他单位数组",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "outputAmount": {
                    "description": "出库数量",
                    "type": "number"
                },
                "outputMoreUnitsArr": {
                    "description": "出库其他单位数组",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/models.UnitItems"
                    }
                },
                "productId": {
                    "description": "产品id",
                    "type": "string"
                },
                "productName": {
                    "description": "产品名称",
                    "type": "string"
                },
                "unit": {
                    "description": "单位",
                    "type": "string"
                },
                "updateTime": {
                    "type": "string"
                },
                "weight": {
                    "description": "重量",
@@ -3817,6 +3968,12 @@
                    "description": "目标位置id",
                    "type": "integer"
                },
                "totalGrossWeight": {
                    "type": "number"
                },
                "totalNetWeight": {
                    "type": "number"
                },
                "updateTime": {
                    "type": "string"
                }
@@ -3946,6 +4103,20 @@
                    "type": "boolean"
                },
                "name": {
                    "type": "string"
                }
            }
        },
        "models.UnitItems": {
            "type": "object",
            "properties": {
                "amount": {
                    "type": "number"
                },
                "floating": {
                    "type": "boolean"
                },
                "unit": {
                    "type": "string"
                }
            }
@@ -4502,6 +4673,25 @@
                }
            }
        },
        "request.GetMonthStats": {
            "type": "object",
            "properties": {
                "date": {
                    "type": "string"
                },
                "keyword": {
                    "type": "string"
                },
                "page": {
                    "description": "页码",
                    "type": "integer"
                },
                "pageSize": {
                    "description": "每页大小",
                    "type": "integer"
                }
            }
        },
        "request.GetProductList": {
            "type": "object",
            "properties": {
@@ -4617,6 +4807,14 @@
                "toLocationId": {
                    "description": "目标位置id",
                    "type": "integer"
                },
                "totalGrossWeight": {
                    "description": "总毛重",
                    "type": "number"
                },
                "totalNetWeight": {
                    "description": "总净重",
                    "type": "number"
                }
            }
        },
docs/swagger.yaml
@@ -540,6 +540,10 @@
      deliveryAdvanceTime:
        description: 客户前置时间(天)
        type: number
      grossUnit:
        type: string
      grossWeight:
        type: number
      id:
        type: string
      inStorageExplain:
@@ -597,9 +601,19 @@
        - $ref: '#/definitions/constvar.MaterialMode'
        description: MaterialType constvar.ProductType  `gorm:"index;type:int(11);comment:物料类型(数字)"
          json:"materialType"`
      moreUnit:
        type: boolean
      moreUnitList:
        items:
          $ref: '#/definitions/models.UnitItems'
        type: array
      name:
        description: 物料名称
        type: string
      netUnit:
        type: string
      netWeight:
        type: number
      note:
        type: string
      orderAdvanceTime:
@@ -668,6 +682,62 @@
      volume:
        description: 体积
        type: number
      weight:
        description: 重量
        type: number
    type: object
  models.MonthStats:
    properties:
      MoreUnitsArr:
        description: 期末其他单位数组
        items:
          $ref: '#/definitions/models.UnitItems'
        type: array
      amount:
        description: 期末结余数量
        type: number
      beginAmount:
        description: 期初数量
        type: number
      beginMoreUnitsArr:
        description: 期初其他单位数组
        items:
          $ref: '#/definitions/models.UnitItems'
        type: array
      createTime:
        type: string
      date:
        description: 日期 2024-04
        type: string
      id:
        type: integer
      inputAmount:
        description: 入库数量
        type: number
      inputMoreUnitsArr:
        description: 入库其他单位数组
        items:
          $ref: '#/definitions/models.UnitItems'
        type: array
      outputAmount:
        description: 出库数量
        type: number
      outputMoreUnitsArr:
        description: 出库其他单位数组
        items:
          $ref: '#/definitions/models.UnitItems'
        type: array
      productId:
        description: 产品id
        type: string
      productName:
        description: 产品名称
        type: string
      unit:
        description: 单位
        type: string
      updateTime:
        type: string
      weight:
        description: 重量
        type: number
@@ -811,6 +881,10 @@
      toLocationId:
        description: 目标位置id
        type: integer
      totalGrossWeight:
        type: number
      totalNetWeight:
        type: number
      updateTime:
        type: string
    type: object
@@ -897,6 +971,15 @@
      isDefault:
        type: boolean
      name:
        type: string
    type: object
  models.UnitItems:
    properties:
      amount:
        type: number
      floating:
        type: boolean
      unit:
        type: string
    type: object
  models.Warehouse:
@@ -1284,6 +1367,19 @@
      type:
        type: integer
    type: object
  request.GetMonthStats:
    properties:
      date:
        type: string
      keyword:
        type: string
      page:
        description: 页码
        type: integer
      pageSize:
        description: 每页大小
        type: integer
    type: object
  request.GetProductList:
    properties:
      categoryId:
@@ -1368,6 +1464,12 @@
      toLocationId:
        description: 目标位置id
        type: integer
      totalGrossWeight:
        description: 总毛重
        type: number
      totalNetWeight:
        description: 总净重
        type: number
    type: object
  request.OperationList:
    properties:
@@ -2139,6 +2241,37 @@
      summary: 获取位置报表
      tags:
      - 报表
  /api-wms/v1/forms/monthStats:
    post:
      parameters:
      - description: 查询参数
        in: body
        name: object
        required: true
        schema:
          $ref: '#/definitions/request.GetMonthStats'
      - 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/models.MonthStats'
                  type: array
              type: object
      summary: 月度统计库存报表
      tags:
      - 报表
  /api-wms/v1/location/addLocation:
    post:
      parameters:
go.mod
@@ -9,7 +9,7 @@
    github.com/dgrijalva/jwt-go v3.2.0+incompatible
    github.com/gin-gonic/gin v1.9.0
    github.com/golang-jwt/jwt/v4 v4.5.0
    github.com/google/uuid v1.3.1
    github.com/google/uuid v1.4.0
    github.com/huichen/sego v0.0.0-20210824061530-c87651ea5c76
    github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
    github.com/nsqio/go-nsq v1.1.0
@@ -62,6 +62,7 @@
    github.com/fsnotify/fsnotify v1.6.0 // indirect
    github.com/gabriel-vasile/mimetype v1.4.2 // indirect
    github.com/gin-contrib/sse v0.1.0 // indirect
    github.com/go-co-op/gocron v1.37.0 // indirect
    github.com/go-ini/ini v1.67.0 // indirect
    github.com/go-logr/logr v1.2.4 // indirect
    github.com/go-logr/stdr v1.2.2 // indirect
@@ -104,6 +105,7 @@
    github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // 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/sirupsen/logrus v1.9.3 // indirect
    github.com/spf13/afero v1.9.3 // indirect
    github.com/spf13/jwalterweatherman v1.1.0 // indirect
go.sum
@@ -46,6 +46,8 @@
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/RoaringBitmap/roaring v1.2.3 h1:yqreLINqIrX22ErkKI0vY47/ivtJr6n+kMhVOVmhWBY=
github.com/RoaringBitmap/roaring v1.2.3/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE=
github.com/adamzy/cedar-go v0.0.0-20170805034717-80a9c64b256d h1:ir/IFJU5xbja5UaBEQLjcvn7aAU01nqU/NUyOBEU+ew=
@@ -142,11 +144,14 @@
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
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-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -250,6 +255,8 @@
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
@@ -273,10 +280,12 @@
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kirinlabs/HttpRequest v1.1.1 h1:eBbFzpRd/Y7vQhRY30frHK3yAJiT1wDlB31Ryzyklc0=
github.com/kirinlabs/HttpRequest v1.1.1/go.mod h1:XV38fA4rXZox83tlEV9KIQ7Cdsut319x6NGzVLuRlB8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -287,6 +296,7 @@
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
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=
@@ -317,6 +327,7 @@
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
@@ -326,6 +337,7 @@
github.com/open-policy-agent/opa v0.57.1/go.mod h1:YYcVsWcdOW47owR0zElx8HPYZK60vL0MOPsEmh13us4=
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
github.com/pelletier/go-toml/v2 v2.0.9/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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -348,7 +360,11 @@
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.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
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.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
main.go
@@ -19,6 +19,7 @@
    "wms/proto/purchase_wms"
    "wms/router"
    "wms/service"
    "wms/task"
)
func main() {
@@ -75,6 +76,8 @@
    go service.InitLocationReportData()
    go service.InitHistoryReportData()
    task.Init()
    logx.Error(server.ListenAndServe().Error())
}
models/common.go
New file
@@ -0,0 +1,13 @@
package models
import "github.com/shopspring/decimal"
type GroupCount struct {
    Class string
    Total int64
}
type GroupSum struct {
    Class string
    Sum   decimal.Decimal
}
models/db.go
@@ -118,6 +118,8 @@
        LogisticCompany{},
        FileTemplateAttachment{},
        MoveHistory{},
        Lock{},
        MonthStats{},
    )
    return err
}
models/location_product_amount.go
@@ -289,3 +289,25 @@
    return nil
}
func (slf *LocationProductAmountSearch) GroupCount(field string) ([]*GroupCount, error) {
    var (
        db     = slf.build()
        result = make([]*GroupCount, 0)
    )
    if err := db.Select("count(*) as total, " + field + " as class").Group(field).Scan(&result).Error; err != nil {
        return nil, fmt.Errorf("select group err: %v", err)
    }
    return result, nil
}
func (slf *LocationProductAmountSearch) GroupSum(groupField string, sumField string) ([]*GroupSum, error) {
    var (
        db     = slf.build()
        result = make([]*GroupSum, 0)
    )
    if err := db.Select("sum(" + sumField + ") as sum, " + groupField + " as class").Group(groupField).Scan(&result).Error; err != nil {
        return nil, fmt.Errorf("select group err: %v", err)
    }
    return result, nil
}
models/lock.go
New file
@@ -0,0 +1,115 @@
package models
import (
    "fmt"
    "gorm.io/gorm"
    "time"
    "wms/pkg/mysqlx"
)
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/material.go
@@ -109,6 +109,7 @@
        Orm         *gorm.DB
        CategoryIds []int
        Preload     bool
        Fields      string
    }
    IdAndName struct {
@@ -258,6 +259,11 @@
    return slf
}
func (slf *MaterialSearch) SetFields(fields string) *MaterialSearch {
    slf.Fields = fields
    return slf
}
func (slf *MaterialSearch) build() *gorm.DB {
    var db = slf.Orm.Table(slf.TableName())
@@ -322,6 +328,10 @@
    }
    if len(slf.CategoryIds) > 0 {
        db = db.Where("category_id in ?", slf.CategoryIds)
    }
    if slf.Fields != "" {
        db = db.Select(slf.Fields)
    }
    if slf.Preload {
@@ -611,3 +621,11 @@
    return nil
}
func MaterialMap(records []*Material) (m map[string]*Material) {
    m = make(map[string]*Material, len(records))
    for _, record := range records {
        m[record.ID] = record
    }
    return m
}
models/month_stats.go
New file
@@ -0,0 +1,349 @@
package models
import (
    "encoding/json"
    "fmt"
    "github.com/shopspring/decimal"
    "gorm.io/gorm"
    "wms/pkg/mysqlx"
)
type (
    // MonthStats 移动历史
    MonthStats struct {
        WmsModel
        Id          int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
        ProductId   string `json:"productId" gorm:"type:varchar(255);not null;comment:产品id"`   //产品id
        ProductName string `json:"productName" gorm:"type:varchar(255);not null;comment:产品名称"` //产品名称
        Unit        string `json:"unit" gorm:"type:char(10);not null;comment:单位"`              //单位
        BeginAmount       decimal.Decimal `json:"beginAmount" gorm:"type:decimal(30,10);not null;comment:数量"` //期初数量
        BeginMoreUnitsArr []UnitItems     `json:"beginMoreUnitsArr" gorm:"-"`                                 //期初其他单位数组
        BeginMoreUnits    string          `json:"-" gorm:"type:varchar(1000);not null;default:''"`            //期初其他单位json字符串
        InputAmount       decimal.Decimal `json:"inputAmount" gorm:"type:decimal(30,10);not null;comment:数量"` //入库数量
        InputMoreUnitsArr []UnitItems     `json:"inputMoreUnitsArr" gorm:"-"`                                 //入库其他单位数组
        InputMoreUnits    string          `json:"-" gorm:"type:varchar(1000);not null;default:''"`            //入库其他单位json字符串
        OutputAmount       decimal.Decimal `json:"outputAmount" gorm:"type:decimal(30,10);not null;comment:数量"` //出库数量
        OutputMoreUnitsArr []UnitItems     `json:"outputMoreUnitsArr" gorm:"-"`                                 //出库其他单位数组
        OutputMoreUnits    string          `json:"-" gorm:"type:varchar(1000);not null;default:''"`             //出库其他单位json字符串
        EndAmount       decimal.Decimal `json:"amount" gorm:"type:decimal(30,10);not null;comment:数量"` //期末结余数量
        EndMoreUnitsArr []UnitItems     `json:"MoreUnitsArr" gorm:"-"`                                 //期末其他单位数组
        EndMoreUnits    string          `json:"-" gorm:"type:varchar(1000);not null;default:''"`       //期末其他单位json字符串
        Weight decimal.Decimal `json:"weight" gorm:"type:decimal(20,5);not null;comment:重量"`     //重量
        Date   string          `json:"date" gorm:"index;type:varchar(255); not null;default ''"` //日期 2024-04
    }
    MonthStatsSearch struct {
        MonthStats
        Order    string
        PageNum  int
        PageSize int
        Keyword  string
        Orm      *gorm.DB
        Preload  bool
        Fields   string
    }
)
func (slf *MonthStats) TableName() string {
    return "wms_month_stats"
}
func (slf *MonthStats) BeforeCreate(tx *gorm.DB) error {
    if len(slf.BeginMoreUnitsArr) != 0 {
        str, err := json.Marshal(slf.BeginMoreUnitsArr)
        if err != nil {
            return err
        }
        slf.BeginMoreUnits = string(str)
    }
    if len(slf.EndMoreUnitsArr) != 0 {
        str, err := json.Marshal(slf.EndMoreUnitsArr)
        if err != nil {
            return err
        }
        slf.EndMoreUnits = string(str)
    }
    if len(slf.InputMoreUnitsArr) != 0 {
        str, err := json.Marshal(slf.InputMoreUnitsArr)
        if err != nil {
            return err
        }
        slf.InputMoreUnits = string(str)
    }
    if len(slf.OutputMoreUnitsArr) != 0 {
        str, err := json.Marshal(slf.OutputMoreUnitsArr)
        if err != nil {
            return err
        }
        slf.OutputMoreUnits = string(str)
    }
    return nil
}
func (slf *MonthStats) AfterFind(tx *gorm.DB) error {
    if slf.BeginMoreUnits != "" {
        var arr []UnitItems
        err := json.Unmarshal([]byte(slf.BeginMoreUnits), &arr)
        if err != nil {
            return err
        }
        slf.BeginMoreUnitsArr = arr
    }
    if slf.EndMoreUnits != "" {
        var arr []UnitItems
        err := json.Unmarshal([]byte(slf.EndMoreUnits), &arr)
        if err != nil {
            return err
        }
        slf.EndMoreUnitsArr = arr
    }
    if slf.InputMoreUnits != "" {
        var arr []UnitItems
        err := json.Unmarshal([]byte(slf.InputMoreUnits), &arr)
        if err != nil {
            return err
        }
        slf.InputMoreUnitsArr = arr
    }
    if slf.OutputMoreUnits != "" {
        var arr []UnitItems
        err := json.Unmarshal([]byte(slf.OutputMoreUnits), &arr)
        if err != nil {
            return err
        }
        slf.OutputMoreUnitsArr = arr
    }
    return nil
}
func NewMonthStatsSearch() *MonthStatsSearch {
    return &MonthStatsSearch{Orm: mysqlx.GetDB()}
}
func (slf *MonthStatsSearch) SetOrm(tx *gorm.DB) *MonthStatsSearch {
    slf.Orm = tx
    return slf
}
func (slf *MonthStatsSearch) SetPage(page, size int) *MonthStatsSearch {
    slf.PageNum, slf.PageSize = page, size
    return slf
}
func (slf *MonthStatsSearch) SetOrder(order string) *MonthStatsSearch {
    slf.Order = order
    return slf
}
func (slf *MonthStatsSearch) SetID(id int) *MonthStatsSearch {
    slf.Id = id
    return slf
}
func (slf *MonthStatsSearch) SetKeyword(keyword string) *MonthStatsSearch {
    slf.Keyword = keyword
    return slf
}
func (slf *MonthStatsSearch) SetPreload(preload bool) *MonthStatsSearch {
    slf.Preload = preload
    return slf
}
func (slf *MonthStatsSearch) SetDate(date string) *MonthStatsSearch {
    slf.Date = date
    return slf
}
func (slf *MonthStatsSearch) SetFields(fields string) *MonthStatsSearch {
    slf.Fields = fields
    return slf
}
func (slf *MonthStatsSearch) build() *gorm.DB {
    var db = slf.Orm.Model(&MonthStats{})
    if slf.Id != 0 {
        db = db.Where("id = ?", slf.Id)
    }
    if slf.Order != "" {
        db = db.Order(slf.Order)
    }
    if slf.Keyword != "" {
        kw := fmt.Sprintf("%%%v%%", slf.Keyword)
        db = db.Where("product_id like ? or product_name like ?", kw, kw)
    }
    if slf.Date != "" {
        db = db.Where("date = ?", slf.Date)
    }
    if slf.Fields != "" {
        db = db.Select(slf.Fields)
    }
    return db
}
// Create 单条插入
func (slf *MonthStatsSearch) Create(record *MonthStats) error {
    var db = slf.build()
    if err := db.Create(record).Error; err != nil {
        return err
    }
    return nil
}
// CreateBatch 批量插入
func (slf *MonthStatsSearch) CreateBatch(records []*MonthStats) error {
    var db = slf.build()
    if err := db.Create(&records).Error; err != nil {
        return fmt.Errorf("create batch err: %v, records: %+v", err, records)
    }
    return nil
}
func (slf *MonthStatsSearch) Update(record *MonthStats) error {
    var db = slf.build()
    if err := db.Omit("CreatedAt").Updates(record).Error; err != nil {
        return fmt.Errorf("save err: %v, record: %+v", err, record)
    }
    return nil
}
func (slf *MonthStatsSearch) UpdateByMap(upMap map[string]interface{}) error {
    var (
        db = slf.build()
    )
    if err := db.Updates(upMap).Error; err != nil {
        return fmt.Errorf("update by map err: %v, upMap: %+v", err, upMap)
    }
    return nil
}
func (slf *MonthStatsSearch) UpdateByQuery(query string, args []interface{}, upMap map[string]interface{}) error {
    var (
        db = slf.Orm.Table(slf.TableName()).Where(query, args...)
    )
    if err := db.Updates(upMap).Error; err != nil {
        return fmt.Errorf("update by query err: %v, query: %s, args: %+v, upMap: %+v", err, query, args, upMap)
    }
    return nil
}
func (slf *MonthStatsSearch) Delete() error {
    var db = slf.build()
    return db.Delete(&MonthStats{}).Error
}
func (slf *MonthStatsSearch) First() (*MonthStats, error) {
    var (
        record = new(MonthStats)
        db     = slf.build()
    )
    if err := db.First(record).Error; err != nil {
        return record, err
    }
    return record, nil
}
func (slf *MonthStatsSearch) Find() ([]*MonthStats, int64, error) {
    var (
        records = make([]*MonthStats, 0)
        total   int64
        db      = slf.build()
    )
    if err := db.Count(&total).Error; err != nil {
        return records, total, fmt.Errorf("find count err: %v", err)
    }
    if slf.PageNum*slf.PageSize > 0 {
        db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
    }
    if err := db.Find(&records).Error; err != nil {
        return records, total, fmt.Errorf("find records err: %v", err)
    }
    return records, total, nil
}
func (slf *MonthStatsSearch) FindNotTotal() ([]*MonthStats, error) {
    var (
        records = make([]*MonthStats, 0)
        db      = slf.build()
    )
    if slf.PageNum*slf.PageSize > 0 {
        db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
    }
    if err := db.Find(&records).Error; err != nil {
        return records, fmt.Errorf("find records err: %v", err)
    }
    return records, nil
}
// FindByQuery 指定条件查询.
func (slf *MonthStatsSearch) FindByQuery(query string, args []interface{}) ([]*MonthStats, int64, error) {
    var (
        records = make([]*MonthStats, 0)
        total   int64
        db      = slf.Orm.Table(slf.TableName()).Where(query, args...)
    )
    if err := db.Count(&total).Error; err != nil {
        return records, total, fmt.Errorf("find by query count err: %v", err)
    }
    if slf.PageNum*slf.PageSize > 0 {
        db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
    }
    if err := db.Find(&records).Error; err != nil {
        return records, total, fmt.Errorf("find by query records err: %v, query: %s, args: %+v", err, query, args)
    }
    return records, total, nil
}
// FindByQueryNotTotal 指定条件查询&不查询总条数.
func (slf *MonthStatsSearch) FindByQueryNotTotal(query string, args []interface{}) ([]*MonthStats, error) {
    var (
        records = make([]*MonthStats, 0)
        db      = slf.Orm.Table(slf.TableName()).Where(query, args...)
    )
    if slf.PageNum*slf.PageSize > 0 {
        db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
    }
    if err := db.Find(&records).Error; err != nil {
        return records, fmt.Errorf("find by query records err: %v, query: %s, args: %+v", err, query, args)
    }
    return records, nil
}
func MonthStatsMap(records []*MonthStats) (m map[string]*MonthStats) {
    m = make(map[string]*MonthStats, len(records))
    for _, record := range records {
        m[record.ProductId] = record
    }
    return m
}
models/operation.go
@@ -4,6 +4,7 @@
    "fmt"
    "github.com/shopspring/decimal"
    "gorm.io/gorm"
    "time"
    "wms/constvar"
    "wms/pkg/mysqlx"
)
@@ -70,6 +71,9 @@
        Ids                 []int
        SourceNumbers       []string
        SalesDetailsNumbers []string
        Fields              string
        BeginTime           time.Time
        EndTime             time.Time
    }
)
@@ -103,6 +107,11 @@
func (slf *OperationSearch) SetKeyword(keyword string) *OperationSearch {
    slf.Keyword = keyword
    return slf
}
func (slf *OperationSearch) SetFields(fields string) *OperationSearch {
    slf.Fields = fields
    return slf
}
@@ -163,6 +172,12 @@
func (slf *OperationSearch) SetOperationSource(operationSource constvar.OperationSource) *OperationSearch {
    slf.OperationSource = operationSource
    return slf
}
func (slf *OperationSearch) SetTimeBetween(beginTime, endTime time.Time) *OperationSearch {
    slf.BeginTime = beginTime
    slf.EndTime = endTime
    return slf
}
@@ -228,6 +243,13 @@
        db = db.Where("operation_source = ?", slf.OperationSource)
    }
    if slf.Fields != "" {
        db = db.Select(slf.Fields)
    }
    if !slf.BeginTime.IsZero() && !slf.EndTime.IsZero() {
        db = db.Where("created_at between ? and ?", slf.BeginTime, slf.EndTime)
    }
    return db
}
@@ -351,6 +373,18 @@
    return records, nil
}
func (slf *OperationSearch) FindIds() ([]int, error) {
    var (
        records = make([]int, 0)
        db      = slf.build()
    )
    if err := db.Find(&records).Error; err != nil {
        return records, fmt.Errorf("find records err: %v", err)
    }
    return records, nil
}
// FindByQuery 指定条件查询.
func (slf *OperationSearch) FindByQuery(query string, args []interface{}) ([]*Operation, int64, error) {
    var (
models/operation_details.go
@@ -12,8 +12,8 @@
    OperationDetails struct {
        WmsModel
        Id          int    `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
        OperationID int    `json:"operationId" gorm:"type:int;not null;comment:操作记录id"`      //操作id
        ProductId   string `json:"productId" gorm:"type:varchar(191);not null;comment:产品id"` //产品id
        OperationID int    `json:"operationId" gorm:"index;type:int;not null;comment:操作记录id"` //操作id
        ProductId   string `json:"productId" gorm:"type:varchar(191);not null;comment:产品id"`  //产品id
        //ProductName string          `json:"productName" gorm:"type:varchar(255);not null;comment:产品名称"` //产品名称
        Amount decimal.Decimal `json:"amount" gorm:"type:decimal(20,2);not null;comment:数量"` //数量
        //Unit        string          `json:"unit" gorm:"type:varchar(31);comment:单位"`                    //单位
@@ -31,12 +31,14 @@
    OperationDetailsSearch struct {
        OperationDetails
        Order    string
        PageNum  int
        PageSize int
        Keyword  string
        Orm      *gorm.DB
        Preload  bool
        Order        string
        PageNum      int
        PageSize     int
        Keyword      string
        Orm          *gorm.DB
        Preload      bool
        OperationIDs []int
        Fields       string
    }
)
@@ -83,6 +85,16 @@
    return slf
}
func (slf *OperationDetailsSearch) SetOperationIds(operationIds []int) *OperationDetailsSearch {
    slf.OperationIDs = operationIds
    return slf
}
func (slf *OperationDetailsSearch) SetFields(fields string) *OperationDetailsSearch {
    slf.Fields = fields
    return slf
}
func (slf *OperationDetailsSearch) SetProductId(productId string) *OperationDetailsSearch {
    slf.ProductId = productId
    return slf
@@ -111,6 +123,14 @@
    }
    if slf.Preload {
        db = db.Preload("Product")
    }
    if len(slf.OperationIDs) > 0 {
        db = db.Where("operation_id in ?", slf.OperationIDs)
    }
    if slf.Fields != "" {
        db = db.Select(slf.Fields)
    }
    return db
@@ -276,3 +296,14 @@
    return records, nil
}
func (slf *OperationDetailsSearch) GroupSum(groupField string, sumField string) ([]*GroupSum, error) {
    var (
        db     = slf.build()
        result = make([]*GroupSum, 0)
    )
    if err := db.Select("sum(" + sumField + ") as sum, " + groupField + " as class").Group(groupField).Scan(&result).Error; err != nil {
        return nil, fmt.Errorf("select group err: %v", err)
    }
    return result, nil
}
request/report_forms_request.go
@@ -25,3 +25,9 @@
    ProductId     string `json:"productId"`
    LocationId    int    `json:"locationId"`
}
type GetMonthStats struct {
    PageInfo
    Keyword string `json:"keyword"`
    Date    string `json:"date"`
}
router/router.go
@@ -156,6 +156,7 @@
        reportFormsAPI.POST("getInventoryForms", reportFormsController.GetInventoryForms) //获取库存报表
        reportFormsAPI.POST("getHistory", reportFormsController.GetHistory)               //获取库存历史
        reportFormsAPI.POST("getLocationForms", reportFormsController.GetLocationForms)   //获取位置报表
        reportFormsAPI.POST("monthStats", reportFormsController.MonthStats)               //获取月度统计报表
    }
    //重订货规则
service/month_stats.go
New file
@@ -0,0 +1,5 @@
package service
func GetStats() {
}
task/month_stats.go
New file
@@ -0,0 +1,189 @@
package task
import (
    "encoding/json"
    "github.com/shopspring/decimal"
    "time"
    "wms/constvar"
    "wms/models"
    "wms/pkg/logx"
)
func MonthStats() {
    //加锁,只需要一个进程运行此任务
    var (
        lockName  = "monthStats"
        serviceID = "wms"
    )
    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)
        }
    }()
    date := time.Now().Format("2006-01")
    lastDate := time.Now().AddDate(0, -1, 0).Format("2006-01")
    oldRecords, err := models.NewMonthStatsSearch().SetDate(lastDate).SetFields("id, product_id").FindNotTotal()
    if err != nil {
        logx.Errorf("MonthStats get last date record err:%v", err)
        return
    }
    oldRecordsMap := models.MonthStatsMap(oldRecords)
    //本月期初数量/上月结余数量
    groupSumList, err := models.NewLocationProductAmountSearch().GroupSum("product_id", "amount")
    productIds := make([]string, 0, len(groupSumList))
    for _, groupSum := range groupSumList {
        productIds = append(productIds, groupSum.Class)
    }
    products, err := models.NewMaterialSearch().SetFields("id, name, unit, weight, more_unit, more_unit_value").SetIDs(productIds).FindNotTotal()
    if err != nil {
        logx.Errorf("MonthStats get products err:%v", err)
        return
    }
    productMap := models.MaterialMap(products)
    beginTime, endTime := GetLastMonthPeriod()
    inputMap, err := GetStatsByOperationType(beginTime, endTime, constvar.BaseOperationTypeIncoming)
    if err != nil {
        logx.Errorf("MonthStats GetStatsByOperationType input err:%v", err)
        return
    }
    outputMap, err := GetStatsByOperationType(beginTime, endTime, constvar.BaseOperationTypeOutgoing)
    if err != nil {
        logx.Errorf("MonthStats GetStatsByOperationType output err:%v", err)
        return
    }
    var record models.MonthStats
    for _, groupSum := range groupSumList {
        productId := groupSum.Class
        if productMap[productId] == nil {
            continue
        }
        product := productMap[productId]
        amount := groupSum.Sum
        record = models.MonthStats{
            ProductId:   productId,
            ProductName: product.Name,
            BeginAmount: amount,
            Unit:        product.Unit,
            Weight:      product.Weight.Mul(amount),
            Date:        date,
        }
        var (
            moreUnits       string
            inputMoreUnits  string
            outputMoreUnits string
        )
        if product.MoreUnit {
            moreValueArr := make([]models.UnitItems, 0, len(product.MoreUnitList))
            inputMoreValueArr := make([]models.UnitItems, 0, len(product.MoreUnitList))
            outputMoreValueArr := make([]models.UnitItems, 0, len(product.MoreUnitList))
            for _, unitItem := range product.MoreUnitList {
                moreValueArr = append(moreValueArr, models.UnitItems{
                    Amount:   amount.Mul(unitItem.Amount),
                    Unit:     unitItem.Unit,
                    Floating: unitItem.Floating,
                })
                bys, _ := json.Marshal(moreValueArr)
                moreUnits = string(bys)
                if !inputMap[productId].IsZero() {
                    inputMoreValueArr = append(inputMoreValueArr, models.UnitItems{
                        Amount:   inputMap[productId].Mul(unitItem.Amount),
                        Unit:     unitItem.Unit,
                        Floating: unitItem.Floating,
                    })
                    bys, _ = json.Marshal(inputMoreValueArr)
                    inputMoreUnits = string(bys)
                }
                if !outputMap[productId].IsZero() {
                    outputMoreValueArr = append(outputMoreValueArr, models.UnitItems{
                        Amount:   outputMap[productId].Mul(unitItem.Amount),
                        Unit:     unitItem.Unit,
                        Floating: unitItem.Floating,
                    })
                    bys, _ = json.Marshal(outputMoreValueArr)
                    outputMoreUnits = string(bys)
                }
            }
        }
        record.BeginMoreUnits = moreUnits
        err = models.NewMonthStatsSearch().Create(&record)
        if err != nil {
            logx.Errorf("NewMonthStatsSearch Create err:%v, record: %+v", err, record)
        }
        if oldRecordsMap[productId] != nil && (!inputMap[productId].IsZero() || !outputMap[productId].IsZero()) {
            record.InputAmount = inputMap[productId]
            record.InputMoreUnits = inputMoreUnits
            record.OutputAmount = outputMap[productId]
            record.OutputMoreUnits = outputMoreUnits
            m := map[string]interface{}{
                "input_amount":      inputMap[productId],
                "input_more_units":  inputMoreUnits,
                "output_amount":     outputMap[productId],
                "output_more_units": outputMoreUnits,
                "end_more_units":    moreUnits,
                "end_amount":        amount,
            }
            err = models.NewMonthStatsSearch().SetID(oldRecordsMap[productId].Id).UpdateByMap(m)
            if err != nil {
                logx.Errorf("NewMonthStatsSearch UpdateByMap err:%v, id:%v, m:%+v", err, oldRecordsMap[productId].ID, m)
            }
        }
    }
    return
}
func GetStatsByOperationType(beginTime, endTime time.Time, operationType constvar.BaseOperationType) (m map[string]decimal.Decimal, err error) {
    operationIds, err := models.NewOperationSearch().SetBaseOperationType(operationType).SetFields("id").SetTimeBetween(beginTime, endTime).FindIds()
    if err != nil {
        return
    }
    groupSumList, err := models.NewOperationDetailsSearch().SetOperationIds(operationIds).SetFields("product_id, amount").GroupSum("product_id", "amount")
    if err != nil {
        return
    }
    m = make(map[string]decimal.Decimal, len(groupSumList))
    for _, v := range groupSumList {
        m[v.Class] = v.Sum
    }
    return
}
// GetLastMonthPeriod 返回上个月的月初时间和月末时间
func GetLastMonthPeriod() (time.Time, time.Time) {
    // 获取当前时间
    now := time.Now()
    // 计算上个月的年份和月份
    lastMonth := now.AddDate(0, -1, 0)
    lastYear, lastMonthNum, _ := lastMonth.Date()
    // 获取上个月的第一天的日期(即上个月月初)
    firstDayOfLastMonth := time.Date(lastYear, lastMonthNum, 1, 0, 0, 0, 0, now.Location())
    // 获取本月第一天的日期(即本月月初)
    firstDayOfThisMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
    // 上个月月末时间即为本月月初减去一秒
    lastDayOfLastMonth := firstDayOfThisMonth.Add(-time.Second)
    return firstDayOfLastMonth, lastDayOfLastMonth
}
task/tasklist.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(MonthStats) //每月初执行一次
    s.StartAsync()
}