daShangDao_kfzgw-info/redis/redisDll.go
97694732@qq.com ac2a39742d 各种修改
2026-06-11 13:21:55 +08:00

335 lines
9.1 KiB
Go
Raw Permalink 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
import (
"encoding/json"
"fmt"
"log"
"strconv"
"strings"
"time"
)
// KfzVerifyPriceInfo 主结构体
type KfzVerifyPriceInfo struct {
Isbn string `json:"isbn"` // ISBN
OnSaleCount string `json:"onSaleCount"` // 在售数量
AvgPrice string `json:"avgPrice"` // 平均价格
LastPushTime string `json:"lastPushTime"` // 最后推送时间
Source string `json:"source"` // 来源
Data []BookItem `json:"data"` // 商品列表
}
// BookItem 商品项的具体结构
type BookItem struct {
Price string `json:"price"` // 价格 "17.01"
ShippingFee float64 `json:"shippingFee"` // 运费 0 或 5.8
Condition string `json:"condition"` // 品相 "八五品"
ImgBigUrl string `json:"imgBigUrl"` // 图片URL
ShopAvgShippingTime string `json:"shopAvgShippingTime"` // 平均发货时间 "10"
ShopSuccessOrderRate string `json:"shopSuccessOrderRate"` // 成功率 "90.03"
GoodsUrl string `json:"goodsUrl"` // 商品URL "575550/9643470711"
Title string `json:"title"` // 标题
GoodsImgCount int `json:"goodsImgCount"` // 图片数量 9
}
// ParseRedisData 解析Redis返回的数据
func ParseRedisData(redisData interface{}) (*KfzVerifyPriceInfo, error) {
// 将redisData转换为[]interface{}类型
data, ok := redisData.([]interface{})
if !ok {
return nil, fmt.Errorf("redis数据格式错误: 期望数组,得到 %T", redisData)
}
// 检查数组长度
if len(data) < 6 {
return nil, fmt.Errorf("redis数据格式错误: 数组长度不足期望至少6个元素实际 %d", len(data))
}
// 创建结果对象
result := &KfzVerifyPriceInfo{}
// 解析ISBN (索引0)
if isbn, ok := data[0].(string); ok {
result.Isbn = isbn
} else {
result.Isbn = fmt.Sprintf("%v", data[0])
}
// 解析在售数量 (索引2)
if onSaleCount, ok := data[2].(string); ok {
result.OnSaleCount = onSaleCount
} else {
result.OnSaleCount = fmt.Sprintf("%v", data[2])
}
// 解析平均价格 (索引3)
if avgPrice, ok := data[3].(string); ok {
result.AvgPrice = avgPrice
} else {
result.AvgPrice = fmt.Sprintf("%v", data[3])
}
// 解析最后推送时间 (索引4)
if lastPushTime, ok := data[4].(string); ok {
result.LastPushTime = lastPushTime
} else {
result.LastPushTime = fmt.Sprintf("%v", data[4])
}
// 解析来源 (索引5)
if source, ok := data[5].(string); ok {
result.Source = source
} else {
result.Source = fmt.Sprintf("%v", data[5])
}
// 解析商品列表 (索引1)
bookItems, err := parseBookItems(data[1])
if err != nil {
return nil, fmt.Errorf("解析商品列表失败: %v", err)
}
result.Data = bookItems
return result, nil
}
// parseBookItems 解析商品列表
func parseBookItems(items interface{}) ([]BookItem, error) {
// 将items转换为[]interface{}
itemList, ok := items.([]interface{})
if !ok {
return nil, fmt.Errorf("商品列表格式错误: 期望数组,得到 %T", items)
}
bookItems := make([]BookItem, 0, len(itemList))
for i, item := range itemList {
// 每个商品项应该是一个包含9个元素的数组
bookData, ok := item.([]interface{})
if !ok {
log.Printf("第%d个商品格式错误: 期望数组,得到 %T", i, item)
continue
}
if len(bookData) < 9 {
log.Printf("第%d个商品数据长度不足: 期望至少9个元素实际 %d", i, len(bookData))
continue
}
bookItem := BookItem{}
// 解析价格 (索引0)
if price, ok := bookData[0].(string); ok {
bookItem.Price = price
} else {
bookItem.Price = fmt.Sprintf("%v", bookData[0])
}
// 解析运费 (索引1)
switch v := bookData[1].(type) {
case float64:
bookItem.ShippingFee = v
case int:
bookItem.ShippingFee = float64(v)
case string:
if f, err := strconv.ParseFloat(v, 64); err == nil {
bookItem.ShippingFee = f
}
default:
bookItem.ShippingFee = 0
}
// 解析品相 (索引2)
if condition, ok := bookData[2].(string); ok {
bookItem.Condition = condition
} else {
bookItem.Condition = fmt.Sprintf("%v", bookData[2])
}
// 解析图片URL (索引3)
if imgUrl, ok := bookData[3].(string); ok {
bookItem.ImgBigUrl = imgUrl
} else {
bookItem.ImgBigUrl = fmt.Sprintf("%v", bookData[3])
}
// 解析平均发货时间 (索引4)
if shippingTime, ok := bookData[4].(string); ok {
bookItem.ShopAvgShippingTime = shippingTime
} else {
bookItem.ShopAvgShippingTime = fmt.Sprintf("%v", bookData[4])
}
// 解析成功率 (索引5)
if successRate, ok := bookData[5].(string); ok {
bookItem.ShopSuccessOrderRate = successRate
} else {
bookItem.ShopSuccessOrderRate = fmt.Sprintf("%v", bookData[5])
}
// 解析商品URL (索引6)
if goodsUrl, ok := bookData[6].(string); ok {
bookItem.GoodsUrl = goodsUrl
} else {
bookItem.GoodsUrl = fmt.Sprintf("%v", bookData[6])
}
// 解析标题 (索引7)
if title, ok := bookData[7].(string); ok {
bookItem.Title = title
} else {
bookItem.Title = fmt.Sprintf("%v", bookData[7])
}
// 解析图片数量 (索引8)
switch v := bookData[8].(type) {
case int:
bookItem.GoodsImgCount = v
case float64:
bookItem.GoodsImgCount = int(v)
case string:
if count, err := strconv.Atoi(v); err == nil {
bookItem.GoodsImgCount = count
}
default:
bookItem.GoodsImgCount = 0
}
bookItems = append(bookItems, bookItem)
}
return bookItems, nil
}
// GetValueFromDB1 当从DB2获取失败时从DB1的cp85hash中查找对应的key并加1
func GetValueFromDB1(redisClient *RedisClient, originalKey string) (string, error) {
// 提取ISBN号去掉"cp:"前缀)
isbn := strings.TrimPrefix(originalKey, "cp:")
// 切换到DB1
err := redisClient.SelectDB(1)
if err != nil {
return "", fmt.Errorf("切换到DB1失败: %v", err)
}
// 从cp85hash中获取对应的值
hashKey := "cp85"
value, err := redisClient.HGet(hashKey, isbn)
if err != nil {
return "", fmt.Errorf("从cp85hash获取数据失败: %v", err)
}
log.Println("cp85Isbn:", isbn, "value:", value)
// 将值转换为整数并加1
intValue, err := strconv.Atoi(value)
if err != nil {
return "", fmt.Errorf("值转换失败: %v", err)
}
newValue := intValue + 1
// 更新hash中的值
err = redisClient.HSet(hashKey, isbn, strconv.Itoa(newValue))
if err != nil {
return "", fmt.Errorf("更新cp85hash值失败: %v", err)
}
log.Printf("成功更新DB1中cp85hash的键 %s值从 %d 增加到 %d", isbn, intValue, newValue)
// 切换回DB2保持一致性
err = redisClient.SelectDB(2)
if err != nil {
log.Printf("切换回DB2失败: %v", err)
}
return "", nil
}
// 修改您的main函数
func main() {
// 自定义配置
config := &RedisConfig{
Addr: "36.212.20.113:7963",
Password: "j8nZ4jra2E",
DB: 2,
PoolSize: 20,
MinIdleConns: 10,
DialTimeout: 5 * time.Second,
ReadTimeout: 3 * time.Second,
WriteTimeout: 3 * time.Second,
PoolTimeout: 4 * time.Second,
}
// 使用自定义配置
redisClient := NewRedisClient(config)
defer redisClient.Close()
// 字符串操作示例
key := "cp:9787040110951"
// 获取字符串值
val, err := redisClient.Get(key)
if err != nil {
log.Printf("从DB2获取失败: %v", err)
// 尝试从DB1的cp85hash中查找并加1
newValue, db1Err := GetValueFromDB1(redisClient, key)
if db1Err != nil {
log.Printf("从DB1获取也失败: %v", db1Err)
return
}
fmt.Printf("从DB1的cp85hash中找到并更新值: %s\n", newValue)
return
}
fmt.Printf("键 %s 的原始值: %s\n", key, val)
// 由于Redis返回的是JSON字符串需要先解析
var redisData interface{}
err = json.Unmarshal([]byte(val), &redisData)
if err != nil {
log.Printf("JSON解析失败: %v", err)
return
}
// 解析为结构体
result, err := ParseRedisData(redisData)
if err != nil {
log.Printf("解析Redis数据失败: %v", err)
return
}
// 输出解析后的结构体
fmt.Println("\n=== 解析后的数据 ===")
fmt.Printf("ISBN: %s\n", result.Isbn)
fmt.Printf("在售数量: %s\n", result.OnSaleCount)
fmt.Printf("平均价格: %s\n", result.AvgPrice)
fmt.Printf("最后推送时间: %s\n", result.LastPushTime)
fmt.Printf("来源: %s\n", result.Source)
fmt.Printf("商品数量: %d\n", len(result.Data))
// 输出商品列表
for i, item := range result.Data {
fmt.Printf("\n--- 商品 %d ---\n", i+1)
fmt.Printf(" 价格: %s\n", item.Price)
fmt.Printf(" 运费: %.2f\n", item.ShippingFee)
fmt.Printf(" 品相: %s\n", item.Condition)
fmt.Printf(" 图片URL: %s\n", item.ImgBigUrl)
fmt.Printf(" 平均发货时间: %s\n", item.ShopAvgShippingTime)
fmt.Printf(" 成功率: %s\n", item.ShopSuccessOrderRate)
fmt.Printf(" 商品URL: %s\n", item.GoodsUrl)
fmt.Printf(" 标题: %s\n", item.Title)
fmt.Printf(" 图片数量: %d\n", item.GoodsImgCount)
}
// 如果需要转换为JSON
jsonResult, err := json.MarshalIndent(result, "", " ")
if err != nil {
log.Printf("JSON序列化失败: %v", err)
} else {
fmt.Println("\n=== JSON格式输出 ===")
fmt.Println(string(jsonResult))
}
}