first commit

This commit is contained in:
2025-09-21 18:27:25 +08:00
commit 02e1c4bd63
528 changed files with 55690 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
package admin_query
import (
"context"
"hm-server/app/main/api/internal/svc"
"hm-server/app/main/api/internal/types"
"hm-server/common/globalkey"
"hm-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminGetQueryCleanupConfigListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminGetQueryCleanupConfigListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetQueryCleanupConfigListLogic {
return &AdminGetQueryCleanupConfigListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminGetQueryCleanupConfigListLogic) AdminGetQueryCleanupConfigList(req *types.AdminGetQueryCleanupConfigListReq) (resp *types.AdminGetQueryCleanupConfigListResp, err error) {
// 构建查询条件
builder := l.svcCtx.QueryCleanupConfigModel.SelectBuilder().
Where("del_state = ?", globalkey.DelStateNo)
if req.Status > 0 {
builder = builder.Where("status = ?", req.Status)
}
// 查询配置列表
configs, err := l.svcCtx.QueryCleanupConfigModel.FindAll(l.ctx, builder, "id ASC")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理配置列表失败 err: %v", err)
}
// 构建响应
resp = &types.AdminGetQueryCleanupConfigListResp{
Items: make([]types.QueryCleanupConfigItem, 0, len(configs)),
}
for _, config := range configs {
item := types.QueryCleanupConfigItem{
Id: config.Id,
ConfigKey: config.ConfigKey,
ConfigValue: config.ConfigValue,
ConfigDesc: config.ConfigDesc,
Status: config.Status,
CreateTime: config.CreateTime.Format("2006-01-02 15:04:05"),
UpdateTime: config.UpdateTime.Format("2006-01-02 15:04:05"),
}
resp.Items = append(resp.Items, item)
}
return resp, nil
}

View File

@@ -0,0 +1,126 @@
package admin_query
import (
"context"
"sync"
"hm-server/app/main/api/internal/svc"
"hm-server/app/main/api/internal/types"
"hm-server/app/main/model"
"hm-server/common/globalkey"
"hm-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/mr"
)
type AdminGetQueryCleanupDetailListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminGetQueryCleanupDetailListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetQueryCleanupDetailListLogic {
return &AdminGetQueryCleanupDetailListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminGetQueryCleanupDetailListLogic) AdminGetQueryCleanupDetailList(req *types.AdminGetQueryCleanupDetailListReq) (resp *types.AdminGetQueryCleanupDetailListResp, err error) {
// 1. 验证清理日志是否存在
_, err = l.svcCtx.QueryCleanupLogModel.FindOne(l.ctx, req.LogId)
if err != nil {
if err == model.ErrNotFound {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "清理日志不存在, log_id: %d", req.LogId)
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理日志失败, log_id: %d, err: %v", req.LogId, err)
}
// 2. 构建查询条件
builder := l.svcCtx.QueryCleanupDetailModel.SelectBuilder().
Where("cleanup_log_id = ?", req.LogId).
Where("del_state = ?", globalkey.DelStateNo)
// 3. 并发获取总数和列表
var total int64
var details []*model.QueryCleanupDetail
err = mr.Finish(func() error {
var err error
total, err = l.svcCtx.QueryCleanupDetailModel.FindCount(l.ctx, builder, "id")
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理详情总数失败 err: %v", err)
}
return nil
}, func() error {
var err error
details, err = l.svcCtx.QueryCleanupDetailModel.FindPageListByPage(l.ctx, builder, req.Page, req.PageSize, "id DESC")
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理详情列表失败 err: %v", err)
}
return nil
})
if err != nil {
return nil, err
}
// 4. 获取所有产品ID
productIds := make([]int64, 0, len(details))
for _, detail := range details {
productIds = append(productIds, detail.ProductId)
}
// 5. 并发获取产品信息
productMap := make(map[int64]string)
var mu sync.Mutex
err = mr.MapReduceVoid(func(source chan<- interface{}) {
for _, productId := range productIds {
source <- productId
}
}, func(item interface{}, writer mr.Writer[struct{}], cancel func(error)) {
productId := item.(int64)
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, productId)
if err != nil && !errors.Is(err, model.ErrNotFound) {
cancel(errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询产品信息失败, product_id: %d, err: %v", productId, err))
return
}
mu.Lock()
if product != nil {
productMap[productId] = product.ProductName
} else {
productMap[productId] = "" // 产品不存在时设置为空字符串
}
mu.Unlock()
writer.Write(struct{}{})
}, func(pipe <-chan struct{}, cancel func(error)) {
for range pipe {
}
})
if err != nil {
return nil, err
}
// 6. 构建响应
resp = &types.AdminGetQueryCleanupDetailListResp{
Total: total,
Items: make([]types.QueryCleanupDetailItem, 0, len(details)),
}
for _, detail := range details {
item := types.QueryCleanupDetailItem{
Id: detail.Id,
CleanupLogId: detail.CleanupLogId,
QueryId: detail.QueryId,
OrderId: detail.OrderId,
UserId: detail.UserId,
ProductName: productMap[detail.ProductId],
QueryState: detail.QueryState,
CreateTimeOld: detail.CreateTimeOld.Format("2006-01-02 15:04:05"),
CreateTime: detail.CreateTime.Format("2006-01-02 15:04:05"),
}
resp.Items = append(resp.Items, item)
}
return resp, nil
}

