This commit is contained in:
2026-06-19 12:53:33 +08:00
parent 69d6377bc6
commit b9819b913b
19 changed files with 1243 additions and 5 deletions

View File

@@ -0,0 +1,37 @@
package admin_query_whitelist
import (
"context"
"tydata-server/app/main/api/internal/svc"
"tydata-server/app/main/api/internal/types"
tianyuanapi "tydata-server/app/main/api/internal/service/tianyuanapi_sdk"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminQueryWhitelistAppendLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminQueryWhitelistAppendLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminQueryWhitelistAppendLogic {
return &AdminQueryWhitelistAppendLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminQueryWhitelistAppendLogic) AdminQueryWhitelistAppend(req *types.AdminQueryWhitelistAppendReq) (resp *types.AdminQueryWhitelistOpResp, err error) {
return l.executeWhitelistOp(whitelistOpInput{
Action: actionAppend,
Name: req.Name,
IdCard: req.IdCard,
ApiCodes: req.ApiCodes,
Remark: req.Remark,
}, func(client *tianyuanapi.Client, payload tianyuanapi.WhitelistEntryPayload, mgmtKey string) (*tianyuanapi.WhitelistResponse, error) {
return client.AppendWhitelistEntry(payload, mgmtKey)
})
}

View File

@@ -0,0 +1,37 @@
package admin_query_whitelist
import (
"context"
"tydata-server/app/main/api/internal/svc"
"tydata-server/app/main/api/internal/types"
tianyuanapi "tydata-server/app/main/api/internal/service/tianyuanapi_sdk"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminQueryWhitelistCreateLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminQueryWhitelistCreateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminQueryWhitelistCreateLogic {
return &AdminQueryWhitelistCreateLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminQueryWhitelistCreateLogic) AdminQueryWhitelistCreate(req *types.AdminQueryWhitelistCreateReq) (resp *types.AdminQueryWhitelistOpResp, err error) {
return l.executeWhitelistOp(whitelistOpInput{
Action: actionCreate,
Name: req.Name,
IdCard: req.IdCard,
ApiCodes: req.ApiCodes,
Remark: req.Remark,
}, func(client *tianyuanapi.Client, payload tianyuanapi.WhitelistEntryPayload, mgmtKey string) (*tianyuanapi.WhitelistResponse, error) {
return client.CreateWhitelistEntry(payload, mgmtKey)
})
}

View File

@@ -0,0 +1,109 @@
package admin_query_whitelist
import (
"context"
"tydata-server/app/main/api/internal/svc"
"tydata-server/app/main/api/internal/types"
"tydata-server/app/main/model"
"tydata-server/common/globalkey"
"tydata-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/mr"
)
type AdminQueryWhitelistOpLogListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAdminQueryWhitelistOpLogListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminQueryWhitelistOpLogListLogic {
return &AdminQueryWhitelistOpLogListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminQueryWhitelistOpLogListLogic) AdminQueryWhitelistOpLogList(req *types.AdminQueryWhitelistOpLogListReq) (resp *types.AdminQueryWhitelistOpLogListResp, err error) {
builder := l.svcCtx.QueryWhitelistOpLogModel.SelectBuilder().
Where("del_state = ?", globalkey.DelStateNo)
if req.IdCard != nil && *req.IdCard != "" {
builder = builder.Where("id_card = ?", *req.IdCard)
}
if req.Action != nil && *req.Action != "" {
builder = builder.Where("action = ?", *req.Action)
}
if req.TianyuanCode != nil {
builder = builder.Where("tianyuan_code = ?", *req.TianyuanCode)
}
var total int64
var logs []*model.QueryWhitelistOpLog
err = mr.Finish(func() error {
var err error
total, err = l.svcCtx.QueryWhitelistOpLogModel.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.QueryWhitelistOpLogModel.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
}
adminNameMap := make(map[int64]string)
resp = &types.AdminQueryWhitelistOpLogListResp{
Total: total,
Items: make([]types.QueryWhitelistOpLogItem, 0, len(logs)),
}
for _, log := range logs {
adminName := ""
if cached, ok := adminNameMap[log.AdminUserId]; ok {
adminName = cached
} else {
adminUser, findErr := l.svcCtx.AdminUserModel.FindOne(l.ctx, log.AdminUserId)
if findErr == nil && adminUser != nil {
adminName = adminUser.RealName
if adminName == "" {
adminName = adminUser.Username
}
}
adminNameMap[log.AdminUserId] = adminName
}
item := types.QueryWhitelistOpLogItem{
Id: log.Id,
AdminUserId: log.AdminUserId,
AdminUserName: adminName,
Action: log.Action,
Name: log.Name,
IdCard: log.IdCard,
IdCardMasked: log.IdCardMasked.String,
ApiCodes: parseJSONStringArray(log.ApiCodes),
Remark: log.Remark.String,
TianyuanCode: int(log.TianyuanCode),
TianyuanMessage: log.TianyuanMessage.String,
TransactionId: log.TransactionId.String,
EntryId: log.EntryId.String,
EntryStatus: log.EntryStatus.String,
EntryApiCodes: parseJSONStringArray(log.EntryApiCodes.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,157 @@
package admin_query_whitelist
import (
"context"
"database/sql"
"encoding/json"
"regexp"
"strings"
"tydata-server/app/main/api/internal/svc"
"tydata-server/app/main/api/internal/types"
"tydata-server/app/main/model"
tianyuanapi "tydata-server/app/main/api/internal/service/tianyuanapi_sdk"
"tydata-server/common/ctxdata"
"tydata-server/common/xerr"
"github.com/pkg/errors"
)
const (
actionCreate = "create"
actionAppend = "append"
)
var idCardPattern = regexp.MustCompile(`^\d{17}[\dXx]$`)
type whitelistOpInput struct {
Action string
Name string
IdCard string
ApiCodes []string
Remark string
}
func validateWhitelistInput(input whitelistOpInput) error {
name := strings.TrimSpace(input.Name)
if name == "" {
return xerr.NewErrMsg("姓名不能为空")
}
idCard := strings.TrimSpace(input.IdCard)
if !idCardPattern.MatchString(idCard) {
return xerr.NewErrMsg("身份证号格式不正确")
}
if len(input.ApiCodes) == 0 {
return xerr.NewErrMsg("产品编码不能为空")
}
for _, code := range input.ApiCodes {
if strings.TrimSpace(code) == "" {
return xerr.NewErrMsg("产品编码不能为空")
}
}
return nil
}
func (l *AdminQueryWhitelistCreateLogic) executeWhitelistOp(input whitelistOpInput, call func(client *tianyuanapi.Client, payload tianyuanapi.WhitelistEntryPayload, mgmtKey string) (*tianyuanapi.WhitelistResponse, error)) (*types.AdminQueryWhitelistOpResp, error) {
return executeWhitelistOp(l.ctx, l.svcCtx, input, call)
}
func (l *AdminQueryWhitelistAppendLogic) executeWhitelistOp(input whitelistOpInput, call func(client *tianyuanapi.Client, payload tianyuanapi.WhitelistEntryPayload, mgmtKey string) (*tianyuanapi.WhitelistResponse, error)) (*types.AdminQueryWhitelistOpResp, error) {
return executeWhitelistOp(l.ctx, l.svcCtx, input, call)
}
func executeWhitelistOp(
ctx context.Context,
svcCtx *svc.ServiceContext,
input whitelistOpInput,
call func(client *tianyuanapi.Client, payload tianyuanapi.WhitelistEntryPayload, mgmtKey string) (*tianyuanapi.WhitelistResponse, error),
) (*types.AdminQueryWhitelistOpResp, error) {
if err := validateWhitelistInput(input); err != nil {
return nil, err
}
adminUserId, err := ctxdata.GetUidFromCtx(ctx)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取管理员信息失败, %+v", err)
}
mgmtKey := strings.TrimSpace(svcCtx.Config.Tianyuanapi.WhitelistMgmtKey)
if mgmtKey == "" {
return nil, xerr.NewErrMsg("未配置天远白名单管理密钥")
}
if svcCtx.TianyuanapiClient == nil {
return nil, xerr.NewErrMsg("天远API客户端未初始化")
}
name := strings.TrimSpace(input.Name)
idCard := strings.TrimSpace(strings.ToUpper(input.IdCard))
apiCodes := make([]string, 0, len(input.ApiCodes))
for _, code := range input.ApiCodes {
apiCodes = append(apiCodes, strings.TrimSpace(code))
}
payload := tianyuanapi.WhitelistEntryPayload{
Name: name,
IdCard: idCard,
ApiCodes: apiCodes,
Remark: strings.TrimSpace(input.Remark),
}
apiResp, err := call(svcCtx.TianyuanapiClient, payload, mgmtKey)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "调用天远白名单接口失败, %+v", err)
}
apiCodesJSON, _ := json.Marshal(apiCodes)
opLog := &model.QueryWhitelistOpLog{
AdminUserId: adminUserId,
Action: input.Action,
Name: name,
IdCard: idCard,
ApiCodes: string(apiCodesJSON),
TianyuanCode: int64(apiResp.Code),
TianyuanMessage: sql.NullString{String: apiResp.Message, Valid: apiResp.Message != ""},
TransactionId: sql.NullString{String: apiResp.TransactionID, Valid: apiResp.TransactionID != ""},
}
if payload.Remark != "" {
opLog.Remark = sql.NullString{String: payload.Remark, Valid: true}
}
if apiResp.Data != nil {
opLog.IdCardMasked = sql.NullString{String: apiResp.Data.IdCardMasked, Valid: apiResp.Data.IdCardMasked != ""}
opLog.EntryId = sql.NullString{String: apiResp.Data.Id, Valid: apiResp.Data.Id != ""}
opLog.EntryStatus = sql.NullString{String: apiResp.Data.Status, Valid: apiResp.Data.Status != ""}
if len(apiResp.Data.ApiCodes) > 0 {
entryCodesJSON, _ := json.Marshal(apiResp.Data.ApiCodes)
opLog.EntryApiCodes = sql.NullString{String: string(entryCodesJSON), Valid: true}
}
}
if _, err = svcCtx.QueryWhitelistOpLogModel.Insert(ctx, nil, opLog); err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "保存操作记录失败, %+v", err)
}
resp := &types.AdminQueryWhitelistOpResp{
Success: apiResp.Code == 0,
TianyuanCode: apiResp.Code,
TianyuanMessage: apiResp.Message,
TransactionId: apiResp.TransactionID,
}
if apiResp.Data != nil {
resp.EntryId = apiResp.Data.Id
resp.IdCardMasked = apiResp.Data.IdCardMasked
resp.EntryApiCodes = apiResp.Data.ApiCodes
resp.EntryStatus = apiResp.Data.Status
}
return resp, nil
}
func parseJSONStringArray(raw string) []string {
if strings.TrimSpace(raw) == "" {
return []string{}
}
var items []string
if err := json.Unmarshal([]byte(raw), &items); err != nil {
return []string{raw}
}
return items
}