新增新个人和企业司法

This commit is contained in:
liangzai 2025-03-18 22:07:42 +08:00
parent 30ef77f90c
commit d5200d00c9
12 changed files with 393 additions and 4 deletions

View File

@ -8,7 +8,7 @@ info (
)
type request {
data string `json:"data"`
Data string `json:"data"`
}
@server (
@ -74,6 +74,9 @@ service api-api {
@handler FLXG0V3B
post /FLXG0V3B (request) returns (string)
@handler FLXG0V4B
post /FLXG0V4B (request) returns (string)
}
@server (
@ -88,6 +91,9 @@ service api-api {
@handler QYGL8261
post /QYGL8261 (request) returns (string)
@handler QYGL8271
post /QYGL8271 (request) returns (string)
@handler QYGL45BD
post /QYGL45BD (request) returns (string)

View File

@ -0,0 +1,30 @@
package FLXG
import (
"net/http"
"tianyuan-api/pkg/errs"
"tianyuan-api/pkg/response"
"github.com/zeromicro/go-zero/rest/httpx"
"tianyuan-api/apps/api/internal/logic/FLXG"
"tianyuan-api/apps/api/internal/svc"
"tianyuan-api/apps/api/internal/types"
)
func FLXG0V4BHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.Request
if err := httpx.Parse(r, &req); err != nil {
response.Fail(r.Context(), w, errs.ErrParamValidation, nil)
return
}
l := FLXG.NewFLXG0V4BLogic(r.Context(), svcCtx)
resp, err := l.FLXG0V4B(&req)
if err != nil {
response.Fail(r.Context(), w, err, resp)
} else {
response.Success(r.Context(), w, resp)
}
}
}

View File

@ -0,0 +1,31 @@
package QYGL
import (
"net/http"
"tianyuan-api/apps/api/internal/logic/QYGL"
"tianyuan-api/apps/api/internal/svc"
"tianyuan-api/apps/api/internal/types"
"tianyuan-api/pkg/errs"
"tianyuan-api/pkg/response"
"github.com/zeromicro/go-zero/rest/httpx"
)
func QYGL8271Handler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.Request
if err := httpx.Parse(r, &req); err != nil {
response.Fail(r.Context(), w, errs.ErrParamValidation, nil)
return
}
l := QYGL.NewQYGL8271Logic(r.Context(), svcCtx)
resp, err := l.QYGL8271(&req)
if err != nil {
response.Fail(r.Context(), w, err, resp)
} else {
response.Success(r.Context(), w, resp)
}
}
}

View File

@ -1,5 +1,5 @@
// Code generated by goctl. DO NOT EDIT.
// goctl 1.7.2
// goctl 1.7.3
package handler
@ -26,6 +26,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/FLXG0V3B",
Handler: FLXG.FLXG0V3BHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/FLXG0V4B",
Handler: FLXG.FLXG0V4BHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/FLXG162A",
@ -173,6 +178,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/QYGL8261",
Handler: QYGL.QYGL8261Handler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/QYGL8271",
Handler: QYGL.QYGL8271Handler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/QYGLB4C0",

View File

@ -0,0 +1,111 @@
package FLXG
import (
"context"
"encoding/hex"
"tianyuan-api/apps/api/internal/common"
"tianyuan-api/apps/api/internal/validator"
"tianyuan-api/apps/api/internal/westmodel"
"tianyuan-api/pkg/crypto"
"tianyuan-api/pkg/errs"
"tianyuan-api/apps/api/internal/svc"
"tianyuan-api/apps/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type FLXG0V4BLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewFLXG0V4BLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FLXG0V4BLogic {
return &FLXG0V4BLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *FLXG0V4BLogic) FLXG0V4B(req *types.Request) (resp string, err *errs.AppError) {
var status string
var charges bool
var remark = ""
secretKey, ok := l.ctx.Value("secretKey").(string)
if !ok {
return "", errs.ErrSystem
}
transactionID, ok := l.ctx.Value("transactionID").(string)
if !ok {
return "", errs.ErrSystem
}
userId, userIdOk := l.ctx.Value("userId").(int64)
if !userIdOk {
return "", errs.ErrSystem
}
productCode, productCodeOk := l.ctx.Value("productCode").(string)
if !productCodeOk || productCode == "" {
return "", errs.ErrSystem
}
defer func() {
if err != nil {
status = "failed"
charges = false
} else {
status = "success"
charges = true
}
sendApiRequestMessageErr := l.svcCtx.ApiRequestMqsService.SendApiRequestMessage(l.ctx, transactionID, userId, productCode, status, charges, remark)
if sendApiRequestMessageErr != nil {
logx.Errorf("发送 API 请求消息失败: %v", err)
}
}()
// 1、解密
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return "", errs.ErrSystem
}
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return "", errs.ErrParamDecryption
}
// 2、校验
var data validator.FLXG0V4BRequest
if validatorErr := validator.ValidateAndParse(decryptData, &data); validatorErr != nil {
return "", errs.ErrParamValidation
}
// 3、西部加密
westConfig := l.svcCtx.Config.WestConfig
encryptedFields, encryptStructFieldsErr := common.EncryptStructFields(data, westConfig.Key)
if encryptStructFieldsErr != nil {
logx.Errorf("西部加密错误:%v", encryptStructFieldsErr)
return "", errs.ErrSystem
}
// 4、发送请求到西部
logx.Infof("交易号:%s", transactionID)
apiRequest := common.MapStructToAPIRequest(encryptedFields, westmodel.FLXG0V4BFieldMapping, "data")
westResp, callAPIErr := l.svcCtx.WestDexService.CallAPI("G22SC01", apiRequest, l.svcCtx.Config.WestConfig.SecretId)
if callAPIErr != nil {
if callAPIErr.Code == errs.ErrDataSource.Code {
encryptData, aesEncrypt := crypto.AesEncrypt(westResp, key)
if aesEncrypt != nil {
return "", errs.ErrSystem
}
return encryptData, callAPIErr
}
return "", callAPIErr
}
encryptData, aesEncrypt := crypto.AesEncrypt(westResp, key)
if aesEncrypt != nil {
return "", errs.ErrSystem
}
return encryptData, nil
}

