This commit is contained in:
2026-06-20 15:13:58 +08:00
parent 6c4029e645
commit 8ccd20f69e
24 changed files with 526 additions and 888 deletions

View File

@@ -2,10 +2,17 @@ package admin_query
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"strings"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/xerr"
"ycc-server/pkg/lzkit/crypto"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
@@ -27,7 +34,6 @@ func NewAdminDeleteQueryFeatureDataLogic(ctx context.Context, svcCtx *svc.Servic
}
func (l *AdminDeleteQueryFeatureDataLogic) AdminDeleteQueryFeatureData(req *types.AdminDeleteQueryFeatureDataReq) (resp *types.AdminDeleteQueryFeatureDataResp, err error) {
// 基本参数校验
if req.QueryId == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("QueryId 不能为空"), "")
}
@@ -35,8 +41,56 @@ func (l *AdminDeleteQueryFeatureDataLogic) AdminDeleteQueryFeatureData(req *type
return nil, errors.Wrapf(xerr.NewErrMsg("feature_api_id 不能为空"), "")
}
// 使用事务调用 WhitelistService.DeleteFeatureFromQueryData保持与其它删除逻辑一致
queryModel, err := l.svcCtx.QueryModel.FindOne(l.ctx, req.QueryId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("查询记录不存在"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询报告记录失败, %v", err)
}
queryParams, err := decryptQueryParams(l.svcCtx, queryModel)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取查询参数失败, %v", err)
}
idCard, _ := queryParams["id_card"].(string)
if idCard == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("查询参数中缺少身份证号,无法添加白名单"), "")
}
name, _ := queryParams["name"].(string)
if strings.TrimSpace(name) == "" {
name = "*"
}
adminUserID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取管理员信息失败, %v", err)
}
mainApiId := extractMainApiId(req.FeatureApiId)
feature, err := l.svcCtx.FeatureModel.FindOneByApiId(l.ctx, mainApiId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("模块不存在"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询模块信息失败, %v", err)
}
remark := fmt.Sprintf("后台删除报告模块自动同步 query_id=%s feature=%s", req.QueryId, feature.ApiId)
l.svcCtx.QueryWhitelistSyncService.TrySync(
l.ctx,
name,
idCard,
[]string{feature.ApiId},
remark,
)
err = l.svcCtx.QueryModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
if wlErr := l.svcCtx.WhitelistService.EnsureFreeWhitelist(ctx, session, idCard, feature, adminUserID, req.QueryId); wlErr != nil {
return wlErr
}
return l.svcCtx.WhitelistService.DeleteFeatureFromQueryData(ctx, session, req.QueryId, req.FeatureApiId)
})
if err != nil {
@@ -46,6 +100,37 @@ func (l *AdminDeleteQueryFeatureDataLogic) AdminDeleteQueryFeatureData(req *type
return &types.AdminDeleteQueryFeatureDataResp{
Success: true,
Message: "删除成功(如果原本不存在该模块数据,则视为已删除)",
Message: "删除成功,已同步本地白名单并尽力同步天远查询白名单(若原本不存在该模块数据,则视为已删除)",
}, nil
}
func extractMainApiId(featureApiId string) string {
if idx := strings.Index(featureApiId, "_"); idx > 0 {
return featureApiId[:idx]
}
return featureApiId
}
func decryptQueryParams(svcCtx *svc.ServiceContext, queryModel *model.Query) (map[string]interface{}, error) {
if queryModel.QueryParams == "" {
return nil, errors.New("查询参数为空")
}
secretKey := svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return nil, errors.Wrap(decodeErr, "获取AES密钥失败")
}
decryptedParams, decryptErr := crypto.AesDecrypt(queryModel.QueryParams, key)
if decryptErr != nil {
return nil, errors.Wrap(decryptErr, "解密查询参数失败")
}
var params map[string]interface{}
if unmarshalErr := json.Unmarshal(decryptedParams, &params); unmarshalErr != nil {
return nil, errors.Wrap(unmarshalErr, "解析查询参数失败")
}
return params, nil
}

View File

