Commit 74f4cda3 by dliangx

add caj9 to this server

parent bec31acf
...@@ -7,8 +7,9 @@ import ( ...@@ -7,8 +7,9 @@ import (
) )
// var dsn = "root:Pannong12306@tcp(127.0.0.1:3306)/pr_order?charset=utf8&parseTime=True&loc=Local" // var dsn = "root:Pannong12306@tcp(127.0.0.1:3306)/pr_order?charset=utf8&parseTime=True&loc=Local"
var dsn = `demeter:ajc4crb.buj-GHJ!pzw@tcp(10.0.0.2:3306)/pr_order?useUnicode=true&characterEncoding=utf8&useSSL=false` //var dsn = `demeter:ajc4crb.buj-GHJ!pzw@tcp(10.0.0.2:3306)/pr_order?useUnicode=true&characterEncoding=utf8&useSSL=false`
var dsn = `tkdb:wpx2HGQ7djx*mgp-vct@tcp(10.0.0.2:3306)/pr_order?useUnicode=true&characterEncoding=utf8&useSSL=false`
var DB *sql.DB var DB *sql.DB
func init() { func init() {
......
package handler
import (
"context"
"encoding/json"
"fmt"
"math"
"strconv"
"strings"
"time"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/common/utils"
"nlt.com/pf/db"
"nlt.com/pf/model"
utl "nlt.com/pf/utils"
)
func DecryptAndQuery(ctx context.Context, c *app.RequestContext) {
// 获取加密的idcard参数
encryptedId := c.Query("idcard")
if encryptedId == "" {
c.JSON(400, map[string]interface{}{
"code": 400,
"message": "idcard parameter is required",
})
return
}
// SM4解密
id, err := utl.SM4Decrypt(encryptedId)
if err != nil {
c.JSON(400, map[string]interface{}{
"code": 400,
"message": "decrypt failed",
})
return
}
// 查询并转换数据
result := QueryAndTransform(id)
// 将结果转为JSON字符串
jsonData, err := json.Marshal(result)
if err != nil {
c.JSON(500, map[string]interface{}{
"code": 500,
"message": "marshal failed",
})
return
}
// SM4加密结果
encryptedResult, err := utl.SM4Encrypt(string(jsonData))
if err != nil {
c.JSON(500, map[string]interface{}{
"code": 500,
"message": "encrypt failed",
})
return
}
// 返回加密后的结果
c.JSON(200, map[string]interface{}{
"code": 200,
"data": encryptedResult,
})
}
func QueryAndTransform(id string) model.TkDirectResp {
var whitelist model.Whitelist
// 使用原生SQL查询
row := db.DB.QueryRow("SELECT id, name, id_card, code, cooperation_years, operation_scale, "+
"operation_variety, contract_amount, age, fund_account, company_name, "+
"social_credit, guarantee_rate, fund_trustees, advice_crd_amt, "+
"contract_effective_date, operation_unit, status, create_time, calc_amt "+
"FROM whitelist WHERE id = ?", id)
err := row.Scan(
&whitelist.Id,
&whitelist.Name,
&whitelist.IdCard,
&whitelist.Code,
&whitelist.CooperationYears,
&whitelist.OperationScale,
&whitelist.OperationVariety,
&whitelist.ContractAmount,
&whitelist.Age,
&whitelist.FundAccount,
&whitelist.CompanyName,
&whitelist.SocialCredit,
&whitelist.GuaranteeRate,
&whitelist.FundTrustees,
&whitelist.AdviceCrdAmt,
&whitelist.ContractEffectiveDate,
&whitelist.OperationUnit,
&whitelist.Status,
&whitelist.CreateTime,
&whitelist.CalcAmt,
)
if err != nil {
return model.TkDirectResp{}
}
// 查询明细数据
rows, err := db.DB.Query("SELECT busi_his_intervals, purchases, amount, unit_value "+
"FROM whitelist_detail WHERE whitelist_id = ?", id)
if err != nil {
return model.TkDirectResp{}
}
defer rows.Close()
var details []model.WhitelistDetail
for rows.Next() {
var detail model.WhitelistDetail
err := rows.Scan(
&detail.BusiHisIntervals,
&detail.Purchases,
&detail.Amount,
&detail.UnitValue,
)
if err != nil {
continue
}
details = append(details, detail)
}
whitelist.Detail = details
return Transform(whitelist)
}
func Transform(whitelist model.Whitelist) model.TkDirectResp {
resp := model.TkDirectResp{
Channeltype: "TK",
Coplatform: "天康担保",
Loanprop: "担保贷款",
Prdcode: "prdcode",
Prdtype: "prdtype",
Ywcjm: "DBAB600060090001",
Certtype: "1",
Certcode: whitelist.IdCard,
Custname: whitelist.Name,
Sysregdate: "99991231",
Greencreditpolicyflag: "1",
Tpobjid: whitelist.Code,
Coyears: whitelist.CooperationYears,
Cultivatedamount: whitelist.OperationScale,
Cultivatedspecies: whitelist.OperationVariety,
Partnerlevel: "0",
Loaflag: "Y",
Badcreditrecordflag: "N",
Contractamt: strconv.Itoa(whitelist.ContractAmount),
Custage: whitelist.Age,
Trusteesaccount: whitelist.FundAccount,
}
// Handle company name logic
if whitelist.CompanyName == "" {
resp.Shopname = "农户"
resp.Creditcode = "000000000000000000"
resp.Farmersflag = "1"
} else {
resp.Shopname = whitelist.CompanyName
resp.Creditcode = whitelist.SocialCredit
resp.Farmersflag = "0"
}
// Convert guarantee rate from percentage to decimal
guaranteeRate, _ := strconv.ParseFloat(whitelist.GuaranteeRate, 64)
resp.Guaranteedrates = guaranteeRate / 100
resp.Trustees = whitelist.FundTrustees
resp.Workingyears = whitelist.CooperationYears
resp.Advicecrdamt = float64(whitelist.AdviceCrdAmt)
var details []model.TKDirectDetailResp
total1 := 0.0
total2 := 0.0
count := 1
remaining := 0
if len(whitelist.Detail) > 0 {
count = len(whitelist.Detail)
remaining = 13 - count
for _, detail := range whitelist.Detail {
de := model.TKDirectDetailResp{}
// 处理日期
hisInterval := detail.BusiHisIntervals
if idx := strings.Index(hisInterval, "至"); idx != -1 {
datastr1 := hisInterval[idx+len("至"):]
if yearIdx := strings.Index(datastr1, "年"); yearIdx != -1 {
datastr2 := datastr1[:yearIdx]
upyear, err := strconv.Atoi(datastr2)
if err == nil {
currentYear := time.Now().Year()
if currentYear >= upyear {
de.Statisym = fmt.Sprintf("%s01", datastr2)
} else {
de.Statisym = fmt.Sprintf("%d01", currentYear)
}
}
}
}
// 设置购买金额
purchaseAmount, _ := strconv.ParseFloat(detail.Purchases, 64)
if purchaseAmount != 0 {
de.Custamt = purchaseAmount
}
amount, _ := strconv.ParseFloat(detail.Amount, 64)
de.Yearmat = amount
unitValue, _ := strconv.ParseFloat(detail.UnitValue, 64)
// 根据不同种类设置单位值
switch resp.Cultivatedspecies {
case "鱼":
de.Unitvalue = math.Max(100, math.Min(200000, unitValue))
case "猪":
de.Unitvalue = math.Max(1000, math.Min(10000, unitValue))
case "牛":
de.Unitvalue = math.Max(1000, math.Min(50000, unitValue))
case "鸡":
de.Unitvalue = math.Max(50, math.Min(1000, unitValue))
case "玉米":
de.Unitvalue = math.Max(1000, math.Min(100000, unitValue))
}
// 计算总和
switch resp.Cultivatedspecies {
case "鱼", "猪", "牛", "鸡":
total1 += de.Custamt
total2 += de.Yearmat * de.Unitvalue
case "玉米":
total2 += de.Yearmat * de.Unitvalue
}
details = append(details, de)
}
resp.Details = details[0]
}
total0 := float64(whitelist.AdviceCrdAmt)
// 处理不同种类的计算逻辑
switch {
case resp.Cultivatedspecies == "鱼" || resp.Cultivatedspecies == "猪" || resp.Cultivatedspecies == "牛":
speciesMap := map[string]string{
"鱼": "1",
"猪": "2",
"牛": "3",
}
resp.Cultivatedspecies = speciesMap[resp.Cultivatedspecies]
total1 = total1 * 0.8 / float64(count)
total2 = total2 * 0.8 / float64(count)
// 简化最小值计算
resp.CalcAmt = math.Floor(math.Min(math.Min(total0, total1), total2)*100) / 100
case resp.Cultivatedspecies == "鸡":
resp.Cultivatedspecies = "4"
total1 = total1 * 0.7 / float64(count)
total2 = total2 * 0.7 / float64(count)
resp.CalcAmt = math.Floor(math.Min(math.Min(total0, total1), total2)*100) / 100
case resp.Cultivatedspecies == "玉米":
resp.Cultivatedspecies = "5"
total2 = total2 * 0.7 / float64(count)
resp.CalcAmt = math.Floor(math.Min(total0, total2)*100) / 100
}
// 添加剩余的空记录
var remainingDetails []model.TKDirectDetailResp
for i := 0; i < remaining; i++ {
de := model.TKDirectDetailResp{
Statisym: fmt.Sprintf("2099%02d", i+1),
Custamt: 0,
Yearmat: 0,
Unitvalue: 0,
}
remainingDetails = append(remainingDetails, de)
}
// Fix: Create a slice with the single Details item
allDetails := append(remainingDetails, resp.Details)
resp.Details = allDetails[0] // Take first item since resp.Details is a single struct
return resp
}
func UpdateWhitelist(ctx context.Context, c *app.RequestContext) {
// 获取code参数
code := c.Query("code")
if code == "" {
c.JSON(400, utils.H{
"code": 400,
"message": "code parameter is required",
})
return
}
status := c.Query("status")
if status == "" {
c.JSON(400, utils.H{
"code": 400,
"message": "status parameter is required",
})
return
}
// 查询当前状态
var currentStatus string
err := db.DB.QueryRow("SELECT status FROM tk_whitelist WHERE code = ?", code).Scan(&currentStatus)
if err != nil {
c.JSON(500, utils.H{
"code": 500,
"message": "query failed",
})
return
}
// 确认状态为2
if currentStatus != "2" {
c.JSON(400, utils.H{
"code": 400,
"message": "status must be 2 to update",
})
return
}
// 更新whitelist表中的status字段
_, err = db.DB.Exec("UPDATE tk_whitelist SET status = ? WHERE code = ?", status, code)
if err != nil {
c.JSON(500, utils.H{
"code": 500,
"message": "update failed",
})
return
}
// 返回成功响应
c.JSON(200, utils.H{
"code": 200,
"message": "update successful",
})
}
package model
type TkDirectResp struct {
Channeltype string `json:"CHANNEL_TYPE"`
// 合作平台 CO_PLATFORM
Coplatform string `json:"CO_PLATFORM"`
// 贷款属性 LOAN_PROP
Loanprop string `json:"LOAN_PROP"`
// 产品类别 PRD_TYPE
Prdtype string `json:"PRD_TYPE"`
// 产品代码 PRD_CODE
Prdcode string `json:"PRD_CODE"`
// 业务场景码 YWCJM
Ywcjm string `json:"YWCJM"`
// 证件类型 CERT_TYPE
Certtype string `json:"CERT_TYPE"`
// 证件号码 CERT_CODE
Certcode string `json:"CERT_CODE"`
// 客户名称 CUST_NAME
Custname string `json:"CUST_NAME"`
// 企业名称 SHOP_NAME
Shopname string `json:"SHOP_NAME"`
// 统一社会信用代码 CREDIT_CODE
Creditcode string `json:"CREDIT_CODE"`
// 企业成立日期 SYSREG_DATE
Sysregdate string `json:"SYSREG_DATE"`
// 是否农户 FARMERS_FLAG
Farmersflag string `json:"FARMERS_FLAG"`
// 是否绿色贷款 GREEN_CREDIT_POLICY_FLAG
Greencreditpolicyflag string `json:"GREEN_CREDIT_POLICY_FLAG"`
// 第三方对象id TP_OBJ_ID
Tpobjid string `json:"TP_OBJ_ID"`
// 合作年限 CO_YEARS
Coyears int `json:"CO_YEARS"`
// 平台经营年限 PLATFORM_DEPT_YEAR
Platformdeptyear string `json:"PLATFORM_DEPT_YEAR"`
// 农户养殖规模 CULTIVATED_AMOUNT
Cultivatedamount int `json:"CULTIVATED_AMOUNT"`
// 农户养殖种类:编码待定 CULTIVATED_SPECIES
Cultivatedspecies string `json:"CULTIVATED_SPECIES"`
// 合作方评级 PARTNER_LEVEL
Partnerlevel string `json:"PARTNER_LEVEL"`
// 合作方建议额度 ADVICE_CRD_AMT
Advicecrdamt float64 `json:"ADVICE_CRD_AMT"`
// 相关行业从业年限 WORKING_YEARS
Workingyears int `json:"WORKING_YEARS"`
// 是否中标 LOA_FLAG
Loaflag string `json:"LOA_FLAG"`
// 过往是否有不良记录 BAD_CREDIT_RECORD_FLAG
Badcreditrecordflag string `json:"BAD_CREDIT_RECORD_FLAG"`
// 合同额度 CONTRACT_AMT
Contractamt string `json:"CONTRACT_AMT"`
// 客户年龄 CUST_AGE
Custage int `json:"CUST_AGE"`
// 资金账户号 SELLSTABRANK
Trusteesaccount string `json:"TRUSTEES_ACCOUNT"`
// 担保费率 DEPOSIT_RATIO
Guaranteedrates float64 `json:"GUARANTEED_RATES"`
// 经验所在地区域(区域归属) AREA_CODE
Areacode string `json:"AREA_CODE"`
// 行业代码 INDUSTRY_CODE
Industrycode string `json:"INDUSTRY_CODE"`
// 行业名称 INDUSTRY_NAME
Industryname string `json:"INDUSTRY_NAME"`
// 二级行业编号 INDUSTRY_CODE1
Industrycode1 string `json:"INDUSTRY_CODE1"`
// 二级行业名称 INDUSTRY_NAME1
Trustees string `json:"TRUSTEES"`
CalcAmt float64
Details TKDirectDetailResp `json:"detail"`
}
type TKDirectDetailResp struct {
//统计年月 statis_ym
Statisym string `json:"STATIS_YM"`
//年度饲料成本(养殖:当期饲料采购额(元),种植:空)
Custamt float64 `json:"CUST_AMT"`
//年度数量(养殖:养殖/出栏数量(亩/头/羽),种植:当期总亩产量(公斤))
Yearmat float64 `json:"YEAR_MAT"`
//年度单位产值(养殖:单位产值(元),种植:当期总亩产量(公斤))
Unitvalue float64 `json:"UNIT_VALUE"`
}
package model
import "time"
type Whitelist struct {
Id int
Name string
IdCard string
Code string
Age int
CooperationYears int
// 合同有限年限
ContractEffectiveDate string
// 合同金额
ContractAmount int
// 建议授信额度
AdviceCrdAmt int
// 担保费率
GuaranteeRate string
// 养殖或种植种类
// 养殖种类(牛、猪、羊、鸡、鱼)
// 种植面积(亩)
OperationVariety string
// 养殖或种植数量
// 在栏规模(亩/头/羽)种植面积(亩)
OperationScale int
// 单位 养殖(亩/头/羽)种植(亩)
OperationUnit string
// 资金受托方
FundTrustees string
// 资金账户号
FundAccount string
Status int
CreateTime time.Time
CompanyName string
SocialCredit string
CalcAmt float64
Detail []WhitelistDetail
}
type WhitelistDetail struct {
Id int
// 关联天康白名单ID;
WlId int
// 合作经营时间段
BusiHisIntervals string
// 当期饲料采购额(元) 当期总亩产量(公斤)
Purchases string
// 养殖/出栏数量(亩/头/羽),总亩产量(公斤)
Amount string
// 养殖-单位产值(元).每亩产值
UnitValue string
}
...@@ -9,4 +9,6 @@ func Register(r *server.Hertz) { ...@@ -9,4 +9,6 @@ func Register(r *server.Hertz) {
r.POST("/nlt/pufa/auth", handler.Auth) r.POST("/nlt/pufa/auth", handler.Auth)
r.POST("/nlt/pufa/queryPayResult", handler.QueryPayResult) r.POST("/nlt/pufa/queryPayResult", handler.QueryPayResult)
r.POST("/nlt/pufa/queryJumpUrl", handler.QueryJumpUrl) r.POST("/nlt/pufa/queryJumpUrl", handler.QueryJumpUrl)
r.POST("/nltLoanOrder/getPersonCredit", handler.DecryptAndQuery)
r.POST("/nltLoanOrder/updateWhitelist", handler.UpdateWhitelist)
} }
package utils
import (
"bytes"
"encoding/base64"
"github.com/tjfoc/gmsm/sm4"
)
var (
// SM4密钥,必须是16字节
// sm4Key = []byte("0480b0a8ae076531"
sm4Key = []byte{215, 245, 197, 26, 84, 14, 225, 38, 98, 19, 40, 49, 197, 118, 196, 68}
)
func PKCS5Padding(plainText []byte, blockSize int) []byte {
padding := blockSize - len(plainText)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(plainText, padtext...)
}
func PKCS5UnPadding(encrypt []byte) []byte {
padding := encrypt[len(encrypt)-1]
return encrypt[:len(encrypt)-int(padding)]
}
// SM4Encrypt SM4加密
func SM4Encrypt(plainText string) (string, error) {
// 创建SM4加密器
block, err := sm4.NewCipher(sm4Key)
if err != nil {
return "", err
}
// 明文填充
plainBytes := []byte(plainText)
plainBytes = PKCS5Padding(plainBytes, block.BlockSize())
// 加密
cipherBytes := make([]byte, len(plainBytes))
block.Encrypt(cipherBytes, plainBytes)
// Base64编码
return base64.StdEncoding.EncodeToString(cipherBytes), nil
}
// SM4Decrypt SM4解密
func SM4Decrypt(cipherText string) (string, error) {
// Base64解码
cipherBytes, err := base64.StdEncoding.DecodeString(cipherText)
if err != nil {
return "", err
}
// 创建SM4解密器
block, err := sm4.NewCipher(sm4Key)
if err != nil {
return "", err
}
// 解密
plainBytes := make([]byte, len(cipherBytes))
block.Decrypt(plainBytes, cipherBytes)
// 去除填充
plainBytes = PKCS5UnPadding(plainBytes)
return string(plainBytes), nil
}
package utils
import (
"fmt"
"testing"
)
func TestSM4Encrypt(t *testing.T) {
plainText := "Hello, World!"
expectedCipherText := "f3G5aPgCn/PDEY4DgHajRA==" // Replace with the expected Base64 encoded cipher text
cipherText, err := SM4Encrypt(plainText)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
fmt.Println(cipherText)
if cipherText != expectedCipherText {
t.Errorf("expected %s, got %s", expectedCipherText, cipherText)
}
}
func TestSM4Decrypt(t *testing.T) {
cipherText := "f3G5aPgCn/PDEY4DgHajRA==" // Replace with the Base64 encoded cipher text from the previous test
expectedPlainText := "Hello, World!"
plainText, err := SM4Decrypt(cipherText)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
fmt.Println(plainText)
if plainText != expectedPlainText {
t.Errorf("expected %s, got %s", "0480b0a8ae076531c78759901e1ab0bbc982523e11d36fbe33645ebc20ac981094c62a32efe0ccc7da02d1a2875aacb260bdd4a8f8f12cab50e83c03275dcb2496", plainText)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment