diff --git a/config.yaml b/config.yaml index c861bcd..e20b9b0 100644 --- a/config.yaml +++ b/config.yaml @@ -12,10 +12,10 @@ database: encrypt_key: "0123456789abcdef0123456789abcdef" task_database: - host: nj-cynosdbmysql-grp-1v6vxn5f.sql.tencentcdb.com - port: "26247" - user: root - password: Long6166@@ + host: 36.212.7.35 + port: "3306" + user: zhishu + password: KSwx1MDcRW name: task jwt: diff --git a/controllers/process.go b/controllers/process.go index 51e33f9..6d6bd43 100644 --- a/controllers/process.go +++ b/controllers/process.go @@ -562,7 +562,13 @@ func (r *ProcessApi) UnlockSalesOrderInventory(c *gin.Context) { } userInfo := utils.GetUserInfo(c) - resp, err := processService.UnlockSalesOrderInventory(req.SoNo, userInfo.Username, userInfo.ID, database.GetDB(c)) + + aboutID := req.AboutId + if aboutID == 0 { + aboutID = userInfo.AboutID + } + + resp, err := processService.UnlockSalesOrderInventory(aboutID, req.AssociationOrderNo, userInfo.Username, userInfo.ID) if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "解锁销售订单库存异常", err, c, req) return diff --git a/models/request/process.go b/models/request/process.go index 37d1f0f..7ba9856 100644 --- a/models/request/process.go +++ b/models/request/process.go @@ -135,7 +135,8 @@ type CancelSalesOrderRequest struct { // UnlockSalesOrderInventoryRequest 解锁销售订单库存请求 type UnlockSalesOrderInventoryRequest struct { - SoNo string `form:"so_no" binding:"required"` // 订单编号 + AboutId int64 `form:"about_id"` // 租户ID(用于确定分库) + AssociationOrderNo string `form:"association_order_no" binding:"required"` // 关联订单号(第三方订单号) } type CancelOutboundWaveRequest struct { diff --git a/service/employee.go b/service/employee.go index 97ed432..401a3fc 100644 --- a/service/employee.go +++ b/service/employee.go @@ -94,9 +94,15 @@ func (s *EmployeeService) Login(req systemReq.LoginRequest, userType string, c * var employeeLevel models.EmployeeLevel levelResult := database.DB.Where("emp_id = ? AND is_del = ?", employee.ID, 0).First(&employeeLevel) if levelResult.Error == nil { + // 如果等级为5(至尊版),将max_num设置为999(不限制) + maxNum := employeeLevel.MaxNum + if employeeLevel.Level == 5 { + maxNum = 999 + } + levelInfo = &systemRes.EmployeeLevelInfo{ Level: employeeLevel.Level, // 等级 - MaxNum: employeeLevel.MaxNum, // 最大数量 + MaxNum: maxNum, // 最大数量(等级5时为999) ExpireTime: employeeLevel.ExpireTime, // 到期时间 PayTime: employeeLevel.PayTime, // 支付时间 } @@ -286,8 +292,11 @@ func (s *EmployeeService) AddEmployee(req systemReq.AddEmployeeRequest) (*system return nil, utils.NewError("主账号已过期,无法创建子账号") } - // 检查max_num限制,如果max_num为0表示没权限 - if parentEmployeeLevel.MaxNum > 0 { + // 检查max_num限制 + // 如果等级为5(至尊版)或max_num为999/-1,表示不限制子账号数量 + if parentEmployeeLevel.Level == 5 || parentEmployeeLevel.MaxNum == 999 || parentEmployeeLevel.MaxNum == -1 { + // 至尊版或不限制模式,无需检查子账号数量 + } else if parentEmployeeLevel.MaxNum > 0 { var currentSubCount int64 database.DB.Model(&models.Employee{}).Where("fid = ? AND deleted_at = 0", req.Fid).Count(¤tSubCount) @@ -302,7 +311,6 @@ func (s *EmployeeService) AddEmployee(req systemReq.AddEmployeeRequest) (*system return nil, utils.NewError("子账号的到期时间不能超过主账号的到期时间") } } - hashedPassword, err := utils.HashPassword(req.Password) if err != nil { return nil, utils.NewError("密码加密失败") @@ -515,10 +523,10 @@ func GetLevelConfig(level int8) interface{} { LevelName: "旗舰版(20个子账号,235元/30天)", // 等级名称 }, 5: { - Level: 5, // 等级 - MaxNum: 25, // 最大数量 - Price: 24500, // 价格 - LevelName: "至尊版(25个子账号,245元/30天)", // 等级名称 + Level: 5, // 等级 + MaxNum: 999, // 最大数量(999表示不限制) + Price: 24500, // 价格 + LevelName: "至尊版(不限制子账号数量,245元/30天)", // 等级名称 }, } // 获取所有等级配置 @@ -610,9 +618,17 @@ func (s *EmployeeService) SetEmployeeLevel(req systemReq.SetEmployeeLevelRequest } // 记录开通日志 - operationRemark := fmt.Sprintf("开通%s(等级%d),可创建子账号数量上限:%d,价格:%d元,时长:%d个月,到期时间:%s", - levelConfig.LevelName, levelConfig.Level, levelConfig.MaxNum, (levelConfig.Price*req.Duration)/100, req.Duration, + /*operationRemark := fmt.Sprintf("开通%s(等级%d),可创建子账号数量上限:%d,价格:%d元,时长:%d个月,到期时间:%s", + levelConfig.LevelName, levelConfig.Level, levelConfig.MaxNum, (levelConfig.Price*req.Duration)/100, req.Duration, + time.Unix(expireTime, 0).Format("2006-01-02"))*/ + maxNumText := "不限制" + if levelConfig.MaxNum > 0 { + maxNumText = fmt.Sprintf("%d", levelConfig.MaxNum) + } + operationRemark := fmt.Sprintf("开通%s(等级%d),可创建子账号数量上限:%s,价格:%d元,时长:%d个月,到期时间:%s", + levelConfig.LevelName, levelConfig.Level, maxNumText, (levelConfig.Price*req.Duration)/100, req.Duration, time.Unix(expireTime, 0).Format("2006-01-02")) + if err := s.createEmployeeLevelLog(req.EmpId, 1, oldLevel, levelConfig.Level, oldMaxNum, levelConfig.MaxNum, oldExpireTime, expireTime, levelConfig.Price*req.Duration, req.PayTime, operatorID, operatorName, operationRemark); err != nil { return err } @@ -658,8 +674,19 @@ func (s *EmployeeService) SetEmployeeLevel(req systemReq.SetEmployeeLevelRequest } // 记录升级日志 - operationRemark := fmt.Sprintf("等级从%d升级到%d(%s),子账号数量上限从%d调整为%d,价格:%d元,时长:%d个月,新到期时间:%s", - oldLevel, levelConfig.Level, levelConfig.LevelName, oldMaxNum, levelConfig.MaxNum, (levelConfig.Price*req.Duration)/100, req.Duration, + /*operationRemark := fmt.Sprintf("等级从%d升级到%d(%s),子账号数量上限从%d调整为%d,价格:%d元,时长:%d个月,新到期时间:%s", + oldLevel, levelConfig.Level, levelConfig.LevelName, oldMaxNum, levelConfig.MaxNum, (levelConfig.Price*req.Duration)/100, req.Duration, + time.Unix(expireTime, 0).Format("2006-01-02"))*/ + oldMaxNumText := "不限制" + if oldMaxNum > 0 { + oldMaxNumText = fmt.Sprintf("%d", oldMaxNum) + } + newMaxNumText := "不限制" + if levelConfig.MaxNum > 0 { + newMaxNumText = fmt.Sprintf("%d", levelConfig.MaxNum) + } + operationRemark := fmt.Sprintf("等级从%d升级到%d(%s),子账号数量上限从%s调整为%s,价格:%d元,时长:%d个月,新到期时间:%s", + oldLevel, levelConfig.Level, levelConfig.LevelName, oldMaxNumText, newMaxNumText, (levelConfig.Price*req.Duration)/100, req.Duration, time.Unix(expireTime, 0).Format("2006-01-02")) if err := s.createEmployeeLevelLog(req.EmpId, 2, oldLevel, levelConfig.Level, oldMaxNum, levelConfig.MaxNum, oldExpireTime, expireTime, levelConfig.Price*req.Duration, req.PayTime, operatorID, operatorName, operationRemark); err != nil { return err diff --git a/service/process.go b/service/process.go index 2356532..0a5e388 100644 --- a/service/process.go +++ b/service/process.go @@ -3436,7 +3436,6 @@ func (s *ProcessService) CancelOutboundWave(waveID int64, operator string, opera // CancelSalesOrder 取消销售订单并释放锁定库存 func (s *ProcessService) CancelSalesOrder(orderID int64, operator string, operatorID int64, db ...*gorm.DB) error { - databaseConn := database.OptionalDB(db...) now := time.Now().Unix() @@ -3447,12 +3446,15 @@ func (s *ProcessService) CancelSalesOrder(orderID int64, operator string, operat return fmt.Errorf("销售订单不存在: %v", err) } - if salesOrder.Status == constant.SalesStatusShipped || salesOrder.Status == constant.SalesStatusCancelled { - return fmt.Errorf("订单状态不允许取消,当前状态: %s", getSalesStatusText(salesOrder.Status)) + if salesOrder.Status == constant.SalesStatusShipped { + return fmt.Errorf("订单已发货,无法取消") + } + if salesOrder.Status == constant.SalesStatusCancelled { + return fmt.Errorf("订单已取消") } var orderItems []models.SalesOrderItem - if err := tx.Where("sales_order_id = ? AND is_del = 0", orderID).Find(&orderItems).Error; err != nil { + if err := tx.Where("sales_order_id = ? AND is_del = 0", salesOrder.ID).Find(&orderItems).Error; err != nil { return fmt.Errorf("查询订单明细失败: %v", err) } @@ -3464,15 +3466,8 @@ func (s *ProcessService) CancelSalesOrder(orderID int64, operator string, operat } } - if err := tx.Model(&salesOrder).Updates(map[string]interface{}{ - "status": constant.SalesStatusCancelled, - "updated_at": now, - }).Error; err != nil { - return fmt.Errorf("更新销售订单状态失败: %v", err) - } - if err := tx.Model(&models.SalesOrderItem{}). - Where("sales_order_id = ? AND is_del = 0", orderID). + Where("sales_order_id = ? AND is_del = 0", salesOrder.ID). Updates(map[string]interface{}{ "allocated_quantity": 0, "updated_at": now, @@ -3480,40 +3475,31 @@ func (s *ProcessService) CancelSalesOrder(orderID int64, operator string, operat return fmt.Errorf("重置订单明细已分配数量失败: %v", err) } - if salesOrder.Status == constant.SalesStatusAllocated || salesOrder.Status == constant.SalesStatusPicking { - var waveHeader models.WaveHeader - if err := tx.Where("related_order_id = ? AND direction = ? AND is_del = 0", - orderID, constant.DirectionOutbound).First(&waveHeader).Error; err == nil { - if err := tx.Model(&models.WaveHeader{}).Where("id = ?", waveHeader.ID).Updates(map[string]interface{}{ - "status": constant.WaveStatusCancelled, - "updated_at": now, - }).Error; err != nil { - return fmt.Errorf("更新关联波次状态失败: %v", err) - } - - if err := tx.Model(&models.WaveTask{}).Where("wave_id = ?", waveHeader.ID).Updates(map[string]interface{}{ - "status": constant.WaveStatusCancelled, - "updated_at": now, - }).Error; err != nil { - return fmt.Errorf("更新关联波次任务状态失败: %v", err) - } - } + if err := tx.Model(&salesOrder).Updates(map[string]interface{}{ + "status": constant.SalesStatusCancelled, + "updated_at": now, + }).Error; err != nil { + return fmt.Errorf("更新销售订单状态失败: %v", err) } return nil }) } -// UnlockSalesOrderInventory 解锁销售订单库存(不取消订单) -func (s *ProcessService) UnlockSalesOrderInventory(soNo string, operator string, operatorID int64, db ...*gorm.DB) (*systemRes.UnlockInventoryResponse, error) { - databaseConn := database.OptionalDB(db...) +// CancelSalesOrder 取消销售订单并释放锁定库存 +// ... existing code ... +func (s *ProcessService) UnlockSalesOrderInventory(aboutID int64, associationOrderNo string, operator string, operatorID int64) (*systemRes.UnlockInventoryResponse, error) { + databaseConn, err := database.GetTenantDB(aboutID) + if err != nil { + return nil, fmt.Errorf("获取数据库连接失败: %v", err) + } now := time.Now().Unix() var unlockResp *systemRes.UnlockInventoryResponse - err := executeInTransactionWithDB(databaseConn, func(tx *gorm.DB) error { + err = executeInTransactionWithDB(databaseConn, func(tx *gorm.DB) error { var salesOrder models.SalesOrder - if err := tx.Where("so_no = ? AND is_del = 0", soNo).First(&salesOrder).Error; err != nil { + if err := tx.Where("association_order_no = ? AND is_del = 0", associationOrderNo).First(&salesOrder).Error; err != nil { return fmt.Errorf("销售订单不存在: %v", err) } @@ -3593,8 +3579,8 @@ func (s *ProcessService) UnlockSalesOrderInventory(soNo string, operator string, } unlockResp = &systemRes.UnlockInventoryResponse{ - SoNo: soNo, - AssociationOrderNo: salesOrder.AssociationOrderNo, + SoNo: salesOrder.SoNo, + AssociationOrderNo: associationOrderNo, Items: responseItems, } @@ -4156,20 +4142,7 @@ func (s *ProcessService) syncProductsToExternal(receivingOrderID, waveTaskID, us group.totalQty += item.quantity } else { // 新建ISBN组 - // imgList := parseImageList(product.LiveImage) - - var imgList []string - if product.LiveImage != nil && len(product.LiveImage) > 0 { - var rawImgList []string - if err := json.Unmarshal(product.LiveImage, &rawImgList); err == nil { - for _, imgStr := range rawImgList { - imgStr = strings.TrimSpace(imgStr) - if imgStr != "" { - imgList = append(imgList, imgStr) - } - } - } - } + imgList := parseImageList(product.LiveImage) skuCode := warehouse.Code if item.locationID > 0 { @@ -4201,7 +4174,7 @@ func (s *ProcessService) syncProductsToExternal(receivingOrderID, waveTaskID, us "book_name": group.product.Name, "image_object": map[string]interface{}{ "carousel_url_array": group.imgList, - "white_background_url": []string{}, + "white_background_url": "", "detail_url_object": map[string]interface{}{}, "introduction_url": []string{}, "catalogue_url": []string{}, @@ -4249,20 +4222,7 @@ func (s *ProcessService) syncProductsToExternal(receivingOrderID, waveTaskID, us } isbn := product.Barcode - // imgList := parseImageList(product.LiveImage) - - var imgList []string - if product.LiveImage != nil && len(product.LiveImage) > 0 { - var rawImgList []string - if err := json.Unmarshal(product.LiveImage, &rawImgList); err == nil { - for _, imgStr := range rawImgList { - imgStr = strings.TrimSpace(imgStr) - if imgStr != "" { - imgList = append(imgList, imgStr) - } - } - } - } + imgList := parseImageList(product.LiveImage) skuCode := warehouse.Code if item.locationID > 0 { @@ -4283,7 +4243,7 @@ func (s *ProcessService) syncProductsToExternal(receivingOrderID, waveTaskID, us "book_name": product.Name, "image_object": map[string]interface{}{ "carousel_url_array": imgList, - "white_background_url": []string{}, + "white_background_url": "", "detail_url_object": map[string]interface{}{}, "introduction_url": []string{}, "catalogue_url": []string{}, diff --git a/service/product.go b/service/product.go index b756cd7..1bf6432 100644 --- a/service/product.go +++ b/service/product.go @@ -2256,7 +2256,7 @@ func (s *ProductService) batchPushProductBody(db *gorm.DB, outTask models.OutTas "book_name": product.Name, "image_object": map[string]interface{}{ "carousel_url_array": imgList, - "white_background_url": []string{}, + "white_background_url": "", "detail_url_object": map[string]interface{}{}, "introduction_url": []string{}, "catalogue_url": []string{}, @@ -2444,7 +2444,7 @@ func (s *ProductService) syncPriceToExternalTaskWithOptionalWave(outTask models. "book_name": product.Name, "image_object": map[string]interface{}{ "carousel_url_array": imgList, - "white_background_url": []string{}, + "white_background_url": "", "detail_url_object": map[string]interface{}{}, "introduction_url": []string{}, "catalogue_url": []string{}, @@ -2613,7 +2613,7 @@ func (s *ProductService) syncPriceToExternalTask(outTask models.OutTask, product "book_name": product.Name, "image_object": map[string]interface{}{ "carousel_url_array": imgList, - "white_background_url": []string{}, + "white_background_url": "", "detail_url_object": map[string]interface{}{}, "introduction_url": []string{}, "catalogue_url": []string{},