package main /* #include #include */ import "C" import ( "context" "encoding/json" "fmt" "log" "os" "path/filepath" "runtime" "strings" "sync" "time" "unicode/utf8" "unsafe" "xianyv/controller" route "xianyv/http/route" "xianyv/http/service" _type "xianyv/type" "xianyv/utils/iniConfigUtil" "xianyv/utils/tokenConsumerUtil" "github.com/redis/go-redis/v9" ) // ServerManager 使用结构体封装服务器状态,避免全局变量 type ServerManager struct { mu sync.RWMutex server *service.HTTPServer cfg _type.Config isRunning bool configPath string configLoaded bool tokenService *tokenConsumerUtil.RedisTokenConsumerService redisClient *redis.Client tokenInitOnce sync.Once configLoadOnce sync.Once // 新增:专门用于配置加载 configLoadErr error } // ConsoleCommand 定义控制台命令结构 type ConsoleCommand struct { Action string `json:"action"` Data map[string]interface{} `json:"data"` Result chan ConsoleResult `json:"-"` } // ConsoleResult 定义控制台命令结果 type ConsoleResult struct { Success bool `json:"success"` Message string `json:"message"` Data []byte `json:"data,omitempty"` } var ( serverManager *ServerManager once sync.Once consoleChan chan ConsoleCommand consoleMode bool // 标记是否处于控制台模式 ) // 初始化ServerManager单例 func getServerManager() *ServerManager { once.Do(func() { serverManager = &ServerManager{} consoleChan = make(chan ConsoleCommand, 10) }) return serverManager } //export FreeCString func FreeCString(str *C.char) { if str != nil { C.free(unsafe.Pointer(str)) } } //export StartServer func StartServer(configFile *C.char) *C.char { manager := getServerManager() manager.mu.Lock() defer manager.mu.Unlock() if manager.isRunning { return C.CString("Server is already running") } // 设置配置文件路径 if configFile != nil { manager.configPath = C.GoString(configFile) } else { manager.configPath = "config.ini" } // 读取配置文件 if err := manager.readConfigFile(configFile); err != nil { return C.CString("Error reading config: " + err.Error()) } // 启动HTTP服务 router := route.RegisterRoutes(&manager.cfg) manager.server = service.NewServer(manager.cfg.Http.Addr, router) // 使用可取消的上下文 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // 启动服务器 started := make(chan error, 1) go func() { log.Println("HTTP服务启动中...") started <- manager.server.Start(ctx) }() // 等待服务器启动或超时 select { case err := <-started: if err != nil { return C.CString("Error starting service: " + err.Error()) } manager.isRunning = true return C.CString("Server started successfully on " + manager.cfg.Http.Addr) case <-ctx.Done(): return C.CString("Server start timeout") } } //export StopServer func StopServer() *C.char { manager := getServerManager() manager.mu.Lock() defer manager.mu.Unlock() if !manager.isRunning { return C.CString("Server is not running") } if manager.server != nil { if err := manager.server.Stop(); err != nil { return C.CString("Error stopping service: " + err.Error()) } manager.server = nil } manager.isRunning = false return C.CString("Server stopped successfully") } //export GetServerStatus func GetServerStatus() *C.char { manager := getServerManager() manager.mu.RLock() defer manager.mu.RUnlock() if manager.isRunning { return C.CString("Running") } return C.CString("Stopped") } //export GetServerAddress func GetServerAddress() *C.char { manager := getServerManager() manager.mu.RLock() defer manager.mu.RUnlock() if manager.isRunning && manager.server != nil { return C.CString(manager.cfg.Http.Addr) } return C.CString("") } //export ReloadConfig func ReloadConfig(configFile *C.char) *C.char { manager := getServerManager() manager.mu.Lock() defer manager.mu.Unlock() if configFile != nil { manager.configPath = C.GoString(configFile) } if err := manager.readConfigFile(configFile); err != nil { return C.CString("Error reloading config: " + err.Error()) } return C.CString("Config reloaded successfully") } //export ExecuteGoodsCreat func ExecuteGoodsCreat(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } // 添加调试输出 jsonStr := C.GoString(bodyJson) return manager.executeGoodsCreatInternal(jsonStr) } //export ExecuteGoodsCreatNew func ExecuteGoodsCreatNew(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } // 添加调试输出 jsonStr := C.GoString(bodyJson) return manager.executeGoodsCreatInternalNew(jsonStr) } //export ExecuteOtherTypeGoods func ExecuteOtherTypeGoods(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } // 添加调试输出 jsonStr := C.GoString(bodyJson) return manager.executeOtherTypeGoodsInternal(jsonStr) } //export ExecuteGoodsPublish func ExecuteGoodsPublish(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeGoodsPublishInternal(jsonStr) } //export ExecuteGoodsDownShelf func ExecuteGoodsDownShelf(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeGoodsDownShelfInternal(jsonStr) } //export ExecuteGoodsFlash func ExecuteGoodsFlash(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeGoodsFlashInternal(jsonStr) } //export ExecuteGoodsEditPrice func ExecuteGoodsEditPrice(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeGoodsEditPriceInternal(jsonStr) } //export ExecuteGoodsEditStock func ExecuteGoodsEditStock(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeGoodsEditStockInternal(jsonStr) } //export ExecuteSelectGoodsListPrice func ExecuteSelectGoodsListPrice(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) res := manager.executeSelectGoodsListInternal(jsonStr) return res } //export ExecuteSelectShopListPrice func ExecuteSelectShopListPrice(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeSelectShopListInternal(jsonStr) } //export ExecuteOpenExpressCompanies func ExecuteOpenExpressCompanies(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeOpenExpressCompanies(jsonStr) } //export ExecuteOpenOrderShip func ExecuteOpenOrderShip(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeOpenOrderShip(jsonStr) } //export ExecuteXyOrderSynchronization func ExecuteXyOrderSynchronization(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeXyOrderSynchronization(jsonStr) } //export ExecuteGetGoodsDetail func ExecuteGetGoodsDetail(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeGetGoosDetailInternal(jsonStr) } //export ExecuteCountOuterId func ExecuteCountOuterId(bodyJson *C.char, configFile *C.char) *C.char { manager := getServerManager() if err := manager.ensureConfigLoaded(configFile); err != nil { return C.CString("加载配置时出错: " + err.Error()) } jsonStr := C.GoString(bodyJson) return manager.executeGetOuterIdInternal(jsonStr) } func (sm *ServerManager) executeGoodsCreatInternal(jsonStr string) *C.char { var memStatsStart, memStatsEnd runtime.MemStats runtime.ReadMemStats(&memStatsStart) start := time.Now() defer func() { runtime.ReadMemStats(&memStatsEnd) duration := time.Since(start) alloc := memStatsEnd.TotalAlloc - memStatsStart.TotalAlloc numGC := memStatsEnd.NumGC - memStatsStart.NumGC log.Printf("ExecuteGoodsCreat - Duration: %v, Alloc: %d bytes, GC: %d times", duration, alloc, numGC) }() // 清理输入字符串(计时) t0 := time.Now() cleanedJSON := cleanInputString(jsonStr) log.Printf("cleanInputString elapsed=%v", time.Since(t0)) // 解析JSON(计时) t1 := time.Now() var body _type.Body if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { log.Printf("json.Unmarshal failed: %v (elapsed=%v)", err, time.Since(t1)) return C.CString("Error: Invalid JSON format - " + err.Error()) } log.Printf("json.Unmarshal elapsed=%v", time.Since(t1)) // 创建商品控制器(计时) t2 := time.Now() goodsController := &controller.GoodsController{ ExcelPath: sm.cfg.File.ExcelPath, TxtPath: sm.cfg.File.TxtPath, SheetName: sm.cfg.File.SheetName, } log.Printf("create GoodsController elapsed=%v", time.Since(t2)) // 执行商品创建(计时) t3 := time.Now() createResponse, err := goodsController.GoodsCreatController( body, sm.cfg.BatchCreatRequest.Path, sm.cfg.App.Domain, false, ) log.Printf("GoodsCreatController elapsed=%v", time.Since(t3)) if err != nil { if createResponse == nil || len(createResponse) == 0 { return C.CString("") } log.Printf("alloc C.CString for error response elapsed=%v", time.Since(start)) return C.CString(string(createResponse)) } // 返回成功结果 if createResponse == nil || len(createResponse) == 0 { return C.CString("") } log.Printf("alloc C.CString for success response elapsed=%v", time.Since(start)) return C.CString(string(createResponse)) } func (sm *ServerManager) executeGoodsCreatInternalNew(jsonStr string) *C.char { var memStatsStart, memStatsEnd runtime.MemStats runtime.ReadMemStats(&memStatsStart) start := time.Now() defer func() { runtime.ReadMemStats(&memStatsEnd) duration := time.Since(start) alloc := memStatsEnd.TotalAlloc - memStatsStart.TotalAlloc numGC := memStatsEnd.NumGC - memStatsStart.NumGC log.Printf("ExecuteGoodsCreat - Duration: %v, Alloc: %d bytes, GC: %d times", duration, alloc, numGC) }() // 清理输入字符串(计时) t0 := time.Now() cleanedJSON := cleanInputString(jsonStr) log.Printf("cleanInputString elapsed=%v", time.Since(t0)) // 解析JSON(计时) t1 := time.Now() var body _type.BodyNew if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { log.Printf("json.Unmarshal failed: %v (elapsed=%v)", err, time.Since(t1)) return C.CString("Error: Invalid JSON format - " + err.Error()) } log.Printf("json.Unmarshal elapsed=%v", time.Since(t1)) // 创建商品控制器(计时) t2 := time.Now() goodsController := &controller.GoodsController{ ExcelPath: sm.cfg.File.ExcelPath, TxtPath: sm.cfg.File.TxtPath, SheetName: sm.cfg.File.SheetName, } log.Printf("create GoodsController elapsed=%v", time.Since(t2)) // 执行商品创建(计时) t3 := time.Now() createResponse, err := goodsController.GoodsCreatControllerNew( body, sm.cfg.BatchCreatRequest.Path, sm.cfg.App.Domain, false, ) log.Printf("GoodsCreatController elapsed=%v", time.Since(t3)) if err != nil { if createResponse == nil || len(createResponse) == 0 { return C.CString("") } log.Printf("alloc C.CString for error response elapsed=%v", time.Since(start)) return C.CString(string(createResponse)) } // 返回成功结果 if createResponse == nil || len(createResponse) == 0 { return C.CString("") } log.Printf("alloc C.CString for success response elapsed=%v", time.Since(start)) return C.CString(string(createResponse)) } func (sm *ServerManager) executeOtherTypeGoodsInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.Body if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } // 创建商品控制器 goodsController := &controller.GoodsController{ ExcelPath: sm.cfg.File.ExcelPath, TxtPath: sm.cfg.File.TxtPath, SheetName: sm.cfg.File.SheetName, } // 执行商品创建 createResponse, err := goodsController.GoodsCreatController( body, sm.cfg.BatchCreatRequest.Path, sm.cfg.App.Domain, true, ) if err != nil { if createResponse == nil || len(createResponse) == 0 { return C.CString("") } return C.CString(string(createResponse)) } // 返回成功结果 if createResponse == nil || len(createResponse) == 0 { return C.CString("") } return C.CString(string(createResponse)) } func (sm *ServerManager) executeGoodsPublishInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.ListedProducts if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========PublishBody: %v", body) response, err := controller.Publish(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeGoodsDownShelfInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) time.Sleep(100 * time.Millisecond) // 解析JSON var body _type.DownAndFlash if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========DownShelfBody: %v", body) response, err := controller.DownShelf(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeGoodsFlashInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.DownAndFlash if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========FlashBody: %v", body) response, err := controller.Flash(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeGoodsEditPriceInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.EditPrices if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========EditPriceBody: %v", body) response, err := controller.EditPrices(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeSelectShopListInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.GetShopList if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========EditStockBody: %v", body) response, err := controller.GetShopList(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeOpenExpressCompanies(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.GetShopList if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========EditStockBody: %v", body) response, err := controller.ExpressCompanies(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeOpenOrderShip(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.GetOrderShip if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========EditStockBody: %v", body) response, err := controller.OrderShip(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeXyOrderSynchronization(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.GetOrderShip if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========EditStockBody: %v", body) response, err := controller.XyOrderSynchronization(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeSelectGoodsListInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 先检查JSON中是否有online_time字段 var tempMap map[string]interface{} if err := json.Unmarshal([]byte(cleanedJSON), &tempMap); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } var response []byte var err error if onlineTime, exists := tempMap["online_time"]; exists && onlineTime != nil { var bodyWithTime _type.SelectGoodsListWithTime if err := json.Unmarshal([]byte(cleanedJSON), &bodyWithTime); err != nil { return C.CString("Error: Invalid JSON format for WithTime - " + err.Error()) } fmt.Printf("===========SelectGoodsListWithTime: %v", bodyWithTime) response, err = controller.SelectGoodsListWithTime(bodyWithTime) } else { var bodyWithoutTime _type.SelectGoodsListWithoutTime if err := json.Unmarshal([]byte(cleanedJSON), &bodyWithoutTime); err != nil { return C.CString("Error: Invalid JSON format for WithoutTime - " + err.Error()) } fmt.Printf("===========SelectGoodsListWithoutTime: %v", bodyWithoutTime) response, err = controller.SelectGoodsListWithoutTime(bodyWithoutTime) } if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeGoodsEditStockInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.EditStock if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========SelectShopListBody: %v", body) response, err := controller.EditStock(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeGetGoosDetailInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 解析JSON var body _type.GetGoosDetail if err := json.Unmarshal([]byte(cleanedJSON), &body); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } fmt.Printf("===========GetGoodsDetailBody: %v", body) response, err := controller.GetGoosDetail(body) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func (sm *ServerManager) executeGetShopDetailInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 先检查JSON中是否有online_time字段 var tempMap map[string]interface{} if err := json.Unmarshal([]byte(cleanedJSON), &tempMap); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } var response []byte var err error if onlineTime, exists := tempMap["online_time"]; exists && onlineTime != nil { var bodyWithTime _type.SelectGoodsListWithTime if err := json.Unmarshal([]byte(cleanedJSON), &bodyWithTime); err != nil { return C.CString("Error: Invalid JSON format for WithTime - " + err.Error()) } fmt.Printf("===========SelectGoodsListWithTime: %v", bodyWithTime) response, err = controller.SelectGoodsListWithTime(bodyWithTime) } else { var bodyWithoutTime _type.SelectGoodsListWithoutTime if err := json.Unmarshal([]byte(cleanedJSON), &bodyWithoutTime); err != nil { return C.CString("Error: Invalid JSON format for WithoutTime - " + err.Error()) } fmt.Printf("===========SelectGoodsListWithoutTime: %v", bodyWithoutTime) response, err = controller.SelectGoodsListWithoutTime(bodyWithoutTime) } if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } if response == nil || len(response) == 0 { return C.CString("") } // 添加统计逻辑 responseWithStats, err := addOuterIDStatsToResponse(response) if err != nil { // 如果统计失败,仍然返回原始数据 fmt.Printf("===========统计outer_id失败: %v\n", err) return C.CString(string(response)) } return C.CString(string(responseWithStats)) } func (sm *ServerManager) executeGetOuterIdInternal(jsonStr string) *C.char { // 清理输入字符串 cleanedJSON := cleanInputString(jsonStr) // 先检查JSON中是否有online_time字段 var tempMap map[string]interface{} if err := json.Unmarshal([]byte(cleanedJSON), &tempMap); err != nil { return C.CString("Error: Invalid JSON format - " + err.Error()) } var response []byte var err error // 我们先调用一次拿到分页信息(count,page_size),然后根据 count 和 page_size 计算总页数,循环获取所有页并合并 list 来做整体统计 var initialPageNo int32 = 1 var pageSize int32 = 100 var combinedList []map[string]interface{} if onlineTime, exists := tempMap["online_time"]; exists && onlineTime != nil { var bodyWithTime _type.SelectGoodsListWithTime if err := json.Unmarshal([]byte(cleanedJSON), &bodyWithTime); err != nil { return C.CString("Error: Invalid JSON format for WithTime - " + err.Error()) } fmt.Printf("===========SelectGoodsListWithTime: %v", bodyWithTime) initialPageNo = bodyWithTime.PageNo if bodyWithTime.PageSize > 0 { pageSize = bodyWithTime.PageSize } // 第一次请求 response, err = controller.SelectGoodsListWithTime(bodyWithTime) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } // 解析第一次响应以获取 count 和 list var resp struct { Code int `json:"code"` Msg string `json:"msg"` Data struct { Count int `json:"count"` List []map[string]interface{} `json:"list"` PageNo int `json:"page_no"` PageSize int `json:"page_size"` } `json:"data"` } if err := json.Unmarshal(response, &resp); err != nil { // 无法解析则直接返回原始响应 return C.CString(string(response)) } combinedList = append(combinedList, resp.Data.List...) totalCount := resp.Data.Count if resp.Data.PageSize > 0 { pageSize = int32(resp.Data.PageSize) } // 计算总页数 totalPages := 1 if pageSize > 0 { totalPages = (totalCount + int(pageSize) - 1) / int(pageSize) } // 逐页拉取其余页(跳过已取得的 initialPageNo) for p := 1; p <= totalPages; p++ { if int32(p) == initialPageNo { continue } bodyWithTime.PageNo = int32(p) pageResp, pageErr := controller.SelectGoodsListWithTime(bodyWithTime) if pageErr != nil { // 记录并继续(使用已有数据) fmt.Printf("Warning: 获取第 %d 页失败: %v\n", p, pageErr) continue } var pageParsed struct { Data struct { List []map[string]interface{} `json:"list"` } `json:"data"` } if perr := json.Unmarshal(pageResp, &pageParsed); perr != nil { fmt.Printf("Warning: 解析第 %d 页响应失败: %v\n", p, perr) continue } combinedList = append(combinedList, pageParsed.Data.List...) } // 将 combinedList 按要求注入到最终响应中并返回(在原始 response 的 data 中添加 outer_id_stats) finalRespMap := make(map[string]interface{}) if err := json.Unmarshal(response, &finalRespMap); err != nil { ptr := C.CBytes(response) return (*C.char)(ptr) } // 计算统计 stats := make(map[string]interface{}) outerCount := make(map[string]int) for _, item := range combinedList { if v, ok := item["outer_id"].(string); ok { if v == "" { outerCount["__empty__"]++ } else { outerCount[v]++ } } } stats["total_count"] = len(combinedList) stats["distribution"] = outerCount // 注入到 data if dataMap, ok := finalRespMap["data"].(map[string]interface{}); ok { dataMap["outer_id_stats"] = stats } bts, merr := json.Marshal(finalRespMap) if merr != nil { return C.CString(string(response)) } return C.CString(string(bts)) } else { var bodyWithoutTime _type.SelectGoodsListWithoutTime if err := json.Unmarshal([]byte(cleanedJSON), &bodyWithoutTime); err != nil { return C.CString("Error: Invalid JSON format for WithoutTime - " + err.Error()) } fmt.Printf("===========SelectGoodsListWithoutTime: %v", bodyWithoutTime) initialPageNo = bodyWithoutTime.PageNo if bodyWithoutTime.PageSize > 0 { pageSize = bodyWithoutTime.PageSize } response, err = controller.SelectGoodsListWithoutTime(bodyWithoutTime) if err != nil { if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } var resp struct { Code int `json:"code"` Msg string `json:"msg"` Data struct { Count int `json:"count"` List []map[string]interface{} `json:"list"` PageNo int `json:"page_no"` PageSize int `json:"page_size"` } `json:"data"` } if err := json.Unmarshal(response, &resp); err != nil { return C.CString(string(response)) } combinedList = append(combinedList, resp.Data.List...) totalCount := resp.Data.Count if resp.Data.PageSize > 0 { pageSize = int32(resp.Data.PageSize) } totalPages := 1 if pageSize > 0 { totalPages = (totalCount + int(pageSize) - 1) / int(pageSize) } for p := 1; p <= totalPages; p++ { if int32(p) == initialPageNo { continue } bodyWithoutTime.PageNo = int32(p) pageResp, pageErr := controller.SelectGoodsListWithoutTime(bodyWithoutTime) if pageErr != nil { fmt.Printf("Warning: 获取第 %d 页失败: %v\n", p, pageErr) continue } var pageParsed struct { Data struct { List []map[string]interface{} `json:"list"` } `json:"data"` } if perr := json.Unmarshal(pageResp, &pageParsed); perr != nil { fmt.Printf("Warning: 解析第 %d 页响应失败: %v\n", p, perr) continue } combinedList = append(combinedList, pageParsed.Data.List...) } finalRespMap := make(map[string]interface{}) if err := json.Unmarshal(response, &finalRespMap); err != nil { ptr := C.CBytes(response) return (*C.char)(ptr) } stats := make(map[string]interface{}) outerCount := make(map[string]int) for _, item := range combinedList { if v, ok := item["outer_id"].(string); ok { if v == "" { outerCount["__empty__"]++ } else { outerCount[v]++ } } } stats["total_count"] = len(combinedList) stats["distribution"] = outerCount if dataMap, ok := finalRespMap["data"].(map[string]interface{}); ok { dataMap["outer_id_stats"] = stats } bts, merr := json.Marshal(finalRespMap) if merr != nil { return C.CString(string(response)) } return C.CString(string(bts)) } if err != nil { if response == nil || len(response) == 0 { return C.CString("") } ptr := C.CBytes(response) return (*C.char)(ptr) } if response == nil || len(response) == 0 { return C.CString("") } return C.CString(string(response)) } func main() { } func (sm *ServerManager) readConfigFile(configFile *C.char) error { if configFile == nil { return fmt.Errorf("configFile参数为空指针") } goConfigFile := C.GoString(configFile) if !utf8.ValidString(goConfigFile) { return fmt.Errorf("invalid UTF-8 encoding in config file path") } if goConfigFile == "" { return fmt.Errorf("configFile参数为空字符串") } // 设置硬编码路径或使用默认值 if sm.configPath == "" { sm.configPath = goConfigFile log.Printf("使用配置文件路径: %s", sm.configPath) } else { log.Printf("警告:configPath参数将被忽略,使用Go代码中的硬编码配置路径: %s", sm.configPath) } if _, err := os.Stat(sm.configPath); os.IsNotExist(err) { exePath, _ := os.Executable() exeDir := filepath.Dir(exePath) defaultConfig := filepath.Join(exeDir, "config.ini") if _, err := os.Stat(defaultConfig); err == nil { sm.configPath = defaultConfig } else { log.Printf("配置文件不存在: %s", sm.configPath) return err } } if err := iniConfigUtil.LoadConfig(&sm.cfg, sm.configPath); err != nil { log.Printf("加载配置失败: %v", err) return err } fmt.Printf("Config-bathCreat:\n requestPath: %v\n", sm.cfg.BatchCreatRequest.Path) fmt.Printf("Config-File:\n txtPath: %v,\n excelPath: %v,\n sheetName: %v\n", sm.cfg.File.TxtPath, sm.cfg.File.ExcelPath, sm.cfg.File.SheetName) return nil } func cleanInputString(input string) string { // 移除BOM字符 if len(input) >= 3 && input[0] == 0xEF && input[1] == 0xBB && input[2] == 0xBF { input = input[3:] } // 标准化换行符 input = strings.ReplaceAll(input, "\r\n", "\n") input = strings.ReplaceAll(input, "\r", "\n") // 移除首尾空白 return strings.TrimSpace(input) } // 统一的配置加载方法 func (sm *ServerManager) ensureConfigLoaded(configFile *C.char) error { sm.configLoadOnce.Do(func() { sm.mu.Lock() defer sm.mu.Unlock() if configFile != nil { sm.configPath = C.GoString(configFile) } else if sm.configPath == "" { sm.configPath = "config.ini" } sm.configLoadErr = sm.readConfigFile(configFile) if sm.configLoadErr == nil { sm.configLoaded = true log.Printf("配置加载完成,AppId: %d", sm.cfg.App.AppId) } }) return sm.configLoadErr } // 将统计结果添加到响应中的辅助函数 func addOuterIDStatsToResponse(originalResponse []byte) ([]byte, error) { var responseMap map[string]interface{} if err := json.Unmarshal(originalResponse, &responseMap); err != nil { return nil, fmt.Errorf("解析响应JSON失败: %v", err) } // 获取统计结果 stats := getOuterIDStats(originalResponse) // 将统计结果添加到response的data中 if data, exists := responseMap["data"].(map[string]interface{}); exists { data["outer_id_stats"] = stats responseMap["data"] = data } return json.Marshal(responseMap) } // 获取outer_id统计 func getOuterIDStats(responseData []byte) map[string]interface{} { stats := make(map[string]interface{}) var data struct { Data struct { List []struct { OuterID string `json:"outer_id"` } `json:"list"` } `json:"data"` } if err := json.Unmarshal(responseData, &data); err != nil { return stats } outerIDCount := make(map[string]int) totalCount := len(data.Data.List) for _, item := range data.Data.List { outerID := item.OuterID if outerID == "" { outerID = "(空)" } outerIDCount[outerID]++ } stats["total_count"] = totalCount stats["distribution"] = outerIDCount return stats }