@@ -53,6 +53,17 @@ func buildQueryWhitelistPayload(name, idCard string, apiCodes []string, remark s
return payload
}
// SyncQueryWhitelistToTianyuan 将产品编码同步到天远查询白名单(先追加,规则不存在则创建)
func SyncQueryWhitelistToTianyuan(
ctx context.Context,
svcCtx *svc.ServiceContext,
name, idCard string,
apiCodes []string,
remark string,
) error {
return svcCtx.QueryWhitelistSyncService.Sync(ctx, name, idCard, apiCodes, remark)
}
func callQueryWhitelistMgmt(
svcCtx *svc.ServiceContext,
apiPath string,

View File

@@ -1,99 +0,0 @@
package admin_whitelist
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminBatchCreateWhitelistLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminBatchCreateWhitelistLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminBatchCreateWhitelistLogic {
return &AdminBatchCreateWhitelistLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminBatchCreateWhitelistLogic) AdminBatchCreateWhitelist(req *types.AdminBatchCreateWhitelistReq) (resp *types.AdminBatchCreateWhitelistResp, err error) {
if req.IdCard == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("身份证号不能为空"), "")
}
if len(req.FeatureIds) == 0 {
return nil, errors.Wrapf(xerr.NewErrMsg("请至少选择一个模块"), "")
}
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取管理员信息失败, %v", err)
}
amount := 0.0
if req.Amount != nil {
amount = *req.Amount
}
status, err := parseWhitelistStatus(req.Status)
if err != nil {
return nil, err
}
resp = &types.AdminBatchCreateWhitelistResp{
Items: make([]types.AdminBatchCreateWhitelistResultItem, 0, len(req.FeatureIds)),
}
for _, featureId := range req.FeatureIds {
item := types.AdminBatchCreateWhitelistResultItem{
FeatureId: featureId,
}
feature, findErr := l.svcCtx.FeatureModel.FindOne(l.ctx, featureId)
if findErr != nil {
if errors.Is(findErr, model.ErrNotFound) {
item.Action = "failed"
item.Message = "模块不存在"
resp.FailCount++
} else {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询模块失败, %v", findErr)
}
resp.Items = append(resp.Items, item)
continue
}
result, createErr := createOrReactivateWhitelist(l.ctx, l.svcCtx, userID, req.IdCard, feature, amount, status)
if createErr != nil {
item.FeatureApiId = feature.ApiId
item.FeatureName = feature.Name
item.Action = "failed"
item.Message = createErr.Error()
resp.FailCount++
resp.Items = append(resp.Items, item)
continue
}
item.FeatureApiId = result.FeatureApiId
item.FeatureName = result.FeatureName
item.Action = result.Action
item.Message = result.Message
switch result.Action {
case whitelistActionSkipped:
resp.SkipCount++
case whitelistActionCreated, whitelistActionReactivated:
resp.SuccessCount++
}
resp.Items = append(resp.Items, item)
}
return resp, nil
}

View File

@@ -1,69 +0,0 @@
package admin_whitelist
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminCreateWhitelistLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminCreateWhitelistLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminCreateWhitelistLogic {
return &AdminCreateWhitelistLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminCreateWhitelistLogic) AdminCreateWhitelist(req *types.AdminCreateWhitelistReq) (resp *types.AdminCreateWhitelistResp, err error) {
if req.IdCard == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("身份证号不能为空"), "")
}
if req.FeatureId == "" {
return nil, errors.Wrapf(xerr.NewErrMsg("模块不能为空"), "")
}
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取管理员信息失败, %v", err)
}
feature, err := l.svcCtx.FeatureModel.FindOne(l.ctx, req.FeatureId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("模块不存在"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询模块失败, %v", err)
}
amount := 0.0
if req.Amount != nil {
amount = *req.Amount
}
status, err := parseWhitelistStatus(req.Status)
if err != nil {
return nil, err
}
result, err := createOrReactivateWhitelist(l.ctx, l.svcCtx, userID, req.IdCard, feature, amount, status)
if err != nil {
return nil, err
}
if result.Action == whitelistActionSkipped {
return nil, errors.Wrapf(xerr.NewErrMsg("该身份证号已存在生效的白名单记录"), "")
}
return &types.AdminCreateWhitelistResp{Id: result.Id}, nil
}

View File

