Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into feature/auth

This commit is contained in:
eson
2023-08-08 14:18:45 +08:00
115 changed files with 3189 additions and 504 deletions

View File

@@ -56,14 +56,18 @@ var (
CodeSafeValueRangeErr = &StatusResponse{5040, "value not in range"} // 值不在范围内
CodeTemplateErr = &StatusResponse{5040, "template parsed error"} // 模板解析错误
CodeOrderNotFoundErr = &StatusResponse{5030, "order not found"} //未找到订单
CodeCloudOrderNotFoundErr = &StatusResponse{5031, "cloud order not found"} //未找到云仓订单
CodeOrderNotCancelledErr = &StatusResponse{5032, "current order cannot be cancelled"} // 当前订单无法取消
CodeOrderNotFoundErr = &StatusResponse{5030, "order not found"} //未找到订单
CodeCloudOrderNotFoundErr = &StatusResponse{5031, "cloud order not found"} //未找到云仓订单
CodeOrderNotCancelledErr = &StatusResponse{5032, "current order cannot be cancelled"} // 当前订单无法取消
CodeOrderCancelledNotOk = &StatusResponse{5033, "current order cancelled failed"} // 当前订单取消失败
CodeOrderCancelledOk = &StatusResponse{5034, "current order cancelled successful"} // 当前订单取消成功
CodePayNotFoundErr = &StatusResponse{5020, "pay info not found"} // 支付信息无法查询
CodePayCancelOk = &StatusResponse{5021, "cancellation successful"} // 支付取消成功
CodePayCancelNotOk = &StatusResponse{5022, "cancellation failed"} // 支付取消失败
CodePaybackNotOk = &StatusResponse{5023, "pay back failed"} // 支付回调处理失败
CodeGuestDupErr = &StatusResponse{5010, "user is already guest and does not need to reapply"} // 用户已经是访客用户,无需重复申请
CodeGuestGenErr = &StatusResponse{5011, "serialization failed for guest ID"} // 访客ID序列化失败
@@ -77,8 +81,8 @@ var (
CodeAesCbcEncryptionErr = &StatusResponse{5106, "encryption data err"} // 加密数据失败
CodeAesCbcDecryptionErr = &StatusResponse{5107, "decryption data err"} // 解密数据失败
CodeSharedStateErr = &StatusResponse{5201, "shared state server err"} // 状态机错误
CodeEmailConfirmationErr = &StatusResponse{5202, "email confirmation err"} // email 验证错误
CodeFileUploadErr = &StatusResponse{5110, "file upload err"} // 文件上传失败
CodeFileUploadLogoErr = &StatusResponse{5111, "logo upload err"} // 用户上传LOGO失败
)
type Response struct {

18
utils/file/base64.go Normal file
View File

@@ -0,0 +1,18 @@
package file
import (
"encoding/base64"
"net/http"
"strings"
)
func FileBase64ToByte(fileData string) ([]byte, string, error) {
RBase64Point := strings.LastIndex(fileData, ";base64,") + 8
fileDataStr := fileData[RBase64Point:]
dist, err := base64.StdEncoding.DecodeString(fileDataStr)
if err != nil {
return nil, "", err
}
contentType := http.DetectContentType(dist)
return dist, contentType, nil
}

View File

@@ -107,3 +107,5 @@ func FormatS3KeyNameGuest(guestid int64, now time.Time, env string, category Typ
}
}
// generateS3KeyName 生成

View File

@@ -1,4 +1,4 @@
package handler
package handlers
import (
"encoding/json"

View File

@@ -0,0 +1,64 @@
package handlers
import (
"fusenapi/constants"
"fusenapi/utils/pay"
"github.com/zeromicro/go-zero/core/mr"
)
type (
PayInfo struct {
TradeNo string `json:"trade_no"`
PaymentMethod int64 `json:"payment_method"`
Key string `json:"key"`
}
PayRefundHandlerReq struct {
PayInfoList []PayInfo
}
PayRefundHandlerRes struct {
}
)
// 申请第三方退款
func PayRefundHandler(req *PayRefundHandlerReq) (res PayRefundHandlerRes, err error) {
_, err = mr.MapReduce(func(source chan<- interface{}) {
for _, payInfo := range req.PayInfoList {
source <- payInfo
}
}, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) {
payConfig := new(pay.Config)
payInfo := item.(PayInfo)
switch payInfo.PaymentMethod {
case int64(constants.PAYMETHOD_STRIPE):
// stripe 支付
payConfig.Stripe.Key = payInfo.Key
}
payDriver := pay.NewPayDriver(payInfo.PaymentMethod, payConfig)
_, err = payDriver.PayRefund(&pay.PayRefundReq{
TradeNo: payInfo.TradeNo,
})
if err != nil {
// Notice 如果不加 cancel(err),会返回校验成功的id; 如果加上cancel(err),返回的结果会是一个空列表
// Notice 实际上,如果这里返回错误,其他协程直接就退出了!
// Notice 看实际中业务的需求情况来定了...
cancel(err)
}
// Notice 这个必须加!
writer.Write(payInfo)
}, func(pipe <-chan interface{}, writer mr.Writer[interface{}], cancel func(error)) {
var payInfoList []PayInfo
for p := range pipe {
payInfoList = append(payInfoList, p.(PayInfo))
}
// Notice 这个必须加!
writer.Write(payInfoList)
})
if err != nil {
return res, err
}
return res, nil
}

81
utils/hash/hash.go Normal file
View File

@@ -0,0 +1,81 @@
package hash
import (
"bytes"
"crypto/sha256"
"encoding/json"
"fmt"
"reflect"
"sort"
)
func JsonHashKey(v interface{}) string {
if reflect.TypeOf(v).Kind() == reflect.String {
var obj interface{}
err := json.Unmarshal([]byte(v.(string)), &obj)
if err == nil {
// 反序列化成功,直接替换v
v = obj
}
}
h := sha256.New()
h.Write(marshalOrdered(v))
return fmt.Sprintf("%x", h.Sum(nil))
}
func marshalOrdered(v interface{}) []byte {
switch v := v.(type) {
case map[string]interface{}:
sortedKeys := make([]string, 0, len(v))
for key := range v {
sortedKeys = append(sortedKeys, key)
}
sort.Strings(sortedKeys)
var buf bytes.Buffer
buf.WriteByte('{')
for i, key := range sortedKeys {
if i > 0 {
buf.WriteByte(',')
}
b, err := json.Marshal(key)
if err != nil {
panic(err)
}
buf.Write(b)
buf.WriteByte(':')
b = marshalOrdered(v[key])
buf.Write(b)
}
buf.WriteByte('}')
return buf.Bytes()
case []interface{}:
var buf bytes.Buffer
sort.Slice(v, func(i, j int) bool {
return bytes.Compare(marshalOrdered(v[i]), marshalOrdered(v[j])) == 1
})
buf.WriteByte('[')
for i, val := range v {
if i > 0 {
buf.WriteByte(',')
}
b := marshalOrdered(val)
buf.Write(b)
}
buf.WriteByte(']')
return buf.Bytes()
default:
b, err := json.Marshal(v)
if err != nil {
panic(err)
}
return b
}
}

View File

@@ -0,0 +1,8 @@
package mq_consumer_factory
import "context"
// 消费mq消息要实现对应Run方法
type MqHandle interface {
Run(ctx context.Context, data []byte) error
}

View File

@@ -20,7 +20,12 @@ func NewPayDriver(PayMethod int64, config *Config) Pay {
// Pay 支付集成接口
type Pay interface {
// 支付预处理
GeneratePrepayment(req *GeneratePrepaymentReq) (res *GeneratePrepaymentRes, err error)
// 支付退款申请
PayRefund(req *PayRefundReq) (res *PayRefundRes, err error)
}
type GeneratePrepaymentReq struct {
@@ -41,3 +46,10 @@ type GeneratePrepaymentRes struct {
ClientSecret string `json:"clientSecret"` //交易密钥
SessionId string `json:"session_id"` //SessionId
}
type PayRefundReq struct {
TradeNo string `json:"trade_no"` // 交易编号
}
type PayRefundRes struct {
}

View File

@@ -3,12 +3,25 @@ package pay
import (
"github.com/stripe/stripe-go/v74"
"github.com/stripe/stripe-go/v74/checkout/session"
"github.com/stripe/stripe-go/v74/refund"
"github.com/zeromicro/go-zero/core/logx"
)
type Stripe struct {
Key string `json:"key"`
}
// 生成退款
func (stripePay *Stripe) PayRefund(req *PayRefundReq) (res *PayRefundRes, err error) {
stripe.Key = stripePay.Key
params := &stripe.RefundParams{PaymentIntent: stripe.String(req.TradeNo)}
_, err = refund.New(params)
if err != nil {
logx.Error(err)
}
return res, err
}
// 生成预付款
func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *GeneratePrepaymentRes, err error) {
var productData stripe.CheckoutSessionLineItemPriceDataProductDataParams

View File

@@ -0,0 +1,42 @@
package websocket_data
// websocket数据交互
type DataTransferData struct {
T string `json:"t"` //消息类型
D interface{} `json:"d"` //传递的消息
}
// websocket接受要云渲染处理的数据
type RenderImageReqMsg struct {
RenderId string `json:"render_id"` //渲染id
RenderData RenderData `json:"render_data"`
}
type RenderData struct {
TemplateTagId int64 `json:"template_tag_id"` //模板标签id
ProductId int64 `json:"product_id"` //产品id
Data interface{} `json:"data"` //面片数据
UserId int64 `json:"user_id"` //用户id
}
// websocket发送渲染完的数据
type RenderImageRspMsg struct {
RenderId string `json:"render_id"` //渲染id
Image string `json:"image"` //渲染结果图片
}
// 渲染服务器回调数据
type RenderImageNotify struct {
TaskId string `json:"task_id"`
Image string `json:"image"`
}
type ThirdPartyLoginRspMsg struct {
//websocket三方登录的通知数据
Token string `json:"token"`
}
// 发送到渲染组装的mq数据
type AssembleRenderData struct {
TaskId string `json:"task_id"`
RenderId string `json:"render_id"`
RenderData RenderData `json:"render_data"`
}