Files
sim-server/app/main/api/internal/logic/query/queryexamplelogic.go
2026-02-09 14:23:18 +08:00

166 lines
5.5 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 query
import (
"context"
"encoding/hex"
"encoding/json"
"sim-server/app/main/api/internal/svc"
"sim-server/app/main/api/internal/types"
"sim-server/common/xerr"
"sim-server/pkg/lzkit/crypto"
"strings"
"github.com/bytedance/sonic"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
// comboExampleDataItem 组合包示例 Content 解密后的单条结构,与 APIResponseData 一致,便于按模块展开
type comboExampleDataItem struct {
ApiID string `json:"apiID"`
Data json.RawMessage `json:"data"`
Success bool `json:"success"`
Timestamp string `json:"timestamp"`
}
type QueryExampleLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewQueryExampleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryExampleLogic {
return &QueryExampleLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp string, err error) {
// 根据产品特性标识获取产品信息
product, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, req.Feature)
if err != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 获取商品信息失败, %v", err)
}
secretKeyHex := l.svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKeyHex)
if decodeErr != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 解析AES密钥失败, %v", decodeErr)
}
// 创建一个空的Query结构体来存储结果
query := types.Query{
Product: product.ProductEn,
ProductName: product.ProductName,
QueryData: make([]types.QueryItem, 0),
QueryParams: make(map[string]interface{}),
}
query.QueryParams = map[string]interface{}{
"id_card": "45000000000000000",
"mobile": "13700000000",
"name": "张老三",
}
// 查询ProductFeatureModel获取产品相关的功能列表
builder := l.svcCtx.ProductFeatureModel.SelectBuilder().Where("product_id = ?", product.Id)
productFeatures, err := l.svcCtx.ProductFeatureModel.FindAll(l.ctx, builder, "")
if err != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 查询 ProductFeatureModel 错误: %v", err)
}
// 从每个启用的特性获取示例数据并合并
for _, pf := range productFeatures {
if pf.Enable != 1 {
continue // 跳过未启用的特性
}
// 根据特性ID查找示例数据
example, err := l.svcCtx.ExampleModel.FindOneByFeatureId(l.ctx, pf.FeatureId)
if err != nil {
logx.Infof("示例报告, 特性ID %s 无示例数据: %v", pf.FeatureId, err)
continue // 如果没有示例数据就跳过
}
// 获取对应的Feature信息
feature, err := l.svcCtx.FeatureModel.FindOne(l.ctx, pf.FeatureId)
if err != nil {
logx.Infof("示例报告, 无法获取特性ID %s 的信息: %v", pf.FeatureId, err)
continue
}
// 组合包api_id 前四位为 COMB示例 Content 为多条 APIResponseData 的 JSON 数组,按子模块展开为多个 Tab
if strings.HasPrefix(feature.ApiId, "COMB") {
if example.Content == "000" {
continue
}
decryptedData, decryptErr := crypto.AesDecrypt(example.Content, key)
if decryptErr != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 组合包解密失败: %v", decryptErr)
}
var comboItems []comboExampleDataItem
if err := sonic.Unmarshal([]byte(decryptedData), &comboItems); err != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 组合包示例解析失败: %v", err)
}
for i, item := range comboItems {
subFeature, subErr := l.svcCtx.FeatureModel.FindOneByApiId(l.ctx, item.ApiID)
featureName := item.ApiID
if subErr == nil && subFeature != nil {
featureName = subFeature.Name
}
query.QueryData = append(query.QueryData, types.QueryItem{
Feature: map[string]interface{}{
"featureName": featureName,
"sort": pf.Sort*1000 + int64(i), // 保持组合包整体顺序,子项按索引排
},
Data: map[string]interface{}{
"apiID": item.ApiID,
"data": item.Data,
"success": item.Success,
"timestamp": item.Timestamp,
},
})
}
continue
}
var queryItem types.QueryItem
// 解密查询数据
// 解析示例内容
if example.Content == "000" {
queryItem.Data = example.Content
} else {
// 解密数据
decryptedData, decryptErr := crypto.AesDecrypt(example.Content, key)
if decryptErr != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 解密数据失败: %v", decryptErr)
}
err = sonic.Unmarshal([]byte(decryptedData), &queryItem.Data)
if err != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 解析示例内容失败: %v", err)
}
}
// 添加特性信息
queryItem.Feature = map[string]interface{}{
"featureName": feature.Name,
"sort": pf.Sort,
}
// 添加到查询数据中
query.QueryData = append(query.QueryData, queryItem)
}
queryBytes, marshalErr := sonic.Marshal(query)
if marshalErr != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 序列化查询结果失败: %v", marshalErr)
}
encryptedQuery, encryptErr := crypto.AesEncrypt(queryBytes, key)
if encryptErr != nil {
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 加密查询结果失败: %v", encryptErr)
}
return encryptedQuery, nil
}