View File

@@ -0,0 +1,88 @@
package admin_query
import (
"context"
"hm-server/app/main/api/internal/svc"
"hm-server/app/main/api/internal/types"
"hm-server/app/main/model"
"hm-server/common/globalkey"
"hm-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/mr"
)
type AdminGetQueryCleanupLogListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminGetQueryCleanupLogListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetQueryCleanupLogListLogic {
return &AdminGetQueryCleanupLogListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminGetQueryCleanupLogListLogic) AdminGetQueryCleanupLogList(req *types.AdminGetQueryCleanupLogListReq) (resp *types.AdminGetQueryCleanupLogListResp, err error) {
// 构建查询条件
builder := l.svcCtx.QueryCleanupLogModel.SelectBuilder().
Where("del_state = ?", globalkey.DelStateNo)
if req.Status > 0 {
builder = builder.Where("status = ?", req.Status)
}
if req.StartTime != "" {
builder = builder.Where("cleanup_time >= ?", req.StartTime)
}
if req.EndTime != "" {
builder = builder.Where("cleanup_time <= ?", req.EndTime)
}
// 并发获取总数和列表
var total int64
var logs []*model.QueryCleanupLog
err = mr.Finish(func() error {
var err error
total, err = l.svcCtx.QueryCleanupLogModel.FindCount(l.ctx, builder, "id")
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理日志总数失败 err: %v", err)
}
return nil
}, func() error {
var err error
logs, err = l.svcCtx.QueryCleanupLogModel.FindPageListByPage(l.ctx, builder, req.Page, req.PageSize, "id DESC")
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询清理日志列表失败 err: %v", err)
}
return nil
})
if err != nil {
return nil, err
}
// 构建响应
resp = &types.AdminGetQueryCleanupLogListResp{
Total: total,
Items: make([]types.QueryCleanupLogItem, 0, len(logs)),
}
for _, log := range logs {
item := types.QueryCleanupLogItem{
Id: log.Id,
CleanupTime: log.CleanupTime.Format("2006-01-02 15:04:05"),
CleanupBefore: log.CleanupBefore.Format("2006-01-02 15:04:05"),
Status: log.Status,
AffectedRows: log.AffectedRows,
ErrorMsg: log.ErrorMsg.String,
Remark: log.Remark.String,
CreateTime: log.CreateTime.Format("2006-01-02 15:04:05"),
}
resp.Items = append(resp.Items, item)
}
return resp, nil
}

View File