View File

@ -0,0 +1,111 @@
package QYGL
import (
"context"
"encoding/hex"
"tianyuan-api/apps/api/internal/common"
"tianyuan-api/apps/api/internal/svc"
"tianyuan-api/apps/api/internal/types"
"tianyuan-api/apps/api/internal/validator"
"tianyuan-api/apps/api/internal/westmodel"
"tianyuan-api/pkg/crypto"
"tianyuan-api/pkg/errs"
"github.com/zeromicro/go-zero/core/logx"
)
type QYGL8271Logic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewQYGL8271Logic(ctx context.Context, svcCtx *svc.ServiceContext) *QYGL8271Logic {
return &QYGL8271Logic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *QYGL8271Logic) QYGL8271(req *types.Request) (resp string, err *errs.AppError) {
var status string
var charges bool
var remark = ""
secretKey, ok := l.ctx.Value("secretKey").(string)
if !ok {
return "", errs.ErrSystem
}
transactionID, ok := l.ctx.Value("transactionID").(string)
if !ok {
return "", errs.ErrSystem
}
userId, userIdOk := l.ctx.Value("userId").(int64)
if !userIdOk {
return "", errs.ErrSystem
}
productCode, productCodeOk := l.ctx.Value("productCode").(string)
if !productCodeOk || productCode == "" {
return "", errs.ErrSystem
}
defer func() {
if err != nil {
status = "failed"
charges = false
} else {
status = "success"
charges = true
}
sendApiRequestMessageErr := l.svcCtx.ApiRequestMqsService.SendApiRequestMessage(l.ctx, transactionID, userId, productCode, status, charges, remark)
if sendApiRequestMessageErr != nil {
logx.Errorf("发送 API 请求消息失败: %v", err)
}
}()
// 1、解密
key, decodeErr := hex.DecodeString(secretKey)
if decodeErr != nil {
return "", errs.ErrSystem
}
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
if aesDecryptErr != nil || len(decryptData) == 0 {
return "", errs.ErrParamDecryption
}
// 2、校验
var data validator.QYGL8271Request
if validatorErr := validator.ValidateAndParse(decryptData, &data); validatorErr != nil {
return "", errs.ErrParamValidation
}
// 3、西部加密
westConfig := l.svcCtx.Config.WestConfig
encryptedFields, encryptStructFieldsErr := common.EncryptStructFields(data, westConfig.Key)
if encryptStructFieldsErr != nil {
logx.Errorf("西部加密错误:%v", encryptStructFieldsErr)
return "", errs.ErrSystem
}
// 4、发送请求到西部
logx.Infof("交易号:%s", transactionID)
apiRequest := common.MapStructToAPIRequest(encryptedFields, westmodel.QYGL8271FieldMapping, "data")
westResp, callAPIErr := l.svcCtx.WestDexService.CallAPI("Q03SC01", apiRequest, l.svcCtx.Config.WestConfig.SecretId)
if callAPIErr != nil {
if callAPIErr.Code == errs.ErrDataSource.Code {
encryptData, aesEncrypt := crypto.AesEncrypt(westResp, key)
if aesEncrypt != nil {
return "", errs.ErrSystem
}
return encryptData, callAPIErr
}
return "", callAPIErr
}
encryptData, aesEncrypt := crypto.AesEncrypt(westResp, key)
if aesEncrypt != nil {
return "", errs.ErrSystem
}
return encryptData, nil
}

View File

@ -1,5 +1,5 @@
// Code generated by goctl. DO NOT EDIT.
// goctl 1.7.2
// goctl 1.7.3
package types

View File

@ -12,6 +12,7 @@ var customMessages = map[string]string{
"ID.required": "id_card 是必填项",
"ID.validID": "id 必须为有效的身份证号码",
"TimeRange.validTimeRange": "time_range 必须为1到5的数字表示年",
"AuthDate.validAuthDate": "auth_date 日期范围格式必须为yyyyMMdd-yyyyMMdd范围不超过5年且当前时间必须在范围内",
}
// 获取自定义错误消息

