下架白名单补充支付回调删除数据以及后台运维补充删除

This commit is contained in:
2026-03-16 14:37:35 +08:00
parent a63e4a9dbb
commit 0b87a39c41
10 changed files with 142 additions and 21 deletions

View File

@@ -28,6 +28,10 @@ service main {
@handler AdminGetQueryCleanupConfigList
get /cleanup/configs (AdminGetQueryCleanupConfigListReq) returns (AdminGetQueryCleanupConfigListResp)
@doc "按 QueryId+FeatureApiId 补删单条查询的某个模块数据(仅内部运维使用)"
@handler AdminDeleteQueryFeatureData
post /cleanup/delete/feature (AdminDeleteQueryFeatureDataReq) returns (AdminDeleteQueryFeatureDataResp)
@doc "更新清理配置"
@handler AdminUpdateQueryCleanupConfig
put /cleanup/config (AdminUpdateQueryCleanupConfigReq) returns (AdminUpdateQueryCleanupConfigResp)
@@ -131,3 +135,14 @@ type AdminGetQueryCleanupConfigListResp {
type AdminUpdateQueryCleanupConfigResp {
Success bool `json:"success"` // 是否成功
}
// 运维补删接口:按 QueryId+FeatureApiId 删除单条查询中的指定模块数据
type AdminDeleteQueryFeatureDataReq {
QueryId string `json:"query_id"` // 查询IDQuery表ID
FeatureApiId string `json:"feature_api_id"` // 模块API标识与前台 OfflineFeature 一致)
}
type AdminDeleteQueryFeatureDataResp {
Success bool `json:"success"` // 是否删除成功(或数据本就不存在)
Message string `json:"message"` // 结果说明
}

View File

@@ -288,7 +288,7 @@ service main {
@handler CheckFeatureWhitelistStatus
get /whitelist/check (CheckFeatureWhitelistStatusReq) returns (CheckFeatureWhitelistStatusResp)
// 下架单个模块(创建订单并支付
// 下架单个模块(统一入口:创建/补充白名单并根据 QueryId 删除本次报告中的模块数据
@handler OfflineFeature
post /whitelist/offline (OfflineFeatureReq) returns (OfflineFeatureResp)

View File

@@ -0,0 +1,29 @@
package admin_query
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"ycc-server/app/main/api/internal/logic/admin_query"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/common/result"
"ycc-server/pkg/lzkit/validator"
)
func AdminDeleteQueryFeatureDataHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.AdminDeleteQueryFeatureDataReq
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r, w, err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
l := admin_query.NewAdminDeleteQueryFeatureDataLogic(r.Context(), svcCtx)
resp, err := l.AdminDeleteQueryFeatureData(&req)
result.HttpResult(r, w, resp, err)
}
}

View File