@@ -1,43 +0,0 @@
package admin_whitelist
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminDeleteWhitelistLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminDeleteWhitelistLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminDeleteWhitelistLogic {
return &AdminDeleteWhitelistLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminDeleteWhitelistLogic) AdminDeleteWhitelist(req *types.AdminDeleteWhitelistReq) (resp *types.AdminDeleteWhitelistResp, err error) {
record, err := l.svcCtx.UserFeatureWhitelistModel.FindOne(l.ctx, req.Id)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("白名单记录不存在"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询白名单记录失败, %v", err)
}
if err = l.svcCtx.UserFeatureWhitelistModel.DeleteSoft(l.ctx, nil, record); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "删除白名单记录失败, %v", err)
}
return &types.AdminDeleteWhitelistResp{Success: true}, nil
}

View File

@@ -1,111 +0,0 @@
package admin_whitelist
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/Masterminds/squirrel"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminGetWhitelistListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminGetWhitelistListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetWhitelistListLogic {
return &AdminGetWhitelistListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminGetWhitelistListLogic) AdminGetWhitelistList(req *types.AdminGetWhitelistListReq) (resp *types.AdminGetWhitelistListResp, err error) {
builder := l.svcCtx.UserFeatureWhitelistModel.SelectBuilder()
if req.IdCard != nil && *req.IdCard != "" {
builder = builder.Where("id_card LIKE ?", "%"+*req.IdCard+"%")
}
if req.FeatureApiId != nil && *req.FeatureApiId != "" {
builder = builder.Where("feature_api_id LIKE ?", "%"+*req.FeatureApiId+"%")
}
if req.Status != nil {
builder = builder.Where("status = ?", *req.Status)
}
total, err := l.svcCtx.UserFeatureWhitelistModel.FindCount(l.ctx, builder, "id")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询白名单总数失败, %v", err)
}
list, err := l.svcCtx.UserFeatureWhitelistModel.FindPageListByPage(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询白名单列表失败, %v", err)
}
featureNameMap := l.buildFeatureNameMap(list)
items := make([]types.AdminWhitelistListItem, 0, len(list))
for _, w := range list {
items = append(items, types.AdminWhitelistListItem{
Id: w.Id,
IdCard: w.IdCard,
FeatureId: w.FeatureId,
FeatureApiId: w.FeatureApiId,
FeatureName: featureNameMap[w.FeatureId],
UserId: w.UserId,
Amount: w.Amount,
Status: w.Status,
StatusText: whitelistStatusText(w.Status),
CreateTime: w.CreateTime.Format("2006-01-02 15:04:05"),
UpdateTime: w.UpdateTime.Format("2006-01-02 15:04:05"),
})
}
return &types.AdminGetWhitelistListResp{
Total: total,
Items: items,
}, nil
}
func (l *AdminGetWhitelistListLogic) buildFeatureNameMap(list []*model.UserFeatureWhitelist) map[string]string {
featureNameMap := make(map[string]string)
if len(list) == 0 {
return featureNameMap
}
featureIds := make([]string, 0, len(list))
seen := make(map[string]struct{}, len(list))
for _, w := range list {
if _, ok := seen[w.FeatureId]; ok {
continue
}
seen[w.FeatureId] = struct{}{}
featureIds = append(featureIds, w.FeatureId)
}
featureBuilder := l.svcCtx.FeatureModel.SelectBuilder().Where(squirrel.Eq{"id": featureIds})
features, err := l.svcCtx.FeatureModel.FindAll(l.ctx, featureBuilder, "")
if err != nil {
l.Errorf("批量查询模块名称失败: %v", err)
return featureNameMap
}
for _, f := range features {
featureNameMap[f.Id] = f.Name
}
return featureNameMap
}
func whitelistStatusText(status int64) string {
if status == 1 {
return "生效"
}
return "已失效"
}

View File

@@ -1,57 +0,0 @@
package admin_whitelist
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminUpdateWhitelistLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminUpdateWhitelistLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminUpdateWhitelistLogic {
return &AdminUpdateWhitelistLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminUpdateWhitelistLogic) AdminUpdateWhitelist(req *types.AdminUpdateWhitelistReq) (resp *types.AdminUpdateWhitelistResp, err error) {
if req.Status == nil && req.Amount == nil {
return nil, errors.Wrapf(xerr.NewErrMsg("请至少提供一个更新字段"), "")
}
record, err := l.svcCtx.UserFeatureWhitelistModel.FindOne(l.ctx, req.Id)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("白名单记录不存在"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询白名单记录失败, %v", err)
}
if req.Status != nil {
if *req.Status != 1 && *req.Status != 2 {
return nil, errors.Wrapf(xerr.NewErrMsg("状态值无效,仅支持 1=生效 或 2=已失效"), "")
}
record.Status = *req.Status
}
if req.Amount != nil {
record.Amount = *req.Amount
}
if err = l.svcCtx.UserFeatureWhitelistModel.UpdateWithVersion(l.ctx, nil, record); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新白名单记录失败, %v", err)
}
return &types.AdminUpdateWhitelistResp{Success: true}, nil
}

