Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into feature/auth
This commit is contained in:
@@ -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
18
utils/file/base64.go
Normal 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
|
||||
}
|
||||
@@ -107,3 +107,5 @@ func FormatS3KeyNameGuest(guestid int64, now time.Time, env string, category Typ
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// generateS3KeyName 生成
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package handler
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
64
utils/handlers/payHandler.go
Normal file
64
utils/handlers/payHandler.go
Normal 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
81
utils/hash/hash.go
Normal 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
|
||||
}
|
||||
}
|
||||
8
utils/mq_consumer_factory/mq.go
Normal file
8
utils/mq_consumer_factory/mq.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package mq_consumer_factory
|
||||
|
||||
import "context"
|
||||
|
||||
// 消费mq消息要实现对应Run方法
|
||||
type MqHandle interface {
|
||||
Run(ctx context.Context, data []byte) error
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
42
utils/websocket_data/render_data.go
Normal file
42
utils/websocket_data/render_data.go
Normal 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"`
|
||||
}
|
||||
Reference in New Issue
Block a user