647 lines
17 KiB
Go
647 lines
17 KiB
Go
package controller
|
||
|
||
import (
|
||
"context"
|
||
"crypto/md5"
|
||
"fmt"
|
||
"getErpSendPublishing/utils"
|
||
"getErpSendPublishing/utils/dbConnectUtil"
|
||
"log"
|
||
"net/http"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// GoodsFormRequest 定义接收的表单数据结构
|
||
type GoodsFormRequest struct {
|
||
ShopID int64 `form:"shopid" binding:"required,min=1"` // 店铺ID,必须大于0
|
||
GoodsID int64 `form:"goodsid" binding:"required,min=1"` // 商品ID,必须大于0
|
||
ISBN string `form:"isbn" binding:"required"` // ISBN,必须提供
|
||
}
|
||
|
||
// CenterBookBatchItem 批量提交的单个商品数据结构
|
||
type CenterBookBatchItem struct {
|
||
ISBN string `json:"isbn"`
|
||
TotalPrice string `json:"totalPrice"`
|
||
ImgBigUrl string `json:"imgBigUrl"`
|
||
}
|
||
|
||
// GoodsController 控制器结构
|
||
type GoodsController struct {
|
||
// 可以在这里注入服务层依赖
|
||
}
|
||
|
||
// BatchProcessCenterBooks 批量处理中心图书数据
|
||
func BatchProcessCenterBooks(ctx *gin.Context) {
|
||
// 1. 直接获取参数
|
||
shopIDStr := ctx.PostForm("shopid")
|
||
|
||
// 2. 空值检查
|
||
if shopIDStr == "" {
|
||
log.Printf("[WARN] shopid参数为空 (路径: %s, IP: %s)",
|
||
ctx.FullPath(), ctx.ClientIP())
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopid不能为空",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 3. 转换并验证shopid格式
|
||
shopID, err := strconv.ParseInt(shopIDStr, 10, 64)
|
||
if err != nil || shopID <= 0 {
|
||
log.Printf("[WARN] 无效的shopid: %s (错误: %v)", shopIDStr, err)
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopid必须为正整数",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 4. 解析JSON请求体中的图书列表
|
||
var bookItems []CenterBookBatchItem
|
||
if err := ctx.BindJSON(&bookItems); err != nil {
|
||
log.Printf("[WARN] JSON解析失败: %v (路径: %s, IP: %s)",
|
||
err, ctx.FullPath(), ctx.ClientIP())
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "JSON格式错误",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 5. 检查图书列表是否为空
|
||
if len(bookItems) == 0 {
|
||
log.Printf("[WARN] 图书列表为空 (shopid: %d)", shopID)
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "图书列表不能为空",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 6. 使用全局的Redis连接池(避免每次创建新连接)
|
||
redisClient := utils.RedisTwoForParseFormData
|
||
if redisClient == nil {
|
||
log.Printf("[ERROR] Redis连接未初始化")
|
||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 500,
|
||
"message": "系统内部错误",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 7. 构建Redis key
|
||
redisKey := fmt.Sprintf("%d", shopID)
|
||
|
||
// 8. 去重处理:遍历图书列表,移除重复的ISBN
|
||
var deduplicatedItems []CenterBookBatchItem
|
||
var skippedItems []CenterBookBatchItem
|
||
|
||
for _, item := range bookItems {
|
||
// 检查ISBN是否为空
|
||
if item.ISBN == "" {
|
||
log.Printf("[WARN] 发现空的ISBN,跳过处理 (shopid: %d)", shopID)
|
||
continue
|
||
}
|
||
|
||
// 生成MD5加密的ISBN
|
||
hash := md5.Sum([]byte(item.ISBN))
|
||
encryptedIsbn := fmt.Sprintf("%x", hash)
|
||
|
||
// 检查是否存在重复数据
|
||
exists, err := redisClient.HGet(redisKey, encryptedIsbn)
|
||
if err == nil && exists != "" {
|
||
// 存在重复数据,记录并跳过
|
||
log.Printf("[INFO] 检测到重复数据: shopid=%d, isbn=%s", shopID, item.ISBN)
|
||
skippedItems = append(skippedItems, item)
|
||
continue
|
||
}
|
||
|
||
// 非重复数据,添加到去重后列表
|
||
deduplicatedItems = append(deduplicatedItems, item)
|
||
}
|
||
|
||
// 9. 如果没有有效数据,返回错误
|
||
if len(deduplicatedItems) == 0 {
|
||
log.Printf("[INFO] 所有数据均为重复数据,无有效处理项 (shopid: %d)", shopID)
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 1,
|
||
"message": "所有数据均为重复数据",
|
||
"success": false,
|
||
"data": gin.H{
|
||
"total": len(bookItems),
|
||
"skipped": len(skippedItems),
|
||
"processed": 0,
|
||
"original_items": bookItems,
|
||
"deduplicated_items": deduplicatedItems,
|
||
"skipped_items": skippedItems,
|
||
},
|
||
})
|
||
return
|
||
}
|
||
|
||
// 10. 关键成功日志
|
||
log.Printf("[INFO] 批量处理图书数据: shopid=%d, 总数=%d, 去重后=%d, 跳过=%d",
|
||
shopID, len(bookItems), len(deduplicatedItems), len(skippedItems))
|
||
|
||
// 11. 返回结果
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 0,
|
||
"message": "success",
|
||
"success": true,
|
||
"data": gin.H{
|
||
"shopid": shopID,
|
||
"total": len(bookItems),
|
||
"deduplicated_count": len(deduplicatedItems),
|
||
"skipped_count": len(skippedItems),
|
||
"original_items": bookItems,
|
||
"deduplicated_items": deduplicatedItems,
|
||
"skipped_items": skippedItems,
|
||
},
|
||
})
|
||
}
|
||
|
||
// validateGoodsRequest 业务层面的验证
|
||
func (c *GoodsController) validateGoodsRequest(ctx context.Context, req *GoodsFormRequest) error {
|
||
// 基础验证
|
||
if req.ShopID <= 0 {
|
||
return fmt.Errorf("店铺ID必须大于0")
|
||
}
|
||
|
||
if req.GoodsID <= 0 {
|
||
return fmt.Errorf("商品ID必须大于0")
|
||
}
|
||
|
||
if req.ISBN == "" {
|
||
return fmt.Errorf("ISBN不能为空")
|
||
}
|
||
|
||
// 业务限制(根据实际情况调整)
|
||
if req.ShopID > 1000000000 {
|
||
return fmt.Errorf("店铺ID超出系统限制")
|
||
}
|
||
|
||
if req.GoodsID > 1000000000 {
|
||
return fmt.Errorf("商品ID超出系统限制")
|
||
}
|
||
|
||
// ISBN长度限制
|
||
if len(req.ISBN) > 20 {
|
||
return fmt.Errorf("ISBN长度超出限制")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// ParseFormData 表单解析
|
||
func ParseFormData(ctx *gin.Context) {
|
||
// 1. 直接获取参数
|
||
shopIDStr := ctx.PostForm("shopid")
|
||
isbn := ctx.PostForm("isbn")
|
||
|
||
// 2. 空值检查(移除了 goodsid)
|
||
if shopIDStr == "" || isbn == "" {
|
||
log.Printf("[WARN] 参数为空 (路径: %s, IP: %s)",
|
||
ctx.FullPath(), ctx.ClientIP())
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopid和isbn不能为空",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 3. 转换并验证数字格式(只保留 shopid 验证)
|
||
shopID, err := strconv.ParseInt(shopIDStr, 10, 64)
|
||
if err != nil || shopID <= 0 {
|
||
log.Printf("[WARN] 无效的shopid: %s (错误: %v)", shopIDStr, err)
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopid必须为正整数",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 4. 使用全局的Redis连接池(避免每次创建新连接)
|
||
redisClient := utils.RedisTwoForParseFormData
|
||
if redisClient == nil {
|
||
log.Printf("[ERROR] Redis连接未初始化")
|
||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 500,
|
||
"message": "系统内部错误",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 5. 生成MD5加密的ISBN
|
||
hash := md5.Sum([]byte(isbn))
|
||
encryptedIsbn := fmt.Sprintf("%x", hash)
|
||
|
||
//fmt.Println("encryptedIsbn:", encryptedIsbn)
|
||
|
||
// 6. 构建Redis key
|
||
redisKey := fmt.Sprintf("%d", shopID)
|
||
|
||
// 7. 检查是否存在重复数据
|
||
exists, err := redisClient.HGet(redisKey, encryptedIsbn)
|
||
if err == nil && exists != "" {
|
||
// 存在重复数据
|
||
log.Printf("[INFO] 检测到重复数据: shopid=%d, isbn=%s", shopID, isbn)
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 1,
|
||
"message": "已有重复数据",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 8. 关键成功日志
|
||
log.Printf("[INFO] 表单数据解析成功: shopid=%d, isbn=%s", shopID, isbn)
|
||
|
||
// 9. 返回结果
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 0,
|
||
"message": "success",
|
||
"data": gin.H{
|
||
"shopid": shopID,
|
||
"isbn": isbn,
|
||
},
|
||
"success": true,
|
||
})
|
||
}
|
||
|
||
// NewParseFormData 处理包含更多参数的表单数据
|
||
func NewParseFormData(ctx *gin.Context) {
|
||
// 1. 直接获取参数
|
||
shopIDStr := ctx.PostForm("shopId")
|
||
isbn := ctx.PostForm("isbn")
|
||
shopType := ctx.PostForm("shopType")
|
||
price := ctx.PostForm("price")
|
||
condition := ctx.PostForm("condition")
|
||
|
||
// 2. 空值检查
|
||
if shopIDStr == "" || isbn == "" {
|
||
log.Printf("[WARN] 参数为空 (路径: %s, IP: %s)",
|
||
ctx.FullPath(), ctx.ClientIP())
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopId和isbn不能为空",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 3. 转换并验证数字格式
|
||
shopID, err := strconv.ParseInt(shopIDStr, 10, 64)
|
||
if err != nil || shopID <= 0 {
|
||
log.Printf("[WARN] 无效的shopId: %s (错误: %v)", shopIDStr, err)
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopId必须为正整数",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 4. 使用全局的Redis连接池(避免每次创建新连接)
|
||
redisClient := utils.RedisTwoForParseFormData
|
||
if redisClient == nil {
|
||
log.Printf("[ERROR] Redis连接未初始化")
|
||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 500,
|
||
"message": "系统内部错误",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 5. 构建Redis key
|
||
redisKey := fmt.Sprintf("%d", shopID)
|
||
|
||
// 6. 根据shopType生成不同的加密key
|
||
var encryptedKey string
|
||
switch shopType {
|
||
case "1", "5":
|
||
// shopType为1或5时,使用ISBN的MD5
|
||
hash := md5.Sum([]byte(isbn))
|
||
encryptedKey = fmt.Sprintf("%x", hash)
|
||
case "2":
|
||
// shopType为2时,拼接isbn:price:condition后MD5
|
||
combinedKey := fmt.Sprintf("%s:%s:%s", isbn, price, condition)
|
||
hash := md5.Sum([]byte(combinedKey))
|
||
encryptedKey = fmt.Sprintf("%x", hash)
|
||
default:
|
||
// 其他情况默认使用ISBN的MD5
|
||
hash := md5.Sum([]byte(isbn))
|
||
encryptedKey = fmt.Sprintf("%x", hash)
|
||
}
|
||
|
||
// 7. 检查是否存在重复数据
|
||
exists, err := redisClient.HGet(redisKey, encryptedKey)
|
||
if err == nil && exists != "" {
|
||
// 存在重复数据
|
||
log.Printf("[INFO] 检测到重复数据: shopId=%d, isbn=%s, shopType=%s", shopID, isbn, shopType)
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 0,
|
||
"message": "success",
|
||
"success": true,
|
||
"data": gin.H{
|
||
"deduplicated": false,
|
||
"isRepeat": true,
|
||
"shopId": shopID,
|
||
"isbn": isbn,
|
||
"shopType": shopType,
|
||
"price": price,
|
||
"condition": condition,
|
||
},
|
||
})
|
||
return
|
||
}
|
||
|
||
// 8. 关键成功日志
|
||
log.Printf("[INFO] 数据检查完成: shopId=%d, isbn=%s, shopType=%s, price=%s, condition=%s",
|
||
shopID, isbn, shopType, price, condition)
|
||
|
||
// 9. 返回结果
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 0,
|
||
"message": "success",
|
||
"success": true,
|
||
"data": gin.H{
|
||
"deduplicated": true,
|
||
"isRepeat": false,
|
||
"shopId": shopID,
|
||
"isbn": isbn,
|
||
"shopType": shopType,
|
||
"price": price,
|
||
"condition": condition,
|
||
},
|
||
})
|
||
}
|
||
|
||
// MultipleStores 闲鱼多点店铺去重
|
||
func MultipleStores(ctx *gin.Context) {
|
||
// 1. 直接获取参数
|
||
shopIDsStr := ctx.PostForm("shopIds")
|
||
isbn := ctx.PostForm("isbn")
|
||
|
||
// 2. 空值检查
|
||
if shopIDsStr == "" || isbn == "" {
|
||
log.Printf("[WARN] 参数为空 (路径: %s, IP: %s)",
|
||
ctx.FullPath(), ctx.ClientIP())
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopIds和isbn不能为空",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 3. 使用全局的Redis连接池(避免每次创建新连接)
|
||
redisClient := utils.RedisTwoForParseFormData
|
||
if redisClient == nil {
|
||
log.Printf("[ERROR] Redis连接未初始化")
|
||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 500,
|
||
"message": "系统内部错误",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 4. 生成MD5加密的ISBN
|
||
hash := md5.Sum([]byte(isbn))
|
||
encryptedIsbn := fmt.Sprintf("%x", hash)
|
||
|
||
// 5. 解析shopIds数组(支持逗号分隔,兼容JSON数组格式如 [id1,id2,id3])
|
||
// 去除可能的首尾方括号
|
||
shopIDsStr = strings.TrimSpace(shopIDsStr)
|
||
shopIDsStr = strings.TrimPrefix(shopIDsStr, "[")
|
||
shopIDsStr = strings.TrimSuffix(shopIDsStr, "]")
|
||
|
||
shopIDStrs := strings.Split(shopIDsStr, ",")
|
||
|
||
// 6. 遍历每个shopId,逐个检查是否存在重复数据
|
||
for _, idStr := range shopIDStrs {
|
||
idStr = strings.TrimSpace(idStr)
|
||
|
||
// 跳过空字符串
|
||
if idStr == "" {
|
||
continue
|
||
}
|
||
|
||
// 转换并验证shopId格式
|
||
shopID, err := strconv.ParseInt(idStr, 10, 64)
|
||
if err != nil || shopID <= 0 {
|
||
log.Printf("[WARN] 无效的shopId: %s (错误: %v)", idStr, err)
|
||
continue
|
||
}
|
||
|
||
// 构建Redis key
|
||
redisKey := fmt.Sprintf("%d", shopID)
|
||
|
||
// 检查是否存在重复数据
|
||
exists, err := redisClient.HGet(redisKey, encryptedIsbn)
|
||
if err == nil && exists != "" {
|
||
// 存在重复数据,立即返回不继续查询
|
||
log.Printf("[INFO] 检测到重复数据: shopId=%d, isbn=%s", shopID, isbn)
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 1,
|
||
"message": "已有重复数据",
|
||
"success": false,
|
||
"data": gin.H{
|
||
"shopId": shopID,
|
||
"isbn": isbn,
|
||
},
|
||
})
|
||
return
|
||
}
|
||
}
|
||
|
||
// 7. 关键成功日志
|
||
log.Printf("[INFO] 表单数据解析成功: shopIds=%s, isbn=%s", shopIDsStr, isbn)
|
||
|
||
// 8. 返回结果
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 0,
|
||
"message": "success",
|
||
"data": gin.H{
|
||
"shopIds": shopIDsStr,
|
||
"isbn": isbn,
|
||
},
|
||
"success": true,
|
||
})
|
||
}
|
||
|
||
func SingleShopMultipleStores(ctx *gin.Context) {
|
||
// 1. 直接获取参数
|
||
shopIDStr := ctx.PostForm("shopId")
|
||
isbn := ctx.PostForm("isbn")
|
||
|
||
// 2. 空值检查(移除了 goodsid)
|
||
if shopIDStr == "" || isbn == "" {
|
||
log.Printf("[WARN] 参数为空 (路径: %s, IP: %s)",
|
||
ctx.FullPath(), ctx.ClientIP())
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopid和isbn不能为空",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 3. 转换并验证数字格式(只保留 shopid 验证)
|
||
shopID, err := strconv.ParseInt(shopIDStr, 10, 64)
|
||
if err != nil || shopID <= 0 {
|
||
log.Printf("[WARN] 无效的shopid: %s (错误: %v)", shopIDStr, err)
|
||
|
||
ctx.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 400,
|
||
"message": "shopid必须为正整数",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 4. 使用全局的Redis连接池(避免每次创建新连接)
|
||
redisClient := utils.RedisTwoForParseFormData
|
||
if redisClient == nil {
|
||
log.Printf("[ERROR] Redis连接未初始化")
|
||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 500,
|
||
"message": "系统内部错误",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 5. 使用全局MySQL连接池(单例,在main.go启动时初始化)
|
||
db := dbConnectUtil.DB
|
||
if db == nil {
|
||
log.Printf("[ERROR] 全局MySQL连接池未初始化")
|
||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 500,
|
||
"message": "系统内部错误",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 6. 生成MD5加密的ISBN
|
||
hash := md5.Sum([]byte(isbn))
|
||
encryptedIsbn := fmt.Sprintf("%x", hash)
|
||
|
||
// 7. 查询当前店铺的mall_id
|
||
var mallID string
|
||
err = db.QueryRow(`
|
||
SELECT mall_id
|
||
FROM t_shop
|
||
WHERE shop_type LIKE '%5%'
|
||
AND del_flag LIKE '%0%'
|
||
AND id = ?`, shopID).Scan(&mallID)
|
||
if err != nil {
|
||
// mall_id未找到,不做去重处理,直接返回成功
|
||
log.Printf("[INFO] 未找到店铺mall_id: shopid=%d, err=%v", shopID, err)
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 0,
|
||
"message": "success",
|
||
"data": gin.H{
|
||
"shopid": shopID,
|
||
"isbn": isbn,
|
||
},
|
||
"success": true,
|
||
})
|
||
return
|
||
}
|
||
|
||
// 8. 根据mall_id查询所有关联店铺id
|
||
rows, err := db.Query(`
|
||
SELECT id FROM t_shop
|
||
WHERE shop_type LIKE '%5%'
|
||
AND del_flag LIKE '%0%'
|
||
AND mall_id = ?`, mallID)
|
||
if err != nil {
|
||
log.Printf("[ERROR] 查询关联店铺失败: mall_id=%s, err=%v", mallID, err)
|
||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 500,
|
||
"message": "系统内部错误",
|
||
"success": false,
|
||
})
|
||
return
|
||
}
|
||
defer rows.Close()
|
||
|
||
// 9. 遍历所有关联店铺id,参考ParseFormData第5步之后的逻辑检查重复
|
||
var relatedShopIDs []int64
|
||
for rows.Next() {
|
||
var relatedShopID int64
|
||
if err := rows.Scan(&relatedShopID); err != nil {
|
||
log.Printf("[WARN] 扫描关联店铺id失败: %v", err)
|
||
continue
|
||
}
|
||
relatedShopIDs = append(relatedShopIDs, relatedShopID)
|
||
}
|
||
|
||
for _, relatedShopID := range relatedShopIDs {
|
||
// 构建Redis key
|
||
redisKey := fmt.Sprintf("%d", relatedShopID)
|
||
|
||
// 检查是否存在重复数据
|
||
exists, err := redisClient.HGet(redisKey, encryptedIsbn)
|
||
if err == nil && exists != "" {
|
||
// 存在重复数据,立即返回不继续查询
|
||
log.Printf("[INFO] 检测到重复数据: shopId=%d, isbn=%s (关联mall_id=%s)", relatedShopID, isbn, mallID)
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 1,
|
||
"message": "已有重复数据",
|
||
"success": false,
|
||
"data": gin.H{
|
||
"shopId": relatedShopID,
|
||
"isbn": isbn,
|
||
"mallId": mallID,
|
||
"relatedShopCount": len(relatedShopIDs),
|
||
},
|
||
})
|
||
return
|
||
}
|
||
}
|
||
|
||
// 10. 关键成功日志
|
||
log.Printf("[INFO] 多点店铺去重检查完成: shopid=%d, isbn=%s, mall_id=%s, 关联店铺数=%d",
|
||
shopID, isbn, mallID, len(relatedShopIDs))
|
||
|
||
// 11. 返回结果
|
||
ctx.JSON(http.StatusOK, gin.H{
|
||
"code": 0,
|
||
"message": "success",
|
||
"data": gin.H{
|
||
"shopid": shopID,
|
||
"isbn": isbn,
|
||
"mallId": mallID,
|
||
"relatedShopCount": len(relatedShopIDs),
|
||
"relatedShopIds": relatedShopIDs,
|
||
},
|
||
"success": true,
|
||
})
|
||
}
|