From dc4fcbf857af7950c5699d2a7e9bb0ac15c82449 Mon Sep 17 00:00:00 2001 From: liangzai <2440983361@qq.com> Date: Fri, 6 Feb 2026 13:34:49 +0800 Subject: [PATCH] f --- app/main/api/etc/main.dev.yaml | 17 +- app/main/api/etc/main.yaml | 11 +- app/main/api/internal/config/config.go | 13 +- .../admin_order/adminrefundorderlogic.go | 9 +- .../internal/logic/pay/alipaycallbacklogic.go | 4 +- .../logic/pay/wechatpaycallbacklogic.go | 4 +- .../internal/logic/query/queryservicelogic.go | 998 ++++----------- .../api/internal/queue/paySuccessNotify.go | 8 +- .../api/internal/service/alipayService.go | 42 +- .../api/internal/service/apirequestService.go | 263 ++++ app/main/api/internal/types/query.go | 85 ++ deploy/sql/product_feature_inserts.sql | 1099 +++++++++++++++++ 12 files changed, 1796 insertions(+), 757 deletions(-) create mode 100644 deploy/sql/product_feature_inserts.sql diff --git a/app/main/api/etc/main.dev.yaml b/app/main/api/etc/main.dev.yaml index 569a458..76cbef6 100644 --- a/app/main/api/etc/main.dev.yaml +++ b/app/main/api/etc/main.dev.yaml @@ -20,12 +20,19 @@ VerifyCode: Encrypt: SecretKey: "ff83609b2b24fc73196aac3d3dfb874f" Alipay: - AppID: "2021004161631930" - PrivateKey: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCRrZNr8DNs4LhPSulTLEg4RLREWVSFGS+Nl5Q2FxQ8DgkUYV+p3kfi4XmB2W/Ruz4egPxEB0V/xj75OktVphVKY8rI6OaNnVoFVe5NqGa5MTj3wLwBIv/hMHA1VAru2KLIv9R1FR7LpWmreHSkpJ65CD2mZqYuMCekOfzMQZIGgSagEU4my0bLbFWw7M3qZz4vm2KUtm4Ew28OUJDkqygjPzXgS5l5niYQvqPjiQNdnTtoIcNcHo07tS8lmf/hdgq9EtVfY7Y0brESfgvOoVJeg1hTHEj0hyWnnWPeA4HD2izANP/5ObRX4ZVqpVju+7PSpbeFd71fxbR1blAVnrqTAgMBAAECggEASpkwHN3r9507xJ7/zG+oq+fCyB1WgrHbAA7W/rviyL4HOECE1F/XP/9mUXAfKq9PqB81D0EJ/dxu8wE/AqUB0g44EZnyNiKVrpXKakoKEFt8aKJxo8NgdNhxHV3kG1skQNi62xntoysZaY1NbeI+xVHLACMghhZytk5bfd02Ac3rMBz3X8Cl1R+3mgU0zFc5f476VRxywiRQM+QNJIaHDNB4vw1TKI0K92mEKD8lOuNZD7d5TCBZi3r08t8FFAkMjIMDiFvFRFmAqMg3NyaIGUkLVDU2zUP0Vlzmo9ghCV9hluqDqeP4RhxQydOw+rxGBk+crYQBhPyYOI/I9PFXAQKBgQDHSRRTPqYbCfztmwk3AIH7VN6izyU3FljEXAsdf+UVJpRa8429J3e+sB96jxhiwVlCzX4CDjsa/Pu0iQQx22a0AZs5GTE0MJ1FVydfGlyqF6/hRS4TswSkklW3be7/KDAjgj2+/wap+mN7rRmDkdvxgCJG6MiWuRAthhg/g16wIwKBgQC7Iu7D4yQXRKheL6p6pbMtE+oD58/EJ2vO8ZUz3LiPc9pZ6+bp4nkBP6JOuYiB5jkzWQifKe6hsXpv06kWzaBEzz4f4SUpWDmdBchNoct3pB/k66FaxHLO/pG4RV86hqscqTdutmdC62bbwM6yCtJ+3rS5rlCxDGQkGJbM+wM60QKBgH5nQyYeCbwC1NRdTzX883VYerLoEyHi4cEC5OX8NnD4/IbIDzJYc2KXUhAp7XzOSPDPaMqi/ih7KKh1dByvnnA0yKEp8oS5BThzNHzlOruEtMF9YOGL3jkIvKfRahOcCRSsyr94AWEVeb57qEBE5y5CaPtzMbAwiCtn779xc0DjAoGAZwEGXWokDm6rIhSoiJO2OQSyFW4+LSDptWHCF2bRa5yAPmiblHck1awaAa0b1yxKpdnG5hzljbirxOvDMZsDMXzFHDUICGbYZ3asVxbMcNE1AQM1sElbTFZRDRWaIhPIEaGOsnDSC8KYvjK1UsikLlMVNPMe1SUV5cxnDPLJR1ECgYEAw8M09uLylPtfGq7oyE2R6xC2kUA8EJ6aapJgUs/UZ6dtjtvudbYzUo0Cgnb12hpN3hfLc5O0/P4nRzZ72Hm43cMiRNLJi4BYCa0m/mCxq+RcoBWYQTIraHnR17yIQhxt5IBRVjgbvYCnryx5Jd5wjOvv7DdnGFJLepzSJwlGqeU=" + AppID: "2021006121698606" + PrivateKey: "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCx3TqaCUgZIMfG8Lu8fqkKqKLzONB9NBp4qCM2CAgxkUK1fd48XZ3ANDzfzNoeIbLbR/VL3ZUgyX/F8jO7Cit71JS58X9b1ngeRyBdaiBhLZgHb7Ngg0f1zDJuq8H6/i3Tiu9PaH0iOFKeaFCCpkakFyXjp//rqkcj2bPfa6lX0bD4YcILz8DC3iPy/cXHrHwaBryhYouYA3bKFROHykfF5D+tS2PZdR13BiDVElwDuquZCMdRdISfTw8snp5HSxA0TyRZIiGrtU3WvSKxYi2s8smZl/uYN1uj4w4GOivnTrkBdLy6DBqvgqRsCeYDDV5UyjtbAhvksZH60EWS3HTfAgMBAAECggEAK4dv+xjAa13pZpet6nC5ICGrV4kVBT9GJzdG/scycicRw2cdh3qFy+884qy4yN0Ib8AJmVqOT6rguWoQHPtdLv4Us/kVaT1wwkA3/ISnjgDhjxhYNwuKBe7GfO1OGQYx4u7CqJVy4ngUSC5RXdghu7Dqle+co2lV5cE20zv/Ar2nYo4p9fxcl/XAttqdRyby3ge6zJZP46Ru4CHzFzyUsrJYC575R3Jq68Zrr/+v0BmpEm/wAmoQE8W0ElMMH+Jw0twj+4l6PaUcq9oUVIL9wzl7ay1B6dKyxEOyinGYrmd65NzsTu8HhEpFdvQ+1O27XyahLsNWpSamJlV23ns/EQKBgQDd2UiQQRrj+itfa1/Zehy8MstEICw73LMDk129yNG9cU8U4y5vaTJkAcDTfme08B3uVVhsIUhJsFdgnh4ayyYW3jsB5BBBgszhwYQciH7f/3nE3rcX/TIs6yQAQkPhQi2RNSdn3SrCIhxgu9TwrZIDyQYJ6kk/9qEmZd93RrhOBwKBgQDNPpS1jFt4l08kzCHzfTvTbIu5z/6NPxmRSpcrdkoOAUfzlKSkRnKJuzkFSJEmWpFXILfNiza1dBYncg60Lu58yXpaGlLbVmxeFem+DdQm55lgl28d8Ssg6nlCTqE/tjB5LZ6qn8KEkWSj6gXH37pU1XFZh0A3+EIytnL7NnrsaQKBgGMaGUw3iSemLZHmiV7BKez4U80PAjOLl3xVbF7HQsp5v3X5NlkWiSgbkGPp57HwQa6h+Wn0RDKGz8GdYJ1fephklb92fbyGDbgblkSYxPSTT3Yed3QD61IdiGuFLoWF5o0jTYMcTWmDi2G7BpitMLj4J/Zt7mLgbYSVpYnG0bYpAoGAS7Tfya/CNdMqQFqD03rITI5nY9zS+mriFXO8Gy4A1vWmArU7ndTWfvNubwJ7d/hEUC0jX1AQmBH/8gDiZ5hAJAt1dDLtiTZxtqrCk3YqYUdgjf6N4C+LRxL2M30pgYTEkI5BTpKrf5bZ1pSGGVnvM0egDfQTvhF26ZnfA8buxLECgYAssWTLQ2Ou2NJ8N3HJx54kpKLwf218ulINsH6opcot22hbVfj0rc7lAcMe9FTGgmSgrbZG9QqAC2BpSHDeSC4C57iSYhG86tq/jwvNsV1miPV9RRj3CvwZkbHzCwqhRvCPS/QUgTzG3Z9pljYLkZjuMkb9jp814GbwEGPeoucefw==" AlipayPublicKey: "" - AppCertPath: "etc/merchant/appCertPublicKey_2021004161631930.crt" + AppCertPath: "etc/merchant/appCertPublicKey_2021006121698606.crt" AlipayCertPath: "etc/merchant/alipayCertPublicKey_RSA2.crt" AlipayRootCertPath: "etc/merchant/alipayRootCert.crt" + + AppIDBak: "2021004161631930" + PrivateKeyBak: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCRrZNr8DNs4LhPSulTLEg4RLREWVSFGS+Nl5Q2FxQ8DgkUYV+p3kfi4XmB2W/Ruz4egPxEB0V/xj75OktVphVKY8rI6OaNnVoFVe5NqGa5MTj3wLwBIv/hMHA1VAru2KLIv9R1FR7LpWmreHSkpJ65CD2mZqYuMCekOfzMQZIGgSagEU4my0bLbFWw7M3qZz4vm2KUtm4Ew28OUJDkqygjPzXgS5l5niYQvqPjiQNdnTtoIcNcHo07tS8lmf/hdgq9EtVfY7Y0brESfgvOoVJeg1hTHEj0hyWnnWPeA4HD2izANP/5ObRX4ZVqpVju+7PSpbeFd71fxbR1blAVnrqTAgMBAAECggEASpkwHN3r9507xJ7/zG+oq+fCyB1WgrHbAA7W/rviyL4HOECE1F/XP/9mUXAfKq9PqB81D0EJ/dxu8wE/AqUB0g44EZnyNiKVrpXKakoKEFt8aKJxo8NgdNhxHV3kG1skQNi62xntoysZaY1NbeI+xVHLACMghhZytk5bfd02Ac3rMBz3X8Cl1R+3mgU0zFc5f476VRxywiRQM+QNJIaHDNB4vw1TKI0K92mEKD8lOuNZD7d5TCBZi3r08t8FFAkMjIMDiFvFRFmAqMg3NyaIGUkLVDU2zUP0Vlzmo9ghCV9hluqDqeP4RhxQydOw+rxGBk+crYQBhPyYOI/I9PFXAQKBgQDHSRRTPqYbCfztmwk3AIH7VN6izyU3FljEXAsdf+UVJpRa8429J3e+sB96jxhiwVlCzX4CDjsa/Pu0iQQx22a0AZs5GTE0MJ1FVydfGlyqF6/hRS4TswSkklW3be7/KDAjgj2+/wap+mN7rRmDkdvxgCJG6MiWuRAthhg/g16wIwKBgQC7Iu7D4yQXRKheL6p6pbMtE+oD58/EJ2vO8ZUz3LiPc9pZ6+bp4nkBP6JOuYiB5jkzWQifKe6hsXpv06kWzaBEzz4f4SUpWDmdBchNoct3pB/k66FaxHLO/pG4RV86hqscqTdutmdC62bbwM6yCtJ+3rS5rlCxDGQkGJbM+wM60QKBgH5nQyYeCbwC1NRdTzX883VYerLoEyHi4cEC5OX8NnD4/IbIDzJYc2KXUhAp7XzOSPDPaMqi/ih7KKh1dByvnnA0yKEp8oS5BThzNHzlOruEtMF9YOGL3jkIvKfRahOcCRSsyr94AWEVeb57qEBE5y5CaPtzMbAwiCtn779xc0DjAoGAZwEGXWokDm6rIhSoiJO2OQSyFW4+LSDptWHCF2bRa5yAPmiblHck1awaAa0b1yxKpdnG5hzljbirxOvDMZsDMXzFHDUICGbYZ3asVxbMcNE1AQM1sElbTFZRDRWaIhPIEaGOsnDSC8KYvjK1UsikLlMVNPMe1SUV5cxnDPLJR1ECgYEAw8M09uLylPtfGq7oyE2R6xC2kUA8EJ6aapJgUs/UZ6dtjtvudbYzUo0Cgnb12hpN3hfLc5O0/P4nRzZ72Hm43cMiRNLJi4BYCa0m/mCxq+RcoBWYQTIraHnR17yIQhxt5IBRVjgbvYCnryx5Jd5wjOvv7DdnGFJLepzSJwlGqeU=" + AlipayPublicKeyBak: "" + AppCertPathBak: "etc/merchant/bak/appCertPublicKey_2021004161631930.crt" + AlipayCertPathBak: "etc/merchant/bak/alipayCertPublicKey_RSA2.crt" + AlipayRootCertPathBak: "etc/merchant/bak/alipayRootCert.crt" IsProduction: true NotifyUrl: "https://www.tianyuancha.cn/api/v1/pay/alipay/callback" ReturnURL: "https://www.tianyuancha.cn/payment/result" @@ -52,7 +59,7 @@ Ali: Code: "d55b58829efb41c8aa8e86769cba4844" SystemConfig: ThreeVerify: false - CommissionSafeMode: false # 佣金安全防御模式:true-冻结模式,false-直接结算模式 + CommissionSafeMode: false # 佣金安全防御模式:true-冻结模式,false-直接结算模式 WechatH5: AppID: "wxa581992dc74d860e" AppSecret: "4de1fbf521712247542d49907fcd5dbf" @@ -79,4 +86,4 @@ Tianyuanapi: Timeout: 60 Authorization: FileBaseURL: "https://www.tianyuancha.cn/api/v1/auth-docs" # 授权书文件访问基础URL -ExtensionTime: 24 # 佣金解冻延迟时间,单位:24小时 \ No newline at end of file +ExtensionTime: 24 # 佣金解冻延迟时间,单位:24小时 diff --git a/app/main/api/etc/main.yaml b/app/main/api/etc/main.yaml index 2513f21..5e57048 100644 --- a/app/main/api/etc/main.yaml +++ b/app/main/api/etc/main.yaml @@ -37,6 +37,13 @@ Alipay: AppCertPath: "etc/merchant/appCertPublicKey_2021006121698606.crt" AlipayCertPath: "etc/merchant/alipayCertPublicKey_RSA2.crt" AlipayRootCertPath: "etc/merchant/alipayRootCert.crt" + + AppIDBak: "2021004161631930" + PrivateKeyBak: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCRrZNr8DNs4LhPSulTLEg4RLREWVSFGS+Nl5Q2FxQ8DgkUYV+p3kfi4XmB2W/Ruz4egPxEB0V/xj75OktVphVKY8rI6OaNnVoFVe5NqGa5MTj3wLwBIv/hMHA1VAru2KLIv9R1FR7LpWmreHSkpJ65CD2mZqYuMCekOfzMQZIGgSagEU4my0bLbFWw7M3qZz4vm2KUtm4Ew28OUJDkqygjPzXgS5l5niYQvqPjiQNdnTtoIcNcHo07tS8lmf/hdgq9EtVfY7Y0brESfgvOoVJeg1hTHEj0hyWnnWPeA4HD2izANP/5ObRX4ZVqpVju+7PSpbeFd71fxbR1blAVnrqTAgMBAAECggEASpkwHN3r9507xJ7/zG+oq+fCyB1WgrHbAA7W/rviyL4HOECE1F/XP/9mUXAfKq9PqB81D0EJ/dxu8wE/AqUB0g44EZnyNiKVrpXKakoKEFt8aKJxo8NgdNhxHV3kG1skQNi62xntoysZaY1NbeI+xVHLACMghhZytk5bfd02Ac3rMBz3X8Cl1R+3mgU0zFc5f476VRxywiRQM+QNJIaHDNB4vw1TKI0K92mEKD8lOuNZD7d5TCBZi3r08t8FFAkMjIMDiFvFRFmAqMg3NyaIGUkLVDU2zUP0Vlzmo9ghCV9hluqDqeP4RhxQydOw+rxGBk+crYQBhPyYOI/I9PFXAQKBgQDHSRRTPqYbCfztmwk3AIH7VN6izyU3FljEXAsdf+UVJpRa8429J3e+sB96jxhiwVlCzX4CDjsa/Pu0iQQx22a0AZs5GTE0MJ1FVydfGlyqF6/hRS4TswSkklW3be7/KDAjgj2+/wap+mN7rRmDkdvxgCJG6MiWuRAthhg/g16wIwKBgQC7Iu7D4yQXRKheL6p6pbMtE+oD58/EJ2vO8ZUz3LiPc9pZ6+bp4nkBP6JOuYiB5jkzWQifKe6hsXpv06kWzaBEzz4f4SUpWDmdBchNoct3pB/k66FaxHLO/pG4RV86hqscqTdutmdC62bbwM6yCtJ+3rS5rlCxDGQkGJbM+wM60QKBgH5nQyYeCbwC1NRdTzX883VYerLoEyHi4cEC5OX8NnD4/IbIDzJYc2KXUhAp7XzOSPDPaMqi/ih7KKh1dByvnnA0yKEp8oS5BThzNHzlOruEtMF9YOGL3jkIvKfRahOcCRSsyr94AWEVeb57qEBE5y5CaPtzMbAwiCtn779xc0DjAoGAZwEGXWokDm6rIhSoiJO2OQSyFW4+LSDptWHCF2bRa5yAPmiblHck1awaAa0b1yxKpdnG5hzljbirxOvDMZsDMXzFHDUICGbYZ3asVxbMcNE1AQM1sElbTFZRDRWaIhPIEaGOsnDSC8KYvjK1UsikLlMVNPMe1SUV5cxnDPLJR1ECgYEAw8M09uLylPtfGq7oyE2R6xC2kUA8EJ6aapJgUs/UZ6dtjtvudbYzUo0Cgnb12hpN3hfLc5O0/P4nRzZ72Hm43cMiRNLJi4BYCa0m/mCxq+RcoBWYQTIraHnR17yIQhxt5IBRVjgbvYCnryx5Jd5wjOvv7DdnGFJLepzSJwlGqeU=" + AlipayPublicKeyBak: "" + AppCertPathBak: "etc/merchant/bak/appCertPublicKey_2021004161631930.crt" + AlipayCertPathBak: "etc/merchant/bak/alipayCertPublicKey_RSA2.crt" + AlipayRootCertPathBak: "etc/merchant/bak/alipayRootCert.crt" IsProduction: true NotifyUrl: "https://www.tianyuancha.cn/api/v1/pay/alipay/callback" ReturnURL: "https://www.tianyuancha.cn/payment/result" @@ -63,7 +70,7 @@ Ali: Code: "d55b58829efb41c8aa8e86769cba4844" SystemConfig: ThreeVerify: true - CommissionSafeMode: false # 佣金安全防御模式:true-冻结模式,false-直接结算模式 + CommissionSafeMode: false # 佣金安全防御模式:true-冻结模式,false-直接结算模式 WechatH5: AppID: "wxa581992dc74d860e" AppSecret: "4de1fbf521712247542d49907fcd5dbf" @@ -88,4 +95,4 @@ Tianyuanapi: Timeout: 60 Authorization: FileBaseURL: "https://www.tianyuancha.cn/api/v1/auth-docs" # 授权书文件访问基础URL -ExtensionTime: 24 # 佣金解冻延迟时间,单位:24小时 \ No newline at end of file +ExtensionTime: 24 # 佣金解冻延迟时间,单位:24小时 diff --git a/app/main/api/internal/config/config.go b/app/main/api/internal/config/config.go index b8fac11..14b9607 100644 --- a/app/main/api/internal/config/config.go +++ b/app/main/api/internal/config/config.go @@ -53,9 +53,16 @@ type AlipayConfig struct { AppCertPath string // 应用公钥证书路径 AlipayCertPath string // 支付宝公钥证书路径 AlipayRootCertPath string // 根证书路径 - IsProduction bool - NotifyUrl string - ReturnURL string + // Bak 仅用于 2026-02-02 18:26 之前的订单退款 + AppIDBak string + PrivateKeyBak string + AlipayPublicKeyBak string + AppCertPathBak string + AlipayCertPathBak string + AlipayRootCertPathBak string + IsProduction bool + NotifyUrl string + ReturnURL string } type WxpayConfig struct { AppID string diff --git a/app/main/api/internal/logic/admin_order/adminrefundorderlogic.go b/app/main/api/internal/logic/admin_order/adminrefundorderlogic.go index 71d92ff..9be6549 100644 --- a/app/main/api/internal/logic/admin_order/adminrefundorderlogic.go +++ b/app/main/api/internal/logic/admin_order/adminrefundorderlogic.go @@ -75,10 +75,13 @@ func (l *AdminRefundOrderLogic) getAndValidateOrder(orderId int64, refundAmount return order, nil } -// handleAlipayRefund 处理支付宝退款 +// handleAlipayRefund 处理支付宝退款(2026-02-02 18:26 前的订单走 bak 商户号) func (l *AdminRefundOrderLogic) handleAlipayRefund(order *model.Order, req *types.AdminRefundOrderReq) (*types.AdminRefundOrderResp, error) { - // 调用支付宝退款接口 - refundResp, err := l.svcCtx.AlipayService.AliRefund(l.ctx, order.OrderNo, req.RefundAmount) + orderPayTime := &order.CreateTime + if order.PayTime.Valid { + orderPayTime = &order.PayTime.Time + } + refundResp, err := l.svcCtx.AlipayService.AliRefund(l.ctx, order.OrderNo, req.RefundAmount, orderPayTime) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "AdminRefundOrder, 支付宝退款失败 err: %v", err) } diff --git a/app/main/api/internal/logic/pay/alipaycallbacklogic.go b/app/main/api/internal/logic/pay/alipaycallbacklogic.go index 2265528..88a532f 100644 --- a/app/main/api/internal/logic/pay/alipaycallbacklogic.go +++ b/app/main/api/internal/logic/pay/alipaycallbacklogic.go @@ -218,7 +218,9 @@ func (l *AlipayCallbackLogic) handleRefund(order *model.AgentMembershipRechargeO return refundErr } } else { - refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount) + // 代理会员订单以创建时间为准,2026-02-02 18:26 前的订单走 bak 商户号 + orderPayTime := order.CreateTime + refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, &orderPayTime) if refundErr != nil { return refundErr } diff --git a/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go b/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go index af08b4f..30a0ab1 100644 --- a/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go +++ b/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go @@ -221,7 +221,9 @@ func (l *WechatPayCallbackLogic) handleRefund(order *model.AgentMembershipRechar return refundErr } } else { - refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount) + // 代理会员订单以创建时间为准,2026-02-02 18:26 前的订单走 bak 商户号 + orderPayTime := order.CreateTime + refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, &orderPayTime) if refundErr != nil { return refundErr } diff --git a/app/main/api/internal/logic/query/queryservicelogic.go b/app/main/api/internal/logic/query/queryservicelogic.go index 3aa3220..fb98767 100644 --- a/app/main/api/internal/logic/query/queryservicelogic.go +++ b/app/main/api/internal/logic/query/queryservicelogic.go @@ -48,591 +48,109 @@ func (l *QueryServiceLogic) QueryService(req *types.QueryServiceReq) (resp *type return l.PreprocessLogic(req, req.Product) } -var productProcessors = map[string]func(*QueryServiceLogic, *types.QueryServiceReq) (*types.QueryServiceResp, error){ - "marriage": (*QueryServiceLogic).ProcessMarriageLogic, - "homeservice": (*QueryServiceLogic).ProcessHomeServiceLogic, - "riskassessment": (*QueryServiceLogic).ProcessRiskAssessmentLogic, - "companyinfo": (*QueryServiceLogic).ProcessCompanyInfoLogic, - "rentalinfo": (*QueryServiceLogic).ProcessRentalInfoLogic, - "preloanbackgroundcheck": (*QueryServiceLogic).ProcessPreLoanBackgroundCheckLogic, - "backgroundcheck": (*QueryServiceLogic).ProcessBackgroundCheckLogic, - "personalData": (*QueryServiceLogic).ProcessPersonalDataLogic, - "toc_PersonalLawsuit": (*QueryServiceLogic).ProcessTocPersonalLawsuitLogic, - "toc_EnterpriseLawsuit": (*QueryServiceLogic).ProcessTocEnterpriseLawsuitLogic, - "toc_ExecutedPerson": (*QueryServiceLogic).ProcessTocExecutedPersonLogic, - "toc_LimitHigh": (*QueryServiceLogic).ProcessTocLimitHighLogic, - "toc_Marriage": (*QueryServiceLogic).ProcessTocMarriageLogic, - "toc_PersonalMarriageStatus": (*QueryServiceLogic).ProcessTocPersonalMarriageStatusLogic, - "toc_MarriageStatusRegisterTime": (*QueryServiceLogic).ProcessTocMarriageStatusRegisterTimeLogic, - "toc_MarriageStatusSupplement": (*QueryServiceLogic).ProcessTocMarriageStatusSupplementLogic, - "toc_MarriageStatusVerify": (*QueryServiceLogic).ProcessTocMarriageStatusVerifyLogic, - "toc_DualMarriageStatusRegisterTime": (*QueryServiceLogic).ProcessTocDualMarriageStatusRegisterTimeLogic, - "toc_VehiclesUnderName": (*QueryServiceLogic).ProcessTocVehiclesUnderNameLogic, +// queryHandlerFunc 通用查询 handler:解密后的数据 + 产品名 -> 校验并返回待缓存的 params +// 新增产品时只需在 productHandlers 里加一行并选用已有 handler 类型即可,无需再写 ProcessXxx +type queryHandlerFunc func(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) + +var productHandlers = map[string]queryHandlerFunc{ + "marriage": runMarriageReq, + "homeservice": runMarriageReq, + "riskassessment": runMarriageReq, + "companyinfo": runMarriageReq, + "rentalinfo": runMarriageReq, + "preloanbackgroundcheck": runMarriageReq, + "backgroundcheck": runMarriageReq, + "personalData": runMarriageReq, + "toc_PersonalLawsuit": runMarriageReq, + "toc_EnterpriseLawsuit": runEntLawsuitReq, + "toc_ExecutedPerson": runMarriageReq, + "toc_LimitHigh": runMarriageReq, + "toc_Marriage": runMarriageReq, + "toc_PersonalMarriageStatus": runMarriageReq, + "toc_MarriageStatusRegisterTime": runMarriageReq, + "toc_MarriageStatusSupplement": runMarriageReq, + "toc_MarriageStatusVerify": runMarriageReq, + "toc_DualMarriageStatusRegisterTime": runDualMarriageReq, + "toc_VehiclesUnderName": runMarriageReq, + "toc_VehiclesUnderNamePlate": runMarriageReq, + "toc_PersonVehicleVerification": runPersonVehicleVerificationReq, + "toc_PersonVehicleVerificationDetail": runPersonVehicleVerificationReq, + // 车辆类产品(按 md 传参) + "toc_VehiclesUnderNameCount": runVehiclesUnderNameCountReq, + "toc_VehicleStaticInfo": runVehicleVinCodeReq, + "toc_VehicleMileageMixed": runVehicleMileageMixedReq, + "toc_VehicleVinValuation": runVehicleVinValuationReq, + "toc_VehicleTransferSimple": runVehicleTransferSimpleReq, + "toc_VehicleTransferDetail": runVehicleVinCodeReq, + "toc_VehicleMaintenanceSimple": runVehicleMaintenanceSimpleReq, + "toc_VehicleMaintenanceDetail": runVehicleMaintenanceDetailReq, + "toc_VehicleClaimDetail": runVehicleClaimDetailReq, + "toc_VehicleClaimVerify": runVehicleClaimVerifyReq, } func (l *QueryServiceLogic) PreprocessLogic(req *types.QueryServiceReq, product string) (*types.QueryServiceResp, error) { - if processor, exists := productProcessors[product]; exists { - return processor(l, req) // 调用对应的处理函数 + decryptData, err := l.DecryptData(req.Data) + if err != nil { + return nil, err } - return nil, errors.New("未找到相应的处理程序") + handler, exists := productHandlers[product] + if !exists { + return nil, errors.New("未找到相应的处理程序") + } + params, err := handler(l, decryptData, product) + if err != nil { + return nil, err + } + return l.commonQueryTail(params, product) } -func (l *QueryServiceLogic) ProcessMarriageLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr +// commonQueryTail 通用收尾:写缓存、生成 token 并返回 +func (l *QueryServiceLogic) commonQueryTail(params map[string]interface{}, product string) (*types.QueryServiceResp, error) { + userID, err := l.GetOrCreateUser() + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) } + cacheNo, cacheDataErr := l.CacheData(params, product, userID) + if cacheDataErr != nil { + return nil, cacheDataErr + } + token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) + } + now := time.Now().Unix() + return &types.QueryServiceResp{ + Id: cacheNo, + AccessToken: token, + AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, + RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, + }, nil +} - // 校验参数 +// runMarriageReq 姓名+身份证+手机+验证码 类产品(婚恋、家政、司法涉诉、婚姻状况、名下车辆等) +func runMarriageReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.MarriageReq 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) } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { + if verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile); verifyErr != nil { return nil, verifyErr } - - // 缓存 - params := map[string]interface{}{ + return map[string]interface{}{ "name": data.Name, "id_card": data.IDCard, "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "marriage", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, }, nil } -// 处理家政服务相关逻辑 -func (l *QueryServiceLogic) ProcessHomeServiceLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - - // 校验参数 - var data types.HomeServiceReq - 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) - } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - - // 缓存 - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "homeservice", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理风险评估相关逻辑 -func (l *QueryServiceLogic) ProcessRiskAssessmentLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - - // 校验参数 - var data types.RiskAssessmentReq - 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) - } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - - // 缓存 - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "riskassessment", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理公司信息查询相关逻辑 -func (l *QueryServiceLogic) ProcessCompanyInfoLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - - // 校验参数 - var data types.CompanyInfoReq - 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) - } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - - // 缓存 - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "companyinfo", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理租赁信息查询相关逻辑 -func (l *QueryServiceLogic) ProcessRentalInfoLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - - // 校验参数 - var data types.RentalInfoReq - 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) - } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - - // 缓存 - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "rentalinfo", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理贷前背景检查相关逻辑 -func (l *QueryServiceLogic) ProcessPreLoanBackgroundCheckLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - - // 校验参数 - var data types.PreLoanBackgroundCheckReq - 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) - } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - - // 缓存 - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "preloanbackgroundcheck", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理人事背调相关逻辑 -func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - - // 校验参数 - var data types.BackgroundCheckReq - 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) - } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - - // 缓存 - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "backgroundcheck", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} -func (l *QueryServiceLogic) ProcessPersonalDataLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - - // 校验参数 - var data types.PersonalDataReq - 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) - } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - - // 缓存 - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "personalData", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理个人司法涉诉查询相关逻辑(二要素) -func (l *QueryServiceLogic) ProcessTocPersonalLawsuitLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - return l.processTocPersonalLawsuitFlow(req, "toc_PersonalLawsuit") -} - -// 处理婚姻状况查询相关逻辑(二要素) -func (l *QueryServiceLogic) ProcessTocMarriageLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - return l.processTocMarriageFlow(req, "toc_Marriage") -} - -// 处理名下车辆查询相关逻辑(二要素) -func (l *QueryServiceLogic) ProcessTocVehiclesUnderNameLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - // AES解密 - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - - // 校验参数 - var data types.MarriageReq - 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) - } - - // 校验验证码 - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - - // 校验要素(代理走三要素,非代理走二要素) - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - - // 缓存 - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "toc_VehiclesUnderName", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - - // 获取当前时间戳 - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理企业司法涉诉查询(企业名称+统一社会信用代码+手机+验证码) -func (l *QueryServiceLogic) ProcessTocEnterpriseLawsuitLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } +// runEntLawsuitReq 企业司法涉诉:企业名称+统一社会信用代码+手机+验证码 +func runEntLawsuitReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.EntLawsuitReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) @@ -640,163 +158,18 @@ func (l *QueryServiceLogic) ProcessTocEnterpriseLawsuitLogic(req *types.QuerySer if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } - params := map[string]interface{}{ + return map[string]interface{}{ "ent_name": data.EntName, "ent_code": data.EntCode, "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, "toc_EnterpriseLawsuit", userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, }, nil } -// 处理被执行人查询(与个人司法涉诉同流程) -func (l *QueryServiceLogic) ProcessTocExecutedPersonLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - return l.processTocPersonalLawsuitFlow(req, "toc_ExecutedPerson") -} - -// 处理限制高消费查询(与个人司法涉诉同流程) -func (l *QueryServiceLogic) ProcessTocLimitHighLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - return l.processTocPersonalLawsuitFlow(req, "toc_LimitHigh") -} - -// processTocPersonalLawsuitFlow 个人司法涉诉/被执行人/限高共用流程(二要素+验证码) -func (l *QueryServiceLogic) processTocPersonalLawsuitFlow(req *types.QueryServiceReq, product string) (*types.QueryServiceResp, error) { - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - var data types.MarriageReq - 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) - } - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, product, userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理个人婚姻状态 / 婚姻状态查询(登记时间版)/(补证版)/婚姻状态核验(与 toc_Marriage 同流程) -func (l *QueryServiceLogic) ProcessTocPersonalMarriageStatusLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - return l.processTocMarriageFlow(req, "toc_PersonalMarriageStatus") -} - -func (l *QueryServiceLogic) ProcessTocMarriageStatusRegisterTimeLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - return l.processTocMarriageFlow(req, "toc_MarriageStatusRegisterTime") -} - -func (l *QueryServiceLogic) ProcessTocMarriageStatusSupplementLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - return l.processTocMarriageFlow(req, "toc_MarriageStatusSupplement") -} - -func (l *QueryServiceLogic) ProcessTocMarriageStatusVerifyLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - return l.processTocMarriageFlow(req, "toc_MarriageStatusVerify") -} - -// processTocMarriageFlow 婚姻状况类产品共用流程(二要素+验证码) -func (l *QueryServiceLogic) processTocMarriageFlow(req *types.QueryServiceReq, product string) (*types.QueryServiceResp, error) { - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } - var data types.MarriageReq - 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) - } - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { - return nil, verifyCodeErr - } - verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile) - if verifyErr != nil { - return nil, verifyErr - } - params := map[string]interface{}{ - "name": data.Name, - "id_card": data.IDCard, - "mobile": data.Mobile, - } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) - } - cacheNo, cacheDataErr := l.CacheData(params, product, userID) - if cacheDataErr != nil { - return nil, cacheDataErr - } - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) - } - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, - }, nil -} - -// 处理双人婚姻状态(登记时间版) -func (l *QueryServiceLogic) ProcessTocDualMarriageStatusRegisterTimeLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) { - decryptData, DecryptDataErr := l.DecryptData(req.Data) - if DecryptDataErr != nil { - return nil, DecryptDataErr - } +// runDualMarriageReq 双人婚姻状态:男方/女方姓名+身份证+手机+验证码 +func runDualMarriageReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { var data types.TocDualMarriageReq if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) @@ -804,8 +177,7 @@ func (l *QueryServiceLogic) ProcessTocDualMarriageStatusRegisterTimeLogic(req *t if validatorErr := validator.Validate(data); validatorErr != nil { return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } - verifyCodeErr := l.VerifyCode(data.Mobile, data.Code) - if verifyCodeErr != nil { + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { return nil, verifyCodeErr } if verifyErr := l.VerifyTwo(data.NameMan, data.IDCardMan); verifyErr != nil { @@ -814,33 +186,193 @@ func (l *QueryServiceLogic) ProcessTocDualMarriageStatusRegisterTimeLogic(req *t if verifyErr := l.VerifyTwo(data.NameWoman, data.IDCardWoman); verifyErr != nil { return nil, verifyErr } - params := map[string]interface{}{ - "name": data.NameMan, - "id_card": data.IDCardMan, - "mobile": data.Mobile, - "name_man": data.NameMan, - "id_card_man": data.IDCardMan, - "name_woman": data.NameWoman, + return map[string]interface{}{ + "name": data.NameMan, + "id_card": data.IDCardMan, + "mobile": data.Mobile, + "name_man": data.NameMan, + "id_card_man": data.IDCardMan, + "name_woman": data.NameWoman, "id_card_woman": data.IDCardWoman, + }, nil +} + +// runPersonVehicleVerificationReq 人车核验简版:姓名+号牌类型+车牌号 +func runPersonVehicleVerificationReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocPersonVehicleVerification + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } - userID, err := l.GetOrCreateUser() - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err) + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } - cacheNo, cacheDataErr := l.CacheData(params, "toc_DualMarriageStatusRegisterTime", userID) - if cacheDataErr != nil { - return nil, cacheDataErr + + return map[string]interface{}{ + "name": data.Name, + "plate_no": data.CarLicense, + "carplate_type": data.CarType, + }, nil +} + +// runVehiclesUnderNameCountReq 名下车辆(数量) QCXG4D2E:仅 user_type + id_card +func runVehiclesUnderNameCountReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehiclesUnderNameCountReq + if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr) } - token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal) - if err != nil { - return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID) + if validatorErr := validator.Validate(data); validatorErr != nil { + return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr) } - now := time.Now().Unix() - return &types.QueryServiceResp{ - Id: cacheNo, - AccessToken: token, - AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, - RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, + userType := data.UserType + if userType == "" { + userType = "1" + } + return map[string]interface{}{ + "user_type": userType, + "id_card": data.IDCard, + }, nil +} + +// runVehicleVinCodeReq 仅 vin_code(车辆静态信息、过户详版等) +func runVehicleVinCodeReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehicleVinCodeReq + 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) + } + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { + return nil, verifyCodeErr + } + return map[string]interface{}{ + "vin_code": data.VinCode, + }, nil +} + +// runVehicleMileageMixedReq 车辆里程记录(混合) QCXG1U4U +func runVehicleMileageMixedReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehicleMileageMixedReq + 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) + } + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { + return nil, verifyCodeErr + } + return map[string]interface{}{ + "vin_code": data.VinCode, + "return_url": data.ReturnURL, + "image_url": data.ImageURL, + }, nil +} + +// runVehicleVinValuationReq 二手车VIN估值 QCXGY7F2(仅必填) +func runVehicleVinValuationReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehicleVinValuationReq + 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) + } + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { + return nil, verifyCodeErr + } + return map[string]interface{}{ + "vin_code": data.VinCode, + "vehicle_location": data.VehicleLocation, + "first_registrationdate": data.FirstRegistrationDate, + }, nil +} + +// runVehicleTransferSimpleReq 车辆过户简版 QCXG1H7Y(仅必填 vin_code) +func runVehicleTransferSimpleReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehicleTransferSimpleReq + 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) + } + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { + return nil, verifyCodeErr + } + return map[string]interface{}{"vin_code": data.VinCode}, nil +} + +// runVehicleMaintenanceSimpleReq 车辆维保简版 QCXG3Y6B(仅必填 vin_code, return_url) +func runVehicleMaintenanceSimpleReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehicleMaintenanceSimpleReq + 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) + } + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { + return nil, verifyCodeErr + } + return map[string]interface{}{ + "vin_code": data.VinCode, + "return_url": data.ReturnURL, + }, nil +} + +// runVehicleMaintenanceDetailReq 车辆维保详细版 QCXG3Z3L(仅必填 vin_code, return_url) +func runVehicleMaintenanceDetailReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehicleMaintenanceDetailReq + 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) + } + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { + return nil, verifyCodeErr + } + return map[string]interface{}{ + "vin_code": data.VinCode, + "return_url": data.ReturnURL, + }, nil +} + +// runVehicleClaimDetailReq 车辆出险详版 QCXGP00W(仅必填 vin_code, return_url, vlphoto_data),vlphoto_data 由 API 层加密为 data +func runVehicleClaimDetailReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehicleClaimDetailReq + 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) + } + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { + return nil, verifyCodeErr + } + return map[string]interface{}{ + "vin_code": data.VinCode, + "return_url": data.ReturnURL, + "vlphoto_data": data.VlphotoData, + }, nil +} + +// runVehicleClaimVerifyReq 车辆出险记录核验 QCXG6B4E +func runVehicleClaimVerifyReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) { + var data types.TocVehicleClaimVerifyReq + 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) + } + if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil { + return nil, verifyCodeErr + } + return map[string]interface{}{ + "vin_code": data.VINCode, + "authorized": data.Authorized, }, nil } diff --git a/app/main/api/internal/queue/paySuccessNotify.go b/app/main/api/internal/queue/paySuccessNotify.go index ced491c..2e21b60 100644 --- a/app/main/api/internal/queue/paySuccessNotify.go +++ b/app/main/api/internal/queue/paySuccessNotify.go @@ -266,8 +266,12 @@ func (l *PaySuccessNotifyUserHandler) handleError(ctx context.Context, err error logx.Infof("已发起微信退款申请, orderID: %d, amount: %f", order.Id, order.Amount) return asynq.SkipRetry } else { - // 支付宝退款为同步结果,这里直接根据返回结果更新订单和佣金/钱包 - refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount) + // 支付宝退款为同步结果,2026-02-02 18:26 前的订单走 bak 商户号 + orderPayTime := &order.CreateTime + if order.PayTime.Valid { + orderPayTime = &order.PayTime.Time + } + refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, orderPayTime) if refundErr != nil { logx.Error(refundErr) return asynq.SkipRetry diff --git a/app/main/api/internal/service/alipayService.go b/app/main/api/internal/service/alipayService.go index 556a190..b6e0044 100644 --- a/app/main/api/internal/service/alipayService.go +++ b/app/main/api/internal/service/alipayService.go @@ -16,9 +16,13 @@ import ( "github.com/smartwalle/alipay/v3" ) +// AlipayBakRefundCutoff bak 支付宝仅用于该时间点之前的订单退款(2026年2月2日 18:26 下午,CST) +var AlipayBakRefundCutoff = time.Date(2026, 2, 2, 18, 26, 0, 0, time.FixedZone("CST", 8*3600)) + type AliPayService struct { - config config.AlipayConfig - AlipayClient *alipay.Client + config config.AlipayConfig + AlipayClient *alipay.Client + AlipayClientBak *alipay.Client // 仅用于 2026-02-02 18:26 前订单的退款 } // NewAliPayService 是一个构造函数,用于初始化 AliPayService @@ -44,10 +48,30 @@ func NewAliPayService(c config.Config) *AliPayService { panic(fmt.Sprintf("加载根证书失败: %v", err)) } - return &AliPayService{ + svc := &AliPayService{ config: c.Alipay, AlipayClient: client, } + + // 初始化 bak 支付宝客户端(仅用于 2026-02-02 18:26 前订单的退款) + if c.Alipay.AppIDBak != "" && c.Alipay.PrivateKeyBak != "" { + bakClient, err := alipay.New(c.Alipay.AppIDBak, c.Alipay.PrivateKeyBak, c.Alipay.IsProduction) + if err != nil { + panic(fmt.Sprintf("创建支付宝 bak 客户端失败: %v", err)) + } + if err = bakClient.LoadAppCertPublicKeyFromFile(c.Alipay.AppCertPathBak); err != nil { + panic(fmt.Sprintf("加载 bak 应用公钥证书失败: %v", err)) + } + if err = bakClient.LoadAlipayCertPublicKeyFromFile(c.Alipay.AlipayCertPathBak); err != nil { + panic(fmt.Sprintf("加载 bak 支付宝公钥证书失败: %v", err)) + } + if err = bakClient.LoadAliPayRootCertFromFile(c.Alipay.AlipayRootCertPathBak); err != nil { + panic(fmt.Sprintf("加载 bak 根证书失败: %v", err)) + } + svc.AlipayClientBak = bakClient + } + + return svc } func (a *AliPayService) CreateAlipayAppOrder(amount float64, subject string, outTradeNo string) (string, error) { @@ -116,16 +140,20 @@ func (a *AliPayService) CreateAlipayOrder(ctx context.Context, amount float64, s } } -// AliRefund 发起支付宝退款 -func (a *AliPayService) AliRefund(ctx context.Context, outTradeNo string, refundAmount float64) (*alipay.TradeRefundRsp, error) { +// AliRefund 发起支付宝退款。orderPayTime 为订单支付时间(或创建时间),若在 2026-02-02 18:26 之前则使用 bak 商户号退款;传 nil 则使用主商户号。 +func (a *AliPayService) AliRefund(ctx context.Context, outTradeNo string, refundAmount float64, orderPayTime *time.Time) (*alipay.TradeRefundRsp, error) { + client := a.AlipayClient + if orderPayTime != nil && !orderPayTime.After(AlipayBakRefundCutoff) && a.AlipayClientBak != nil { + client = a.AlipayClientBak + } + refund := alipay.TradeRefund{ OutTradeNo: outTradeNo, RefundAmount: lzUtils.ToAlipayAmount(refundAmount), OutRequestNo: fmt.Sprintf("refund-%s", outTradeNo), } - // 发起退款请求 - refundResp, err := a.AlipayClient.TradeRefund(ctx, refund) + refundResp, err := client.TradeRefund(ctx, refund) if err != nil { return nil, fmt.Errorf("支付宝退款请求错误:%v", err) } diff --git a/app/main/api/internal/service/apirequestService.go b/app/main/api/internal/service/apirequestService.go index 7a894be..cbfcb7e 100644 --- a/app/main/api/internal/service/apirequestService.go +++ b/app/main/api/internal/service/apirequestService.go @@ -2,6 +2,7 @@ package service import ( "context" + "encoding/hex" "encoding/json" "errors" "fmt" @@ -13,6 +14,7 @@ import ( "tyc-server/app/main/api/internal/config" tianyuanapi "tyc-server/app/main/api/internal/service/tianyuanapi_sdk" "tyc-server/app/main/model" + "tyc-server/pkg/lzkit/crypto" "github.com/Masterminds/squirrel" "github.com/tidwall/gjson" @@ -175,6 +177,9 @@ var requestProcessors = map[string]func(*ApiRequestService, []byte) ([]byte, err "BehaviorRiskScan": (*ApiRequestService).ProcessBehaviorRiskScanRequest, "YYSYBE08": (*ApiRequestService).ProcessYYSYBE08Request, "YYSY09CD": (*ApiRequestService).ProcessYYSY09CDRequest, + "QCXGGB2Q": (*ApiRequestService).ProcessQCXGGB2QRequest, + "QCXGYTS2": (*ApiRequestService).ProcessQCXGYTS2Request, + "QCXG5F3A": (*ApiRequestService).ProcessQCXG5F3ARequest, "FLXG0687": (*ApiRequestService).ProcessFLXG0687Request, "FLXG3D56": (*ApiRequestService).ProcessFLXG3D56Request, "FLXG0V4B": (*ApiRequestService).ProcesFLXG0V4BRequest, @@ -197,6 +202,17 @@ var requestProcessors = map[string]func(*ApiRequestService, []byte) ([]byte, err "IVYZ3P9M": (*ApiRequestService).ProcessIVYZ3P9MRequest, "FLXG7E8F": (*ApiRequestService).ProcessFLXG7E8FRequest, "QCXG9P1C": (*ApiRequestService).ProcessQCXG9P1CFRequest, + // 车辆类接口(传参后续配置,先透传缓存 params) + "QCXG4D2E": (*ApiRequestService).ProcessQCXG4D2ERequest, + "QCXG5U0Z": (*ApiRequestService).ProcessQCXG5U0ZRequest, + "QCXG1U4U": (*ApiRequestService).ProcessQCXG1U4URequest, + "QCXGY7F2": (*ApiRequestService).ProcessQCXGY7F2Request, + "QCXG1H7Y": (*ApiRequestService).ProcessQCXG1H7YRequest, + "QCXG4I1Z": (*ApiRequestService).ProcessQCXG4I1ZRequest, + "QCXG3Y6B": (*ApiRequestService).ProcessQCXG3Y6BRequest, + "QCXG3Z3L": (*ApiRequestService).ProcessQCXG3Z3LRequest, + "QCXGP00W": (*ApiRequestService).ProcessQCXGP00WRequest, + "QCXG6B4E": (*ApiRequestService).ProcessQCXG6B4ERequest, } // PreprocessRequestApi 调用指定的请求处理函数 @@ -1104,6 +1120,253 @@ func (a *ApiRequestService) ProcessQYGL6F2DRequest(params []byte) ([]byte, error return nil, fmt.Errorf("响应code错误%s", code.String()) } +// ProcessQCXGGB2QRequest 人车核验简版 +func (a *ApiRequestService) ProcessQCXGGB2QRequest(params []byte) ([]byte, error) { + plateNo := gjson.GetBytes(params, "plate_no") + carplateType := gjson.GetBytes(params, "carplate_type") + name := gjson.GetBytes(params, "name") + + if !plateNo.Exists() || !carplateType.Exists() || !name.Exists() { + return nil, errors.New("api请求, QCXGGB2Q, 获取相关参数失败") + } + + resp, err := a.tianyuanapi.CallInterface("QCXGGB2Q", map[string]interface{}{ + "plate_no": plateNo.String(), + "carplate_type": carplateType.String(), + "name": name.String(), + }) + + if err != nil { + return nil, err + } + + return convertTianyuanResponse(resp) +} + +// ProcessQCXGYTS2Request 人车核验详版 +func (a *ApiRequestService) ProcessQCXGYTS2Request(params []byte) ([]byte, error) { + plateNo := gjson.GetBytes(params, "plate_no") + carplateType := gjson.GetBytes(params, "carplate_type") + name := gjson.GetBytes(params, "name") + + if !plateNo.Exists() || !carplateType.Exists() || !name.Exists() { + return nil, errors.New("api请求, QCXGYTS2, 获取相关参数失败") + } + + resp, err := a.tianyuanapi.CallInterface("QCXGYTS2", map[string]interface{}{ + "plate_no": plateNo.String(), + "carplate_type": carplateType.String(), + "name": name.String(), + }) + + if err != nil { + return nil, err + } + + return convertTianyuanResponse(resp) +} + +// ProcessQCXG5F3ARequest 名下车辆(车牌) +func (a *ApiRequestService) ProcessQCXG5F3ARequest(params []byte) ([]byte, error) { + idCard := gjson.GetBytes(params, "id_card") + name := gjson.GetBytes(params, "name") + if !idCard.Exists() || !name.Exists() { + return nil, errors.New("api请求, QCXG5F3A, 获取相关参数失败") + } + + resp, err := a.tianyuanapi.CallInterface("QCXG5F3A", map[string]interface{}{ + "id_card": idCard.String(), + "name": name.String(), + }) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +// processVehicleApiPassThrough 车辆类接口通用透传:将缓存 params 原样传给天远(传参后续按接口文档再细化) +func (a *ApiRequestService) processVehicleApiPassThrough(params []byte, apiID string) ([]byte, error) { + var m map[string]interface{} + if err := json.Unmarshal(params, &m); err != nil { + return nil, fmt.Errorf("api请求, %s, 解析参数失败: %w", apiID, err) + } + resp, err := a.tianyuanapi.CallInterface(apiID, m) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +// 车辆 API 按 md 从缓存 params 提取字段并调用天远 + +func (a *ApiRequestService) ProcessQCXG4D2ERequest(params []byte) ([]byte, error) { + m := map[string]interface{}{} + if err := json.Unmarshal(params, &m); err != nil { + return nil, fmt.Errorf("api请求, QCXG4D2E, 解析参数失败: %w", err) + } + body := map[string]interface{}{} + if v, ok := m["user_type"].(string); ok && v != "" { + body["user_type"] = v + } else { + body["user_type"] = "1" + } + if v, ok := m["id_card"].(string); ok { + body["id_card"] = v + } else { + return nil, errors.New("api请求, QCXG4D2E, 缺少 id_card") + } + resp, err := a.tianyuanapi.CallInterface("QCXG4D2E", body) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXG5U0ZRequest(params []byte) ([]byte, error) { + vin := gjson.GetBytes(params, "vin_code") + if !vin.Exists() || vin.String() == "" { + return nil, errors.New("api请求, QCXG5U0Z, 缺少 vin_code") + } + resp, err := a.tianyuanapi.CallInterface("QCXG5U0Z", map[string]interface{}{"vin_code": vin.String()}) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXG1U4URequest(params []byte) ([]byte, error) { + body := buildVehicleBody(params, []string{"vin_code", "return_url", "image_url"}, nil) + if body["vin_code"] == nil || body["return_url"] == nil || body["image_url"] == nil { + return nil, errors.New("api请求, QCXG1U4U, 缺少必填参数 vin_code/return_url/image_url") + } + resp, err := a.tianyuanapi.CallInterface("QCXG1U4U", body) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXGY7F2Request(params []byte) ([]byte, error) { + body := buildVehicleBody(params, []string{"vin_code", "vehicle_location", "first_registrationdate"}, nil) + if body["vin_code"] == nil || body["vehicle_location"] == nil || body["first_registrationdate"] == nil { + return nil, errors.New("api请求, QCXGY7F2, 缺少必填参数 vin_code/vehicle_location/first_registrationdate") + } + resp, err := a.tianyuanapi.CallInterface("QCXGY7F2", body) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXG1H7YRequest(params []byte) ([]byte, error) { + vin := gjson.GetBytes(params, "vin_code") + if !vin.Exists() || vin.String() == "" { + return nil, errors.New("api请求, QCXG1H7Y, 缺少 vin_code") + } + resp, err := a.tianyuanapi.CallInterface("QCXG1H7Y", map[string]interface{}{"vin_code": vin.String()}) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXG4I1ZRequest(params []byte) ([]byte, error) { + vin := gjson.GetBytes(params, "vin_code") + if !vin.Exists() || vin.String() == "" { + return nil, errors.New("api请求, QCXG4I1Z, 缺少 vin_code") + } + resp, err := a.tianyuanapi.CallInterface("QCXG4I1Z", map[string]interface{}{"vin_code": vin.String()}) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXG3Y6BRequest(params []byte) ([]byte, error) { + body := buildVehicleBody(params, []string{"vin_code", "return_url"}, nil) + if body["vin_code"] == nil || body["return_url"] == nil { + return nil, errors.New("api请求, QCXG3Y6B, 缺少必填参数 vin_code/return_url") + } + resp, err := a.tianyuanapi.CallInterface("QCXG3Y6B", body) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXG3Z3LRequest(params []byte) ([]byte, error) { + body := buildVehicleBody(params, []string{"vin_code", "return_url"}, nil) + if body["vin_code"] == nil || body["return_url"] == nil { + return nil, errors.New("api请求, QCXG3Z3L, 缺少必填参数 vin_code/return_url") + } + resp, err := a.tianyuanapi.CallInterface("QCXG3Z3L", body) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXGP00WRequest(params []byte) ([]byte, error) { + vin := gjson.GetBytes(params, "vin_code") + returnURL := gjson.GetBytes(params, "return_url") + vlphoto := gjson.GetBytes(params, "vlphoto_data") + if !vin.Exists() || vin.String() == "" || !returnURL.Exists() || returnURL.String() == "" || !vlphoto.Exists() || vlphoto.String() == "" { + return nil, errors.New("api请求, QCXGP00W, 缺少必填参数 vin_code/return_url/vlphoto_data") + } + key, err := hex.DecodeString(a.config.Encrypt.SecretKey) + if err != nil { + return nil, fmt.Errorf("api请求, QCXGP00W, 密钥解析失败: %w", err) + } + encData, err := crypto.AesEncrypt([]byte(vlphoto.String()), key) + if err != nil { + return nil, fmt.Errorf("api请求, QCXGP00W, 加密行驶证数据失败: %w", err) + } + resp, err := a.tianyuanapi.CallInterface("QCXGP00W", map[string]interface{}{ + "vin_code": vin.String(), + "return_url": returnURL.String(), + "data": encData, + }) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +func (a *ApiRequestService) ProcessQCXG6B4ERequest(params []byte) ([]byte, error) { + vin := gjson.GetBytes(params, "vin_code") + auth := gjson.GetBytes(params, "authorized") + if !vin.Exists() || vin.String() == "" || !auth.Exists() { + return nil, errors.New("api请求, QCXG6B4E, 缺少 vin_code 或 authorized") + } + // 天远文档字段名为 VINCode、Authorized + resp, err := a.tianyuanapi.CallInterface("QCXG6B4E", map[string]interface{}{ + "VINCode": vin.String(), + "Authorized": auth.String(), + }) + if err != nil { + return nil, err + } + return convertTianyuanResponse(resp) +} + +// buildVehicleBody 从 params 中取 required 与 optional 键,仅非空才写入 body +func buildVehicleBody(params []byte, required, optional []string) map[string]interface{} { + body := make(map[string]interface{}) + for _, k := range required { + v := gjson.GetBytes(params, k) + if v.Exists() { + body[k] = v.String() + } + } + for _, k := range optional { + v := gjson.GetBytes(params, k) + if v.Exists() && v.String() != "" { + body[k] = v.String() + } + } + return body +} + // ProcessQCXG7A2BRequest 名下车辆 func (a *ApiRequestService) ProcessQCXG7A2BRequest(params []byte) ([]byte, error) { idCard := gjson.GetBytes(params, "id_card") diff --git a/app/main/api/internal/types/query.go b/app/main/api/internal/types/query.go index 9d768ef..1c9e612 100644 --- a/app/main/api/internal/types/query.go +++ b/app/main/api/internal/types/query.go @@ -122,6 +122,91 @@ type AgentQueryData struct { Mobile string `json:"mobile"` Code string `json:"code"` } + +// 名下车辆(数量) QCXG4D2E:仅 user_type(1-ETC开户人 2-车辆所有人 3-ETC经办人)+id_card,无验证码 +type TocVehiclesUnderNameCountReq struct { + UserType string `json:"user_type"` // 必填,默认 1 + IDCard string `json:"id_card" validate:"required,idCard"` +} + +// 车辆静态信息/过户详版等 仅 vin_code +type TocVehicleVinCodeReq struct { + VinCode string `json:"vin_code" validate:"required"` + Mobile string `json:"mobile" validate:"required,mobile"` + Code string `json:"code" validate:"required"` +} + +// 车辆里程记录(混合) QCXG1U4U +type TocVehicleMileageMixedReq struct { + VinCode string `json:"vin_code" validate:"required"` + PlateNo string `json:"plate_no"` + ReturnURL string `json:"return_url" validate:"required"` + ImageURL string `json:"image_url" validate:"required"` + RegURL string `json:"reg_url"` + EngineNumber string `json:"engine_number"` + Mobile string `json:"mobile" validate:"required,mobile"` + Code string `json:"code" validate:"required"` +} + +// 二手车VIN估值 QCXGY7F2 +type TocVehicleVinValuationReq struct { + VinCode string `json:"vin_code" validate:"required"` + VehicleName string `json:"vehicle_name"` + VehicleLocation string `json:"vehicle_location" validate:"required"` + FirstRegistrationDate string `json:"first_registrationdate" validate:"required"` // yyyy-MM + Color string `json:"color"` + Mobile string `json:"mobile" validate:"required,mobile"` + Code string `json:"code" validate:"required"` +} + +// 车辆过户简版 QCXG1H7Y +type TocVehicleTransferSimpleReq struct { + VinCode string `json:"vin_code" validate:"required"` + PlateNo string `json:"plate_no"` + Mobile string `json:"mobile" validate:"required,mobile"` + Code string `json:"code" validate:"required"` +} + +// 车辆维保简版 QCXG3Y6B +type TocVehicleMaintenanceSimpleReq struct { + VinCode string `json:"vin_code" validate:"required"` + PlateNo string `json:"plate_no"` + ReturnURL string `json:"return_url" validate:"required"` + ImageURL string `json:"image_url"` + RegURL string `json:"reg_url"` + EngineNumber string `json:"engine_number"` + Mobile string `json:"mobile" validate:"required,mobile"` + Code string `json:"code" validate:"required"` +} + +// 车辆维保详细版 QCXG3Z3L +type TocVehicleMaintenanceDetailReq struct { + VinCode string `json:"vin_code" validate:"required"` + PlateNo string `json:"plate_no"` + ReturnURL string `json:"return_url" validate:"required"` + ImageURL string `json:"image_url"` + EngineNumber string `json:"engine_number"` + Mobile string `json:"mobile" validate:"required,mobile"` + Code string `json:"code" validate:"required"` +} + +// 车辆出险详版 QCXGP00W,vlphoto_data 加密后以 data 字段提交 +type TocVehicleClaimDetailReq struct { + VinCode string `json:"vin_code" validate:"required"` + PlateNo string `json:"plate_no"` + ReturnURL string `json:"return_url" validate:"required"` + VlphotoData string `json:"vlphoto_data" validate:"required"` // 行驶证图片 base64,加密后传 API 的 data + Mobile string `json:"mobile" validate:"required,mobile"` + Code string `json:"code" validate:"required"` +} + +// 车辆出险记录核验 QCXG6B4E,VINCode + Authorized(0/1) +type TocVehicleClaimVerifyReq struct { + VINCode string `json:"vin_code" validate:"required"` + Authorized string `json:"authorized" validate:"required"` // 0:否 1:是 + Mobile string `json:"mobile" validate:"required,mobile"` + Code string `json:"code" validate:"required"` +} type AgentIdentifier struct { Product string `json:"product"` AgentID int64 `json:"agent_id"` diff --git a/deploy/sql/product_feature_inserts.sql b/deploy/sql/product_feature_inserts.sql new file mode 100644 index 0000000..d1dc280 --- /dev/null +++ b/deploy/sql/product_feature_inserts.sql @@ -0,0 +1,1099 @@ +-- ============================================================================= +-- 产品与功能点录入脚本(每新增一个产品,在此文件追加对应 SQL) +-- ============================================================================= +-- 表说明: +-- product - 产品(对外售卖项,product_en 需与前端 inquireCategories.feature 及 queryservicelogic productHandlers 一致) +-- feature - 功能点/接口(api_id 需与天远接口及 apirequestService requestProcessors 一致) +-- product_feature - 产品与功能关联(一个产品可挂多个 feature,一般单接口产品为 1 条) +-- +-- 若希望主键自增,可去掉各 INSERT 中的 id 列,由数据库自动分配。 +-- 使用显式 id 时,请确保与现有数据不冲突(可先 SELECT MAX(id) 查看 product/feature/product_feature)。 +-- ============================================================================= + +-- ------------------------------ 人车核验(简版)----------------------------- +-- product 39, feature 83, product_feature 148(示例,若已存在可跳过) +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 39, + NOW(), + NOW(), + NULL, + 0, + 0, + '人车核验(简版)', + 'toc_PersonVehicleVerification', + '
人车核验
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 83, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXGGB2Q', + '人车核验(简版)', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 148, + 39, + 83, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 人车核验(详版)----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 40, + NOW(), + NOW(), + NULL, + 0, + 0, + '人车核验(详版)', + 'toc_PersonVehicleVerificationDetail', + '人车核验详版,提供更丰富的人车匹配详细信息。
', + NULL, + 0.50, + 12.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 84, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXGYTS2', + '人车核验(详版)', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 149, + 40, + 84, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 名下车辆(车牌) ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 41, + NOW(), + NOW(), + NULL, + 0, + 0, + '名下车辆(车牌)', + 'toc_VehiclesUnderNamePlate', + '按身份证与姓名查询名下车辆信息。
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 85, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG5F3A', + '名下车辆(车牌)', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 150, + 41, + 85, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 名下车辆(数量) ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 42, + NOW(), + NOW(), + NULL, + 0, + 0, + '名下车辆(数量)', + 'toc_VehiclesUnderNameCount', + '查询名下车辆数量
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 86, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG4D2E', + '名下车辆(数量)', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 151, + 42, + 86, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 车辆静态信息查询 ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 43, + NOW(), + NOW(), + NULL, + 0, + 0, + '车辆静态信息查询', + 'toc_VehicleStaticInfo', + '车辆静态信息查询
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 87, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG5U0Z', + '车辆静态信息查询', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 152, + 43, + 87, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 车辆里程记录(混合查询) ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 44, + NOW(), + NOW(), + NULL, + 0, + 0, + '车辆里程记录(混合查询)', + 'toc_VehicleMileageMixed', + '车辆里程记录混合查询
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 88, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG1U4U', + '车辆里程记录(混合查询)', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 153, + 44, + 88, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 二手车VIN估值 ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 45, + NOW(), + NOW(), + NULL, + 0, + 0, + '二手车VIN估值', + 'toc_VehicleVinValuation', + '二手车VIN估值
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 89, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXGY7F2', + '二手车VIN估值', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 154, + 45, + 89, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 车辆过户简版查询 ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 46, + NOW(), + NOW(), + NULL, + 0, + 0, + '车辆过户简版查询', + 'toc_VehicleTransferSimple', + '车辆过户简版查询
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 90, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG1H7Y', + '车辆过户简版查询', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 155, + 46, + 90, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 车辆过户详版查询 ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 47, + NOW(), + NOW(), + NULL, + 0, + 0, + '车辆过户详版查询', + 'toc_VehicleTransferDetail', + '车辆过户详版查询
', + NULL, + 0.50, + 12.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 91, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG4I1Z', + '车辆过户详版查询', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 156, + 47, + 91, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 车辆维保简版查询 ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 48, + NOW(), + NOW(), + NULL, + 0, + 0, + '车辆维保简版查询', + 'toc_VehicleMaintenanceSimple', + '车辆维保简版查询
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 92, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG3Y6B', + '车辆维保简版查询', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 157, + 48, + 92, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 车辆维保详细版查询 ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 49, + NOW(), + NOW(), + NULL, + 0, + 0, + '车辆维保详细版查询', + 'toc_VehicleMaintenanceDetail', + '车辆维保详细版查询
', + NULL, + 0.50, + 12.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 93, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG3Z3L', + '车辆维保详细版查询', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 158, + 49, + 93, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 车辆出险详版查询 ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 50, + NOW(), + NOW(), + NULL, + 0, + 0, + '车辆出险详版查询', + 'toc_VehicleClaimDetail', + '车辆出险详版查询
', + NULL, + 0.50, + 12.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 94, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXGP00W', + '车辆出险详版查询', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 159, + 50, + 94, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ------------------------------ 车辆出险记录核验 ----------------------------- +INSERT INTO + `product` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `product_name`, + `product_en`, + `description`, + `notes`, + `cost_price`, + `sell_price` + ) +VALUES ( + 51, + NOW(), + NOW(), + NULL, + 0, + 0, + '车辆出险记录核验', + 'toc_VehicleClaimVerify', + '车辆出险记录核验
', + NULL, + 0.50, + 9.90 + ); + +INSERT INTO + `feature` ( + `id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `api_id`, + `name`, + `cost_price` + ) +VALUES ( + 95, + NOW(), + NOW(), + NULL, + 0, + 0, + 'QCXG6B4E', + '车辆出险记录核验', + 0.80 + ); + +INSERT INTO + `product_feature` ( + `id`, + `product_id`, + `feature_id`, + `create_time`, + `update_time`, + `delete_time`, + `del_state`, + `version`, + `sort`, + `is_important`, + `enable` + ) +VALUES ( + 160, + 51, + 95, + NOW(), + NOW(), + NULL, + 0, + 0, + 1, + 0, + 1 + ); + +-- ============================================================================= +-- 以后每加一个产品,按上面格式追加三块: +-- 1. INSERT INTO product (..., product_name, product_en, ...) +-- 2. INSERT INTO feature (..., api_id, name, ...) +-- 3. INSERT INTO product_feature (..., product_id, feature_id, ...) +-- 注意:id 依次递增,或去掉 id 列改用自增。 +-- ============================================================================= \ No newline at end of file