package controllers import ( "fmt" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "net/http" "psi/constant" "psi/database" systemReq "psi/models/request" systemRes "psi/models/response" "psi/service" "psi/utils" ) type LocationApi struct{} var locationService = service.LocationService{} func (r *LocationApi) GetLocationList(c *gin.Context) { var req systemReq.QueryLocationRequest if err := c.ShouldBindQuery(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "查询库位列表请求参数异常", "参数错误: "+err.Error(), c, err) return } list, total, err := locationService.GetLocationList(req, database.GetDB(c)) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "查询库位列表异常", err, c, req) return } c.JSON(http.StatusOK, gin.H{ "code": 0, "data": gin.H{ "list": list, "total": total, "page": req.Page, "page_size": req.PageSize, }, "msg": "查询成功", }) } // GetAllLocationList 查询所有库位列表(仓库ID可选) func (r *LocationApi) GetAllLocationList(c *gin.Context) { var req systemReq.QueryAllLocationRequest if err := c.ShouldBindQuery(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "查询所有库位列表请求参数异常", "参数错误: "+err.Error(), c, err) return } list, total, err := locationService.GetAllLocationList(req, database.GetDB(c)) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "查询所有库位列表异常", err, c, req) return } c.JSON(http.StatusOK, gin.H{ "code": 0, "data": gin.H{ "list": list, "total": total, "page": req.Page, "page_size": req.PageSize, }, "msg": "查询成功", }) } // GetLocationDetail 获取库位详情 func (r *LocationApi) GetLocationDetail(c *gin.Context) { idStr := c.Param("id") if idStr == "" { utils.ErrorLog(constant.LoggerChannelRequest, logrus.Fields{ "source": "获取库位详情请求参数异常", "err_msg": "ID参数不能为空", }) systemRes.FailWithValidateMessage("参数错误: ID不能为空", c) return } var id int64 if _, err := fmt.Sscanf(idStr, "%d", &id); err != nil || id <= 0 { utils.ErrorLog(constant.LoggerChannelRequest, logrus.Fields{ "source": "获取库位详情请求参数异常", "err_msg": "ID格式错误: " + idStr, }) systemRes.FailWithValidateMessage("参数错误: ID格式不正确", c) return } location, err := locationService.GetLocationDetail(id, database.GetDB(c)) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "查询库位详情异常", err, c, gin.H{"id": id}) return } systemRes.OkWithDetailed(location, "查询成功", c) } // GetLocationInfo 获取库位ID func (r *LocationApi) GetLocationInfo(c *gin.Context) { var req systemReq.GetLocationIdRequest if err := c.ShouldBindQuery(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "获取库位ID请求参数异常", "参数错误: "+err.Error(), c, err) return } location, err := locationService.GetLocationInfo(req.Code, req.WarehouseCode, database.GetDB(c)) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "获取库位ID异常", err, c, gin.H{"code": req.Code}) return } systemRes.OkWithDetailed(location, "查询成功", c) } func (r *LocationApi) CreateLocation(c *gin.Context) { var req systemReq.CreateLocationRequest if err := c.ShouldBind(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "创建库位请求参数异常", "参数错误: "+err.Error(), c, err) return } id, err := locationService.CreateLocation(req, database.GetDB(c)) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "创建库位异常", err, c, req) return } systemRes.OkWithDetailed(gin.H{"id": id}, "创建成功", c) } func (r *LocationApi) BatchGenerateLocations(c *gin.Context) { var req systemReq.BatchGenerateLocationRequest if err := c.ShouldBind(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "批量生成库位请求参数异常", "参数错误: "+err.Error(), c, err) return } if len(req.Groups) == 0 { groups, err := parseGroupsFromForm(c) if err != nil { systemRes.FailWithValidateMessage("参数错误: "+err.Error(), c) return } req.Groups = groups } result, err := locationService.BatchGenerateLocations(req, database.GetDB(c)) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "批量生成库位异常", err, c, req) return } systemRes.OkWithDetailed(result, result.Message, c) } func (r *LocationApi) UpdateLocation(c *gin.Context) { var req systemReq.UpdateLocationRequest if err := c.ShouldBind(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "更新库位请求参数异常", "参数错误: "+err.Error(), c, err) return } if len(req.IDs) == 0 { ids, err := parseIdsFromForm(c) if err != nil { systemRes.FailWithValidateMessage("参数错误: "+err.Error(), c) return } req.IDs = ids } if err := locationService.UpdateLocation(req, database.GetDB(c)); err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "更新库位异常", err, c, req) return } systemRes.OkWithMessage("更新成功", c) } func (r *LocationApi) DeleteLocation(c *gin.Context) { var req systemReq.DeleteLocationRequest if err := c.ShouldBind(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "删除库位请求参数异常", "参数错误: "+err.Error(), c, err) return } if len(req.IDs) == 0 { ids, err := parseIdsFromForm(c) if err != nil { systemRes.FailWithValidateMessage("参数错误: "+err.Error(), c) return } req.IDs = ids } if err := locationService.DeleteLocation(req.IDs, database.GetDB(c)); err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "删除库位异常", err, c, req) return } systemRes.OkWithMessage("删除成功", c) } func (r *LocationApi) SyncLocations(c *gin.Context) { var req systemReq.SyncLocationRequest if err := c.ShouldBindJSON(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "同步库位数据请求参数异常", "参数错误: "+err.Error(), c, err) return } result, err := locationService.SyncLocations(req) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "同步库位数据异常", err, c, req) return } c.JSON(http.StatusOK, gin.H{ "code": 200, "data": result, "msg": "同步完成", }) } // SyncGoods 同步商品数据 func (r *LocationApi) SyncGoods(c *gin.Context) { var req systemReq.SyncGoodsRequest if err := c.ShouldBindJSON(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "同步商品数据请求参数异常", "参数错误: "+err.Error(), c, err) return } result, err := locationService.SyncGoods(req) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "同步商品数据异常", err, c, req) return } c.JSON(http.StatusOK, gin.H{ "code": 200, "msg": "同步完成", "data": gin.H{ "success_count": result.SuccessCount, "fail_count": result.FailCount, "message": result.Message, }, }) } func parseIdsFromForm(c *gin.Context) ([]int64, error) { var ids []int64 for i := 0; i < 100; i++ { idStr := c.PostForm(fmt.Sprintf("ids[%d]", i)) if idStr == "" { break } var id int64 if _, err := fmt.Sscanf(idStr, "%d", &id); err != nil { return nil, fmt.Errorf("第%d个ID格式错误", i) } if id <= 0 { return nil, fmt.Errorf("第%d个ID必须大于0", i) } ids = append(ids, id) } if len(ids) == 0 { return nil, fmt.Errorf("至少需要一个ID") } return ids, nil } func parseGroupsFromForm(c *gin.Context) ([]systemReq.GroupConfig, error) { var groups []systemReq.GroupConfig for i := 0; i < 5; i++ { formatTypeStr := c.PostForm(fmt.Sprintf("groups[%d][format_type]", i)) if formatTypeStr == "" { break } startValue := c.PostForm(fmt.Sprintf("groups[%d][start_value]", i)) endValue := c.PostForm(fmt.Sprintf("groups[%d][end_value]", i)) separator := c.PostForm(fmt.Sprintf("groups[%d][separator]", i)) paddingLenStr := c.PostForm(fmt.Sprintf("groups[%d][padding_len]", i)) if startValue == "" || endValue == "" { return nil, fmt.Errorf("第%d组配置缺少必填字段", i) } var formatType int if _, err := fmt.Sscanf(formatTypeStr, "%d", &formatType); err != nil { return nil, fmt.Errorf("第%d组format_type格式错误", i) } if formatType < 1 || formatType > 4 { return nil, fmt.Errorf("第%d组format_type必须在1-4之间", i) } paddingLen := 0 if paddingLenStr != "" { if _, err := fmt.Sscanf(paddingLenStr, "%d", &paddingLen); err != nil { return nil, fmt.Errorf("第%d组padding_len格式错误", i) } } if separator == "" { separator = "" } group := systemReq.GroupConfig{ FormatType: formatType, StartValue: startValue, EndValue: endValue, PaddingLen: paddingLen, Separator: separator, } groups = append(groups, group) } if len(groups) == 0 { return nil, fmt.Errorf("至少需要一个分组配置") } if len(groups) > 5 { return nil, fmt.Errorf("最多支持5组") } return groups, nil }