Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop
This commit is contained in:
commit
ab312efbb5
|
@ -1,7 +1,6 @@
|
|||
package constants
|
||||
|
||||
// 发票主体页面
|
||||
const MAIN_INVOICE_HTML = `
|
||||
const INVOICE_TEMPLATE = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
|
@ -11,6 +10,26 @@ const MAIN_INVOICE_HTML = `
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Invoice</title>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Montserrat-SemiBold";
|
||||
src: url("https://s3.us-west-1.amazonaws.com/storage.fusenpack.com/b808164b4f7ecc19f560d235db5b1f5b99fe8ab218b606f15debab2b9c4230e2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Montserrat-Medium";
|
||||
src: url("https://s3.us-west-1.amazonaws.com/storage.fusenpack.com/3d91bbd91ba6fac26b8460a078742b61bfd1e2976311c065f8ac9c5270be6901");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Montserrat-Light";
|
||||
src: url("https://s3.us-west-1.amazonaws.com/storage.fusenpack.com/24e580a4a5afebf94596ec7b6c8d9c8d57f75a5429ee757217da552d5f03e5d1");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Montserrat-Regular";
|
||||
src: url("https://s3.us-west-1.amazonaws.com/storage.fusenpack.com/78072d2cbce0a3f88c01ab2830ba3a453f0968b516388e45e9a6fb5e970450b8");
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -22,6 +41,7 @@ const MAIN_INVOICE_HTML = `
|
|||
|
||||
.header_td {
|
||||
width: 50%;
|
||||
font-family: Montserrat-SemiBold;
|
||||
}
|
||||
|
||||
.header_td.logo {
|
||||
|
@ -49,11 +69,13 @@ const MAIN_INVOICE_HTML = `
|
|||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
font-weight: 300;
|
||||
font-family: Montserrat-Light;
|
||||
}
|
||||
|
||||
.information_td.bill {
|
||||
color: #212121;
|
||||
font-weight: 500;
|
||||
font-family: Montserrat-Medium;
|
||||
}
|
||||
|
||||
.information_td.right {
|
||||
|
@ -82,6 +104,7 @@ const MAIN_INVOICE_HTML = `
|
|||
padding: 13px 0 7px;
|
||||
font-weight: 500;
|
||||
color: #212121;
|
||||
font-family: Montserrat-Medium;
|
||||
}
|
||||
|
||||
.bill_td.info {
|
||||
|
@ -89,6 +112,11 @@ const MAIN_INVOICE_HTML = `
|
|||
border-bottom: 1px solid #ccc;
|
||||
padding: 8px 0;
|
||||
font-weight: 400;
|
||||
font-family: Montserrat-Light;
|
||||
}
|
||||
|
||||
.bill_td.info:first-child {
|
||||
font-family: Montserrat-Regular;
|
||||
}
|
||||
|
||||
.bill_warp tr:last-child .bill_td.info {
|
||||
|
@ -104,11 +132,13 @@ const MAIN_INVOICE_HTML = `
|
|||
padding: 8px 0 7px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
font-family: Montserrat-Medium;
|
||||
}
|
||||
|
||||
.total_td.info {
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
font-family: Montserrat-Regular;
|
||||
}
|
||||
|
||||
.total_td.border-dashed {
|
||||
|
@ -124,6 +154,7 @@ const MAIN_INVOICE_HTML = `
|
|||
padding-top: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-family: Montserrat-SemiBold;
|
||||
}
|
||||
|
||||
.notes_warp {
|
||||
|
@ -136,11 +167,13 @@ const MAIN_INVOICE_HTML = `
|
|||
font-weight: 300;
|
||||
width: 50%;
|
||||
line-height: 21px;
|
||||
font-family: Montserrat-Light;
|
||||
}
|
||||
|
||||
.notes_td.title {
|
||||
color: #212121;
|
||||
font-weight: 500;
|
||||
font-family: Montserrat-Medium;
|
||||
}
|
||||
|
||||
.notes_td.notes {
|
||||
|
@ -150,95 +183,102 @@ const MAIN_INVOICE_HTML = `
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<!-- header -->
|
||||
<table class="header_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td class="header_td logo" align="left">
|
||||
<img class="header_logo" src="https://fusenapi.kayue.cn:8010/storage/email/logo.png" alt="logo">
|
||||
</td>
|
||||
<td class="header_td title" align="right">Invoice</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- information -->
|
||||
<table class="information_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td class="information_td bill" align="left">Bill To:</td>
|
||||
<td class="information_td right" align="right">Invoice No. {{invoice_number}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="information_td info" align="left">{{buyer_name}}</td>
|
||||
<td class="information_td right" align="right">Date: {{buy_date}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="information_td info" align="left">{{street}}</td>
|
||||
<td class="information_td" align="right"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="information_td info" align="left">{{city}}</td>
|
||||
<td class="information_td" align="right"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="information_td info" align="left">{{country}}</td>
|
||||
<td class="information_td" align="right"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- bill -->
|
||||
<table class="bill_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||
<!--循环部分-->
|
||||
{{product_loop_html}}
|
||||
<!--循环部分-->
|
||||
</table>
|
||||
<!-- total -->
|
||||
<table class="total_warp" border="0" align="right" cellpadding="0" cellspacing="0" width="50%">
|
||||
<tr>
|
||||
<td class="total_td" align="right">Subtotal</td>
|
||||
<td class="total_td info" align="right">${{subtotal_price}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td" align="right">Shipping Fee</td>
|
||||
<td class="total_td info" align="right">Free</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td border-dashed" align="right">Tax</td>
|
||||
<td class="total_td info border-dashed" align="right">${{tax}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td" align="right">Total</td>
|
||||
<td class="total_td info" align="right">${{total_price}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td border-solid" align="right">Deposit Requested</td>
|
||||
<td class="total_td info border-solid" align="right">${{deposit_price}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td total" align="right">Deposit Due</td>
|
||||
<td class="total_td total" align="right">${{deposit_price}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- notes -->
|
||||
<table class="notes_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td class="notes_td title" align="left">Payment Method:</td>
|
||||
<td class="notes_td title" align="left">Notes:</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="notes_td" align="left">{{payment_method}}</td>
|
||||
<td class="notes_td notes" align="left" rowspan="2">{{notes}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="notes_td" align="left">Account No. {{account_number}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- header -->
|
||||
<table class="header_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td class="header_td logo" align="left">
|
||||
<img class="header_logo" src="https://fusenapi.kayue.cn:8010/storage/email/logo.png" alt="logo">
|
||||
</td>
|
||||
<td class="header_td title" align="right">Invoice</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- information -->
|
||||
<table class="information_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td class="information_td bill" align="left">Bill To:</td>
|
||||
<td class="information_td right" align="right">Invoice No. #20220562040</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="information_td info" align="left">Timmy Turner</td>
|
||||
<td class="information_td right" align="right">Date: 2023/12/04</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="information_td info" align="left">North Street</td>
|
||||
<td class="information_td" align="right"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="information_td info" align="left">London, SE20 3JW</td>
|
||||
<td class="information_td" align="right"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="information_td info" align="left">United Kingdom</td>
|
||||
<td class="information_td" align="right"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- bill -->
|
||||
<table class="bill_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td class="bill_td title" align="left">Product Name</td>
|
||||
<td class="bill_td title" align="right">Price</td>
|
||||
<td class="bill_td title" align="right">Quantity</td>
|
||||
<td class="bill_td title" align="right">Total</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bill_td info" align="left">Plastic bowl</td>
|
||||
<td class="bill_td info" align="right">$01.00</td>
|
||||
<td class="bill_td info" align="right">20,000 Units</td>
|
||||
<td class="bill_td info" align="right">$99.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bill_td info" align="left">Paper bag with handlexxxxxxxxxxxxxxx second line</td>
|
||||
<td class="bill_td info" align="right">$01.00</td>
|
||||
<td class="bill_td info" align="right">20,000 Units</td>
|
||||
<td class="bill_td info" align="right">$99.00</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- total -->
|
||||
<table class="total_warp" border="0" align="right" cellpadding="0" cellspacing="0" width="50%">
|
||||
<tr>
|
||||
<td class="total_td" align="right">Subtotal</td>
|
||||
<td class="total_td info" align="right">$198.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td" align="right">Shipping Fee</td>
|
||||
<td class="total_td info" align="right">Free</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td border-dashed" align="right">Tax</td>
|
||||
<td class="total_td info border-dashed" align="right">$0.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td" align="right">Total</td>
|
||||
<td class="total_td info" align="right">$198.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td border-solid" align="right">Deposit Requested</td>
|
||||
<td class="total_td info border-solid" align="right">$99.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total_td total" align="right">Deposit Due</td>
|
||||
<td class="total_td total" align="right">$99.00</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- notes -->
|
||||
<table class="notes_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td class="notes_td title" align="left">Payment Method:</td>
|
||||
<td class="notes_td title" align="left">Notes:</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="notes_td" align="left">ICBC</td>
|
||||
<td class="notes_td notes" align="left" rowspan="2">Thank you for your business !</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="notes_td" align="left">Account No. :****4589</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
`
|
||||
|
||||
// 产品循环部分{{product_loop_html}}
|
||||
const PRODUCT_LOOP_HTML_CONTENT = ` <tr>
|
||||
<td class="bill_td title" align="left">{{product_name}}</td>
|
||||
<td class="bill_td title" align="right">${{product_item_price}}</td>
|
||||
<td class="bill_td title" align="right">{{purchase_quantity}}</td>
|
||||
<td class="bill_td title" align="right">${{product_total_price}}</td>
|
||||
</tr>`
|
||||
`
|
||||
|
|
|
@ -32,7 +32,16 @@ func (m *FsGuestModel) GenerateGuestID(ctx context.Context, AccessSecret uint64)
|
|||
logx.Error(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
uinfo := &FsUserInfo{
|
||||
Module: FsString("module"),
|
||||
UserId: FsInt64(0),
|
||||
GuestId: &record.GuestId,
|
||||
Metadata: FsBytes("{}"),
|
||||
Ctime: &now,
|
||||
Utime: &now,
|
||||
}
|
||||
return tx.Model(FsUserInfo{}).Create(uinfo).Error
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -79,3 +79,11 @@ func (m *FsUserInfoModel) GetProfile(ctx context.Context, pkey string, userId in
|
|||
}
|
||||
return info, nil
|
||||
}
|
||||
func (m *FsUserInfoModel) FindOneByUser(ctx context.Context, userId, guestId int64) (resp *FsUserInfo, err error) {
|
||||
if userId > 0 {
|
||||
err = m.db.WithContext(ctx).Model(&FsUserInfo{}).Where("user_id = ?", userId).Take(&resp).Error
|
||||
} else {
|
||||
err = m.db.WithContext(ctx).Model(&FsUserInfo{}).Where("user_id = ? and guest_id = ?", userId, guestId).Take(&resp).Error
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
|
|
@ -36,6 +36,11 @@ func FsBool(v bool) *bool {
|
|||
return &v
|
||||
}
|
||||
|
||||
func FsBytes(v string) *[]byte {
|
||||
bs := []byte(v)
|
||||
return &bs
|
||||
}
|
||||
|
||||
// SubscriptionStatus 订阅状态
|
||||
type SubscriptionStatus struct {
|
||||
NotificationEmail struct {
|
||||
|
|
|
@ -48,7 +48,6 @@ func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth
|
|||
)
|
||||
|
||||
if err != nil {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,14 @@ package logic
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/server/product-template-tag/internal/svc"
|
||||
"fusenapi/server/product-template-tag/internal/types"
|
||||
"fusenapi/service/repositories"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/s3url_to_s3id"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
@ -55,21 +56,31 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
|
|||
productTemplateTags []gmodel.FsProductTemplateTags
|
||||
err error
|
||||
)
|
||||
//获取用户需要渲染logo
|
||||
logoInfo, err := l.svcCtx.Repositories.ImageHandle.LogoInfo(l.ctx, &repositories.LogoInfoReq{
|
||||
UserId: userinfo.UserId,
|
||||
GuestId: userinfo.GuestId,
|
||||
})
|
||||
if req.Logo == "" {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "logo is required")
|
||||
}
|
||||
logoResourceId := s3url_to_s3id.GetS3ResourceIdFormUrl(req.Logo)
|
||||
logoInfo, err := l.svcCtx.AllModels.FsUserMaterial.FindOneByLogoResourceId(l.ctx, logoResourceId)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get logo info")
|
||||
}
|
||||
if logoInfo.Metadata == nil || *logoInfo.Metadata == "" {
|
||||
//查询logo素材信息
|
||||
if logoInfo.Metadata == nil || len(*logoInfo.Metadata) == 0 {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "logo info`s metadata is not set")
|
||||
}
|
||||
//获取userInfo信息
|
||||
userProfile, err := l.svcCtx.AllModels.FsUserInfo.FindOneByUser(l.ctx, userinfo.UserId, userinfo.GuestId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "user profile info is not found")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user profile info")
|
||||
}
|
||||
//解析用户素材元数据
|
||||
var metaData map[string]interface{}
|
||||
if err = json.Unmarshal([]byte(*logoInfo.Metadata), &metaData); err != nil {
|
||||
if err = json.Unmarshal(*logoInfo.Metadata, &metaData); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse user metadata")
|
||||
}
|
||||
|
@ -89,18 +100,16 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
|
|||
}
|
||||
//从用户元数据获取选中的颜色数据
|
||||
mapSelectColor := make(map[string]int) //key是模板标签val是选中的索引
|
||||
if logoInfo.UserInfoMetadata != nil && *logoInfo.UserInfoMetadata != "" {
|
||||
//解析用户信息元数据
|
||||
var logoSelectInfo LogoSelect
|
||||
if err = json.Unmarshal([]byte(*logoInfo.UserInfoMetadata), &logoSelectInfo); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse user info metadata")
|
||||
}
|
||||
//设置选中
|
||||
key := logoSelectInfo.LogoSelected.TemplateTagSelected.TemplateTag
|
||||
if _, ok := mapMaterialTemplateTagColors[key]; ok {
|
||||
mapSelectColor[key] = logoSelectInfo.LogoSelected.TemplateTagSelected.SelectedIndex
|
||||
}
|
||||
//解析用户信息元数据
|
||||
var logoSelectInfo LogoSelect
|
||||
if err = json.Unmarshal(*userProfile.Metadata, &logoSelectInfo); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse user info metadata")
|
||||
}
|
||||
//设置选中
|
||||
key := logoSelectInfo.LogoSelected.TemplateTagSelected.TemplateTag
|
||||
if _, ok := mapMaterialTemplateTagColors[key]; ok {
|
||||
mapSelectColor[key] = logoSelectInfo.LogoSelected.TemplateTagSelected.SelectedIndex
|
||||
}
|
||||
var templateTagNameList []string
|
||||
for templateTag, _ := range mapMaterialTemplateTagColors {
|
||||
|
|
|
@ -6,7 +6,8 @@ import (
|
|||
)
|
||||
|
||||
type GetProductTemplateTagsReq struct {
|
||||
Limit int `form:"limit"`
|
||||
Limit int `form:"limit"`
|
||||
Logo string `form:"logo"`
|
||||
}
|
||||
|
||||
type GetProductTemplateTagsRsp struct {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/file"
|
||||
|
@ -63,7 +62,7 @@ func (l *UploadFileBackendLogic) UploadFileBackend(req *types.UploadFileBackendR
|
|||
l.r.ParseMultipartForm(32 << 20)
|
||||
|
||||
fileObject, _, err := l.r.FormFile("file")
|
||||
fmt.Printf("%#v", fileObject)
|
||||
//fmt.Printf("%#v", fileObject)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,no files")
|
||||
|
|
|
@ -72,13 +72,6 @@ var (
|
|||
websocketInChanLen = 2000
|
||||
//每个websocket连接出口缓冲队列长度默认值
|
||||
websocketOutChanLen = 2000
|
||||
//是否开启debug
|
||||
openDebug = true
|
||||
//允许跨域的origin
|
||||
mapAllowOrigin = map[string]struct{}{
|
||||
"https://www.fusen.3718.cn": struct{}{},
|
||||
"http://www.fusen.3718.cn": struct{}{},
|
||||
}
|
||||
)
|
||||
|
||||
// 用户标识的连接增删操作队列传输的值的结构
|
||||
|
@ -102,6 +95,7 @@ type wsConnectItem struct {
|
|||
inChan chan []byte //接受消息缓冲队列(基本属性)
|
||||
outChan chan []byte //要发送回客户端的消息缓冲队列(基本属性)
|
||||
mutex sync.Mutex //互斥锁(基本属性)
|
||||
openDebug bool //是否开启debug
|
||||
userId int64 //用户id(基本属性)
|
||||
guestId int64 //游客id(基本属性)
|
||||
extendRenderProperty extendRenderProperty //扩展云渲染属性(扩展属性)
|
||||
|
@ -109,20 +103,10 @@ type wsConnectItem struct {
|
|||
|
||||
// 请求建立连接,升级websocket协议
|
||||
func (l *DataTransferLogic) DataTransfer(req *types.DataTransferReq, w http.ResponseWriter, r *http.Request) {
|
||||
origin := r.Header.Get("Origin")
|
||||
//判断是不是允许的跨域
|
||||
if !openDebug {
|
||||
upgrader.CheckOrigin = func(r *http.Request) bool {
|
||||
if _, ok := mapAllowOrigin[origin]; !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
//把子协议携带的token设置到标准token头信息中
|
||||
token := r.Header.Get("Sec-Websocket-Protocol")
|
||||
oldWid := req.Wid
|
||||
oldWid = strings.ReplaceAll(oldWid, " ", "+")
|
||||
oldWid = strings.Trim(oldWid, " ")
|
||||
//有token是正常用户,无则是白板用户,也可以连接
|
||||
if token != "" {
|
||||
r.Header.Set("Authorization", "Bearer "+token)
|
||||
|
@ -238,6 +222,7 @@ func (l *DataTransferLogic) setConnPool(conn *websocket.Conn, userInfo *auth.Use
|
|||
renderCtx: renderCtx,
|
||||
renderCtxCancelFunc: renderCtxCancelFunc,
|
||||
},
|
||||
openDebug: true, //默认都开debug
|
||||
}
|
||||
//保存连接
|
||||
mapConnPool.Store(uniqueId, ws)
|
||||
|
@ -254,10 +239,7 @@ func (l *DataTransferLogic) setConnPool(conn *websocket.Conn, userInfo *auth.Use
|
|||
|
||||
// 获取websocket发送到前端使用的数据传输类型(debug开启是文本,否则是二进制)
|
||||
func getWebsocketBaseTransferDataFormat() int {
|
||||
if openDebug {
|
||||
return websocket.TextMessage
|
||||
}
|
||||
return websocket.BinaryMessage
|
||||
return websocket.TextMessage
|
||||
}
|
||||
|
||||
// 获取唯一id
|
||||
|
|
|
@ -4,11 +4,17 @@ import "fusenapi/constants"
|
|||
|
||||
// 入口数据格式错误
|
||||
func (w *wsConnectItem) incomeDataFormatErrResponse(data interface{}) {
|
||||
if !w.openDebug {
|
||||
return
|
||||
}
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, data))
|
||||
}
|
||||
|
||||
// 渲染错误通知
|
||||
func (w *wsConnectItem) renderErrResponse(renderId, requestId, templateTag, taskId, description string, productId, userId, guestId, templateId, modelId, sizeId, elementModelId int64) {
|
||||
if !w.openDebug {
|
||||
return
|
||||
}
|
||||
data := make(map[string]interface{})
|
||||
data["render_id"] = renderId
|
||||
data["request_id"] = requestId
|
||||
|
@ -18,12 +24,12 @@ func (w *wsConnectItem) renderErrResponse(renderId, requestId, templateTag, task
|
|||
if taskId != "" {
|
||||
data["task_id"] = taskId
|
||||
}
|
||||
/*if userId >= 0 {
|
||||
if userId >= 0 {
|
||||
data["user_id"] = userId
|
||||
}
|
||||
if guestId >= 0 {
|
||||
data["guest_id"] = guestId
|
||||
}*/
|
||||
}
|
||||
if templateId > 0 {
|
||||
data["template_id"] = templateId
|
||||
}
|
||||
|
|
|
@ -352,7 +352,7 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
|
|||
if element.Base != nil && *element.Base != "" {
|
||||
tempData = append(tempData, map[string]interface{}{
|
||||
"name": "model",
|
||||
"data": "0," + combineImage + "," + *element.Base + " " + fmt.Sprintf("%d", time.Now().UTC().UnixMilli()),
|
||||
"data": "0," + combineImage + "," + *element.Base,
|
||||
"type": "other",
|
||||
"layer": "0",
|
||||
"is_update": 1,
|
||||
|
@ -437,45 +437,6 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
|
|||
return nil
|
||||
}
|
||||
|
||||
// 发送合图完毕阶段通知消息
|
||||
func (w *wsConnectItem) sendCombineImageStepResponseMessage(renderId, requestId, combineImage string, sizeId, modelId, templateId, combineTime, uploadTime int64) {
|
||||
combineTakesTime := "cache"
|
||||
uploadCombineImageTakesTime := "cache"
|
||||
if combineTime > 0 {
|
||||
combineTakesTime = fmt.Sprintf("%dms", combineTime)
|
||||
}
|
||||
if uploadTime > 0 {
|
||||
uploadCombineImageTakesTime = fmt.Sprintf("%dms", uploadTime)
|
||||
}
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_COMBINE_IMAGE, websocket_data.CombineImageRspMsg{
|
||||
RenderId: renderId,
|
||||
RequestId: requestId,
|
||||
CombineImage: combineImage,
|
||||
SizeId: sizeId,
|
||||
ModelId: modelId,
|
||||
TemplateId: templateId,
|
||||
CombineProcessTime: websocket_data.CombineProcessTime{
|
||||
CombineTakesTime: combineTakesTime,
|
||||
UploadCombineImageTakesTime: uploadCombineImageTakesTime,
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
// 发送组装unity渲染数据完毕阶段通知消息
|
||||
func (w *wsConnectItem) sendAssembleRenderDataStepResponseMessage(renderId string, requestId string) {
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ASSEMBLE_RENDER_DATA, websocket_data.ToUnityRspMsg{RenderId: renderId, RequestId: requestId}))
|
||||
}
|
||||
|
||||
// 发送组装unity渲染数据完毕阶段通知消息
|
||||
func (w *wsConnectItem) sendRenderDataToUnityStepResponseMessage(renderId string, requestId string) {
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_SEND_DATA_TO_UNITY, websocket_data.AssembleRenderDataRspMsg{RenderId: renderId, RequestId: requestId}))
|
||||
}
|
||||
|
||||
// 发送渲染最终结果数据到前端
|
||||
func (w *wsConnectItem) sendRenderResultData(data websocket_data.RenderImageRspMsg) {
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, data))
|
||||
}
|
||||
|
||||
// 组装渲染任务id
|
||||
func (w *wsConnectItem) genRenderTaskId(combineImage string, renderImageData websocket_data.RenderImageReqMsg, model3dInfo *gmodel.FsProductModel3d, productTemplate *gmodel.FsProductTemplateV2, element *gmodel.FsProductTemplateElement) string {
|
||||
//生成任务id(需要把user_id,guest_id设为0)
|
||||
|
@ -502,3 +463,52 @@ func (w *wsConnectItem) genRenderTaskId(combineImage string, renderImageData web
|
|||
}
|
||||
return hash.JsonHashKey(hashMap)
|
||||
}
|
||||
|
||||
// ****************************下面的发送消息的*********************************
|
||||
// 发送合图完毕阶段通知消息
|
||||
func (w *wsConnectItem) sendCombineImageStepResponseMessage(renderId, requestId, combineImage string, sizeId, modelId, templateId, combineTime, uploadTime int64) {
|
||||
if !w.openDebug {
|
||||
return
|
||||
}
|
||||
combineTakesTime := "cache"
|
||||
uploadCombineImageTakesTime := "cache"
|
||||
if combineTime > 0 {
|
||||
combineTakesTime = fmt.Sprintf("%dms", combineTime)
|
||||
}
|
||||
if uploadTime > 0 {
|
||||
uploadCombineImageTakesTime = fmt.Sprintf("%dms", uploadTime)
|
||||
}
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_COMBINE_IMAGE, websocket_data.CombineImageRspMsg{
|
||||
RenderId: renderId,
|
||||
RequestId: requestId,
|
||||
CombineImage: combineImage,
|
||||
SizeId: sizeId,
|
||||
ModelId: modelId,
|
||||
TemplateId: templateId,
|
||||
CombineProcessTime: websocket_data.CombineProcessTime{
|
||||
CombineTakesTime: combineTakesTime,
|
||||
UploadCombineImageTakesTime: uploadCombineImageTakesTime,
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
// 发送组装unity需要的数据完毕消息
|
||||
func (w *wsConnectItem) sendAssembleRenderDataStepResponseMessage(renderId string, requestId string) {
|
||||
if !w.openDebug {
|
||||
return
|
||||
}
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ASSEMBLE_RENDER_DATA, websocket_data.ToUnityRspMsg{RenderId: renderId, RequestId: requestId}))
|
||||
}
|
||||
|
||||
// 发送组装数据到unity完毕阶段通知消息
|
||||
func (w *wsConnectItem) sendRenderDataToUnityStepResponseMessage(renderId string, requestId string) {
|
||||
if !w.openDebug {
|
||||
return
|
||||
}
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_SEND_DATA_TO_UNITY, websocket_data.AssembleRenderDataRspMsg{RenderId: renderId, RequestId: requestId}))
|
||||
}
|
||||
|
||||
// 发送渲染最终结果数据到前端
|
||||
func (w *wsConnectItem) sendRenderResultData(data websocket_data.RenderImageRspMsg) {
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, data))
|
||||
}
|
||||
|
|
|
@ -46,21 +46,6 @@ func deleteUserConnPoolElement(userId, guestId int64, uniqueId string) {
|
|||
userConnPoolCtlChan <- data
|
||||
}
|
||||
|
||||
// 根据用户索引发现链接并发送(广播)消息到出口队列
|
||||
func sendToOutChanByUserIndex(userId, guestId int64, message []byte) {
|
||||
data := userConnPoolCtlChanItem{
|
||||
userId: userId,
|
||||
guestId: guestId,
|
||||
uniqueId: "",
|
||||
message: message,
|
||||
option: 2,
|
||||
}
|
||||
select {
|
||||
case userConnPoolCtlChan <- data:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 消费用户索引创建/删除/发送消息中的任务数据
|
||||
func ConsumeUserConnPoolCtlChanData(ctx context.Context) {
|
||||
defer func() {
|
||||
|
@ -130,3 +115,18 @@ func getmapUserConnPoolUniqueId(userId, guestId int64) (uniqueId string) {
|
|||
}
|
||||
return fmt.Sprintf("%d_%d", userId, guestId)
|
||||
}
|
||||
|
||||
// 根据用户索引发现链接并发送(广播)消息到出口队列
|
||||
func sendToOutChanByUserIndex(userId, guestId int64, message []byte) {
|
||||
data := userConnPoolCtlChanItem{
|
||||
userId: userId,
|
||||
guestId: guestId,
|
||||
uniqueId: "",
|
||||
message: message,
|
||||
option: 2,
|
||||
}
|
||||
select {
|
||||
case userConnPoolCtlChan <- data:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,21 +10,27 @@ info (
|
|||
import "basic.api"
|
||||
|
||||
service auth {
|
||||
// 登录接口
|
||||
@handler UserLoginHandler
|
||||
post /api/auth/login(RequestUserLogin) returns (response);
|
||||
|
||||
// 注册
|
||||
@handler UserRegisterHandler
|
||||
post /api/auth/register(RequestUserRegister) returns (response);
|
||||
|
||||
// 获取cookie, 成为游客
|
||||
@handler AcceptCookieHandler
|
||||
post /api/auth/accept-cookie(request) returns (response);
|
||||
|
||||
// 谷歌第三方登录
|
||||
@handler UserGoogleLoginHandler
|
||||
get /api/auth/oauth2/login/google(RequestGoogleLogin) returns (response);
|
||||
|
||||
// 邮箱校验
|
||||
@handler UserEmailConfirmationHandler
|
||||
get /api/auth/email/confirmation(RequestEmailConfirmation) returns (response);
|
||||
|
||||
// 第三方登录,确认使用邮箱
|
||||
@handler UserEmailRegisterHandler
|
||||
post /api/auth/oauth2/register(RequestEmailRegister) returns (response);
|
||||
|
||||
|
@ -40,6 +46,7 @@ service auth {
|
|||
@handler UserResetPasswordHtmlHandler
|
||||
get /api/auth/reset/password/html(RequestUserResetHtml) returns (response);
|
||||
|
||||
// 用于debug 删除帐号
|
||||
@handler DebugAuthDeleteHandler
|
||||
post /api/auth/debug/delete(RequestAuthDelete) returns (response);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ service product-template-tag {
|
|||
|
||||
//获取产品模板标签列表
|
||||
type GetProductTemplateTagsReq {
|
||||
Limit int `form:"limit"`
|
||||
Limit int `form:"limit"`
|
||||
Logo string `form:"logo"`
|
||||
}
|
||||
type GetProductTemplateTagsRsp {
|
||||
Id int64 `json:"id"`
|
||||
|
|
|
@ -38,9 +38,6 @@ type (
|
|||
}
|
||||
|
||||
ImageHandle = interface {
|
||||
// 获取logo最新信息
|
||||
LogoInfo(ctx context.Context, in *LogoInfoReq) (*LogoInfoRes, error)
|
||||
|
||||
// logo信息
|
||||
LogoInfoSet(ctx context.Context, in *LogoInfoSetReq) (*LogoInfoSetRes, error)
|
||||
|
||||
|
@ -65,106 +62,6 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
func (l *defaultImageHandle) LogoInfo(ctx context.Context, in *LogoInfoReq) (*LogoInfoRes, error) {
|
||||
var metadata *string
|
||||
var logoUrl *string
|
||||
var userInfoMetadata *string
|
||||
// 更新用户信息
|
||||
var module = "profile"
|
||||
userInfoGorm := l.MysqlConn.Where("module = ?", module)
|
||||
userInfo := gmodel.FsUserInfo{}
|
||||
userInfoGorm.Where("user_id = ? and guest_id = ?", in.UserId, in.GuestId)
|
||||
userInfo.UserId = &in.UserId
|
||||
userInfo.GuestId = &in.GuestId
|
||||
/*if in.UserId == 0 && in.GuestId == 0 {
|
||||
userInfoGorm.Where("user_id = ? and guest_id = ?", in.UserId, in.GuestId)
|
||||
} else {
|
||||
if in.UserId > 0 {
|
||||
userInfoGorm.Where("user_id = ?", in.UserId)
|
||||
userInfo.UserId = &in.UserId
|
||||
} else {
|
||||
userInfoGorm.Where("guest_id = ?", in.GuestId)
|
||||
userInfo.GuestId = &in.GuestId
|
||||
}
|
||||
}*/
|
||||
resFirst := userInfoGorm.First(&userInfo)
|
||||
err := resFirst.Error
|
||||
if err != nil {
|
||||
if err != gorm.ErrRecordNotFound {
|
||||
logc.Errorf(ctx, "FsUserInfo First err:%+v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if userInfo.Id != 0 {
|
||||
tmp := string(*userInfo.Metadata)
|
||||
userInfoMetadata = &tmp
|
||||
}
|
||||
var userMaterialInfo gmodel.FsUserMaterial
|
||||
userMaterialModel := gmodel.NewFsUserMaterialModel(l.MysqlConn)
|
||||
var metadataUserInfo struct {
|
||||
LogoSelected struct {
|
||||
TemplateTagSelected *struct {
|
||||
Color [][]string `json:"color"`
|
||||
TemplateTag string `json:"template_tag"`
|
||||
SelectedIndex int64 `json:"selected_index"`
|
||||
} `json:"template_tag_selected"`
|
||||
LogoSelectedId int64 `json:"logo_selected_id"`
|
||||
} `json:"logo_selected"`
|
||||
}
|
||||
userInfo.Id = 0
|
||||
if userInfo.Id == 0 {
|
||||
userMaterialInfo, err = userMaterialModel.FindLatestOne(ctx, in.UserId, in.GuestId)
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
logc.Errorf(ctx, "FsUserMaterial FindLatestOne err:%+v", err)
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if userInfo.Metadata != nil {
|
||||
err = json.Unmarshal([]byte(*userInfo.Metadata), &metadataUserInfo)
|
||||
if err != nil {
|
||||
logc.Errorf(ctx, "userInfo.Metadata Unmarshal err:%+v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if metadataUserInfo.LogoSelected.LogoSelectedId != 0 {
|
||||
userMaterialInfos, err := userMaterialModel.FindOneById(ctx, metadataUserInfo.LogoSelected.LogoSelectedId)
|
||||
if err != nil {
|
||||
if err != gorm.ErrRecordNotFound {
|
||||
logc.Errorf(ctx, "userMaterial findOneById err:%+v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if userMaterialInfos.Id != 0 {
|
||||
userMaterialInfo = *userMaterialInfos
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if userMaterialInfo.Id == 0 {
|
||||
userMaterialInfoDefault, err := userMaterialModel.FindOneById(ctx, 0)
|
||||
if err != nil {
|
||||
if err != gorm.ErrRecordNotFound {
|
||||
logc.Errorf(ctx, "userMaterialModel FindOneById defaul err:%+v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
metadataB := string(*userMaterialInfoDefault.Metadata)
|
||||
metadata = &metadataB
|
||||
logoUrl = userMaterialInfoDefault.ResourceUrl
|
||||
|
||||
} else {
|
||||
metadataB := string(*userMaterialInfo.Metadata)
|
||||
metadata = &metadataB
|
||||
logoUrl = userMaterialInfo.ResourceUrl
|
||||
}
|
||||
return &LogoInfoRes{
|
||||
Metadata: metadata,
|
||||
LogoUrl: logoUrl,
|
||||
UserInfoMetadata: userInfoMetadata,
|
||||
}, nil
|
||||
}
|
||||
|
||||
/* 获取logo最新信息 */
|
||||
|
||||
/* logo信息 */
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package curl
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -32,3 +34,52 @@ func ApiCall(url, method string, header map[string]string, body io.Reader, timeO
|
|||
}
|
||||
return client.Do(requestHandle)
|
||||
}
|
||||
|
||||
// 请求(读取返回字节内容)
|
||||
func ApiCall2(url, method string, header map[string]string, body io.Reader, timeOut time.Duration) (result []byte, err error) {
|
||||
method = strings.ToUpper(method)
|
||||
if method != "GET" && method != "POST" && method != "PUT" && method != "DELETE" {
|
||||
return nil, errors.New("invalid http method")
|
||||
}
|
||||
if url == "" {
|
||||
return nil, errors.New("request url can`t be empty")
|
||||
}
|
||||
client := &http.Client{}
|
||||
if timeOut <= 0 {
|
||||
client.Timeout = time.Second * 15
|
||||
} else {
|
||||
client.Timeout = timeOut
|
||||
}
|
||||
requestHandle, err := http.NewRequest(method, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range header {
|
||||
requestHandle.Header.Set(k, v)
|
||||
}
|
||||
rsp, err := client.Do(requestHandle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rsp.Body.Close()
|
||||
buff := bytes.Buffer{}
|
||||
reader := bufio.NewReader(rsp.Body)
|
||||
for {
|
||||
line, err := reader.ReadBytes('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
_, err = buff.Write(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
_, err = buff.Write(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return buff.Bytes(), nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user