daShangDao_kfzgw-info/zjdydll.go
2025-12-22 19:09:56 +08:00

1238 lines
38 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
import "C"
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"syscall"
"unsafe"
)
// 配置结构
type Configs struct {
App struct {
MaxRetryTimes int `json:"max_retry_times"`
RateLimitDelay int `json:"rate_limit_delay"`
Size int `json:"size"`
DefaultUserAgent string `json:"default_user_agent"`
} `json:"app"`
API struct {
LoginURL string `json:"login_url"`
BookSearchURL string `json:"book_search_url"`
ProductSearchURL string `json:"product_search_url"`
} `json:"api"`
Proxy struct {
Servers string `json:"servers"`
Username string `json:"username"`
Password string `json:"password"`
TailMachineCode string `json:"tail_machine_code"`
TailCardKey string `json:"tail_card_key"`
ProxyFilePath string `json:"proxy_file_path"`
} `json:"proxy"`
}
// API响应结构
type APIResponses struct {
Success bool `json:"success"`
Message string `json:"message,omitempty"`
GoodsNum string `json:"goods_num,omitempty"`
PNum string `json:"pnum,omitempty"`
Data interface{} `json:"data,omitempty"`
Error string `json:"error,omitempty"`
}
// 加载DLL的函数
type kongfzDLL struct {
dll *syscall.DLL
outLogin *syscall.Proc // 孔网登录
outGetUserMsg *syscall.Proc // 获取孔网用户信息
outGetGoodsTplMsg *syscall.Proc // 获取商品模版-已登的店铺
outGetGoodsListMsgFromSelfShop *syscall.Proc // 获取商品列表-已登的店铺
outAddGoods *syscall.Proc // 新增商品-已登的店铺
outDelGoodsFromSelfShop *syscall.Proc // 删除商品-已登的店铺
outGetImageFilterShopId *syscall.Proc // 获取孔网商品图片(官图和拍图)-带有店铺过滤
outGetImageByIsbn *syscall.Proc // 获取孔网商品图片和信息(官图和拍图)
outGetGoodsListMsgByShopId *syscall.Proc // 获取商品列表通过店铺ID
outGetGoodsMsgByDetailUrl *syscall.Proc // 获取商品信息通过商品详情链接
outGetTopGoodsListMsg *syscall.Proc // 获取销量榜商品列表
freeCString *syscall.Proc // 释放C字符串内存
}
// 初始化kongfzDLL
func InitKongfzDLL() (*kongfzDLL, error) {
dllPath := filepath.Join("dll", "kongfz.dll")
if _, err := os.Stat(dllPath); os.IsNotExist(err) {
return nil, fmt.Errorf("kongfz DLL 不存在: %s", dllPath)
}
if dll, err := syscall.LoadDLL(dllPath); err != nil {
return nil, fmt.Errorf("加载 kongfz DLL 失败: %v", err)
} else {
return &kongfzDLL{
dll: dll,
outLogin: dll.MustFindProc("OutLogin"),
outGetUserMsg: dll.MustFindProc("OutGetUserMsg"),
outGetGoodsTplMsg: dll.MustFindProc("OutGetGoodsTplMsg"),
outGetGoodsListMsgFromSelfShop: dll.MustFindProc("OutGetGoodsListMsgFromSelfShop"),
outAddGoods: dll.MustFindProc("OutAddGoods"),
outDelGoodsFromSelfShop: dll.MustFindProc("OutDelGoodsFromSelfShop"),
outGetImageFilterShopId: dll.MustFindProc("OutGetImageFilterShopId"),
outGetImageByIsbn: dll.MustFindProc("OutGetImageByIsbn"),
outGetGoodsListMsgByShopId: dll.MustFindProc("OutGetGoodsListMsgByShopId"),
outGetGoodsMsgByDetailUrl: dll.MustFindProc("OutGetGoodsMsgByDetailUrl"),
outGetTopGoodsListMsg: dll.MustFindProc("OutGetTopGoodsListMsg"),
freeCString: dll.MustFindProc("FreeCString"),
}, nil
}
}
// cStr 获取C字符串
func (m *kongfzDLL) cStr(p uintptr) string {
if p == 0 {
return ""
}
b := []byte{}
for i := uintptr(0); ; i++ {
c := *(*byte)(unsafe.Pointer(p + i))
if c == 0 {
break
}
b = append(b, c)
}
s := string(b)
if m.freeCString != nil {
m.freeCString.Call(p)
}
return s
}
type DLLManager struct {
dll *syscall.DLL
}
func NewDLLManager(dllPath string) (*DLLManager, error) {
dll, err := syscall.LoadDLL(dllPath)
if err != nil {
return nil, fmt.Errorf("加载DLL失败: %v", err)
}
return &DLLManager{dll: dll}, nil
}
func (m *DLLManager) Close() {
if m.dll != nil {
m.dll.Release()
}
}
// 单参数函数调用
func (m *DLLManager) callFunction(funcName string, arg string) (string, error) {
proc, err := m.dll.FindProc(funcName)
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", funcName, err)
}
argPtr, _ := syscall.BytePtrFromString(arg)
r1, _, err := proc.Call(uintptr(unsafe.Pointer(argPtr)))
if err != nil && err.Error() != "The operation completed successfully." {
return "", fmt.Errorf("调用函数 %s 失败: %v", funcName, err)
}
result := (*byte)(unsafe.Pointer(r1))
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))))
}
// 释放内存
freeProc, _ := m.dll.FindProc("FreeString")
if freeProc != nil {
freeProc.Call(r1)
}
return string(resultBytes), nil
}
// 二参数函数调用
func (m *DLLManager) callFunctionTwoArgs(funcName string, args ...string) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("函数 %s 需要2个参数但提供了 %d 个", funcName, len(args))
}
proc, err := m.dll.FindProc(funcName)
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", funcName, err)
}
// 准备参数指针
argPtrs := make([]uintptr, 2)
for i, arg := range args {
argPtr, _ := syscall.BytePtrFromString(arg)
argPtrs[i] = uintptr(unsafe.Pointer(argPtr))
}
r1, _, err := proc.Call(
argPtrs[0], // proxyType
argPtrs[1], // username
)
if err != nil && err.Error() != "The operation completed successfully." {
return "", fmt.Errorf("调用函数 %s 失败: %v", funcName, err)
}
result := (*byte)(unsafe.Pointer(r1))
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))))
}
// 释放内存
freeProc, _ := m.dll.FindProc("FreeString")
if freeProc != nil {
freeProc.Call(r1)
}
return string(resultBytes), nil
}
// 五参数函数调用 - 用于 GetKFZGTImageURL 和 GetKFZSPTImageURL
func (m *DLLManager) callFunctionFiveArgs(funcName string, args ...string) (string, error) {
if len(args) != 5 {
return "", fmt.Errorf("函数 %s 需要5个参数但提供了 %d 个", funcName, len(args))
}
proc, err := m.dll.FindProc(funcName)
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", funcName, err)
}
// 准备参数指针
argPtrs := make([]uintptr, 5)
for i, arg := range args {
argPtr, _ := syscall.BytePtrFromString(arg)
argPtrs[i] = uintptr(unsafe.Pointer(argPtr))
}
r1, _, err := proc.Call(
argPtrs[0], // proxyType
argPtrs[1], // username
argPtrs[2], // password
argPtrs[3], // machineCode
argPtrs[4], // isbn
)
if err != nil && err.Error() != "The operation completed successfully." {
return "", fmt.Errorf("调用函数 %s 失败: %v", funcName, err)
}
result := (*byte)(unsafe.Pointer(r1))
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))))
}
// 释放内存
freeProc, _ := m.dll.FindProc("FreeString")
if freeProc != nil {
freeProc.Call(r1)
}
return string(resultBytes), nil
}
// 六参数函数调用
func (m *DLLManager) callFunctionSixArgs(funcName string, args ...string) (string, error) {
if len(args) != 6 {
return "", fmt.Errorf("函数 %s 需要6个参数但提供了 %d 个", funcName, len(args))
}
proc, err := m.dll.FindProc(funcName)
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", funcName, err)
}
// 准备参数指针
argPtrs := make([]uintptr, 6)
for i, arg := range args {
argPtr, _ := syscall.BytePtrFromString(arg)
argPtrs[i] = uintptr(unsafe.Pointer(argPtr))
}
r1, _, err := proc.Call(
argPtrs[0], // fetchMode
argPtrs[1], // proxyType
argPtrs[2], // username
argPtrs[3], // password
argPtrs[4], // machineCode
argPtrs[5], // isbn
)
if err != nil && err.Error() != "The operation completed successfully." {
return "", fmt.Errorf("调用函数 %s 失败: %v", funcName, err)
}
result := (*byte)(unsafe.Pointer(r1))
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))))
}
// 释放内存
freeProc, _ := m.dll.FindProc("FreeString")
if freeProc != nil {
freeProc.Call(r1)
}
return string(resultBytes), nil
}
// 十二参数函数调用 - 专门用于 GetKFZShopBookInfo
func (m *DLLManager) callFunctionTwelveArgs(funcName string, args ...string) (string, error) {
if len(args) != 12 {
return "", fmt.Errorf("函数 %s 需要12个参数但提供了 %d 个", funcName, len(args))
}
proc, err := m.dll.FindProc(funcName)
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", funcName, err)
}
// 准备参数指针
argPtrs := make([]uintptr, 12)
for i, arg := range args {
argPtr, _ := syscall.BytePtrFromString(arg)
argPtrs[i] = uintptr(unsafe.Pointer(argPtr))
}
r1, _, err := proc.Call(
argPtrs[0], // proxyType
argPtrs[1], // username
argPtrs[2], // password
argPtrs[3], // machineCode
argPtrs[4], // shopId
argPtrs[5], // isImage
argPtrs[6], // bookNum
argPtrs[7], // pageNum
argPtrs[8], // sortType
argPtrs[9], // sort
argPtrs[10], // priceDown
argPtrs[11], // priceUp
)
if err != nil && err.Error() != "The operation completed successfully." {
return "", fmt.Errorf("调用函数 %s 失败: %v", funcName, err)
}
result := (*byte)(unsafe.Pointer(r1))
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))))
}
// 释放内存
freeProc, _ := m.dll.FindProc("FreeString")
if freeProc != nil {
freeProc.Call(r1)
}
return string(resultBytes), nil
}
// 十三参数函数调用 - 专门用于 GetKFZShopBookInfo
func (m *DLLManager) callFunctionThirteenArgs(funcName string, args ...string) (string, error) {
if len(args) != 13 {
return "", fmt.Errorf("函数 %s 需要13个参数但提供了 %d 个", funcName, len(args))
}
proc, err := m.dll.FindProc(funcName)
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", funcName, err)
}
// 准备参数指针
argPtrs := make([]uintptr, 13)
for i, arg := range args {
argPtr, _ := syscall.BytePtrFromString(arg)
argPtrs[i] = uintptr(unsafe.Pointer(argPtr))
}
r1, _, err := proc.Call(
argPtrs[0], // fetchMode
argPtrs[1], // proxyType
argPtrs[2], // username
argPtrs[3], // password
argPtrs[4], // machineCode
argPtrs[5], // shopId
argPtrs[6], // isImage
argPtrs[7], // bookNum
argPtrs[8], // pageNum
argPtrs[9], // sortType
argPtrs[10], // sort
argPtrs[11], // priceDown
argPtrs[12], // priceUp
)
if err != nil && err.Error() != "The operation completed successfully." {
return "", fmt.Errorf("调用函数 %s 失败: %v", funcName, err)
}
result := (*byte)(unsafe.Pointer(r1))
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i))))
}
// 释放内存
freeProc, _ := m.dll.FindProc("FreeString")
if freeProc != nil {
freeProc.Call(r1)
}
return string(resultBytes), nil
}
func (m *DLLManager) Initialize(configJSON string) (string, error) {
return m.callFunction("Initialize", configJSON)
}
// 修改后的 GetKFZGTImageURL - 需要5个参数
func (m *DLLManager) GetKFZGTImageURL(proxyType, username, password, machineCode, isbn string) (string, error) {
return m.callFunctionFiveArgs("GetKFZGTImageURL",
proxyType, username, password, machineCode, isbn)
}
// 修改后的 GetKFZSPTImageURL - 需要5个参数
func (m *DLLManager) GetKFZSPTImageURL(proxyType, username, password, machineCode, isbn string) (string, error) {
return m.callFunctionFiveArgs("GetKFZSPTImageURL",
proxyType, username, password, machineCode, isbn)
}
// 修改后的 GetKFZShopBookInfo - 需要12个参数
func (m *DLLManager) GetKFZShopBookInfo(fetchMode, proxyType, username, password, machineCode, shopId, isImage, bookNum, pageNum, sortType, sort, priceDown, priceUp string) (string, error) {
return m.callFunctionThirteenArgs("GetKFZShopBookInfo",
fetchMode, proxyType, username, password, machineCode, shopId, isImage, bookNum, pageNum, sortType, sort, priceDown, priceUp)
}
// 获取 GetUrlBookDetails - 需要6个参数
func (m *DLLManager) GetUrlBookDetails(fetchMode, proxyType, username, password, machineCode, url string) (string, error) {
return m.callFunctionSixArgs("GetUrlBookDetails", fetchMode, proxyType, username, password, machineCode, url)
}
// 获取 OutLogin
func (m *DLLManager) OutLogin(username, password string) (string, error) {
// 获取函数
proc, err := m.dll.FindProc("OutLogin")
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", "OutLogin", err)
}
// 转换参数
usernamePtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(username)))
passwordPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(password)))
// 调用函数
ret, _, err := proc.Call(usernamePtr, passwordPtr)
if ret == 0 {
return "", fmt.Errorf("DLL调用失败: %v", err)
}
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))))
}
// 释放内存假设DLL提供了FreeMemory函数
findProc, err := m.dll.FindProc("FreeString")
if findProc != nil {
findProc.Call(ret)
}
return string(resultBytes), nil
}
// 获取 OutGetUserMsg
func (m *DLLManager) OutGetUserMsg(token string) (string, error) {
// 获取函数
proc, err := m.dll.FindProc("OutGetUserMsg")
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", "OutGetUserMsg", err)
}
// 转换参数
tokenPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(token)))
// 调用函数
ret, _, err := proc.Call(tokenPtr)
if ret == 0 {
return "", fmt.Errorf("DLL调用失败: %v", err)
}
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))))
}
// 释放内存假设DLL提供了FreeMemory函数
findProc, err := m.dll.FindProc("FreeString")
if findProc != nil {
findProc.Call(ret)
}
return string(resultBytes), nil
}
// 获取 OutGetGoodsTplMsg
func (m *DLLManager) OutGetGoodsTplMsg(token, itemId, proxy string) (string, error) {
// 获取函数
proc, err := m.dll.FindProc("OutGetGoodsTplMsg")
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", "OutGetGoodsTplMsg", err)
}
// 转换参数
tokenPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(token)))
itemIdPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(itemId)))
proxyPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(proxy)))
// 调用函数
ret, _, err := proc.Call(tokenPtr, itemIdPtr, proxyPtr)
if ret == 0 {
return "", fmt.Errorf("DLL调用失败: %v", err)
}
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))))
}
// 释放内存假设DLL提供了FreeMemory函数
findProc, err := m.dll.FindProc("FreeString")
if findProc != nil {
findProc.Call(ret)
}
return string(resultBytes), nil
}
// 获取 OutGetGoodsListMsgFromSelfShop
func (m *DLLManager) OutGetGoodsListMsgFromSelfShop(token string, proxy string, itemSn string, priceMin string, priceMax string, startCreateTime string,
endCreateTime string, requestType string, isItemSnEqual int, page int, size int) (string, error) {
// 获取函数
proc, err := m.dll.FindProc("OutGetGoodsListMsgFromSelfShop")
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", "OutGetGoodsListMsgFromSelfShop", err)
}
// 转换参数
tokenPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(token)))
proxyPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(proxy)))
itemSnPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(itemSn)))
priceMinPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(priceMin)))
priceMaxPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(priceMax)))
startCreateTimePtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(startCreateTime)))
endCreateTimePtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(endCreateTime)))
requestTypePtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(requestType)))
isItemSnEqualPtr := uintptr(isItemSnEqual)
pagePtr := uintptr(page)
sizePtr := uintptr(size)
// 调用函数
ret, _, err := proc.Call(tokenPtr, proxyPtr, itemSnPtr, priceMinPtr, priceMaxPtr, startCreateTimePtr, endCreateTimePtr, requestTypePtr, isItemSnEqualPtr, pagePtr, sizePtr)
if ret == 0 {
return "", fmt.Errorf("DLL调用失败: %v", err)
}
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))))
}
// 释放内存假设DLL提供了FreeMemory函数
findProc, err := m.dll.FindProc("FreeString")
if findProc != nil {
findProc.Call(ret)
}
return string(resultBytes), nil
}
// 获取 OutGetImageByIsbn
func (m *DLLManager) OutGetImageByIsbn(token string, isbn string, proxy string, isLiveImage bool, isReturnMsg bool) (string, error) {
// 获取函数
proc, err := m.dll.FindProc("OutGetImageByIsbn")
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", "OutGetImageByIsbn", err)
}
// 转换参数
tokenPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(token)))
isbnPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(isbn)))
var proxyPtr uintptr
if proxy != "" {
proxyPtr = uintptr(unsafe.Pointer(syscall.StringBytePtr(proxy)))
} else {
proxyPtr = 0
}
var isLiveImageInt int
if isLiveImage {
isLiveImageInt = 0
} else {
isLiveImageInt = 1
}
isLiveImagePtr := uintptr(isLiveImageInt)
var isReturnMsgInt int
if isReturnMsg {
isLiveImageInt = 0
} else {
isLiveImageInt = 1
}
isReturnMsgPtr := uintptr(isReturnMsgInt)
// 调用函数
ret, _, err := proc.Call(tokenPtr, isbnPtr, proxyPtr, isLiveImagePtr, isReturnMsgPtr)
if ret == 0 {
return "", fmt.Errorf("DLL调用失败: %v", err)
}
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))))
}
// 释放内存假设DLL提供了FreeMemory函数
findProc, err := m.dll.FindProc("FreeString")
if findProc != nil {
findProc.Call(ret)
}
return string(resultBytes), nil
}
// 获取 OutGetGoodsMsgByDetailUrl
func (m *DLLManager) OutGetGoodsMsgByDetailUrl(url, proxy string) (string, error) {
// 获取函数
proc, err := m.dll.FindProc("OutGetGoodsMsgByDetailUrl")
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", "OutGetGoodsMsgByDetailUrl", err)
}
// 转换参数
urlPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(url)))
var proxyPtr uintptr
if proxy != "" {
proxyPtr = uintptr(unsafe.Pointer(syscall.StringBytePtr(proxy)))
} else {
proxyPtr = 0
}
// 调用函数
ret, _, err := proc.Call(urlPtr, proxyPtr)
if ret == 0 {
return "", fmt.Errorf("DLL调用失败: %v", err)
}
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))))
}
// 释放内存假设DLL提供了FreeMemory函数
findProc, err := m.dll.FindProc("FreeString")
if findProc != nil {
findProc.Call(ret)
}
return string(resultBytes), nil
}
// 获取 OutGetGoodsListMsgByShopId
func (m *DLLManager) OutGetGoodsListMsgByShopId(shopId int, proxy string, isImage bool,
sortType string, sort string, priceMin float32, priceMax float32,
pageNum, returnNum int) (string, error) {
// 获取函数
proc, err := m.dll.FindProc("OutGetGoodsListMsgByShopId")
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", "OutGetGoodsListMsgByShopId", err)
}
// 转换参数
shopIdPtr := uintptr(shopId)
var isImageInt int
if isImage {
isImageInt = 0
} else {
isImageInt = 1
}
isImagePtr := uintptr(isImageInt)
sortTypePtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(sortType)))
sortPtr := uintptr(unsafe.Pointer(syscall.StringBytePtr(sort)))
priceMinPtr := uintptr(*(*uint32)(unsafe.Pointer(&priceMin)))
priceMaxPtr := uintptr(*(*uint32)(unsafe.Pointer(&priceMax)))
pageNumPtr := uintptr(pageNum)
returnNumPtr := uintptr(returnNum)
var proxyPtr uintptr
if proxy != "" {
proxyPtr = uintptr(unsafe.Pointer(syscall.StringBytePtr(proxy)))
} else {
proxyPtr = 0
}
// 调用函数
ret, _, err := proc.Call(shopIdPtr, proxyPtr, isImagePtr, sortTypePtr, sortPtr, priceMinPtr, priceMaxPtr, pageNumPtr, returnNumPtr)
if ret == 0 {
return "", fmt.Errorf("DLL调用失败: %v", err)
}
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))))
}
// 释放内存假设DLL提供了FreeMemory函数
findProc, err := m.dll.FindProc("FreeString")
if findProc != nil {
findProc.Call(ret)
}
return string(resultBytes), nil
}
// 获取 OutGetTopGoodsListMsg
func (m *DLLManager) OutGetTopGoodsListMsg(catId int, proxy string) (string, error) {
// 获取函数
proc, err := m.dll.FindProc("OutGetTopGoodsListMsg")
if err != nil {
return "", fmt.Errorf("找不到函数 %s: %v", "OutGetTopGoodsListMsg", err)
}
// 转换参数
catIdPtr := uintptr(catId)
var proxyPtr uintptr
if proxy != "" {
proxyPtr = uintptr(unsafe.Pointer(syscall.StringBytePtr(proxy)))
} else {
proxyPtr = 0
}
// 调用函数
ret, _, err := proc.Call(catIdPtr, proxyPtr)
if ret == 0 {
return "", fmt.Errorf("DLL调用失败: %v", err)
}
// 将C字符串转换为Go字符串
var resultBytes []byte
for i := 0; ; i++ {
if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))) == 0 {
break
}
resultBytes = append(resultBytes, *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(ret)) + uintptr(i))))
}
// 释放内存假设DLL提供了FreeMemory函数
findProc, err := m.dll.FindProc("FreeString")
if findProc != nil {
findProc.Call(ret)
}
return string(resultBytes), nil
}
// 创建默认配置
func createDefaultConfig() Config {
var configs Config
// App配置
configs.App.MaxRetryTimes = 3
configs.App.RateLimitDelay = 1000
configs.App.Size = 10
configs.App.DefaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
// API配置
configs.API.LoginURL = "https://login.kongfz.com/Pc/Login/account"
configs.API.BookSearchURL = "https://search.kongfz.com/pc-gw/search-web/client/pc/bookLib/keyword/list"
configs.API.ProductSearchURL = "https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/list"
// 代理配置(需要根据实际情况修改)
configs.Proxy.Servers = "http-dynamic.xiaoxiangdaili.com,http-dynamic-S02.xiaoxiangdaili.com,http-dynamic-S03.xiaoxiangdaili.com,http-dynamic-S04.xiaoxiangdaili.com"
configs.Proxy.Username = "1297757178467602432"
configs.Proxy.Password = "QgQBvP7f"
configs.Proxy.TailMachineCode = "b7bf22a237ec692f13fcc2c43ee63252"
configs.Proxy.TailCardKey = "DL_20_YK_1920acb2129844c2aabade3896560a9b"
configs.Proxy.ProxyFilePath = "dll/proxyConfig.dll"
configs.Database.Username = "newAdmin"
configs.Database.Password = "bYPp8SbBe5F7nz2i"
configs.Database.Host = "146.56.227.42:3306"
configs.Database.Name = "newadmin"
return configs
}
// 获取当前可执行文件所在目录
func getExecutableDir() string {
exePath, err := os.Executable()
if err != nil {
return "."
}
return filepath.Dir(exePath)
}
// 格式化输出JSON响应
func printFormattedResponse(operation string, result string, err error) int {
var apiResp APIResponses
fmt.Printf("\n%s:\n", operation)
fmt.Println("=" + string(make([]byte, 50)) + "=")
if err != nil {
fmt.Printf("❌ 错误: %v\n", err)
}
var count int
if err := json.Unmarshal([]byte(result), &apiResp); err == nil {
if apiResp.Success {
fmt.Printf("✅ 成功: %s\n", apiResp.Message)
if apiResp.Data != nil {
fmt.Println("📊 数据:")
jsonData, _ := json.MarshalIndent(apiResp.Data, "", " ")
fmt.Println(string(jsonData))
// 方法1: 判断 Data 的类型并统计条数
switch data := apiResp.Data.(type) {
case []interface{}:
// 如果是切片/数组
count = len(data)
fmt.Printf("📈 数据条数: %d\n", count)
case []BookInfo:
// 如果是 BookInfo 切片
count = len(data)
fmt.Printf("📚 图书数量: %d\n", count)
case map[string]interface{}:
// 如果是映射
count = len(data)
fmt.Printf("🗂️ 数据字段数: %d\n", count)
case []ProductInfo:
// 如果是 ProductInfo 切片
count = len(data)
fmt.Printf("🛒 商品数量: %d\n", count)
default:
fmt.Printf(" 数据类型: %T\n", apiResp.Data)
}
}
if apiResp.GoodsNum != "" {
fmt.Printf("📦 商品数量: %s\n", apiResp.GoodsNum)
}
if apiResp.PNum != "" {
fmt.Printf("📄 页码: %s\n", apiResp.PNum)
}
} else {
fmt.Printf("❌ 失败: %s\n", apiResp.Error)
}
} else {
fmt.Printf("原始响应: %s\n", result)
// 如果是代理地址,可以进一步处理
if len(result) > 0 && (result[0:4] == "http" || result[0:3] == "socks") {
fmt.Printf("✅ 代理服务器地址获取成功\n")
fmt.Printf("🔗 代理地址: %s\n", result)
}
}
return count
}
// 专门处理代理配置响应的函数
func handleProxyResponse(result string, err error) {
fmt.Printf("\n代理配置测试:\n")
fmt.Println("=" + string(make([]byte, 50)) + "=")
if err != nil {
fmt.Printf("❌ 错误: %v\n", err)
return
}
// 代理配置通常返回代理服务器地址不是JSON格式
fmt.Printf("📡 代理服务器地址: %s\n", result)
fmt.Printf("✅ 代理配置获取成功\n")
// 如果需要,可以在这里进一步处理代理地址
// 例如验证代理格式、提取IP和端口等
if result != "" {
fmt.Printf("🔗 可用代理: %s\n", result)
}
}
// ProxyTypeManager 调用代理类型管理器
func (m *DLLManager) ProxyTypeManager(proxyType, username, password, machineCode string) (string, error) {
proc, err := m.dll.FindProc("ProxyTypeManager")
if err != nil {
return "", fmt.Errorf("找不到函数 ProxyTypeManager: %v", err)
}
// 准备参数
proxyTypePtr, _ := syscall.BytePtrFromString(proxyType)
usernamePtr, _ := syscall.BytePtrFromString(username)
passwordPtr, _ := syscall.BytePtrFromString(password)
machineCodePtr, _ := syscall.BytePtrFromString(machineCode)
// 调用函数
r1, _, err := proc.Call(
uintptr(unsafe.Pointer(proxyTypePtr)),
uintptr(unsafe.Pointer(usernamePtr)),
uintptr(unsafe.Pointer(passwordPtr)),
uintptr(unsafe.Pointer(machineCodePtr)),
)
if err != nil && err.Error() != "The operation completed successfully." {
return "", fmt.Errorf("调用 ProxyTypeManager 失败: %v", err)
}
// 转换结果
result := (*byte)(unsafe.Pointer(r1))
var resultBytes []byte
for i := 0; ; i++ {
bytePtr := (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(result)) + uintptr(i)))
if *bytePtr == 0 {
break
}
resultBytes = append(resultBytes, *bytePtr)
}
// 释放内存
freeProc, _ := m.dll.FindProc("FreeString")
if freeProc != nil {
freeProc.Call(r1)
}
return string(resultBytes), nil
}
// FreeCString 释放C字符串内存
func (m *DLLManager) FreeCString(strPtr uintptr) error {
proc, err := m.dll.FindProc("FreeCString")
if err != nil {
return fmt.Errorf("找不到函数 FreeCString: %v", err)
}
_, _, err = proc.Call(strPtr)
if err != nil && err.Error() != "The operation completed successfully." {
return fmt.Errorf("调用 FreeCString 失败: %v", err)
}
return nil
}
func handleGetKFZShopBookInfo(w http.ResponseWriter, r *http.Request) {
// 加载DLL
manager, err := NewDLLManager("dll/kongfz.dll")
if err != nil {
fmt.Printf("初始化DLL管理器失败: %v", err)
}
//defer manager.Close()
log.Println("✅ DLL加载成功")
// 使用默认配置初始化
config := createDefaultConfig()
initializeConfig(config)
configJSON, err := json.Marshal(config)
if err != nil {
fmt.Printf("序列化配置失败: %v", err)
}
result, err := manager.Initialize(string(configJSON))
if err != nil {
fmt.Printf("初始化失败: %v", err)
}
var initResp APIResponses
if err := json.Unmarshal([]byte(result), &initResp); err != nil {
fmt.Printf("解析初始化响应失败: %v", err)
}
if !initResp.Success {
fmt.Printf("初始化失败: %s", initResp.Message)
}
log.Println("✅ DLL初始化成功")
// 设置响应头
w.Header().Set("Content-Type", "application/json; charset=utf-8")
// 只支持GET请求
if r.Method != http.MethodGet {
sendErrorResponse(w, http.StatusMethodNotAllowed, "只支持GET方法")
return
}
//// 获取代理信息
//typeManager, err := manager.ProxyTypeManager("CALF_ELEPHANT_PROXY", "1297757178467602432", "QgQBvP7f", "")
//if err != nil {
// fmt.Printf(err.Error())
//}
//fmt.Println(typeManager)
//
//user, err := manager.OutLogin("18904056801", "Long6166@@")
//if err != nil {
// fmt.Printf(err.Error())
//}
//fmt.Println(user)
//
//var data APIResponse
//if err := json.Unmarshal([]byte(user), &data); err != nil {
// log.Printf("[ERROR] 解析第 %d 页失败: %v", data, err)
//}
//var token string
//// 从 Data 中提取 token
//if dataMap, ok := data.Data.(map[string]interface{}); ok {
// if tk, exists := dataMap["token"]; exists {
// fmt.Println("Token:", tk)
// token = tk.(string)
// // Token: d322c80960ab6722922912dd2ce219d4b4099d54
// } else {
// fmt.Println("Token 不存在")
// }
//} else {
// fmt.Println("Data 格式不正确")
//}
//fmt.Println(token)
//msg, err := manager.OutGetUserMsg(token)
//if err != nil {
// fmt.Printf(err.Error())
//}
//fmt.Println(msg)
//
//tplMsg, err := manager.OutGetGoodsTplMsg(token, "9142583516", "")
//if err != nil {
// fmt.Printf(err.Error())
//}
//fmt.Println("tplMsg: ", tplMsg)
//
//shop, err := manager.OutGetGoodsListMsgFromSelfShop("a0c75646dfefc23a9c387865d43197283192df0c", "",
// "", "", "", "", "", "allUnSold", 0, 1, 100)
//if err != nil {
// fmt.Printf(err.Error())
//}
//fmt.Println(shop)
// 获取孔网图片
fmt.Println("获取孔网图片")
isbnss, err := manager.OutGetImageByIsbn("81cc0e948433343309dcf3bfe100a802803934e5", "9787020106752", "", true, false)
if err != nil {
fmt.Printf(err.Error())
}
fmt.Println(isbnss)
var api struct {
Success bool `json:"success"`
Data *BookInfo `json:"data"`
}
err = json.Unmarshal([]byte(isbnss), &api)
if err != nil {
fmt.Printf(err.Error())
}
fmt.Println(api.Data.BookPic)
//// 获取cookie
//cookie, err := loginCookie()
//if err != nil {
// fmt.Printf(err.Error())
//}
//fmt.Println(cookie)
//account, err := getRandomAccount()
//if err != nil {
// fmt.Printf(err.Error())
//}
//fmt.Println(account)
//var isbns = []string{
// "9787500601593", "9787506331746", "9787020106752", "9787807089353", "9787536692930", "9787530221532", "9787544270878", "9787208061644", "9787506365437", "9787513708371", "9787513922135", "9787536693968", "9787541151736", "9787544213561", "9787544754781", "9787549204304", "9787108006639", "9787531764700", "9787544253994", "9787540456023", "9787540456429", "9787544267618", "9787544277723", "9787550008496", "9787806070680", "9787806801529", "9787807530244", "9787020008728", "9787020139590", "9787204055401", "9787500680239", "9787505724778", "9787506365680", "9787530221525", "9787536097261",
//}
//
//for _, isbn := range isbns {
// // 获取孔网图片
// isbnss, err := outGetImageByIsbn("", isbn, "", 0, 0)
// if err != nil {
// fmt.Printf(err.Error())
// }
// fmt.Println(isbnss)
//}
//books, num, pNum, err := outGetGoodsListMsgByShopId(3092,
// typeManager, true, "",
// "", 0, 14, 1, 5)
//msg, err := manager.OutGetTopGoodsListMsg(0, "")
//if err != nil {
//
//}
//fmt.Println(msg)
//fetchMode := r.URL.Query().Get("fetchMode")
//proxyType := r.URL.Query().Get("proxyType")
//username := r.URL.Query().Get("username")
//password := r.URL.Query().Get("password")
//machineCode := r.URL.Query().Get("machineCode")
//url := r.URL.Query().Get("url")
//shopId := r.URL.Query().Get("shopId") //https://shop.kongfz.com/793900/all/0_100_0_0_1_sort_desc_0_0/
//isImage := r.URL.Query().Get("isImage")
//bookNum := r.URL.Query().Get("bookNum")
//pageNum := r.URL.Query().Get("pageNum")
//sortType := r.URL.Query().Get("sortType")
//sort := r.URL.Query().Get("sort")
//priceDown := r.URL.Query().Get("priceDown")
//priceUp := r.URL.Query().Get("priceUp")
//details, err := manager.OutGetGoodsMsgByDetailUrl("https://book.kongfz.com/151391/6531924071/", "")
//if err != nil {
//
//}
//fmt.Println(details)
//id, err := manager.OutGetGoodsListMsgByShopId(1181761,
// "", true, "",
// "", 0, 0, 1, 5)
//if err != nil {
// fmt.Println(err)
//}
//fmt.Println(id)
//var pa ShopBookResult
//if err := json.Unmarshal([]byte(id), &pa); err != nil {
// log.Printf("[ERROR] 解析第 %d 页失败: %v", pa, err)
//}
//for _, urls := range pa.Data.Data {
// ss, err := proxyTypeManager("CALF_ELEPHANT_PROXY", "1297757178467602432", "QgQBvP7f", "")
// if err != nil {
// fmt.Printf(err.Error())
// }
// fmt.Println(ss)
// url, err := manager.OutGetGoodsMsgByDetailUrl(urls.DetailURL, ss)
// if err != nil {
// fmt.Println(err)
// }
// fmt.Println(url)
//}
//books, num, pNum, err := outGetGoodsListMsgByShopId(788247,
// typeManager, 1, 0, "",
// "", 0, 0, 1, 5)
//
//fmt.Println(books)
//fmt.Println(num)
//fmt.Println(pNum)
//fmt.Println(err)
//for _, book := range books {
// ss, err := proxyTypeManager("TAIL_PROXY", "", "", "07f4d0fbcff99966c2b37b0c1fb7f01c")
// if err != nil {
// fmt.Printf(err.Error())
// }
// fmt.Println(ss)
// url, err := outGetGoodsMsgByDetailUrl(book.DetailUrl, ss)
// if err != nil {
// fmt.Println(err)
// }
// fmt.Println(url)
//}
}
func manegiyoutGetGoodsListMsgFromSelfShop() {
}
// 发送错误响应
func sendErrorResponse(w http.ResponseWriter, statusCode int, message string) {
response := APIResp{
Success: false,
Message: message,
}
w.WriteHeader(statusCode)
json.NewEncoder(w).Encode(response)
}
type ShopBookResult struct {
Success bool `json:"success"`
Message string `json:"message"`
Data struct {
GoodsNum string `json:"goods_num"`
Pnum string `json:"pnum"`
Data []struct {
BookName string `json:"book_name"`
Author string `json:"author"`
Publisher string `json:"publisher"`
ISBN string `json:"isbn"`
PublishTime int64 `json:"publication_time"`
Edition string `json:"edition"`
PrintTime string `json:"print_time"`
FixPrice string `json:"fix_price"`
BindingLayout string `json:"binding_layout"`
Format string `json:"format"`
Paper string `json:"paper"`
Pages string `json:"pages"`
Wordage string `json:"wordage"`
Languages string `json:"languages"`
Era string `json:"era"`
EngravingMethod string `json:"engraving_method"`
Dimensions string `json:"dimensions"`
VolumeNumber string `json:"volume_number"`
BookPic string `json:"book_pic"`
BookPicS string `json:"book_pic_s"`
SellingPrice string `json:"selling_price"`
Condition string `json:"condition"`
ExpressDeliveryFee string `json:"express_delivery_fee"`
Editor string `json:"editor"`
Category string `json:"category"`
BuyCount string `json:"buy_count"`
SellCount string `json:"sell_count"`
Content string `json:"content"`
Mid int `json:"mid"`
ItemID int64 `json:"item_id"`
ShopID int `json:"shop_id"`
DetailURL string `json:"detail_url"`
} `json:"data"`
} `json:"data"`
}
func main() {
http.HandleFunc("/api/kfzShopBookInfo", handleGetKFZShopBookInfo)
port := "8989"
server := &http.Server{
Addr: ":" + port,
Handler: nil,
}
// 启动服务器
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("服务器启动失败: %v\n", err)
}
}