diff --git a/app/user/cmd/api/Dockerfile b/app/user/cmd/api/Dockerfile index 458d5d3..bbade4b 100644 --- a/app/user/cmd/api/Dockerfile +++ b/app/user/cmd/api/Dockerfile @@ -15,7 +15,7 @@ ADD go.sum . RUN go mod download COPY . . COPY app/user/cmd/api/etc /app/etc -RUN go build -ldflags="-s -w" -o /app/user app/user/cmd/api/user.go +RUN go build -ldflags="-s -w" -o /app/user app/user/cmd/api/main.go FROM scratch @@ -28,4 +28,4 @@ WORKDIR /app COPY --from=builder /app/user /app/user COPY --from=builder /app/etc /app/etc -CMD ["./user", "-f", "etc/user.yaml"] +CMD ["./main", "-f", "etc/main.yaml"] diff --git a/app/user/cmd/api/desc/query/query.api b/app/user/cmd/api/desc/query/query.api index 552e5a7..9441289 100644 --- a/app/user/cmd/api/desc/query/query.api +++ b/app/user/cmd/api/desc/query/query.api @@ -31,6 +31,7 @@ type Query { OrderId int64 `json:"order_id"` // 订单ID UserId int64 `json:"user_id"` // 用户ID ProductName string `json:"product_name"` // 产品ID + QueryParams map[string]interface{} `json:"query_params"` QueryData []map[string]interface{} `json:"query_data"` CreateTime string `json:"create_time"` // 创建时间 UpdateTime string `json:"update_time"` // 更新时间 diff --git a/app/user/cmd/api/etc/user.dev.yaml b/app/user/cmd/api/etc/main.dev.yaml similarity index 95% rename from app/user/cmd/api/etc/user.dev.yaml rename to app/user/cmd/api/etc/main.dev.yaml index 69fee7f..43bc610 100644 --- a/app/user/cmd/api/etc/user.dev.yaml +++ b/app/user/cmd/api/etc/main.dev.yaml @@ -24,12 +24,17 @@ WestConfig: Key: "121a1e41fc1690dd6b90afbcacd80cf4" SecretId: "449159" SecretSecondId: "296804" +YushanConfig: + ApiKey: "4c566c4a4b543164535455685655316c" + AcctID: "YSSJ843926726" + Url: "https://api.yushanshuju.com/credit-gw/service" Alipay: AppID: "2021004165608254" PrivateKey: "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCvo8TmTNnVguKwMYrX0z01PfUlSS+AqwwCH1+/P39q6No+09yO1bjhy4LowtDfwKX8F+IZLl5Cx06f1M8KzPvjQliBAfMJ1FuTEOOXPmtE1YLAYIUMLbltR6Crnp16T28eF41Uo0PUo2ple/oSjWhYgsTJjyBMXY04f6HM2uZlHOhG2aOUz2CDNbvkEhNddazuPMgo8Xl7vwENGDFTPa85HmSSoDppFowLdYfAw2Jl1ilKNg4sOPc6d507nXdgpMlUguwZxol6OQ2hBS6v9OjII5cJ1tyR/klJRapnIPmFaPvhDozYwjU6Z3jMvcbrByl0qNpLrbEFS4pn9hfRo4YrAgMBAAECggEAZAi0Ri6TCqXnEk7FMzMec0p8auYJ5hCFYFgaIkS5/1vroUjtH3TePcu5HXSHnkiMwM2hepIMIaB+SU3dNduVwtOwsJk5oOmP1m0SErv8QFISjBrs7AjGyVS4T8ahDl5bfRoQ5pmuMld4a6B2x0Y+ndqs1ddsn9HQctNOhexOuFsSjX1N3PZxFzfRTmGzxf7kwZGlXMN7G1r3Rp4koylYHVpqjXIK34Anc8SVljxFVkFOk62QvBdYcCucepymHNl0pYwPDCCylPH8OpIXOErmPldTflmoLRc+ywu9rw4I8UvkoPgTe+16he+jdi/N7cwbMTfixq+/Aeadjv2AgMuwkQKBgQDgLS3dRFAc6FMSJIA0FKgv5D/R3NZgWilbOAF11PtnE4AX4i0yZryGtLq+3NWCWYQF8iI60lIy3rEf9zWncwfadhWTEDUBjjrqqU46N2ddTzHsDw09I56TT2vrEwCdmJ2vh1hxPfgE3fSDnKbP4Wkl77JCTH7v0rA1jb65Plt8TwKBgQDIkrXqe/pVHDdxswoPL6em32TnKiaJ/R/UDDio20mgGG7FWEJAY5yYtu0y9Ug7W8PjJE7/cJ2/dwDSvHZm8R0iq8d6XkzN03Z+uvzGnMdUraXJZHSPZ5L/2ofysXjt/OtpA1Sox5++1+obiq6CZ6IYORLSxSf+it1JUbKXsNcVZQKBgQCTPzm7984DXtqJtS38h4D9jBgbWcn6Gd7GSuAyrIXBa76ccXSsgWzdskJjcZxQdUnRufyf1Fwni7yeOXullFoZNazwHxoh/nFWh4SZmqCrWoR5AF36xbW4HtfM3XtvCLqye90s7L5HPB8Kf8/WBcJSJ8JX5/UMw7/4PTWEaaAf4wKBgQCEXu7YVgIccYbV7wdQhm7q3rxFI7hTkU6UL4ylRDQPCJDyhREUValf0DozS1XkdueM3MWWJ8i0N+G/MsohnjdQTnZT+DBQFqM5eEai/Y1AAWpMw5N5oS2O1barIR1iU2053QzeZwCyfuTuUFRjk+mSevhFSgDfKN5qKRTor7kDUQKBgB3fC6jO8XCwimPvpsiGnuddNAq/w8iqSjSwuSvbI0Q7Lq6rvAIw2AmkC5t4kW4JcZLUgDvAs4GFoPDYhoL73vc1e2c35VTNck6IxZSQzzQ9pfXFiLtTe6eqggN4EOPGHKLd92CMAgoeySsp3NydpGSx2N/NUqp8BkoFLQ/k2W9o" AlipayPublicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2CqoCp95w/JV3RT/gzF4/8QmVT1HQNaeW7yUp+mA7x9AbjvlTW/+eRn6oGAL/XhZLjvHD0XjKLVKX0MJVS1aUQHEHEbOJN4Eu8II45OavD4iZISa7Kp9V6AM+i4qTyaeV2wNDnGxHQBaLVUGCfMR+56EK2YpORdE1H9uy72SSQseVb3bmpsV9EW/IJNmcVL/ut3uA1JWAoRmzlQ7ekxg7p8AYXzYPEHQr1tl7W+M4zv9wO9GKZCxIqMA8U3RP5npPfRaCfIRGzXzCqFEEUvWuidOB7frsvN4jiPD07qpL2Bi9LM1X/ee2kC/oM8Uhd7ERZhG8MbZfijZKxgrsDKBcwIDAQAB" IsProduction: true NotifyUrl: "https://6m4685017o.goho.co/api/v1/pay/alipay/callback" + ReturnURL: "http://192.168.10.20/#/pages/report" Wxpay: AppID: "1682635136" MchID: "1682635136" diff --git a/app/user/cmd/api/etc/user.yaml b/app/user/cmd/api/etc/main.yaml similarity index 95% rename from app/user/cmd/api/etc/user.yaml rename to app/user/cmd/api/etc/main.yaml index d625dfe..34228a0 100644 --- a/app/user/cmd/api/etc/user.yaml +++ b/app/user/cmd/api/etc/main.yaml @@ -25,12 +25,17 @@ WestConfig: Key: "121a1e41fc1690dd6b90afbcacd80cf4" SecretId: "449159" SecretSecondId: "296804" +YushanConfig: + ApiKey: "4c566c4a4b543164535455685655316c" + AcctID: "YSSJ843926726" + Url: "https://api.yushanshuju.com/credit-gw/service" Alipay: AppID: "2021004165608254" PrivateKey: "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCvo8TmTNnVguKwMYrX0z01PfUlSS+AqwwCH1+/P39q6No+09yO1bjhy4LowtDfwKX8F+IZLl5Cx06f1M8KzPvjQliBAfMJ1FuTEOOXPmtE1YLAYIUMLbltR6Crnp16T28eF41Uo0PUo2ple/oSjWhYgsTJjyBMXY04f6HM2uZlHOhG2aOUz2CDNbvkEhNddazuPMgo8Xl7vwENGDFTPa85HmSSoDppFowLdYfAw2Jl1ilKNg4sOPc6d507nXdgpMlUguwZxol6OQ2hBS6v9OjII5cJ1tyR/klJRapnIPmFaPvhDozYwjU6Z3jMvcbrByl0qNpLrbEFS4pn9hfRo4YrAgMBAAECggEAZAi0Ri6TCqXnEk7FMzMec0p8auYJ5hCFYFgaIkS5/1vroUjtH3TePcu5HXSHnkiMwM2hepIMIaB+SU3dNduVwtOwsJk5oOmP1m0SErv8QFISjBrs7AjGyVS4T8ahDl5bfRoQ5pmuMld4a6B2x0Y+ndqs1ddsn9HQctNOhexOuFsSjX1N3PZxFzfRTmGzxf7kwZGlXMN7G1r3Rp4koylYHVpqjXIK34Anc8SVljxFVkFOk62QvBdYcCucepymHNl0pYwPDCCylPH8OpIXOErmPldTflmoLRc+ywu9rw4I8UvkoPgTe+16he+jdi/N7cwbMTfixq+/Aeadjv2AgMuwkQKBgQDgLS3dRFAc6FMSJIA0FKgv5D/R3NZgWilbOAF11PtnE4AX4i0yZryGtLq+3NWCWYQF8iI60lIy3rEf9zWncwfadhWTEDUBjjrqqU46N2ddTzHsDw09I56TT2vrEwCdmJ2vh1hxPfgE3fSDnKbP4Wkl77JCTH7v0rA1jb65Plt8TwKBgQDIkrXqe/pVHDdxswoPL6em32TnKiaJ/R/UDDio20mgGG7FWEJAY5yYtu0y9Ug7W8PjJE7/cJ2/dwDSvHZm8R0iq8d6XkzN03Z+uvzGnMdUraXJZHSPZ5L/2ofysXjt/OtpA1Sox5++1+obiq6CZ6IYORLSxSf+it1JUbKXsNcVZQKBgQCTPzm7984DXtqJtS38h4D9jBgbWcn6Gd7GSuAyrIXBa76ccXSsgWzdskJjcZxQdUnRufyf1Fwni7yeOXullFoZNazwHxoh/nFWh4SZmqCrWoR5AF36xbW4HtfM3XtvCLqye90s7L5HPB8Kf8/WBcJSJ8JX5/UMw7/4PTWEaaAf4wKBgQCEXu7YVgIccYbV7wdQhm7q3rxFI7hTkU6UL4ylRDQPCJDyhREUValf0DozS1XkdueM3MWWJ8i0N+G/MsohnjdQTnZT+DBQFqM5eEai/Y1AAWpMw5N5oS2O1barIR1iU2053QzeZwCyfuTuUFRjk+mSevhFSgDfKN5qKRTor7kDUQKBgB3fC6jO8XCwimPvpsiGnuddNAq/w8iqSjSwuSvbI0Q7Lq6rvAIw2AmkC5t4kW4JcZLUgDvAs4GFoPDYhoL73vc1e2c35VTNck6IxZSQzzQ9pfXFiLtTe6eqggN4EOPGHKLd92CMAgoeySsp3NydpGSx2N/NUqp8BkoFLQ/k2W9o" AlipayPublicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2CqoCp95w/JV3RT/gzF4/8QmVT1HQNaeW7yUp+mA7x9AbjvlTW/+eRn6oGAL/XhZLjvHD0XjKLVKX0MJVS1aUQHEHEbOJN4Eu8II45OavD4iZISa7Kp9V6AM+i4qTyaeV2wNDnGxHQBaLVUGCfMR+56EK2YpORdE1H9uy72SSQseVb3bmpsV9EW/IJNmcVL/ut3uA1JWAoRmzlQ7ekxg7p8AYXzYPEHQr1tl7W+M4zv9wO9GKZCxIqMA8U3RP5npPfRaCfIRGzXzCqFEEUvWuidOB7frsvN4jiPD07qpL2Bi9LM1X/ee2kC/oM8Uhd7ERZhG8MbZfijZKxgrsDKBcwIDAQAB" IsProduction: true NotifyUrl: "https://app.quannengcha.com/api/v1/pay/alipay/callback" + ReturnURL: "https://www.quannengcha.com/#/pages/report" Wxpay: AppID: "1682635136" MchID: "1682635136" diff --git a/app/user/cmd/api/internal/config/config.go b/app/user/cmd/api/internal/config/config.go index 741c53a..944d1ba 100644 --- a/app/user/cmd/api/internal/config/config.go +++ b/app/user/cmd/api/internal/config/config.go @@ -17,6 +17,7 @@ type Config struct { Applepay ApplepayConfig Ali AliConfig WestConfig WestConfig + YushanConfig YushanConfig SystemConfig SystemConfig } @@ -44,6 +45,7 @@ type AlipayConfig struct { AlipayPublicKey string IsProduction bool NotifyUrl string + ReturnURL string } type WxpayConfig struct { AppID string @@ -72,7 +74,11 @@ type WestConfig struct { SecretId string SecretSecondId string } - +type YushanConfig struct { + ApiKey string + AcctID string + Url string +} type SystemConfig struct { ThreeVerify bool } diff --git a/app/user/cmd/api/internal/logic/query/querydetailbyorderidlogic.go b/app/user/cmd/api/internal/logic/query/querydetailbyorderidlogic.go index a310b62..2f6fe60 100644 --- a/app/user/cmd/api/internal/logic/query/querydetailbyorderidlogic.go +++ b/app/user/cmd/api/internal/logic/query/querydetailbyorderidlogic.go @@ -115,7 +115,10 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB 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) @@ -155,3 +158,20 @@ func ProcessQueryData(queryData sql.NullString, target *[]map[string]interface{} 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 +} diff --git a/app/user/cmd/api/internal/logic/query/querydetailbyordernologic.go b/app/user/cmd/api/internal/logic/query/querydetailbyordernologic.go index 20c78e0..927ce7c 100644 --- a/app/user/cmd/api/internal/logic/query/querydetailbyordernologic.go +++ b/app/user/cmd/api/internal/logic/query/querydetailbyordernologic.go @@ -111,7 +111,10 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB 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) diff --git a/app/user/cmd/api/internal/logic/query/queryexamplelogic.go b/app/user/cmd/api/internal/logic/query/queryexamplelogic.go index 1a304f0..6a6e53d 100644 --- a/app/user/cmd/api/internal/logic/query/queryexamplelogic.go +++ b/app/user/cmd/api/internal/logic/query/queryexamplelogic.go @@ -27,7 +27,49 @@ func NewQueryExampleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Quer } func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp *types.QueryExampleResp, err error) { - var exampleID int64 = 8 + var exampleID int64 + switch req.Feature { + case "toc_PhoneThreeElements": + exampleID = 83 + case "toc_BankCardBlacklist": + exampleID = 106 + case "toc_IDCardTwoElements": + exampleID = 85 + case "toc_PhoneTwoElements": + exampleID = 86 + case "toc_NetworkDuration": + exampleID = 117 + case "toc_PhoneSecondaryCard": + exampleID = 124 + case "toc_PhoneNumberRisk": + exampleID = 126 + case "toc_BankCardFourElements": + exampleID = 131 + //case "toc_BankCardThreeElements": + // exampleID = 9 + //case "toc_NaturalLifeStatus": + // exampleID = 10 + //case "toc_EducationVerification": + // exampleID = 11 + case "toc_PersonVehicleVerification": + exampleID = 110 + case "toc_VehiclesUnderName": + exampleID = 108 + case "toc_DualMarriage": + exampleID = 103 + case "toc_PersonalBadRecord": + exampleID = 73 + case "toc_ShareholderBusinessRelation": + exampleID = 16 + case "toc_PersonalLawsuit": + exampleID = 75 + case "toc_EnterpriseLawsuit": + exampleID = 81 + case "toc_Marriage": + exampleID = 72 + default: + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "示例报告, 获取示例报告失败: %v", err) + } queryModel, err := l.svcCtx.QueryModel.FindOne(l.ctx, exampleID) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "示例报告, 获取示例报告失败: %v", err) @@ -36,20 +78,24 @@ func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp *type 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) } - - copyErr := copier.Copy(&query, queryModel) - if copyErr != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 示例报告结构体复制失败, %+v", err) + // 复制报告数据 + 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 { diff --git a/app/user/cmd/api/internal/logic/query/queryservicelogic.go b/app/user/cmd/api/internal/logic/query/queryservicelogic.go index 405fc7a..0deab9e 100644 --- a/app/user/cmd/api/internal/logic/query/queryservicelogic.go +++ b/app/user/cmd/api/internal/logic/query/queryservicelogic.go @@ -46,11 +46,23 @@ var productProcessors = map[string]func(*QueryServiceLogic, *types.QueryServiceR "rentalinfo": (*QueryServiceLogic).ProcessRentalInfoLogic, "preloanbackgroundcheck": (*QueryServiceLogic).ProcessPreLoanBackgroundCheckLogic, "backgroundcheck": (*QueryServiceLogic).ProcessBackgroundCheckLogic, - "toc_marriage": (*QueryServiceLogic).ProcessTocMarriageLogic, + "toc_Marriage": (*QueryServiceLogic).ProcessTocMarriageLogic, "toc_PersonalBadRecord": (*QueryServiceLogic).ProcessTocPersonalBadRecordLogic, "toc_ShareholderBusinessRelation": (*QueryServiceLogic).ProcessTocShareholderBusinessRelationLogic, "toc_PersonalLawsuit": (*QueryServiceLogic).ProcessTocPersonalLawsuitLogic, "toc_EnterpriseLawsuit": (*QueryServiceLogic).ProcessTocEnterpriseLawsuitLogic, + "toc_PhoneThreeElements": (*QueryServiceLogic).ProcessTocPhoneThreeElementsLogic, + "toc_PhoneTwoElements": (*QueryServiceLogic).ProcessTocPhoneTwoElementsLogic, + "toc_IDCardTwoElements": (*QueryServiceLogic).ProcessTocIDCardTwoElementsLogic, + "toc_NaturalLifeStatus": (*QueryServiceLogic).ProcessTocNaturalLifeStatusLogic, + "toc_PersonVehicleVerification": (*QueryServiceLogic).ProcessTocPersonVehicleVerificationLogic, + "toc_BankCardBlacklist": (*QueryServiceLogic).ProcessTocBankCardBlacklistLogic, + "toc_VehiclesUnderName": (*QueryServiceLogic).ProcessTocVehiclesUnderNameLogic, + "toc_DualMarriage": (*QueryServiceLogic).ProcessTocDualMarriageLogic, + "toc_PhoneNumberRisk": (*QueryServiceLogic).ProcessTocPhoneNumberRiskLogic, + "toc_NetworkDuration": (*QueryServiceLogic).ProcessTocNetworkDurationLogic, + "toc_PhoneSecondaryCard": (*QueryServiceLogic).ProcessTocPhoneSecondaryCardLogic, + "toc_BankCardFourElements": (*QueryServiceLogic).ProcessTocBankCardFourElementsLogic, } func (l *QueryServiceLogic) PreprocessLogic(req *types.QueryServiceReq, product string) (*types.QueryServiceResp, error) { @@ -442,7 +454,7 @@ func (l *QueryServiceLogic) ProcessTocMarriageLogic(req *types.QueryServiceReq) "id_card": data.IDCard, "mobile": data.Mobile, } - cacheNo, cacheDataErr := l.CacheData(params, "toc_marriage", userID) + cacheNo, cacheDataErr := l.CacheData(params, "toc_Marriage", userID) if cacheDataErr != nil { return nil, cacheDataErr } @@ -618,12 +630,6 @@ func (l *QueryServiceLogic) ProcessTocEnterpriseLawsuitLogic(req *types.QuerySer return nil, verifyCodeErr } - // 校验三要素 后期应改为企业二要素 - //verifyErr := l.Verify(data, data.IDCard, data.Mobile) - //if verifyErr != nil { - // return nil, verifyErr - //} - // 缓存 params := map[string]interface{}{ "ent_name": data.EntName, @@ -636,6 +642,429 @@ func (l *QueryServiceLogic) ProcessTocEnterpriseLawsuitLogic(req *types.QuerySer return &types.QueryServiceResp{Id: cacheNo}, nil } + +func (l *QueryServiceLogic) ProcessTocPhoneThreeElementsLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocPhoneThreeElements + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "name": data.Name, + "id_card": data.IDCard, + "mobile": data.Mobile, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_PhoneThreeElements", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} +func (l *QueryServiceLogic) ProcessTocPhoneTwoElementsLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocPhoneTwoElements + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "name": data.Name, + "mobile": data.Mobile, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_PhoneTwoElements", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// 身份二要素 +func (l *QueryServiceLogic) ProcessTocIDCardTwoElementsLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocIDCardTwoElements + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "name": data.Name, + "id_card": data.IDCard, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_IDCardTwoElements", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// 自然人生存 +func (l *QueryServiceLogic) ProcessTocNaturalLifeStatusLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocIDCardTwoElements + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "name": data.Name, + "id_card": data.IDCard, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_NaturalLifeStatus", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// ProcessTocVehiclesUnderNameLogic 名下车辆那个 +func (l *QueryServiceLogic) ProcessTocVehiclesUnderNameLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocIDCardTwoElements + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "name": data.Name, + "id_card": data.IDCard, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_VehiclesUnderName", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// ProcessTocPersonVehicleVerificationLogic 人车核验 +func (l *QueryServiceLogic) ProcessTocPersonVehicleVerificationLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocPersonVehicleVerification + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "name": data.Name, + "car_type": data.CarType, + "car_license": data.CarLicense, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_PersonVehicleVerification", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// ProcessTocBankCardBlacklistLogic 银行卡黑名单 +func (l *QueryServiceLogic) ProcessTocBankCardBlacklistLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocBankCardBlacklist + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "name": data.Name, + "id_card": data.IDCard, + "mobile": data.Mobile, + "bank_card": data.BankCard, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_BankCardBlacklist", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// ProcessTocDualMarriageLogic 双人婚姻 +func (l *QueryServiceLogic) ProcessTocDualMarriageLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocDualMarriage + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "nameMan": data.NameMan, + "idCardMan": data.IDCardMan, + "nameWoman": data.NameWoman, + "idCardWoman": data.IDCardWoman, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_DualMarriage", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// ProcessTocPhoneNumberRiskLogic 手机号码风险 +func (l *QueryServiceLogic) ProcessTocPhoneNumberRiskLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocPhoneNumberRisk + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "mobile": data.Mobile, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_PhoneNumberRisk", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// ProcessTocNetworkDurationLogic 手机在网时长 +func (l *QueryServiceLogic) ProcessTocNetworkDurationLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocPhoneNumberRisk + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "mobile": data.Mobile, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_NetworkDuration", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// ProcessTocPhoneSecondaryCardLogic 手机二次卡 +func (l *QueryServiceLogic) ProcessTocPhoneSecondaryCardLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocPhoneSecondaryCard + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "mobile": data.Mobile, + "startDate": data.StartDate, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_PhoneSecondaryCard", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} + +// ProcessTocBankCardFourElementsLogic 银行卡四要素 +func (l *QueryServiceLogic) ProcessTocBankCardFourElementsLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { + userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx) + if getUidErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr) + } + + // AES解密 + decryptData, DecryptDataErr := l.DecryptData(req.Data) + if DecryptDataErr != nil { + return nil, DecryptDataErr + } + + // 校验参数 + var data types.TocBankCardBlacklist + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) + } + + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) + } + + params := map[string]interface{}{ + "name": data.Name, + "id_card": data.IDCard, + "mobile": data.Mobile, + "bank_card": data.BankCard, + } + cacheNo, cacheDataErr := l.CacheData(params, "toc_BankCardFourElements", userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + + return &types.QueryServiceResp{Id: cacheNo}, nil +} func (l *QueryServiceLogic) DecryptData(data string) ([]byte, error) { secretKey := l.svcCtx.Config.Encrypt.SecretKey key, decodeErr := hex.DecodeString(secretKey) @@ -670,9 +1099,9 @@ func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) er if l.svcCtx.Config.SystemConfig.ThreeVerify { // 三要素验证 threeVerification := service.ThreeFactorVerificationRequest{ - Name, - IDCard, - Mobile, + Name: Name, + IDCard: IDCard, + Mobile: Mobile, } verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification) if err != nil { @@ -683,8 +1112,8 @@ func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) er } } else { twoVerification := service.TwoFactorVerificationRequest{ - Name, - IDCard, + Name: Name, + IDCard: IDCard, } verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification) if err != nil { diff --git a/app/user/cmd/api/internal/service/alipayService.go b/app/user/cmd/api/internal/service/alipayService.go index 811e2f1..f627162 100644 --- a/app/user/cmd/api/internal/service/alipayService.go +++ b/app/user/cmd/api/internal/service/alipayService.go @@ -71,7 +71,7 @@ func (a *AliPayService) CreateAlipayH5Order(amount float64, subject string, outT TotalAmount: totalAmount, ProductCode: "QUICK_WAP_WAY", // H5支付专用产品码 NotifyURL: a.config.NotifyUrl, // 异步回调通知地址 - ReturnURL: "http://192.168.1.124:5173/#/pages/report", + ReturnURL: a.config.ReturnURL, }, } diff --git a/app/user/cmd/api/internal/service/apirequestService.go b/app/user/cmd/api/internal/service/apirequestService.go index 412a9be..09bc0c7 100644 --- a/app/user/cmd/api/internal/service/apirequestService.go +++ b/app/user/cmd/api/internal/service/apirequestService.go @@ -8,9 +8,13 @@ import ( "github.com/Masterminds/squirrel" "github.com/tidwall/gjson" "github.com/zeromicro/go-zero/core/logx" + "io" + "net/http" + "net/url" "qnc-server/app/user/cmd/api/internal/config" "qnc-server/app/user/model" "qnc-server/pkg/lzkit/crypto" + "strings" "sync" "sync/atomic" "time" @@ -19,17 +23,19 @@ import ( type ApiRequestService struct { config config.Config westDexService *WestDexService + yushanService *YushanService featureModel model.FeatureModel productFeatureModel model.ProductFeatureModel } // NewApiRequestService 是一个构造函数,用于初始化 ApiRequestService -func NewApiRequestService(c config.Config, westDexService *WestDexService, featureModel model.FeatureModel, productFeatureModel model.ProductFeatureModel) *ApiRequestService { +func NewApiRequestService(c config.Config, westDexService *WestDexService, yushanService *YushanService, featureModel model.FeatureModel, productFeatureModel model.ProductFeatureModel) *ApiRequestService { return &ApiRequestService{ config: c, featureModel: featureModel, productFeatureModel: productFeatureModel, westDexService: westDexService, + yushanService: yushanService, } } @@ -97,7 +103,7 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]b result.Error = preprocessErr.Error() result.Data = resp resultsCh <- result - errorsCh <- fmt.Errorf("请求预处理失败: %v", preprocessErr) + errorsCh <- fmt.Errorf("请求失败: %v", preprocessErr) atomic.AddInt32(&errorCount, 1) if atomic.LoadInt32(&errorCount) >= int32(errorLimit) { cancel() @@ -140,14 +146,26 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]b // ------------------------------------请求处理器-------------------------- var requestProcessors = map[string]func(*ApiRequestService, []byte) ([]byte, error){ - "G09SC02": (*ApiRequestService).ProcessG09SC02Request, - "G27BJ05": (*ApiRequestService).ProcessG27BJ05Request, - "G26BJ05": (*ApiRequestService).ProcessG26BJ05Request, - "G34BJ03": (*ApiRequestService).ProcessG34BJ03Request, - "G35SC01": (*ApiRequestService).ProcessG35SC01Request, - "G28BJ05": (*ApiRequestService).ProcessG28BJ05Request, - "G05HZ01": (*ApiRequestService).ProcessG05HZ01Request, - "Q23SC01": (*ApiRequestService).ProcessQ23SC01Request, + "G09SC02": (*ApiRequestService).ProcessG09SC02Request, + "G27BJ05": (*ApiRequestService).ProcessG27BJ05Request, + "G26BJ05": (*ApiRequestService).ProcessG26BJ05Request, + "G34BJ03": (*ApiRequestService).ProcessG34BJ03Request, + "G35SC01": (*ApiRequestService).ProcessG35SC01Request, + "G28BJ05": (*ApiRequestService).ProcessG28BJ05Request, + "G05HZ01": (*ApiRequestService).ProcessG05HZ01Request, + "Q23SC01": (*ApiRequestService).ProcessQ23SC01Request, + "G15BJ02": (*ApiRequestService).ProcessG15BJ02Request, + "G17BJ02": (*ApiRequestService).ProcessG17BJ02Request, + "G08SC02": (*ApiRequestService).ProcessG08SC02Request, + "KZEYS": (*ApiRequestService).ProcessKZEYSRequest, + "P_C_B332": (*ApiRequestService).ProcessP_C_B332Request, + "FIN019": (*ApiRequestService).ProcessFIN019Request, + "CAR061": (*ApiRequestService).ProcessCAR061Request, + "G10SC02": (*ApiRequestService).ProcessG10SC02Request, + "G03HZ01": (*ApiRequestService).ProcessG03HZ01Request, + "G02BJ02": (*ApiRequestService).ProcessG02BJ02Request, + "G19BJ02": (*ApiRequestService).ProcessG19BJ02Request, + "G20GZ01": (*ApiRequestService).ProcessG20GZ01Request, } // PreprocessRequestApi 调用指定的请求处理函数 @@ -524,3 +542,388 @@ func (a *ApiRequestService) ProcessQ23SC01Request(params []byte) ([]byte, error) } return finalDataBytes, nil } +func (a *ApiRequestService) ProcessG15BJ02Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + mobile := gjson.GetBytes(params, "mobile") + + if !name.Exists() || !idCard.Exists() || !mobile.Exists() { + return nil, errors.New("api请求, G15BJ02, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "name": a.westDexService.Encrypt(name.String()), + "idNo": a.westDexService.Encrypt(idCard.String()), + "phone": a.westDexService.Encrypt(mobile.String()), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G15BJ02", request) + if callApiErr != nil { + return nil, callApiErr + } + dataResult := gjson.GetBytes(resp, "data.code") + if !dataResult.Exists() { + return nil, fmt.Errorf("code 字段不存在") + } + code := dataResult.Int() + // 处理允许的 code 值 + if code == 1000 || code == 1003 || code == 1004 || code == 1005 { + return resp, nil + } + + return nil, fmt.Errorf("三要素核验失败: %+v", resp) +} +func (a *ApiRequestService) ProcessG17BJ02Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + mobile := gjson.GetBytes(params, "mobile") + + if !name.Exists() || !mobile.Exists() { + return nil, errors.New("api请求, G17BJ02, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "name": a.westDexService.Encrypt(name.String()), + "phone": a.westDexService.Encrypt(mobile.String()), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G17BJ02", request) + if callApiErr != nil { + return nil, callApiErr + } + dataResult := gjson.GetBytes(resp, "data.code") + if !dataResult.Exists() { + return nil, fmt.Errorf("code 字段不存在") + } + code := dataResult.Int() + // 处理允许的 code 值 + if code == 1000 || code == 1001 { + return resp, nil + } + + return nil, fmt.Errorf("手机二要素核验失败: %+v", resp) +} +func (a *ApiRequestService) ProcessG08SC02Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + + if !name.Exists() || !idCard.Exists() { + return nil, errors.New("api请求, G08SC02, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "xm": a.westDexService.Encrypt(name.String()), + "gmsfzhm": a.westDexService.Encrypt(idCard.String()), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G08SC02", request) + if callApiErr != nil { + return nil, callApiErr + } + return resp, nil +} +func (a *ApiRequestService) ProcessKZEYSRequest(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + + if !name.Exists() || !idCard.Exists() { + return nil, errors.New("api请求, KZEYS, 获取相关参数失败") + } + + appCode := a.config.Ali.Code + requestUrl := "https://kzidcardv1.market.alicloudapi.com/api-mall/api/id_card/check" + + // 构造查询参数 + data := url.Values{} + data.Add("name", name.String()) + data.Add("idcard", idCard.String()) + + req, err := http.NewRequest(http.MethodPost, requestUrl, strings.NewReader(data.Encode())) + if err != nil { + return nil, fmt.Errorf("KZEYS 创建请求失败: %+v", err) + } + req.Header.Set("Authorization", "APPCODE "+appCode) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("KZEYS 请求失败: %+v", err) + } + + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("KZEYS 请求失败, 状态码: %d", resp.StatusCode) + } + + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("KZEYS 响应体读取失败:%v", err) + } + // 使用 gjson 解析 JSON 数据 + code := gjson.GetBytes(respBody, "code").Int() + if code != 200 { + msg := gjson.GetBytes(respBody, "msg").String() + if msg == "" { + msg = "未知错误" + } + return nil, fmt.Errorf("KZEYS 响应失败: %s", msg) + } + + respData := gjson.GetBytes(respBody, "data") + if !respData.Exists() { + return nil, fmt.Errorf("KZEYS 响应, data 字段不存在") + } + dataRaw := respData.Raw + // 成功返回 + return []byte(dataRaw), nil +} + +// 人车核验 +func (a *ApiRequestService) ProcessP_C_B332Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + carType := gjson.GetBytes(params, "car_type") + carLicense := gjson.GetBytes(params, "car_license") + if !name.Exists() || !carType.Exists() || !carLicense.Exists() { + return nil, errors.New("api请求, P_C_B332, 获取相关参数失败: car_number") + } + + request := map[string]interface{}{ + "name": name.String(), + "carType": carType.String(), + "carNumber": carLicense.String(), + } + resp, err := a.yushanService.request("P_C_B332", request) + if err != nil { + return nil, fmt.Errorf("人车核验查询失败: %+v", err) + } + return resp, nil +} + +// 银行卡黑名单 +func (a *ApiRequestService) ProcessFIN019Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + mobile := gjson.GetBytes(params, "mobile") + bankCard := gjson.GetBytes(params, "bank_card") + if !name.Exists() || !idCard.Exists() || !mobile.Exists() || !bankCard.Exists() { + return nil, errors.New("api请求, FIN019, 获取相关参数失败: car_number") + } + + request := map[string]interface{}{ + "name": name.String(), + "cardNo": idCard.String(), + "mobile": mobile.String(), + "cardld": bankCard.String(), + } + resp, err := a.yushanService.request("FIN019", request) + if err != nil { + return nil, fmt.Errorf("银行卡黑名单查询失败: %+v", err) + } + return resp, nil +} + +// 名下车辆 +func (a *ApiRequestService) ProcessCAR061Request(params []byte) ([]byte, error) { + idCard := gjson.GetBytes(params, "id_card") + + if !idCard.Exists() { + return nil, errors.New("api请求, CAR061, 获取相关参数失败") + } + request := map[string]interface{}{ + "cardNo": idCard.String(), + } + resp, err := a.yushanService.request("CAR061", request) + if err != nil { + return nil, fmt.Errorf("名下车辆查询失败: %+v", err) + } + return resp, nil +} +func (a *ApiRequestService) ProcessG10SC02Request(params []byte) ([]byte, error) { + // 提取男方和女方信息 + nameMan := gjson.GetBytes(params, "nameMan") + idCardMan := gjson.GetBytes(params, "idCardMan") + nameWoman := gjson.GetBytes(params, "nameWoman") + idCardWoman := gjson.GetBytes(params, "idCardWoman") + + // 校验是否存在必要参数 + if !nameMan.Exists() || !idCardMan.Exists() || !nameWoman.Exists() || !idCardWoman.Exists() { + return nil, errors.New("请求参数缺失:需要提供男方和女方的姓名及身份证号") + } + + // 构造请求数据 + request := map[string]interface{}{ + "data": map[string]interface{}{ + "certNumMan": a.westDexService.Encrypt(idCardMan.String()), + "nameMan": a.westDexService.Encrypt(nameMan.String()), + "certNumWoman": a.westDexService.Encrypt(idCardWoman.String()), + "nameWoman": a.westDexService.Encrypt(nameWoman.String()), + }, + } + + // 调用 API + resp, callApiErr := a.westDexService.CallAPI("G10SC02", request) + if callApiErr != nil { + return nil, callApiErr + } + + // 解析响应数据 + code := gjson.GetBytes(resp, "code").String() + + // 状态码校验 + if code != "200" { + return nil, fmt.Errorf("婚姻查询失败:%s", string(resp)) + } + + result := gjson.GetBytes(resp, "data.0.maritalStatus") + + if result.Exists() { + responseMap := map[string]string{"status": result.String()} + jsonResponse, err := json.Marshal(responseMap) + if err != nil { + return nil, err + } + return jsonResponse, nil + } else { + return nil, errors.New("查询为空") + } +} + +// 手机号码风险 +func (a *ApiRequestService) ProcessG03HZ01Request(params []byte) ([]byte, error) { + mobile := gjson.GetBytes(params, "mobile") + + if !mobile.Exists() { + return nil, errors.New("api请求, G03HZ01, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "mobile": a.westDexService.Encrypt(mobile.String()), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G03HZ01", request) + if callApiErr != nil { + return nil, callApiErr + } + // 获取 code 字段 + codeResult := gjson.GetBytes(resp, "code") + if !codeResult.Exists() || codeResult.String() != "0000" { + return nil, fmt.Errorf("查询手机号码风险失败, %s", string(resp)) + } + data := gjson.GetBytes(resp, "data.data") + if !data.Exists() { + return nil, fmt.Errorf("查询手机号码风险失败, %s", string(resp)) + } + return []byte(data.Raw), nil +} + +// 手机在网时长 +func (a *ApiRequestService) ProcessG02BJ02Request(params []byte) ([]byte, error) { + mobile := gjson.GetBytes(params, "mobile") + + if !mobile.Exists() { + return nil, errors.New("api请求, G02BJ02, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "phone": a.westDexService.Encrypt(mobile.String()), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G02BJ02", request) + if callApiErr != nil { + return nil, callApiErr + } + // 获取 code 字段 + codeResult := gjson.GetBytes(resp, "code") + validCodes := map[string]bool{"1006": true, "1007": true, "1008": true, "1009": true, "1010": true} + if !validCodes[codeResult.String()] { + return nil, fmt.Errorf("查询手机在网时长失败, %s", string(resp)) + } + data := gjson.GetBytes(resp, "data") + if !data.Exists() { + return nil, fmt.Errorf("查询手机在网时长失败, %s", string(resp)) + } + return []byte(data.Raw), nil +} + +// 手机二次卡 +func (a *ApiRequestService) ProcessG19BJ02Request(params []byte) ([]byte, error) { + mobile := gjson.GetBytes(params, "mobile") + startDate := gjson.GetBytes(params, "startDate") + if !mobile.Exists() { + return nil, errors.New("api请求, G19BJ02, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "phone": a.westDexService.Encrypt(mobile.String()), + "startDate": startDate.String(), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G19BJ02", request) + if callApiErr != nil { + return nil, callApiErr + } + // 获取 code 字段 + codeResult := gjson.GetBytes(resp, "code") + if !codeResult.Exists() || (codeResult.String() != "1025" && codeResult.String() != "1026") { + return nil, fmt.Errorf("手机二次卡失败, %s", string(resp)) + } + data := gjson.GetBytes(resp, "data") + if !data.Exists() { + return nil, fmt.Errorf("手机二次卡失败, %s", string(resp)) + } + return []byte(data.Raw), nil +} + +// 银行卡四要素 +func (a *ApiRequestService) ProcessG20GZ01Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + mobile := gjson.GetBytes(params, "mobile") + bankCard := gjson.GetBytes(params, "bank_card") + + if !mobile.Exists() { + return nil, errors.New("api请求, G20GZ01, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "name": a.westDexService.Encrypt(name.String()), + "idcard": a.westDexService.Encrypt(idCard.String()), + "acc_no": a.westDexService.Encrypt(bankCard.String()), + "mobile": a.westDexService.Encrypt(mobile.String()), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G20GZ01", request) + if callApiErr != nil { + return nil, callApiErr + } + // 获取 code 字段 + codeResult := gjson.GetBytes(resp, "code") + if !codeResult.Exists() || codeResult.String() != "10000" { + return nil, fmt.Errorf("银行卡四要素失败, %s", string(resp)) + } + data := gjson.GetBytes(resp, "data") + if !data.Exists() { + return nil, fmt.Errorf("银行卡四要素失败, %s", string(resp)) + } + // 解析 data.Raw 字符串为接口类型 + var parsedData interface{} + err := json.Unmarshal([]byte(data.String()), &parsedData) + if err != nil { + return nil, fmt.Errorf("解析 data 失败: %v", err) + } + + // 将解析后的数据重新编码为 []byte + resultBytes, err := json.Marshal(parsedData) + if err != nil { + return nil, fmt.Errorf("重新编码 data 失败: %v", err) + } + + return resultBytes, nil +} diff --git a/app/user/cmd/api/internal/service/yushanService.go b/app/user/cmd/api/internal/service/yushanService.go new file mode 100644 index 0000000..912f7f7 --- /dev/null +++ b/app/user/cmd/api/internal/service/yushanService.go @@ -0,0 +1,186 @@ +package service + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/tidwall/gjson" + "io" + "net/http" + "qnc-server/app/user/cmd/api/internal/config" + "strings" + "time" +) + +type YushanService struct { + config config.YushanConfig +} + +func NewYushanService(c config.Config) *YushanService { + return &YushanService{ + config: c.YushanConfig, + } +} + +func (y *YushanService) request(prodID string, params map[string]interface{}) ([]byte, error) { + // 获取当前时间戳 + unixMilliseconds := time.Now().UnixNano() / int64(time.Millisecond) + + // 生成请求序列号 + requestSN, _ := y.GenerateRandomString() + + // 构建请求数据 + reqData := map[string]interface{}{ + "prod_id": prodID, + "req_time": unixMilliseconds, + "request_sn": requestSN, + "req_data": params, + } + + // 将请求数据转换为 JSON 字节数组 + messageBytes, err := json.Marshal(reqData) + if err != nil { + return nil, err + } + + // 获取 API 密钥 + key, err := hex.DecodeString(y.config.ApiKey) + if err != nil { + return nil, err + } + + // 使用 AES CBC 加密请求数据 + cipherText := y.AES_CBC_Encrypt(messageBytes, key) + + // 将加密后的数据编码为 Base64 字符串 + content := base64.StdEncoding.EncodeToString(cipherText) + + // 发起 HTTP 请求 + client := &http.Client{} + req, err := http.NewRequest("POST", y.config.Url, strings.NewReader(content)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("ACCT_ID", y.config.AcctID) + + // 执行请求 + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + // 读取响应体 + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var respData []byte + + if IsJSON(string(body)) { + respData = body + } else { + sDec, err := base64.StdEncoding.DecodeString(string(body)) + if err != nil { + return nil, err + } + respData = y.AES_CBC_Decrypt(sDec, key) + } + retCode := gjson.GetBytes(respData, "retcode").String() + + if retCode == "100000" { + // retcode 为 100000,表示查询为空 + return nil, fmt.Errorf("羽山请求查空: %s", string(respData)) + } else if retCode == "000000" { + // retcode 为 000000,表示有数据,返回 retdata + retData := gjson.GetBytes(respData, "retdata") + if !retData.Exists() { + return nil, fmt.Errorf("羽山请求retdata为空: %s", string(respData)) + } + return []byte(retData.Raw), nil + } else { + return nil, fmt.Errorf("羽山请求未知的状态码: %s", string(respData)) + } + +} + +// 判断字符串是否为 JSON 格式 +func IsJSON(s string) bool { + var js interface{} + return json.Unmarshal([]byte(s), &js) == nil +} + +// GenerateRandomString 生成一个32位的随机字符串订单号 +func (y *YushanService) GenerateRandomString() (string, error) { + // 创建一个16字节的数组 + bytes := make([]byte, 16) + // 读取随机字节到数组中 + if _, err := rand.Read(bytes); err != nil { + return "", err + } + // 将字节数组编码为16进制字符串 + return hex.EncodeToString(bytes), nil +} + +// AEC加密(CBC模式) +func (y *YushanService) AES_CBC_Encrypt(plainText []byte, key []byte) []byte { + //指定加密算法,返回一个AES算法的Block接口对象 + block, err := aes.NewCipher(key) + if err != nil { + panic(err) + } + //进行填充 + plainText = Padding(plainText, block.BlockSize()) + //指定初始向量vi,长度和block的块尺寸一致 + iv := []byte("0000000000000000") + //指定分组模式,返回一个BlockMode接口对象 + blockMode := cipher.NewCBCEncrypter(block, iv) + //加密连续数据库 + cipherText := make([]byte, len(plainText)) + blockMode.CryptBlocks(cipherText, plainText) + //返回base64密文 + return cipherText +} + +// AEC解密(CBC模式) +func (y *YushanService) AES_CBC_Decrypt(cipherText []byte, key []byte) []byte { + //指定解密算法,返回一个AES算法的Block接口对象 + block, err := aes.NewCipher(key) + if err != nil { + panic(err) + } + //指定初始化向量IV,和加密的一致 + iv := []byte("0000000000000000") + //指定分组模式,返回一个BlockMode接口对象 + blockMode := cipher.NewCBCDecrypter(block, iv) + //解密 + plainText := make([]byte, len(cipherText)) + blockMode.CryptBlocks(plainText, cipherText) + //删除填充 + plainText = UnPadding(plainText) + return plainText +} // 对明文进行填充 +func Padding(plainText []byte, blockSize int) []byte { + //计算要填充的长度 + n := blockSize - len(plainText)%blockSize + //对原来的明文填充n个n + temp := bytes.Repeat([]byte{byte(n)}, n) + plainText = append(plainText, temp...) + return plainText +} + +// 对密文删除填充 +func UnPadding(cipherText []byte) []byte { + //取出密文最后一个字节end + end := cipherText[len(cipherText)-1] + //删除填充 + cipherText = cipherText[:len(cipherText)-int(end)] + return cipherText +} diff --git a/app/user/cmd/api/internal/svc/servicecontext.go b/app/user/cmd/api/internal/svc/servicecontext.go index 200c04e..02a3652 100644 --- a/app/user/cmd/api/internal/svc/servicecontext.go +++ b/app/user/cmd/api/internal/svc/servicecontext.go @@ -27,6 +27,7 @@ type ServiceContext struct { WechatPayService *service.WechatPayService ApplePayService *service.ApplePayService WestDexService *service.WestDexService + YushanService *service.YushanService ApiRequestService *service.ApiRequestService AsynqServer *asynq.Server // 服务端 AsynqService *service.AsynqService // 客户端 @@ -51,6 +52,7 @@ func NewServiceContext(c config.Config) *ServiceContext { }, ) westDexService := service.NewWestDexService(c) + yushanService := service.NewYushanService(c) productFeatureModel := model.NewProductFeatureModel(db, c.CacheRedis) featureModel := model.NewFeatureModel(db, c.CacheRedis) return &ServiceContext{ @@ -61,9 +63,10 @@ func NewServiceContext(c config.Config) *ServiceContext { WechatPayService: service.NewWechatPayService(c), ApplePayService: service.NewApplePayService(c), WestDexService: westDexService, + YushanService: yushanService, VerificationService: service.NewVerificationService(c, westDexService), AsynqServer: asynqServer, - ApiRequestService: service.NewApiRequestService(c, westDexService, featureModel, productFeatureModel), + ApiRequestService: service.NewApiRequestService(c, westDexService, yushanService, featureModel, productFeatureModel), AsynqService: service.NewAsynqService(c), UserModel: model.NewUserModel(db, c.CacheRedis), UserAuthModel: model.NewUserAuthModel(db, c.CacheRedis), diff --git a/app/user/cmd/api/internal/types/query.go b/app/user/cmd/api/internal/types/query.go index e0f80a0..4572530 100644 --- a/app/user/cmd/api/internal/types/query.go +++ b/app/user/cmd/api/internal/types/query.go @@ -58,3 +58,46 @@ type EntLawsuitReq struct { Mobile string `json:"mobile" validate:"required,mobile"` Code string `json:"code" validate:"required"` } +type TocPhoneThreeElements struct { + Name string `json:"name" validate:"required,name"` + IDCard string `json:"id_card" validate:"required,idCard"` + Mobile string `json:"mobile" validate:"required,mobile"` +} +type TocPhoneTwoElements struct { + Name string `json:"name" validate:"required,name"` + Mobile string `json:"mobile" validate:"required,mobile"` +} +type TocIDCardTwoElements struct { + Name string `json:"name" validate:"required,name"` + IDCard string `json:"id_card" validate:"required,idCard"` +} +type TocDualMarriage struct { + NameMan string `json:"name_man" validate:"required,name"` + IDCardMan string `json:"id_card_man" validate:"required,idCard"` + NameWoman string `json:"name_woman" validate:"required,name"` + IDCardWoman string `json:"id_card_woman" validate:"required,idCard"` +} +type TocPersonVehicleVerification struct { + Name string `json:"name" validate:"required,name"` + CarType string `json:"car_type" validate:"required"` + CarLicense string `json:"car_license" validate:"required"` +} + +// 银行卡黑名单 +type TocBankCardBlacklist struct { + Name string `json:"name" validate:"required,name"` + IDCard string `json:"id_card" validate:"required,idCard"` + Mobile string `json:"mobile" validate:"required,mobile"` + BankCard string `json:"bank_card" validate:"required"` +} + +// 手机号码风险 +type TocPhoneNumberRisk struct { + Mobile string `json:"mobile" validate:"required,mobile"` +} + +// 手机二次卡 +type TocPhoneSecondaryCard struct { + Mobile string `json:"mobile" validate:"required,mobile"` + StartDate string `json:"start_date" validate:"required"` +} diff --git a/app/user/cmd/api/internal/types/types.go b/app/user/cmd/api/internal/types/types.go index 9b6a375..dab2dfc 100644 --- a/app/user/cmd/api/internal/types/types.go +++ b/app/user/cmd/api/internal/types/types.go @@ -70,6 +70,7 @@ type Query struct { OrderId int64 `json:"order_id"` // 订单ID UserId int64 `json:"user_id"` // 用户ID ProductName string `json:"product_name"` // 产品ID + QueryParams map[string]interface{} `json:"query_params"` QueryData []map[string]interface{} `json:"query_data"` CreateTime string `json:"create_time"` // 创建时间 UpdateTime string `json:"update_time"` // 更新时间 diff --git a/app/user/cmd/api/user.go b/app/user/cmd/api/main.go similarity index 91% rename from app/user/cmd/api/user.go rename to app/user/cmd/api/main.go index 7b40523..4e7ef8b 100644 --- a/app/user/cmd/api/user.go +++ b/app/user/cmd/api/main.go @@ -25,9 +25,9 @@ func main() { // 根据 ENV 加载不同的配置文件 var defaultConfigFile string if env == "development" { - defaultConfigFile = "etc/user.dev.yaml" // 开发环境配置 + defaultConfigFile = "etc/main.dev.yaml" // 开发环境配置 } else { - defaultConfigFile = "etc/user.yaml" // 生产环境配置 + defaultConfigFile = "etc/main.yaml" // 生产环境配置 } configFile := flag.String("f", defaultConfigFile, "the config file") flag.Parse() diff --git a/deploy/sql/product.sql b/deploy/sql/product.sql index be588c1..cfcc245 100644 --- a/deploy/sql/product.sql +++ b/deploy/sql/product.sql @@ -70,7 +70,7 @@ CREATE TABLE `feature` ( `api_id` varchar kujmio,5(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'API标识', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '描述', PRIMARY KEY (`id`), - UNIQUE KEY `unique_api_id` (`api_id`) + UNIQUE KEY `unique_api_id` (`api_id`)`` ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='功能表'; -- ---------------------------- diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..703b933 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,69 @@ +services: + + mysql: + image: mysql:8.0.34 + container_name: qnc_mysql + environment: + # 时区上海 - Time zone Shanghai (Change if needed) + TZ: Asia/Shanghai + # root 密码 - root password + MYSQL_ROOT_PASSWORD: yfg87gyuYiy1 + MYSQL_DATABASE: qnc + MYSQL_USER: qnc + MYSQL_PASSWORD: 5vg67b3UNHu8 + ports: + - "20001:3306" + volumes: + # 数据挂载 - Data mounting + - ./data/mysql/data:/var/lib/mysql + # 日志 + command: + # 将mysql8.0默认密码策略 修改为 原先 策略 (mysql8.0对其默认策略做了更改 会导致密码无法匹配) + # Modify the Mysql 8.0 default password strategy to the original strategy (MySQL8.0 to change its default strategy will cause the password to be unable to match) + --default-authentication-plugin=mysql_native_password + --character-set-server=utf8mb4 + --collation-server=utf8mb4_general_ci + --explicit_defaults_for_timestamp=true + --lower_case_table_names=1 + privileged: true + restart: always + networks: + - qnc_net + + redis: + image: redis:7.4.0 + container_name: qnc_redis + ports: + - "20002:6379" + environment: + # 时区上海 - Time zone Shanghai (Change if needed) + TZ: Asia/Shanghai + volumes: + # 数据文件 - data files + - ./data/redis/data:/data:rw + command: "redis-server --requirepass 3m3WsgyCKWqz --appendonly yes" + privileged: true + restart: always + networks: + - qnc_net + + asynqmon: + image: hibiken/asynqmon:latest + container_name: qnc_asynqmon + ports: + - "20003:8080" + environment: + - TZ=Asia/Shanghai + command: + - '--redis-addr=qnc_redis:6379' + - '--redis-password=3m3WsgyCKWqz' + restart: always + networks: + - qnc_net + depends_on: + - redis + + +networks: + qnc_net: + driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml index 23b3d4d..7be0d80 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -66,8 +66,8 @@ services: depends_on: - redis - user: - container_name: qnc_user + main: + container_name: qnc_main build: context: . dockerfile: ./app/user/cmd/api/Dockerfile diff --git a/pkg/lzkit/validator/error_messages.go b/pkg/lzkit/validator/error_messages.go index 4593f53..a470cdf 100644 --- a/pkg/lzkit/validator/error_messages.go +++ b/pkg/lzkit/validator/error_messages.go @@ -2,18 +2,28 @@ package validator // 定义自定义错误消息 var customMessages = map[string]string{ - "Name.min": "姓名不能少于1个字", - "Name.required": "姓名是必填项", - "Name.name": "姓名只能包含中文", - "Mobile.required": "手机号是必填项", - "Mobile.min": "电话号码必须为有效的中国电话号码", - "Mobile.max": "电话号码必须为有效的中国电话号码", - "Mobile.mobile": "电话号码必须为有效的中国电话号码", - "IDCard.required": "身份证号是必填项", - "IDCard.idCard": "无效的身份证号码", - "Password.min": "密码不能少于8位数", - "Password.max": "密码不能超过32位数", - "Password.password": "密码强度太弱", + "Name.min": "姓名不能少于1个字", + "Name.required": "姓名是必填项", + "Name.name": "姓名只能包含中文", + "NameMan.min": "男方姓名不能少于1个字", + "NameMan.required": "男方姓名是必填项", + "NameMan.name": "男方姓名只能包含中文", + "NameWoman.min": "女方姓名不能少于1个字", + "NameWoman.required": "女方姓名是必填项", + "NameWoman.name": "女方姓名只能包含中文", + "Mobile.required": "手机号是必填项", + "Mobile.min": "电话号码必须为有效的中国电话号码", + "Mobile.max": "电话号码必须为有效的中国电话号码", + "Mobile.mobile": "电话号码必须为有效的中国电话号码", + "IDCard.required": "身份证号是必填项", + "IDCard.idCard": "无效的身份证号码", + "IDCardMan.required": "男方身份证号是必填项", + "IDCardMan.idCard": "无效的男方身份证号码", + "IDCardWoman.required": "女方身份证号是必填项", + "IDCardWoman.idCard": "无效的女方身份证号码", + "Password.min": "密码不能少于8位数", + "Password.max": "密码不能超过32位数", + "Password.password": "密码强度太弱", //"EntCode.required":"请输入统一社会信用代码", //"EntCode.USCI": "请输入正确的统一社会信用代码", }