修改这个/api/sales-order/unlock-inventory里面的第三方订单编号

This commit is contained in:
Administrator 2026-06-25 14:51:28 +08:00
parent c1ae74e703
commit ca5a652334
6 changed files with 82 additions and 88 deletions

View File

@ -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:

View File

@ -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

View File

@ -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 {

View File

@ -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(&currentSubCount)
@ -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

View File

@ -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{},

View File

@ -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{},