daShangDao_xy_dll/cmd/main.go

1256 lines
34 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
/*
#include <stdlib.h>
#include <stdio.h>
*/
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
}