View File

@@ -1,102 +0,0 @@
package admin_whitelist
import (
"context"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/google/uuid"
"github.com/pkg/errors"
)
const (
whitelistActionCreated = "created"
whitelistActionReactivated = "reactivated"
whitelistActionSkipped = "skipped"
)
type createWhitelistResult struct {
Id string
FeatureApiId string
FeatureName string
Action string
Message string
}
func createOrReactivateWhitelist(
ctx context.Context,
svcCtx *svc.ServiceContext,
userID string,
idCard string,
feature *model.Feature,
amount float64,
status int64,
) (*createWhitelistResult, error) {
exists, err := svcCtx.WhitelistService.CheckWhitelistExists(ctx, idCard, feature.Id)
if err != nil {
return nil, err
}
if exists {
return &createWhitelistResult{
FeatureApiId: feature.ApiId,
FeatureName: feature.Name,
Action: whitelistActionSkipped,
Message: "已存在生效白名单",
}, nil
}
builder := svcCtx.UserFeatureWhitelistModel.SelectBuilder().
Where("id_card = ? AND feature_id = ?", idCard, feature.Id)
records, err := svcCtx.UserFeatureWhitelistModel.FindAll(ctx, builder, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询白名单记录失败, %v", err)
}
for _, record := range records {
if record.Status == 2 {
record.Status = status
record.Amount = amount
record.UserId = userID
if updateErr := svcCtx.UserFeatureWhitelistModel.UpdateWithVersion(ctx, nil, record); updateErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新白名单记录失败, %v", updateErr)
}
return &createWhitelistResult{
Id: record.Id,
FeatureApiId: feature.ApiId,
FeatureName: feature.Name,
Action: whitelistActionReactivated,
}, nil
}
}
wl := &model.UserFeatureWhitelist{
Id: uuid.NewString(),
IdCard: idCard,
FeatureId: feature.Id,
FeatureApiId: feature.ApiId,
UserId: userID,
Amount: amount,
Status: status,
}
if _, err = svcCtx.UserFeatureWhitelistModel.Insert(ctx, nil, wl); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建白名单记录失败, %v", err)
}
return &createWhitelistResult{
Id: wl.Id,
FeatureApiId: feature.ApiId,
FeatureName: feature.Name,
Action: whitelistActionCreated,
}, nil
}
func parseWhitelistStatus(status *int64) (int64, error) {
if status == nil {
return 1, nil
}
if *status != 1 && *status != 2 {
return 0, errors.Wrapf(xerr.NewErrMsg("状态值无效,仅支持 1=生效 或 2=已失效"), "")
}
return *status, nil
}

View File