@@ -0,0 +1,189 @@
package admin_query
import (
"context"
"database/sql"
"encoding/hex"
"encoding/json"
"fmt"
"hm-server/app/main/api/internal/svc"
"hm-server/app/main/api/internal/types"
"hm-server/common/xerr"
"hm-server/pkg/lzkit/crypto"
"hm-server/pkg/lzkit/lzUtils"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminGetQueryDetailByOrderIdLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminGetQueryDetailByOrderIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetQueryDetailByOrderIdLogic {
return &AdminGetQueryDetailByOrderIdLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminGetQueryDetailByOrderIdLogic) AdminGetQueryDetailByOrderId(req *types.AdminGetQueryDetailByOrderIdReq) (resp *types.AdminGetQueryDetailByOrderIdResp, err error) {
// 获取报告信息
queryModel, err := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, req.OrderId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
}
var query types.AdminGetQueryDetailByOrderIdResp
query.CreateTime = queryModel.CreateTime.Format("2006-01-02 15:04:05")
query.UpdateTime = queryModel.UpdateTime.Format("2006-01-02 15:04:05")
// 解密查询数据
secretKey := l.svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %+v", err)
}
processParamsErr := ProcessQueryParams(queryModel.QueryParams, &query.QueryParams, key)
if processParamsErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告参数处理失败: %v", processParamsErr)
}
processErr := ProcessQueryData(queryModel.QueryData, &query.QueryData, key)
if processErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结果处理失败: %v", processErr)
}
updateFeatureAndProductFeatureErr := l.UpdateFeatureAndProductFeature(queryModel.ProductId, &query.QueryData)
if updateFeatureAndProductFeatureErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结果处理失败: %v", updateFeatureAndProductFeatureErr)
}
// 复制报告数据
err = copier.Copy(&query, queryModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结构体复制失败, %v", err)
}
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取商品信息失败, %v", err)
}
query.ProductName = product.ProductName
return &types.AdminGetQueryDetailByOrderIdResp{
Id: query.Id,
OrderId: query.OrderId,
UserId: query.UserId,
ProductName: query.ProductName,
QueryParams: query.QueryParams,
QueryData: query.QueryData,
CreateTime: query.CreateTime,
UpdateTime: query.UpdateTime,
QueryState: query.QueryState,
}, nil
}
// ProcessQueryData 解密和反序列化 QueryData
func ProcessQueryData(queryData sql.NullString, target *[]types.AdminQueryItem, key []byte) error {
queryDataStr := lzUtils.NullStringToString(queryData)
if queryDataStr == "" {
return nil
}
// 解密数据
decryptedData, decryptErr := crypto.AesDecrypt(queryDataStr, key)
if decryptErr != nil {
return decryptErr
}
// 解析 JSON 数组
var decryptedArray []map[string]interface{}
unmarshalErr := json.Unmarshal(decryptedData, &decryptedArray)
if unmarshalErr != nil {
return unmarshalErr
}
// 确保 target 具有正确的长度
if len(*target) == 0 {
*target = make([]types.AdminQueryItem, len(decryptedArray))
}
// 填充解密后的数据到 target
for i := 0; i < len(decryptedArray); i++ {
// 直接填充解密数据到 Data 字段
(*target)[i].Data = decryptedArray[i]
}
return nil
}
// ProcessQueryParams解密和反序列化 QueryParams
func ProcessQueryParams(QueryParams string, target *map[string]interface{}, key []byte) error {
// 解密 QueryParams
decryptedData, decryptErr := crypto.AesDecrypt(QueryParams, key)
if decryptErr != nil {
return decryptErr
}
// 反序列化解密后的数据
unmarshalErr := json.Unmarshal(decryptedData, target)
if unmarshalErr != nil {
return unmarshalErr
}
return nil
}
func (l *AdminGetQueryDetailByOrderIdLogic) UpdateFeatureAndProductFeature(productID int64, target *[]types.AdminQueryItem) error {
// 遍历 target 数组,使用倒序遍历,以便删除元素时不影响索引
for i := len(*target) - 1; i >= 0; i-- {
queryItem := &(*target)[i]
// 确保 Data 为 map 类型
data, ok := queryItem.Data.(map[string]interface{})
if !ok {
return fmt.Errorf("queryItem.Data 必须是 map[string]interface{} 类型")
}
// 从 Data 中获取 apiID
apiID, ok := data["apiID"].(string)
if !ok {
return fmt.Errorf("queryItem.Data 中的 apiID 必须是字符串类型")
}
// 查询 Feature
feature, err := l.svcCtx.FeatureModel.FindOneByApiId(l.ctx, apiID)
if err != nil {
// 如果 Feature 查不到,也要删除当前 QueryItem
*target = append((*target)[:i], (*target)[i+1:]...)
continue
}
// 查询 ProductFeatureModel
builder := l.svcCtx.ProductFeatureModel.SelectBuilder().Where("product_id = ?", productID)
productFeatures, err := l.svcCtx.ProductFeatureModel.FindAll(l.ctx, builder, "")
if err != nil {
return fmt.Errorf("查询 ProductFeatureModel 错误: %v", err)
}
// 遍历 productFeatures找到与 feature.ID 关联且 enable == 1 的项
var featureData map[string]interface{}
sort := 0
for _, pf := range productFeatures {
if pf.FeatureId == feature.Id { // 确保和 Feature 关联
sort = int(pf.Sort)
break // 找到第一个符合条件的就退出循环
}
}
featureData = map[string]interface{}{
"featureName": feature.Name,
"sort": sort,
}
// 更新 queryItem 的 Feature 字段(不是数组)
queryItem.Feature = featureData
}
return nil
}

View File

@@ -0,0 +1,63 @@
package admin_query
import (
"context"
"time"
"hm-server/app/main/api/internal/svc"
"hm-server/app/main/api/internal/types"
"hm-server/app/main/model"
"hm-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
type AdminUpdateQueryCleanupConfigLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminUpdateQueryCleanupConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminUpdateQueryCleanupConfigLogic {
return &AdminUpdateQueryCleanupConfigLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminUpdateQueryCleanupConfigLogic) AdminUpdateQueryCleanupConfig(req *types.AdminUpdateQueryCleanupConfigReq) (resp *types.AdminUpdateQueryCleanupConfigResp, err error) {
// 使用事务处理更新操作
err = l.svcCtx.QueryCleanupConfigModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 1. 查询配置是否存在
config, err := l.svcCtx.QueryCleanupConfigModel.FindOne(ctx, req.Id)
if err != nil {
if err == model.ErrNotFound {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "配置不存在, id: %d", req.Id)
}
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询配置失败, id: %d, err: %v", req.Id, err)
}
// 2. 更新配置
config.ConfigValue = req.ConfigValue
config.Status = req.Status
config.UpdateTime = time.Now()
_, err = l.svcCtx.QueryCleanupConfigModel.Update(ctx, session, config)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新配置失败, id: %d, err: %v", req.Id, err)
}
return nil
})
if err != nil {
return nil, err
}
return &types.AdminUpdateQueryCleanupConfigResp{
Success: true,
}, nil
}