增加提现相关的与打款相关逻辑
This commit is contained in:
@@ -1,23 +1,18 @@
|
||||
package paymentaccount
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"hfb_sys/backend/internal/model"
|
||||
"hfb_sys/backend/pkg/crypto"
|
||||
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 加密密钥(生产环境应从配置文件读取)
|
||||
const encryptionKey = "your-32-byte-secret-key-here!!" // 32字节
|
||||
// 删除加密密钥常量
|
||||
|
||||
type Repository struct {
|
||||
db *gorm.DB
|
||||
@@ -75,7 +70,7 @@ func (r *Repository) FindByID(userID, id uint64) (*PaymentAccountDTO, error) {
|
||||
|
||||
func (r *Repository) Create(userID uint64, req CreatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
||||
// 加密账号
|
||||
encryptedNo, err := encrypt(req.AccountNo)
|
||||
encryptedNo, err := crypto.Encrypt(req.AccountNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -208,22 +203,54 @@ func (r *Repository) ValidateRealname(userID uint64, accountName string) error {
|
||||
|
||||
// 获取实名信息
|
||||
var realname model.UserRealname
|
||||
if err := r.db.Where("user_id = ? AND status = ?", userID, "success").
|
||||
if err := r.db.Where("user_id = ? AND status = ?", userID, "verified").
|
||||
First(&realname).Error; err != nil {
|
||||
return ErrRealnameRequired
|
||||
}
|
||||
|
||||
// 验证姓名匹配(去除空格后比较)
|
||||
if strings.ReplaceAll(realname.MaskedName, " ", "") != strings.ReplaceAll(accountName, " ", "") {
|
||||
return ErrAccountNameMismatch
|
||||
// 验证姓名匹配 - 使用加密字段进行精确匹配
|
||||
if realname.EncryptedName != "" {
|
||||
// 有加密字段,解密后精确匹配
|
||||
decryptedName, err := crypto.Decrypt(realname.EncryptedName)
|
||||
if err != nil {
|
||||
// 解密失败,降级到前缀匹配
|
||||
return r.validateByMaskedName(realname.MaskedName, accountName)
|
||||
}
|
||||
// 精确匹配(去除空格)
|
||||
if strings.ReplaceAll(decryptedName, " ", "") != strings.ReplaceAll(accountName, " ", "") {
|
||||
return ErrAccountNameMismatch
|
||||
}
|
||||
} else {
|
||||
// 没有加密字段(旧数据),使用前缀匹配
|
||||
return r.validateByMaskedName(realname.MaskedName, accountName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 使用脱敏姓名进行前缀匹配(兼容旧数据)
|
||||
func (r *Repository) validateByMaskedName(maskedName, accountName string) error {
|
||||
maskedName = strings.ReplaceAll(maskedName, " ", "")
|
||||
inputName := strings.ReplaceAll(accountName, " ", "")
|
||||
|
||||
if strings.Contains(maskedName, "*") {
|
||||
// 提取非星号部分(通常是姓氏)
|
||||
prefix := strings.Split(maskedName, "*")[0]
|
||||
if prefix != "" && !strings.HasPrefix(inputName, prefix) {
|
||||
return ErrAccountNameMismatch
|
||||
}
|
||||
} else {
|
||||
// 完整匹配
|
||||
if maskedName != inputName {
|
||||
return ErrAccountNameMismatch
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) toDTO(account model.UserPaymentAccount) (*PaymentAccountDTO, error) {
|
||||
// 解密账号并脱敏
|
||||
decrypted, err := decrypt(account.AccountNo)
|
||||
decrypted, err := crypto.Decrypt(account.AccountNo)
|
||||
if err != nil {
|
||||
decrypted = account.AccountNo // 降级处理
|
||||
}
|
||||
@@ -275,57 +302,11 @@ func maskAccountNo(accountNo, accountType string) string {
|
||||
return accountNo
|
||||
}
|
||||
|
||||
// AES加密
|
||||
func encrypt(plainText string) (string, error) {
|
||||
block, err := aes.NewCipher([]byte(encryptionKey))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
plainBytes := []byte(plainText)
|
||||
cipherBytes := make([]byte, aes.BlockSize+len(plainBytes))
|
||||
iv := cipherBytes[:aes.BlockSize]
|
||||
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
stream := cipher.NewCFBEncrypter(block, iv)
|
||||
stream.XORKeyStream(cipherBytes[aes.BlockSize:], plainBytes)
|
||||
|
||||
return base64.StdEncoding.EncodeToString(cipherBytes), nil
|
||||
}
|
||||
|
||||
// AES解密
|
||||
func decrypt(cipherText string) (string, error) {
|
||||
block, err := aes.NewCipher([]byte(encryptionKey))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cipherBytes, err := base64.StdEncoding.DecodeString(cipherText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(cipherBytes) < aes.BlockSize {
|
||||
return "", errors.New("ciphertext too short")
|
||||
}
|
||||
|
||||
iv := cipherBytes[:aes.BlockSize]
|
||||
cipherBytes = cipherBytes[aes.BlockSize:]
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
stream.XORKeyStream(cipherBytes, cipherBytes)
|
||||
|
||||
return string(cipherBytes), nil
|
||||
}
|
||||
|
||||
// 获取解密后的账号(仅供内部使用,如提现申请时)
|
||||
func (r *Repository) GetDecryptedAccountNo(userID, id uint64) (string, error) {
|
||||
var account model.UserPaymentAccount
|
||||
if err := r.db.Where("id = ? AND user_id = ?", id, userID).First(&account).Error; err != nil {
|
||||
return "", err
|
||||
}
|
||||
return decrypt(account.AccountNo)
|
||||
return crypto.Decrypt(account.AccountNo)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user