View File

@ -25,6 +25,11 @@ type FLXG0V3BRequest struct {
IDCard string `json:"id_card" validate:"required,validIDCard"`
Name string `json:"name" validate:"required,min=1,validName"`
}
type FLXG0V4BRequest struct {
IDCard string `json:"id_card" validate:"required,validIDCard"`
Name string `json:"name" validate:"required,min=1,validName"`
AuthData string `json:"auth_data" validate:"required,validAuthData"`
}
type FLXG54F5Request struct {
MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"`
}
@ -114,6 +119,11 @@ type QYGL45BDRequest struct {
type QYGL8261Request struct {
EntName string `json:"ent_name" validate:"required,min=1,validName"`
}
type QYGL8271Request struct {
EntName string `json:"ent_name" validate:"required,min=1,validName"`
EntCode string `json:"ent_code" validate:"required,validUSCI"`
AuthDate string `json:"auth_date" validate:"required,validAuthDate"`
}
type QYGLB4C0Request struct {
IDCard string `json:"id_card" validate:"required,validIDCard"`
}

View File

@ -4,9 +4,12 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/go-playground/validator/v10"
"regexp"
"strconv"
"strings"
"time"
"github.com/go-playground/validator/v10"
)
var validate *validator.Validate
@ -50,6 +53,11 @@ func init() {
if err := validate.RegisterValidation("validMobileType", validMobileType); err != nil {
panic(fmt.Sprintf("注册 validMobileType 验证器时发生错误: %v", err))
}
// 注册自定义验证器 validAuthDate
if err := validate.RegisterValidation("validAuthDate", validAuthDate); err != nil {
panic(fmt.Sprintf("注册 validAuthDate 验证器时发生错误: %v", err))
}
}
// ValidateAndParse 封装了解密、解析和校验逻辑
@ -73,6 +81,54 @@ func ValidateAndParse(decryptData []byte, req interface{}) error {
return nil
}
func ValidateAuthDate(date string) error {
// 校验日期格式是否为 yyyyMMdd-yyyyMMdd
validDateRangePattern := `^\d{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])-\d{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$`
matched, _ := regexp.MatchString(validDateRangePattern, date)
if !matched {
return errors.New("日期范围格式错误应为yyyyMMdd-yyyyMMdd")
}
// 分割开始和结束日期
parts := strings.Split(date, "-")
if len(parts) != 2 {
return errors.New("日期范围格式错误应为yyyyMMdd-yyyyMMdd")
}
startDateStr, endDateStr := parts[0], parts[1]
// 解析开始日期
startDate, err := time.Parse("20060102", startDateStr)
if err != nil {
return errors.New("开始日期格式错误")
}
// 解析结束日期
endDate, err := time.Parse("20060102", endDateStr)
if err != nil {
return errors.New("结束日期格式错误")
}
// 校验开始日期不大于结束日期
if startDate.After(endDate) {
return errors.New("开始日期不能大于结束日期")
}
// 校验时间范围不能超过5年
maxDuration := 5 * 365 * 24 * time.Hour // 5年的近似时间不考虑闰年
if endDate.Sub(startDate) > maxDuration {
return errors.New("时间范围不能超过5年")
}
// 校验当前时间在范围内
now := time.Now()
if now.Before(startDate) || now.After(endDate) {
return errors.New("当前时间必须在指定的时间范围内")
}
return nil
}
// 获取验证器实例
func GetValidator() *validator.Validate {
return validate
@ -154,3 +210,15 @@ func validMobileType(fl validator.FieldLevel) bool {
return validTypes[mobileType]
}
// 自定义的日期范围验证器(用于结构体字段验证)
func validAuthDate(fl validator.FieldLevel) bool {
dateRange := fl.Field().String()
// 如果是空字符串,认为是有效的(非必填项)
if dateRange == "" {
return true
}
err := ValidateAuthDate(dateRange)
return err == nil
}

View File

@ -10,6 +10,11 @@ var FLXG0V3BFieldMapping = map[string]string{
"IDCard": "id_card",
"Name": "name",
}
var FLXG0V4BFieldMapping = map[string]string{
"IDCard": "idcard",
"Name": "name",
"AuthDate": "inquired_auth",
}
var FLXG54F5FieldMapping = map[string]string{
"MobileNo": "mobile",
}
@ -99,6 +104,11 @@ var QYGL45BDFieldMapping = map[string]string{
var QYGL8261FieldMapping = map[string]string{
"EntName": "ent_name",
}
var QYGL8271FieldMapping = map[string]string{
"EntName": "org_name",
"EntCode": "uscc",
"AuthDate": "inquired_auth",
}
var QYGLB4C0FieldMapping = map[string]string{
"IDCard": "pid",
}

View File

@ -32,6 +32,7 @@ func ValidatePhoneNumber(phone string) error {
}
return nil
}
func ValidateVerifyCode(redisClient *redis.Redis, phone, code string) error {
// 从 Redis 获取验证码
savedCode, err := redisClient.Get(phone)