@@ -4,6 +4,8 @@ import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"strings"
"ycc-server/app/main/model"
"ycc-server/common/ctxdata"
"ycc-server/common/xerr"
@@ -33,28 +35,32 @@ func NewOfflineFeatureLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Of
}
func (l *OfflineFeatureLogic) OfflineFeature(req *types.OfflineFeatureReq) (resp *types.OfflineFeatureResp, err error) {
// 1. 验证参数
if err := l.validateRequest(req); err != nil {
return nil, err
}
// 2. 获取用户ID并验证代理权限任意等级代理均可下架
userID, err := l.verifyAgent()
if err != nil {
return nil, err
}
// 3. 获取查询记录和身份证号
queryModel, idCard, err := l.getQueryInfo(req.QueryId)
queryModel, idCard, name, err := l.getQueryInfo(req.QueryId)
if err != nil {
return nil, err
}
_ = queryModel // 避免未使用变量警告
// 4. 调用 WhitelistService 统一下架处理
mainApiId := extractMainApiId(req.FeatureApiId)
feature, err := l.svcCtx.FeatureModel.FindOneByApiId(l.ctx, mainApiId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrMsg("模块不存在"), "")
}
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询模块信息失败, %v", err)
}
needPay, amount, whitelistCreated, err := l.svcCtx.WhitelistService.ProcessOfflineFeature(
l.ctx,
nil, // 不使用事务,因为可能只是检查
nil,
idCard,
req.FeatureApiId,
userID,
@@ -64,14 +70,31 @@ func (l *OfflineFeatureLogic) OfflineFeature(req *types.OfflineFeatureReq) (resp
return nil, err
}
// 5. 如果已创建白名单,需要删除报告数据
if needPay {
return &types.OfflineFeatureResp{
Success: false,
NeedPay: true,
Amount: amount,
}, nil
}
if whitelistCreated {
remark := fmt.Sprintf("代理下架自动同步 query_id=%s feature=%s", req.QueryId, feature.ApiId)
l.svcCtx.QueryWhitelistSyncService.TrySync(
l.ctx,
name,
idCard,
[]string{feature.ApiId},
remark,
)
if err := l.deleteQueryData(req.QueryId, req.FeatureApiId); err != nil {
// 删除报告数据失败不影响主流程,只记录日志
logx.Errorf("下架模块后删除报告数据失败:查询记录 %s模块 %s错误%v", req.QueryId, req.FeatureApiId, err)
}
}
_ = queryModel
return &types.OfflineFeatureResp{
Success: whitelistCreated,
NeedPay: needPay,
@@ -79,7 +102,6 @@ func (l *OfflineFeatureLogic) OfflineFeature(req *types.OfflineFeatureReq) (resp
}, nil
}
// validateRequest 验证请求参数
func (l *OfflineFeatureLogic) validateRequest(req *types.OfflineFeatureReq) error {
if req.QueryId == "" {
return errors.Wrapf(xerr.NewErrMsg("查询记录ID不能为空"), "")
@@ -90,7 +112,6 @@ func (l *OfflineFeatureLogic) validateRequest(req *types.OfflineFeatureReq) erro
return nil
}
// verifyAgent 验证是否为代理并返回用户ID任意等级代理均可下架
func (l *OfflineFeatureLogic) verifyAgent() (string, error) {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
@@ -108,61 +129,67 @@ func (l *OfflineFeatureLogic) verifyAgent() (string, error) {
return userID, nil
}
// getQueryInfo 获取查询记录和身份证号
func (l *OfflineFeatureLogic) getQueryInfo(queryId string) (*model.Query, string, error) {
func (l *OfflineFeatureLogic) getQueryInfo(queryId string) (*model.Query, string, string, error) {
queryModel, err := l.svcCtx.QueryModel.FindOne(l.ctx, queryId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, "", errors.Wrapf(xerr.NewErrMsg("查询记录不存在"), "")
return nil, "", "", errors.Wrapf(xerr.NewErrMsg("查询记录不存在"), "")
}
return nil, "", errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询报告记录失败, %v", err)
return nil, "", "", errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询报告记录失败, %v", err)
}
// 解密 QueryParams 获取 idCard
idCard, err := l.extractIdCardFromQueryParams(queryModel)
idCard, name, err := extractPersonInfoFromQueryParams(l.svcCtx, queryModel)
if err != nil {
return nil, "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取身份证号失败, %v", err)
return nil, "", "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取查询参数失败, %v", err)
}
if idCard == "" {
return nil, "", errors.Wrapf(xerr.NewErrMsg("查询参数中缺少身份证号"), "")
return nil, "", "", errors.Wrapf(xerr.NewErrMsg("查询参数中缺少身份证号"), "")
}
return queryModel, idCard, nil
return queryModel, idCard, name, nil
}
// extractIdCardFromQueryParams 从 QueryParams 中提取身份证号
func (l *OfflineFeatureLogic) extractIdCardFromQueryParams(queryModel *model.Query) (string, error) {
func extractMainApiId(featureApiId string) string {
if idx := strings.Index(featureApiId, "_"); idx > 0 {
return featureApiId[:idx]
}
return featureApiId
}
func extractPersonInfoFromQueryParams(svcCtx *svc.ServiceContext, queryModel *model.Query) (idCard, name string, err error) {
if queryModel.QueryParams == "" {
return "", errors.New("查询参数为空")
return "", "", errors.New("查询参数为空")
}
secretKey := l.svcCtx.Config.Encrypt.SecretKey
secretKey := svcCtx.Config.Encrypt.SecretKey
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return "", errors.Wrap(decodeErr, "获取AES密钥失败")
return "", "", errors.Wrap(decodeErr, "获取AES密钥失败")
}
decryptedParams, decryptErr := crypto.AesDecrypt(queryModel.QueryParams, key)
if decryptErr != nil {
return "", errors.Wrap(decryptErr, "解密查询参数失败")
return "", "", errors.Wrap(decryptErr, "解密查询参数失败")
}
var params map[string]interface{}
unmarshalErr := json.Unmarshal(decryptedParams, &params)
if unmarshalErr != nil {
return "", errors.Wrap(unmarshalErr, "解析查询参数失败")
if unmarshalErr := json.Unmarshal(decryptedParams, &params); unmarshalErr != nil {
return "", "", errors.Wrap(unmarshalErr, "解析查询参数失败")
}
idCard, ok := params["id_card"].(string)
if !ok || idCard == "" {
return "", errors.New("查询参数中缺少 id_card 或 id_card 为空")
idCardValue, ok := params["id_card"].(string)
if !ok || idCardValue == "" {
return "", "", errors.New("查询参数中缺少 id_card 或 id_card 为空")
}
return idCard, nil
nameValue, _ := params["name"].(string)
if strings.TrimSpace(nameValue) == "" {
nameValue = "*"
}
return idCardValue, nameValue, nil
}
// deleteQueryData 删除报告数据
func (l *OfflineFeatureLogic) deleteQueryData(queryId, featureApiId string) error {
return l.svcCtx.QueryModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
return l.svcCtx.WhitelistService.DeleteFeatureFromQueryData(ctx, session, queryId, featureApiId)

View File

@@ -172,6 +172,15 @@ func (l *AlipayCallbackLogic) handleWhitelistOrderPayment(w http.ResponseWriter,
return nil
}
if whitelistOrder.Status == 2 {
syncPaidWhitelistOrderToTianyuan(
l.ctx,
l.svcCtx,
whitelistOrder,
buildAgentPaidWhitelistSyncRemark(orderNo),
)
}
// 6. 更新订单和白名单订单 + 创建白名单记录并删除报告数据
err = l.svcCtx.WhitelistOrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 6.1 更新订单状态

View File

@@ -217,6 +217,13 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
}
// 更新白名单订单状态为已支付并处理白名单记录
syncPaidWhitelistOrderToTianyuan(
context.Background(),
l.svcCtx,
whitelistOrder,
buildAgentPaidWhitelistSyncRemark(paymentTypeResp.outTradeNo),
)
err := l.svcCtx.WhitelistOrderModel.Trans(context.Background(), func(transCtx context.Context, session sqlx.Session) error {
// 更新白名单订单状态为已支付
whitelistOrder.Status = 2 // 已支付

View File

@@ -166,6 +166,15 @@ func (l *WechatPayCallbackLogic) handleWhitelistOrderPayment(w http.ResponseWrit
return nil
}
if whitelistOrder.Status == 2 {
syncPaidWhitelistOrderToTianyuan(
l.ctx,
l.svcCtx,
whitelistOrder,
buildAgentPaidWhitelistSyncRemark(orderNo),
)
}
// 6. 更新订单和白名单订单 + 创建白名单记录并删除报告数据
err := l.svcCtx.WhitelistOrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 6.1 更新订单状态

View File

@@ -0,0 +1,28 @@
package pay
import (
"context"
"fmt"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/model"
)
func syncPaidWhitelistOrderToTianyuan(
ctx context.Context,
svcCtx *svc.ServiceContext,
whitelistOrder *model.WhitelistOrder,
remark string,
) {
itemBuilder := svcCtx.WhitelistOrderItemModel.SelectBuilder().
Where("order_id = ?", whitelistOrder.Id)
items, err := svcCtx.WhitelistOrderItemModel.FindAll(ctx, itemBuilder, "")
if err != nil || len(items) == 0 {
return
}
svcCtx.QueryWhitelistSyncService.TrySyncWhitelistOrder(ctx, whitelistOrder, items, remark)
}
func buildAgentPaidWhitelistSyncRemark(orderNo string) string {
return fmt.Sprintf("代理付费下架自动同步 order_no=%s", orderNo)
}