@@ -490,6 +490,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/cleanup/configs",
Handler: admin_query.AdminGetQueryCleanupConfigListHandler(serverCtx),
},
{
// 按 QueryId+FeatureApiId 补删单条查询的某个模块数据(仅内部运维使用)
Method: http.MethodPost,
Path: "/cleanup/delete/feature",
Handler: admin_query.AdminDeleteQueryFeatureDataHandler(serverCtx),
},
{
// 获取清理详情列表
Method: http.MethodGet,

View File

@@ -0,0 +1,30 @@
package admin_query
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminDeleteQueryFeatureDataLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminDeleteQueryFeatureDataLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminDeleteQueryFeatureDataLogic {
return &AdminDeleteQueryFeatureDataLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminDeleteQueryFeatureDataLogic) AdminDeleteQueryFeatureData(req *types.AdminDeleteQueryFeatureDataReq) (resp *types.AdminDeleteQueryFeatureDataResp, err error) {
// todo: add your logic here and delete this line
return
}

View File

@@ -6,6 +6,7 @@ import (
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/lzUtils"
"github.com/google/uuid"
"github.com/pkg/errors"
@@ -123,6 +124,7 @@ func (l *CreateWhitelistOrderLogic) CreateWhitelistOrder(req *types.CreateWhitel
Id: uuid.NewString(),
OrderNo: orderNo,
UserId: userID,
OrderId: lzUtils.StringToNullString(req.OrderId), // 关联的查询订单ID可选用于后续支付回调精确删除报告
IdCard: req.IdCard,
TotalAmount: totalAmount,
Status: 1, // 待支付

View File

@@ -71,6 +71,8 @@ func (s *WhitelistService) EnsureFreeWhitelist(
}
}
// 约定OrderId 字段在白名单表中用于记录“触发本次白名单的查询记录IDQueryId
// 这里的 orderId 即为 OfflineFeature 请求中传入的 QueryId
wl := &model.UserFeatureWhitelist{
Id: uuid.NewString(),
IdCard: idCard,
@@ -198,6 +200,8 @@ func (s *WhitelistService) ProcessOfflineFeature(
}
// 3. 检查是否已有白名单
// 约定:只要调用 OfflineFeature下架成功包含“之前已存在白名单”的情况都应删除“当前这一次查询”的报告数据
// 因此,对于“已存在生效白名单”的场景,这里依然返回 whitelistCreated = true触发上层 OfflineFeatureLogic 删除本次 QueryId 的模块数据
exists, err := s.CheckWhitelistExists(ctx, idCard, feature.Id)
if err != nil {
return false, 0, false, err
@@ -297,6 +301,8 @@ func (s *WhitelistService) createWhitelistFromPaidOrder(
paidOrderId string,
price float64,
) error {
// 约定OrderId 字段在白名单表中用于记录“触发本次白名单的查询记录IDQueryId
// 这里的 orderId 即为 OfflineFeature 请求中传入的 QueryId
wl := &model.UserFeatureWhitelist{
Id: uuid.NewString(),
IdCard: idCard,
@@ -517,7 +523,7 @@ func (s *WhitelistService) CheckQueryDataContainsFeature(
return false, nil
}
// ProcessPaidWhitelistOrder 处理已支付的白名单订单:创建白名单记录并删除报告数据
// ProcessPaidWhitelistOrder 处理已支付的白名单订单:创建白名单记录,并在可精确定位时删除对应报告数据
// order: 支付订单Order表
// whitelistOrder: 白名单订单WhitelistOrder表
func (s *WhitelistService) ProcessPaidWhitelistOrder(
@@ -539,8 +545,31 @@ func (s *WhitelistService) ProcessPaidWhitelistOrder(
return errors.Wrap(err, "查询白名单订单明细失败")
}
// 为每个明细创建白名单记录并删除报告数据
// 为每个明细创建白名单记录,并在能够精确定位 Query 时删除对应报告数据
for _, item := range items {
var queryId string
// 如果白名单订单绑定了查询订单IDorder_id尝试通过 Query.order_id 精确找到对应的查询记录
if whitelistOrder.OrderId.Valid && whitelistOrder.OrderId.String != "" {
queryModel, qErr := s.QueryModel.FindOneByOrderId(ctx, whitelistOrder.OrderId.String)
if qErr != nil {
if errors.Is(qErr, model.ErrNotFound) {
logx.Infof("白名单订单支付成功:订单 %s 绑定的查询订单 %s 未找到对应查询记录,跳过报告删除", whitelistOrder.OrderNo, whitelistOrder.OrderId.String)
} else {
return errors.Wrap(qErr, "根据白名单订单的查询订单ID查找查询记录失败")
}
} else {
queryId = queryModel.Id
// 精确删除该查询下当前模块的数据
if delErr := s.DeleteFeatureFromQueryData(ctx, session, queryId, item.FeatureApiId); delErr != nil {
// 删除报告数据失败不影响白名单记录创建,只记录错误日志
logx.Errorf("白名单订单支付后删除报告数据失败:查询记录 %s模块 %s错误%v", queryId, item.FeatureApiId, delErr)
} else {
logx.Infof("白名单订单支付后删除报告数据成功:查询记录 %s模块 %s", queryId, item.FeatureApiId)
}
}
}
// 创建白名单记录
wl := &model.UserFeatureWhitelist{
Id: uuid.NewString(),
@@ -548,7 +577,9 @@ func (s *WhitelistService) ProcessPaidWhitelistOrder(
FeatureId: item.FeatureId,
FeatureApiId: item.FeatureApiId,
UserId: whitelistOrder.UserId,
OrderId: lzUtils.StringToNullString(""), // 查询订单ID如果有的话会在后续步骤中设置
// 约定UserFeatureWhitelist.OrderId 记录触发本次白名单的查询记录IDQueryId
// 对于支付回调场景,如果成功通过 order_id 找到 Query则将 QueryId 回写到白名单记录中,便于后续审计
OrderId: lzUtils.StringToNullString(queryId),
WhitelistOrderId: lzUtils.StringToNullString(whitelistOrder.Id),
Amount: item.Price,
Status: 1, // 生效
@@ -556,13 +587,10 @@ func (s *WhitelistService) ProcessPaidWhitelistOrder(
if _, err := s.UserFeatureWhitelistModel.Insert(ctx, session, wl); err != nil {
return errors.Wrap(err, "创建白名单记录失败")
}
// 尝试删除报告数据
// 注意由于支付回调时可能不知道具体的查询订单ID这里先尝试根据 id_card 查找
// 如果找不到对应的报告,就跳过删除步骤(不影响主流程)
// 实际的报告数据删除应该在 OfflineFeature 接口中完成(如果提供了 orderId
// 这里暂时不删除,因为无法确定是哪个具体的查询订单
logx.Infof("白名单订单支付成功:订单 %s模块 %s已创建白名单记录。如需删除报告数据请在 OfflineFeature 接口中提供查询订单ID", whitelistOrder.OrderNo, item.FeatureApiId)
// 如果无法通过 order_id 找到 Query仅创建白名单记录不删除任何报告数据避免误删历史记录
if !whitelistOrder.OrderId.Valid || whitelistOrder.OrderId.String == "" || queryId == "" {
logx.Infof("白名单订单支付成功:订单 %s模块 %s已创建白名单记录。由于缺少可用的查询订单ID或对应查询记录未删除任何报告数据", whitelistOrder.OrderNo, item.FeatureApiId)
}
}
return nil

View File

@@ -212,6 +212,16 @@ type AdminDeleteProductResp struct {
Success bool `json:"success"` // 是否成功
}
type AdminDeleteQueryFeatureDataReq struct {
QueryId string `json:"query_id"` // 查询IDQuery表ID
FeatureApiId string `json:"feature_api_id"` // 模块API标识与前台 OfflineFeature 一致)
}
type AdminDeleteQueryFeatureDataResp struct {
Success bool `json:"success"` // 是否删除成功(或数据本就不存在)
Message string `json:"message"` // 结果说明
}
type AdminDeleteUserReq struct {
Id string `path:"id"` // 用户ID
}
@@ -2040,8 +2050,8 @@ type ProductListItem struct {
ProductEn string `json:"product_en"` // 英文名
Description string `json:"description"` // 描述
Notes string `json:"notes"` // 备注
CostPrice float64 `json:"cost_price"` // 成本价(由功能成本累加得出)
SellPrice float64 `json:"sell_price"` // 售价
CostPrice float64 `json:"cost_price"` // 成本价(由功能成本累加得出)
CreateTime string `json:"create_time"` // 创建时间
UpdateTime string `json:"update_time"` // 更新时间
}