调整
This commit is contained in:
commit
7c76066d04
@ -21,11 +21,12 @@ const (
|
|||||||
|
|
||||||
// websocket消息类型(云渲染类别)
|
// websocket消息类型(云渲染类别)
|
||||||
const (
|
const (
|
||||||
WEBSOCKET_RENDER_IMAGE Websocket = "WEBSOCKET_RENDER_IMAGE" //图片渲染消息(1级消息,双向通信)
|
WEBSOCKET_RENDER_IMAGE Websocket = "WEBSOCKET_RENDER_IMAGE" //图片渲染消息(1级消息,双向通信)
|
||||||
WEBSOCKET_RENDER_IMAGE_ERR Websocket = "WEBSOCKET_RENDER_IMAGE_ERR" //图片渲染失败消息(1级消息,单向通信)
|
WEBSOCKET_RENDER_IMAGE_ERR Websocket = "WEBSOCKET_RENDER_IMAGE_ERR" //图片渲染失败消息(1级消息,单向通信)
|
||||||
WEBSOCKET_COMBINE_IMAGE Websocket = "WEBSOCKET_COMBINE_IMAGE" //反回合成刀版图消息(2级消息,单向通信,属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
|
WEBSOCKET_COMBINE_IMAGE Websocket = "WEBSOCKET_COMBINE_IMAGE" //反回合成刀版图消息(2级消息,单向通信,属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
|
||||||
WEBSOCKET_ASSEMBLE_RENDER_DATA Websocket = "WEBSOCKET_ASSEMBLE_RENDER_DATA" //组装unity需要的数据 (2级消息,单向通信,属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
|
WEBSOCKET_ASSEMBLE_RENDER_DATA Websocket = "WEBSOCKET_ASSEMBLE_RENDER_DATA" //组装unity需要的数据 (2级消息,单向通信,属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
|
||||||
WEBSOCKET_SEND_DATA_TO_UNITY Websocket = "WEBSOCKET_SEND_DATA_TO_UNITY" //发送到unity进行渲染 (2级消息,单向通信,属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
|
WEBSOCKET_SEND_DATA_TO_UNITY Websocket = "WEBSOCKET_SEND_DATA_TO_UNITY" //发送到unity进行渲染 (2级消息,单向通信,属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
|
||||||
|
WEBSOCKET_REQUIRE_BROWSER_RESEND_RENDER Websocket = "WEBSOCKET_REQUIRE_BROWSER_RESEND_RENDER" //后端请求前端去重发渲染任务事件(2级消息,单向通信,属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
|
||||||
)
|
)
|
||||||
|
|
||||||
// websocket消息类型(系统数据变更通知)
|
// websocket消息类型(系统数据变更通知)
|
||||||
|
@ -4,16 +4,15 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// casbin_rule 后台--权限规则表
|
// casbin_rule
|
||||||
type CasbinRule struct {
|
type CasbinRule struct {
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 序号
|
PType *string `gorm:"default:'';" json:"p_type"` //
|
||||||
PType *string `gorm:"default:'';" json:"p_type"` //
|
V0 *string `gorm:"default:'';" json:"v0"` //
|
||||||
V0 *string `gorm:"default:'';" json:"v0"` //
|
V1 *string `gorm:"default:'';" json:"v1"` //
|
||||||
V1 *string `gorm:"default:'';" json:"v1"` //
|
V2 *string `gorm:"default:'';" json:"v2"` //
|
||||||
V2 *string `gorm:"default:'';" json:"v2"` //
|
V3 *string `gorm:"default:'';" json:"v3"` //
|
||||||
V3 *string `gorm:"default:'';" json:"v3"` //
|
V4 *string `gorm:"default:'';" json:"v4"` //
|
||||||
V4 *string `gorm:"default:'';" json:"v4"` //
|
V5 *string `gorm:"default:'';" json:"v5"` //
|
||||||
V5 *string `gorm:"default:'';" json:"v5"` //
|
|
||||||
}
|
}
|
||||||
type CasbinRuleModel struct {
|
type CasbinRuleModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
@ -113,8 +113,11 @@ func (s *FsShoppingCartModel) Create(ctx context.Context, data *FsShoppingCart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
func (s *FsShoppingCartModel) Delete(ctx context.Context, userId, id int64) error {
|
func (s *FsShoppingCartModel) Delete(ctx context.Context, userId int64, ids []int64) error {
|
||||||
return s.db.WithContext(ctx).Model(&FsShoppingCart{}).Where("user_id = ? and id = ?", userId, id).Delete(&FsShoppingCart{}).Error
|
if len(ids) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return s.db.WithContext(ctx).Model(&FsShoppingCart{}).Where("user_id = ? and id in (?)", userId, ids).Delete(&FsShoppingCart{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
|
25
model/gmodel/ldap_apis_gen.go
Normal file
25
model/gmodel/ldap_apis_gen.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ldap_apis
|
||||||
|
type LdapApis struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
||||||
|
Method *string `gorm:"default:'';" json:"method"` //
|
||||||
|
Path *string `gorm:"default:'';" json:"path"` //
|
||||||
|
Category *string `gorm:"default:'';" json:"category"` //
|
||||||
|
Remark *string `gorm:"default:'';" json:"remark"` //
|
||||||
|
Creator *string `gorm:"default:'';" json:"creator"` //
|
||||||
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
|
Dtime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"dtime"` //
|
||||||
|
}
|
||||||
|
type LdapApisModel struct {
|
||||||
|
db *gorm.DB
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLdapApisModel(db *gorm.DB) *LdapApisModel { return &LdapApisModel{db: db, name: "ldap_apis"} }
|
2
model/gmodel/ldap_apis_logic.go
Normal file
2
model/gmodel/ldap_apis_logic.go
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
package gmodel
|
||||||
|
// TODO: 使用model的属性做你想做的
|
25
model/gmodel/ldap_casbin_rule_gen.go
Normal file
25
model/gmodel/ldap_casbin_rule_gen.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ldap_casbin_rule 规则权限表
|
||||||
|
type LdapCasbinRule struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
||||||
|
Ptype *string `gorm:"default:'';" json:"ptype"` //
|
||||||
|
V0 *string `gorm:"default:'';" json:"v0"` //
|
||||||
|
V1 *string `gorm:"default:'';" json:"v1"` //
|
||||||
|
V2 *string `gorm:"default:'';" json:"v2"` //
|
||||||
|
V3 *string `gorm:"default:'';" json:"v3"` //
|
||||||
|
V4 *string `gorm:"default:'';" json:"v4"` //
|
||||||
|
V5 *string `gorm:"default:'';" json:"v5"` //
|
||||||
|
}
|
||||||
|
type LdapCasbinRuleModel struct {
|
||||||
|
db *gorm.DB
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLdapCasbinRuleModel(db *gorm.DB) *LdapCasbinRuleModel {
|
||||||
|
return &LdapCasbinRuleModel{db: db, name: "ldap_casbin_rule"}
|
||||||
|
}
|
2
model/gmodel/ldap_casbin_rule_logic.go
Normal file
2
model/gmodel/ldap_casbin_rule_logic.go
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
package gmodel
|
||||||
|
// TODO: 使用model的属性做你想做的
|
29
model/gmodel/ldap_menus_gen.go
Normal file
29
model/gmodel/ldap_menus_gen.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ldap_menus
|
||||||
|
type LdapMenus struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
||||||
|
Name *string `gorm:"default:'';" json:"name"` //
|
||||||
|
Title *string `gorm:"default:'';" json:"title"` //
|
||||||
|
Icon *string `gorm:"default:'';" json:"icon"` //
|
||||||
|
Path *string `gorm:"default:'';" json:"path"` //
|
||||||
|
Sort *int64 `gorm:"default:999;" json:"sort"` //
|
||||||
|
Status *int64 `gorm:"default:1;" json:"status"` //
|
||||||
|
Creator *string `gorm:"default:'';" json:"creator"` //
|
||||||
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
|
Dtime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"dtime"` //
|
||||||
|
}
|
||||||
|
type LdapMenusModel struct {
|
||||||
|
db *gorm.DB
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLdapMenusModel(db *gorm.DB) *LdapMenusModel {
|
||||||
|
return &LdapMenusModel{db: db, name: "ldap_menus"}
|
||||||
|
}
|
2
model/gmodel/ldap_menus_logic.go
Normal file
2
model/gmodel/ldap_menus_logic.go
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
package gmodel
|
||||||
|
// TODO: 使用model的属性做你想做的
|
35
model/gmodel/ldap_users_gen.go
Normal file
35
model/gmodel/ldap_users_gen.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ldap_users
|
||||||
|
type LdapUsers struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
||||||
|
Name *string `gorm:"default:'';" json:"name"` //
|
||||||
|
Nickname *string `gorm:"default:'';" json:"nickname"` //
|
||||||
|
Email *string `gorm:"default:'';" json:"email"` //
|
||||||
|
EnterpriseEmail *string `gorm:"default:'';" json:"enterprise_email"` //
|
||||||
|
JobTitle *string `gorm:"default:'';" json:"job_title"` //
|
||||||
|
Mobile *string `gorm:"default:'';" json:"mobile"` //
|
||||||
|
Gender *int64 `gorm:"default:0;" json:"gender"` // 性别 0未知 1男 2女
|
||||||
|
Avatar *string `gorm:"default:'';" json:"avatar"` //
|
||||||
|
Status *int64 `gorm:"default:1;" json:"status"` // 状态 0禁止 1正常
|
||||||
|
Departmentids *string `gorm:"default:'';" json:"departmentIds"` //
|
||||||
|
EmployeeType *int64 `gorm:"default:0;" json:"employee_type"` // 1:正式员工 2:实习生 3:外包4:劳务 5:顾问
|
||||||
|
UserDn *string `gorm:"default:'';" json:"user_dn"` //
|
||||||
|
JoinTime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"join_time"` //
|
||||||
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
|
Dtime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"dtime"` //
|
||||||
|
}
|
||||||
|
type LdapUsersModel struct {
|
||||||
|
db *gorm.DB
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLdapUsersModel(db *gorm.DB) *LdapUsersModel {
|
||||||
|
return &LdapUsersModel{db: db, name: "ldap_users"}
|
||||||
|
}
|
21
model/gmodel/ldap_users_logic.go
Normal file
21
model/gmodel/ldap_users_logic.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: 使用model的属性做你想做的
|
||||||
|
|
||||||
|
func (u *LdapUsersModel) CreateOrUpdate(ctx context.Context, openId string, data *LdapUsers) error {
|
||||||
|
var info LdapUsers
|
||||||
|
err := u.db.WithContext(ctx).Where("open_id = ?", openId).Take(&info).Error
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return u.db.WithContext(ctx).Create(&data).Error
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return u.db.WithContext(ctx).Where("open_id = ?", openId).Updates(&data).Error
|
||||||
|
}
|
@ -119,6 +119,10 @@ type AllModelsGen struct {
|
|||||||
FsUserStock *FsUserStockModel // fs_user_stock 用户云仓库存
|
FsUserStock *FsUserStockModel // fs_user_stock 用户云仓库存
|
||||||
FsWebSet *FsWebSetModel // fs_web_set 网站配置表
|
FsWebSet *FsWebSetModel // fs_web_set 网站配置表
|
||||||
FsZipCode *FsZipCodeModel // fs_zip_code 邮编表
|
FsZipCode *FsZipCodeModel // fs_zip_code 邮编表
|
||||||
|
LdapApis *LdapApisModel // ldap_apis
|
||||||
|
LdapCasbinRule *LdapCasbinRuleModel // ldap_casbin_rule 规则权限表
|
||||||
|
LdapMenus *LdapMenusModel // ldap_menus
|
||||||
|
LdapUsers *LdapUsersModel // ldap_users
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,6 +243,10 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
|
|||||||
FsUserStock: NewFsUserStockModel(gdb),
|
FsUserStock: NewFsUserStockModel(gdb),
|
||||||
FsWebSet: NewFsWebSetModel(gdb),
|
FsWebSet: NewFsWebSetModel(gdb),
|
||||||
FsZipCode: NewFsZipCodeModel(gdb),
|
FsZipCode: NewFsZipCodeModel(gdb),
|
||||||
|
LdapApis: NewLdapApisModel(gdb),
|
||||||
|
LdapCasbinRule: NewLdapCasbinRuleModel(gdb),
|
||||||
|
LdapMenus: NewLdapMenusModel(gdb),
|
||||||
|
LdapUsers: NewLdapUsersModel(gdb),
|
||||||
}
|
}
|
||||||
return models
|
return models
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
Name: feishu-sync
|
|
||||||
Host: 0.0.0.0
|
|
||||||
Port: 9925
|
|
||||||
Timeout: 15000 #服务超时时间(毫秒)
|
|
||||||
SourceMysql: fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen
|
|
||||||
SourceRabbitMq: ""
|
|
||||||
Auth:
|
|
||||||
AccessSecret: fusen2023
|
|
||||||
AccessExpire: 2592000
|
|
||||||
RefreshAfter: 1592000
|
|
@ -1,37 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/fsconfig"
|
|
||||||
|
|
||||||
"fusenapi/server/feishu-sync/internal/config"
|
|
||||||
"fusenapi/server/feishu-sync/internal/handler"
|
|
||||||
"fusenapi/server/feishu-sync/internal/svc"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
var configFile = flag.String("f", "etc/feishu-sync.yaml", "the config file")
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
var c config.Config
|
|
||||||
fsconfig.StartNacosConfig(*configFile, &c, nil)
|
|
||||||
|
|
||||||
c.Timeout = int64(time.Second * 15)
|
|
||||||
server := rest.MustNewServer(c.RestConf, rest.WithCustomCors(auth.FsCors, func(w http.ResponseWriter) {
|
|
||||||
}))
|
|
||||||
defer server.Stop()
|
|
||||||
|
|
||||||
ctx := svc.NewServiceContext(c)
|
|
||||||
handler.RegisterHandlers(server, ctx)
|
|
||||||
|
|
||||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
|
||||||
server.Start()
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/server/feishu-sync/internal/types"
|
|
||||||
"github.com/zeromicro/go-zero/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
rest.RestConf
|
|
||||||
SourceMysql string
|
|
||||||
Auth types.Auth
|
|
||||||
SourceRabbitMq string
|
|
||||||
FeiShu struct {
|
|
||||||
ApiHost string
|
|
||||||
EncryptKey string
|
|
||||||
VerificationToken string
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
// Code generated by goctl. DO NOT EDIT.
|
|
||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"fusenapi/server/feishu-sync/internal/svc"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|
||||||
server.AddRoutes(
|
|
||||||
[]rest.Route{
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/feishu/webhook",
|
|
||||||
Handler: WebhookHandler(serverCtx),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/server/feishu-sync/internal/logic"
|
|
||||||
"fusenapi/server/feishu-sync/internal/svc"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func WebhookHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// 创建一个业务逻辑层实例
|
|
||||||
l := logic.NewWebhookLogic(r.Context(), svcCtx)
|
|
||||||
l.Webhook(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
type UserWebhookMsg struct {
|
|
||||||
Schema string `json:"schema"`
|
|
||||||
Header struct {
|
|
||||||
EventId string `json:"event_id"`
|
|
||||||
EventType string `json:"event_type"`
|
|
||||||
CreateTime string `json:"create_time"`
|
|
||||||
Token string `json:"token"`
|
|
||||||
AppId string `json:"app_id"`
|
|
||||||
TenantKey string `json:"tenant_key"`
|
|
||||||
} `json:"header"`
|
|
||||||
Event struct {
|
|
||||||
Object struct {
|
|
||||||
OpenId string `json:"open_id"`
|
|
||||||
UnionId string `json:"union_id"`
|
|
||||||
UserId string `json:"user_id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
EnName string `json:"en_name"`
|
|
||||||
Nickname string `json:"nickname"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
EnterpriseEmail string `json:"enterprise_email"`
|
|
||||||
JobTitle string `json:"job_title"`
|
|
||||||
Mobile string `json:"mobile"`
|
|
||||||
Gender int64 `json:"gender"`
|
|
||||||
Avatar struct {
|
|
||||||
Avatar72 string `json:"avatar_72"`
|
|
||||||
Avatar240 string `json:"avatar_240"`
|
|
||||||
Avatar640 string `json:"avatar_640"`
|
|
||||||
AvatarOrigin string `json:"avatar_origin"`
|
|
||||||
} `json:"avatar"`
|
|
||||||
Status struct {
|
|
||||||
IsFrozen bool `json:"is_frozen"`
|
|
||||||
IsResigned bool `json:"is_resigned"`
|
|
||||||
IsActivated bool `json:"is_activated"`
|
|
||||||
IsExited bool `json:"is_exited"`
|
|
||||||
IsUnjoin bool `json:"is_unjoin"`
|
|
||||||
} `json:"status"`
|
|
||||||
DepartmentIds []string `json:"department_ids"`
|
|
||||||
LeaderUserId string `json:"leader_user_id"`
|
|
||||||
City string `json:"city"`
|
|
||||||
Country string `json:"country"`
|
|
||||||
WorkStation string `json:"work_station"`
|
|
||||||
Joint64ime int64 `json:"join_time"`
|
|
||||||
EmployeeNo string `json:"employee_no"`
|
|
||||||
EmployeeType int64 `json:"employee_type"`
|
|
||||||
Orders []struct {
|
|
||||||
DepartmentId string `json:"department_id"`
|
|
||||||
UserOrder int64 `json:"user_order"`
|
|
||||||
DepartmentOrder int64 `json:"department_order"`
|
|
||||||
IsPrimaryDept bool `json:"is_primary_dept"`
|
|
||||||
} `json:"orders"`
|
|
||||||
CustomAttrs []struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Id string `json:"id"`
|
|
||||||
Value struct {
|
|
||||||
Text string `json:"text"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
PcUrl string `json:"pc_url"`
|
|
||||||
OptionId string `json:"option_id"`
|
|
||||||
OptionValue string `json:"option_value"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
PictureUrl string `json:"picture_url"`
|
|
||||||
GenericUser struct {
|
|
||||||
Id string `json:"id"`
|
|
||||||
Type int64 `json:"type"`
|
|
||||||
} `json:"generic_user"`
|
|
||||||
} `json:"value"`
|
|
||||||
} `json:"custom_attrs"`
|
|
||||||
JobLevelId string `json:"job_level_id"`
|
|
||||||
JobFamilyId string `json:"job_family_id"`
|
|
||||||
DottedLineLeaderUserIds []string `json:"dotted_line_leader_user_ids"`
|
|
||||||
} `json:"object"`
|
|
||||||
} `json:"event"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 员工增删改信息
|
|
||||||
func (l *WebhookLogic) OnUserChange(data []byte) error {
|
|
||||||
return nil
|
|
||||||
/*var msg UserWebhookMsg
|
|
||||||
if err := json.Unmarshal(data, &msg); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
avatar, _ := json.Marshal(msg.Event.Object.Avatar)
|
|
||||||
isFrozen := int64(0)
|
|
||||||
if msg.Event.Object.Status.IsFrozen {
|
|
||||||
isFrozen = 1
|
|
||||||
}
|
|
||||||
isResigned := int64(0)
|
|
||||||
if msg.Event.Object.Status.IsResigned {
|
|
||||||
isResigned = 1
|
|
||||||
}
|
|
||||||
isActivated := int64(0)
|
|
||||||
if msg.Event.Object.Status.IsActivated {
|
|
||||||
isActivated = 1
|
|
||||||
}
|
|
||||||
isExited := int64(0)
|
|
||||||
if msg.Event.Object.Status.IsExited {
|
|
||||||
isExited = 1
|
|
||||||
}
|
|
||||||
isUnjoin := int64(0)
|
|
||||||
if msg.Event.Object.Status.IsUnjoin {
|
|
||||||
isUnjoin = 1
|
|
||||||
}
|
|
||||||
departmentIds, _ := json.Marshal(msg.Event.Object.DepartmentIds)
|
|
||||||
orders, _ := json.Marshal(msg.Event.Object.Orders)
|
|
||||||
feiShuMsgCreateTimeInt64, err := strconv.ParseInt(msg.Header.CreateTime, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
feiShuMsgCreateTime := time.UnixMilli(feiShuMsgCreateTimeInt64)
|
|
||||||
return l.svcCtx.AllModels.FsFeishuUser.CreateOrUpdate(l.ctx, msg.Header.AppId, msg.Event.Object.OpenId, &gmodel.FsFeishuUser{
|
|
||||||
AppId: &msg.Header.AppId,
|
|
||||||
OpenId: &msg.Event.Object.OpenId,
|
|
||||||
UnionId: &msg.Event.Object.UnionId,
|
|
||||||
Name: &msg.Event.Object.Name,
|
|
||||||
EnName: &msg.Event.Object.EnName,
|
|
||||||
Nickname: &msg.Event.Object.Nickname,
|
|
||||||
Email: &msg.Event.Object.Email,
|
|
||||||
EnterpriseEmail: &msg.Event.Object.EnterpriseEmail,
|
|
||||||
JobTitle: &msg.Event.Object.JobTitle,
|
|
||||||
Mobile: &msg.Event.Object.Mobile,
|
|
||||||
Gender: &msg.Event.Object.Gender,
|
|
||||||
Avatar: &avatar,
|
|
||||||
IsFrozen: &isFrozen,
|
|
||||||
IsResigned: &isResigned,
|
|
||||||
IsActivated: &isActivated,
|
|
||||||
IsExited: &isExited,
|
|
||||||
IsUnjoin: &isUnjoin,
|
|
||||||
DepartmentIds: &departmentIds,
|
|
||||||
WorkStation: &msg.Event.Object.WorkStation,
|
|
||||||
EmployeeNo: &msg.Event.Object.EmployeeNo,
|
|
||||||
EmployeeType: &msg.Event.Object.EmployeeType,
|
|
||||||
Orders: &orders,
|
|
||||||
Ctime: &feiShuMsgCreateTime,
|
|
||||||
Utime: &feiShuMsgCreateTime,
|
|
||||||
})*/
|
|
||||||
}
|
|
@ -1,150 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fusenapi/model/gmodel"
|
|
||||||
"fusenapi/server/feishu-sync/internal/svc"
|
|
||||||
"fusenapi/utils/feishu"
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type WebhookLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWebhookLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebhookLogic {
|
|
||||||
return &WebhookLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type EncryptWebhookMsg struct {
|
|
||||||
Encrypt string `json:"encrypt"` //加密的消息
|
|
||||||
}
|
|
||||||
type WebhookMsg struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Challenge string `json:"challenge"`
|
|
||||||
Header map[string]interface{} `json:"header"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// webhook消息事件header(body参数)基础信息
|
|
||||||
type BaseWebhookMsgHeaderType struct {
|
|
||||||
EventId string `json:"event_id"` //事件id(可作为消息唯一性确认)
|
|
||||||
EventType string `json:"event_type"` //事件类型
|
|
||||||
CreateTime string `json:"create_time"` //创建时间
|
|
||||||
Token string `json:"token"` //事件token
|
|
||||||
AppId string `json:"app_id"` //app id
|
|
||||||
TenantKey string `json:"tenant_key"` //租户key
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *WebhookLogic) Webhook(w http.ResponseWriter, r *http.Request) {
|
|
||||||
bodyBytes, err := io.ReadAll(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error("读取请求body失败", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer r.Body.Close()
|
|
||||||
//计算签名
|
|
||||||
timestamp := r.Header.Get("X-Lark-Request-Timestamp")
|
|
||||||
nonce := r.Header.Get("X-Lark-Request-Nonce")
|
|
||||||
signature := r.Header.Get("X-Lark-Signature")
|
|
||||||
sign := feishu.CalculateFeiShuWebhookSignature(timestamp, nonce, l.svcCtx.Config.FeiShu.EncryptKey, bodyBytes)
|
|
||||||
if signature != sign {
|
|
||||||
logx.Error("非法的消息,签名验证不通过", sign, "====", signature)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var encryptMsg EncryptWebhookMsg
|
|
||||||
if err = json.Unmarshal(bodyBytes, &encryptMsg); err != nil {
|
|
||||||
logx.Error("反序列化body失败", err, "body数据:", string(bodyBytes))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if encryptMsg.Encrypt == "" {
|
|
||||||
logx.Error("消息加密信息是空的")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//解密
|
|
||||||
realMsgBytes, err := feishu.DecryptFeiShuWebhookMsg(encryptMsg.Encrypt, l.svcCtx.Config.FeiShu.EncryptKey)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//如果只是验证http连接的消息
|
|
||||||
var webhookMsg WebhookMsg
|
|
||||||
if err = json.Unmarshal(realMsgBytes, &webhookMsg); err != nil {
|
|
||||||
logx.Error("反序列化请求body失败", err, "解密数据:", string(realMsgBytes))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//验证连接(直接返回)
|
|
||||||
if webhookMsg.Type == "url_verification" {
|
|
||||||
challengeRsp := map[string]string{
|
|
||||||
"challenge": webhookMsg.Challenge,
|
|
||||||
}
|
|
||||||
b, _ := json.Marshal(challengeRsp)
|
|
||||||
w.Write(b)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bodyHeaderByte, err := json.Marshal(webhookMsg.Header)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error("序列化请求体header失败:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var msgHeader BaseWebhookMsgHeaderType
|
|
||||||
if err = json.Unmarshal(bodyHeaderByte, &msgHeader); err != nil {
|
|
||||||
logx.Error("反序列化请求体中的header失败", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
httpHeaderBytes, _ := json.Marshal(r.Header)
|
|
||||||
httpHeaderStr := string(httpHeaderBytes)
|
|
||||||
//解密后的数据
|
|
||||||
decryptMsgStr := string(realMsgBytes)
|
|
||||||
feiShuMsgCreateTimeInt64, err := strconv.ParseInt(msgHeader.CreateTime, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error("解析消息时间错误:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
feiShuMsgCreateTime := time.UnixMilli(feiShuMsgCreateTimeInt64)
|
|
||||||
now := time.Now().UTC()
|
|
||||||
//把事件加入日志
|
|
||||||
err = l.svcCtx.AllModels.FsFeishuWebhookLog.Create(l.ctx, &gmodel.FsFeishuWebhookLog{
|
|
||||||
AppId: &msgHeader.AppId,
|
|
||||||
EventId: &msgHeader.EventId,
|
|
||||||
EventType: &msgHeader.EventType,
|
|
||||||
HttpHeader: &httpHeaderStr,
|
|
||||||
Data: &encryptMsg.Encrypt,
|
|
||||||
DecryptData: &decryptMsgStr,
|
|
||||||
MsgCtime: &feiShuMsgCreateTime,
|
|
||||||
Ctime: &now,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
logx.Error("保存webhook消息日志失败:", err)
|
|
||||||
}
|
|
||||||
switch msgHeader.EventType {
|
|
||||||
case "contact.department.created_v3": //部门新建
|
|
||||||
case "contact.department.deleted_v3": //部门删除
|
|
||||||
case "contact.department.updated_v3": //部门信息变化
|
|
||||||
case "contact.employee_type_enum.actived_v3": //启动人员类型事件
|
|
||||||
case "contact.employee_type_enum.created_v3": //新建人员类型事件
|
|
||||||
case "contact.employee_type_enum.deactivated_v3": //停用人员类型事件
|
|
||||||
case "contact.employee_type_enum.deleted_v3": //删除人员类型事件
|
|
||||||
case "contact.employee_type_enum.updated_v3": //修改人员类型名称事件
|
|
||||||
case "contact.user.created_v3": //员工入职
|
|
||||||
err = l.OnUserChange(realMsgBytes)
|
|
||||||
case "contact.user.deleted_v3": //员工离职
|
|
||||||
err = l.OnUserChange(realMsgBytes)
|
|
||||||
case "contact.user.updated_v3": //员工信息变化
|
|
||||||
err = l.OnUserChange(realMsgBytes)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
logx.Error("处理事件错误:", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package svc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/initalize"
|
|
||||||
"fusenapi/model/gmodel"
|
|
||||||
"fusenapi/server/feishu-sync/internal/config"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ServiceContext struct {
|
|
||||||
Config config.Config
|
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
|
||||||
AllModels *gmodel.AllModelsGen
|
|
||||||
RabbitMq *initalize.RabbitMqHandle
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
|
||||||
conn := initalize.InitMysql(c.SourceMysql)
|
|
||||||
|
|
||||||
return &ServiceContext{
|
|
||||||
Config: c,
|
|
||||||
MysqlConn: conn,
|
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
|
||||||
RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil),
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
// Code generated by goctl. DO NOT EDIT.
|
|
||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Request struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type Response struct {
|
|
||||||
Code int `json:"code"`
|
|
||||||
Message string `json:"msg"`
|
|
||||||
Data interface{} `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Auth struct {
|
|
||||||
AccessSecret string `json:"accessSecret"`
|
|
||||||
AccessExpire int64 `json:"accessExpire"`
|
|
||||||
RefreshAfter int64 `json:"refreshAfter"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type File struct {
|
|
||||||
Filename string `fsfile:"filename"`
|
|
||||||
Header map[string][]string `fsfile:"header"`
|
|
||||||
Size int64 `fsfile:"size"`
|
|
||||||
Data []byte `fsfile:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Meta struct {
|
|
||||||
TotalCount int64 `json:"total_count"`
|
|
||||||
PageCount int64 `json:"page_count"`
|
|
||||||
CurrentPage int `json:"current_page"`
|
|
||||||
PerPage int `json:"per_page"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set 设置Response的Code和Message值
|
|
||||||
func (resp *Response) Set(Code int, Message string) *Response {
|
|
||||||
return &Response{
|
|
||||||
Code: Code,
|
|
||||||
Message: Message,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set 设置整个Response
|
|
||||||
func (resp *Response) SetWithData(Code int, Message string, Data interface{}) *Response {
|
|
||||||
return &Response{
|
|
||||||
Code: Code,
|
|
||||||
Message: Message,
|
|
||||||
Data: Data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStatus 设置默认StatusResponse(内部自定义) 默认msg, 可以带data, data只使用一个参数
|
|
||||||
func (resp *Response) SetStatus(sr *basic.StatusResponse, data ...interface{}) *Response {
|
|
||||||
newResp := &Response{
|
|
||||||
Code: sr.Code,
|
|
||||||
}
|
|
||||||
if len(data) == 1 {
|
|
||||||
newResp.Data = data[0]
|
|
||||||
}
|
|
||||||
return newResp
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStatusWithMessage 设置默认StatusResponse(内部自定义) 非默认msg, 可以带data, data只使用一个参数
|
|
||||||
func (resp *Response) SetStatusWithMessage(sr *basic.StatusResponse, msg string, data ...interface{}) *Response {
|
|
||||||
newResp := &Response{
|
|
||||||
Code: sr.Code,
|
|
||||||
Message: msg,
|
|
||||||
}
|
|
||||||
if len(data) == 1 {
|
|
||||||
newResp.Data = data[0]
|
|
||||||
}
|
|
||||||
return newResp
|
|
||||||
}
|
|
@ -116,7 +116,7 @@ func (l *CalculateCartPriceLogic) CalculateCartPrice(req *types.CalculateCartPri
|
|||||||
if fittingInfo, ok := mapModel[*cart.FittingId]; ok {
|
if fittingInfo, ok := mapModel[*cart.FittingId]; ok {
|
||||||
fittingPrice = *fittingInfo.Price
|
fittingPrice = *fittingInfo.Price
|
||||||
} else {
|
} else {
|
||||||
return errors.New(fmt.Sprintf("cart contain some one witch lose fitting:%d", *cart.FittingId))
|
logx.Error(fmt.Sprintf("cart contain some one witch lose fitting:%d", *cart.FittingId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//计算价格
|
//计算价格
|
||||||
|
@ -35,7 +35,7 @@ func (l *DeleteCartLogic) DeleteCart(req *types.DeleteCartReq, userinfo *auth.Us
|
|||||||
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in")
|
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in")
|
||||||
}
|
}
|
||||||
//删除购物车
|
//删除购物车
|
||||||
if err := l.svcCtx.AllModels.FsShoppingCart.Delete(l.ctx, userinfo.UserId, req.Id); err != nil {
|
if err := l.svcCtx.AllModels.FsShoppingCart.Delete(l.ctx, userinfo.UserId, req.IdList); err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to delete shopping cart")
|
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to delete shopping cart")
|
||||||
}
|
}
|
||||||
|
@ -116,14 +116,14 @@ func (l *GetCartsLogic) GetCarts(req *types.GetCartsReq, userinfo *auth.UserInfo
|
|||||||
fittingPrice := int64(0)
|
fittingPrice := int64(0)
|
||||||
if *cart.FittingId > 0 {
|
if *cart.FittingId > 0 {
|
||||||
curFittingInfo, ok := mapModel[*cart.FittingId]
|
curFittingInfo, ok := mapModel[*cart.FittingId]
|
||||||
if !ok {
|
if ok {
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, fmt.Sprintf("cart contain some one witch lose fitting:%d", *cart.FittingId))
|
fittingPrice = *curFittingInfo.Price
|
||||||
}
|
//取大的为步进量基数
|
||||||
fittingPrice = *curFittingInfo.Price
|
if *curFittingInfo.PackedUnit > stepPurchaseQuantity {
|
||||||
//取大的为步进量基数
|
stepPurchaseQuantity = *curFittingInfo.PackedUnit
|
||||||
if *curFittingInfo.PackedUnit > stepPurchaseQuantity {
|
}
|
||||||
stepPurchaseQuantity = *curFittingInfo.PackedUnit
|
|
||||||
}
|
}
|
||||||
|
logx.Error(fmt.Sprintf("cart contain some one witch lose fitting:%d", *cart.FittingId))
|
||||||
}
|
}
|
||||||
//计算阶梯价格
|
//计算阶梯价格
|
||||||
totalPrice, itemPrice, err := l.svcCtx.Repositories.NewShoppingCart.CaculateStepPrice(*cart.PurchaseQuantity, stepPrice, fittingPrice)
|
totalPrice, itemPrice, err := l.svcCtx.Repositories.NewShoppingCart.CaculateStepPrice(*cart.PurchaseQuantity, stepPrice, fittingPrice)
|
||||||
|
@ -35,7 +35,7 @@ type DiyInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DeleteCartReq struct {
|
type DeleteCartReq struct {
|
||||||
Id int64 `json:"id"` //购物车id
|
IdList []int64 `json:"id_list"` //购物车id
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetCartsReq struct {
|
type GetCartsReq struct {
|
||||||
|
@ -114,6 +114,11 @@ func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq, userinfo *a
|
|||||||
if ws.conn != nil {
|
if ws.conn != nil {
|
||||||
//发送错误信息给前端
|
//发送错误信息给前端
|
||||||
ws.renderErrResponse(requestId, info.TemplateTag, info.TaskId, "unity云渲染错误:"+req.Msg, 0, 0, 0, 0, 0, 0, 0)
|
ws.renderErrResponse(requestId, info.TemplateTag, info.TaskId, "unity云渲染错误:"+req.Msg, 0, 0, 0, 0, 0, 0, 0)
|
||||||
|
//发送给前端重发消息
|
||||||
|
ws.requestResendRenderResponse(websocket_data.RequestBrowserResendRenderEvent{
|
||||||
|
RequestId: info.RequestId,
|
||||||
|
Description: "unity require resend",
|
||||||
|
})
|
||||||
logx.Info("渲染失败且发送了失败信息:", req.Msg)
|
logx.Info("渲染失败且发送了失败信息:", req.Msg)
|
||||||
} else {
|
} else {
|
||||||
logx.Info("渲染失败且找不到ws连接")
|
logx.Info("渲染失败且找不到ws连接")
|
||||||
|
@ -81,3 +81,11 @@ func (w *wsConnectItem) renderErrResponse(requestId, templateTag, taskId, descri
|
|||||||
}
|
}
|
||||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE_ERR, data))
|
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE_ERR, data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 渲染失败要求重新发起任务
|
||||||
|
func (w *wsConnectItem) requestResendRenderResponse(data websocket_data.RequestBrowserResendRenderEvent) {
|
||||||
|
if w.debug == nil {
|
||||||
|
data.Description = ""
|
||||||
|
}
|
||||||
|
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_REQUIRE_BROWSER_RESEND_RENDER, data))
|
||||||
|
}
|
||||||
|
@ -32,7 +32,7 @@ func (w *wsConnectItem) sendCombineImageStepResponseMessage(requestId, combineIm
|
|||||||
SizeId: sizeId,
|
SizeId: sizeId,
|
||||||
ModelId: modelId,
|
ModelId: modelId,
|
||||||
TemplateId: templateId,
|
TemplateId: templateId,
|
||||||
CombineProcessTime: websocket_data.CombineProcessTime{
|
CombineProcessTime: &websocket_data.CombineProcessTime{
|
||||||
CombineTakesTime: combineTakesTime,
|
CombineTakesTime: combineTakesTime,
|
||||||
UploadCombineImageTakesTime: uploadCombineImageTakesTime,
|
UploadCombineImageTakesTime: uploadCombineImageTakesTime,
|
||||||
},
|
},
|
||||||
|
@ -229,7 +229,13 @@ func (w *wsConnectItem) renderImage(renderImageData websocket_data.RenderImageRe
|
|||||||
}
|
}
|
||||||
res, err := w.logic.svcCtx.Repositories.ImageHandle.LogoCombine(w.logic.ctx, &combineReq)
|
res, err := w.logic.svcCtx.Repositories.ImageHandle.LogoCombine(w.logic.ctx, &combineReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
//发送渲染错误消息
|
||||||
w.renderErrResponse(renderImageData.RequestId, renderImageData.RenderData.TemplateTag, "", "合成刀版图失败:"+err.Error(), renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
|
w.renderErrResponse(renderImageData.RequestId, renderImageData.RenderData.TemplateTag, "", "合成刀版图失败:"+err.Error(), renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
|
||||||
|
//发送给前端重发消息
|
||||||
|
w.requestResendRenderResponse(websocket_data.RequestBrowserResendRenderEvent{
|
||||||
|
RequestId: renderImageData.RequestId,
|
||||||
|
Description: "combine require resend",
|
||||||
|
})
|
||||||
//统计合图失败数
|
//统计合图失败数
|
||||||
increaseCombineRequestErrorCount(w.userId, w.guestId)
|
increaseCombineRequestErrorCount(w.userId, w.guestId)
|
||||||
logx.Error("合成刀版图失败,合成请求数据:", combineReq, "错误信息:", err)
|
logx.Error("合成刀版图失败,合成请求数据:", combineReq, "错误信息:", err)
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
syntax = "v1"
|
|
||||||
|
|
||||||
info (
|
|
||||||
title: "飞书同步服务"// TODO: add title
|
|
||||||
desc: // TODO: add description
|
|
||||||
author: ""
|
|
||||||
email: ""
|
|
||||||
)
|
|
||||||
|
|
||||||
import "basic.api"
|
|
||||||
|
|
||||||
service feishu-sync {
|
|
||||||
//飞书ticket webhook事件接口
|
|
||||||
@handler WebhookHandler
|
|
||||||
post /api/feishu/webhook(request) returns (response);
|
|
||||||
}
|
|
@ -55,7 +55,7 @@ type DiyInfo {
|
|||||||
}
|
}
|
||||||
//删除购物车
|
//删除购物车
|
||||||
type DeleteCartReq {
|
type DeleteCartReq {
|
||||||
Id int64 `json:"id"` //购物车id
|
IdList []int64 `json:"id_list"` //购物车id
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取购物车列表
|
//获取购物车列表
|
||||||
|
40
utils/feishu/api.go
Normal file
40
utils/feishu/api.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package feishu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fusenapi/utils/curl"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FeiShuApi struct {
|
||||||
|
AppId string
|
||||||
|
AppSecret string
|
||||||
|
ApiHost string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取tenant_access_token
|
||||||
|
type GetTenantAccessTokenRsp struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
TenantAccessToken string `json:"tenant_access_token"`
|
||||||
|
Expire int `json:"expire"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FeiShuApi) GetTenantAccessToken() (resp GetTenantAccessTokenRsp, err error) {
|
||||||
|
url := f.ApiHost + "/open-apis/auth/v3/tenant_access_token/internal"
|
||||||
|
header := map[string]string{"Content-Type": "application/json; charset=utf-8"}
|
||||||
|
req := map[string]interface{}{
|
||||||
|
"app_secret": f.AppSecret,
|
||||||
|
"app_id": f.AppId,
|
||||||
|
}
|
||||||
|
postData, _ := json.Marshal(req)
|
||||||
|
rsp, err := curl.ApiCall2(url, "POST", header, bytes.NewReader(postData), time.Second*15)
|
||||||
|
if err != nil {
|
||||||
|
return GetTenantAccessTokenRsp{}, err
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(rsp, &resp); err != nil {
|
||||||
|
return GetTenantAccessTokenRsp{}, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
@ -39,12 +39,12 @@ type RenderProcessTime struct {
|
|||||||
|
|
||||||
// 合图返回数据
|
// 合图返回数据
|
||||||
type CombineImageRspMsg struct {
|
type CombineImageRspMsg struct {
|
||||||
RequestId string `json:"request_id"`
|
RequestId string `json:"request_id"`
|
||||||
CombineImage string `json:"combine_image"` //刀版图
|
CombineImage string `json:"combine_image"` //刀版图
|
||||||
SizeId int64 `json:"size_id"` //尺寸id
|
SizeId int64 `json:"size_id"` //尺寸id
|
||||||
ModelId int64 `json:"model_id"`
|
ModelId int64 `json:"model_id"`
|
||||||
TemplateId int64 `json:"template_id"`
|
TemplateId int64 `json:"template_id"`
|
||||||
CombineProcessTime CombineProcessTime `json:"combine_process_time"`
|
CombineProcessTime *CombineProcessTime `json:"combine_process_time"`
|
||||||
}
|
}
|
||||||
type CombineProcessTime struct {
|
type CombineProcessTime struct {
|
||||||
CombineTakesTime string `json:"combine_takes_time"` //合图时间
|
CombineTakesTime string `json:"combine_takes_time"` //合图时间
|
||||||
@ -71,3 +71,9 @@ type ToUnityIdStruct struct {
|
|||||||
UserId int64 `json:"user_id"`
|
UserId int64 `json:"user_id"`
|
||||||
GuestId int64 `json:"guest_id"`
|
GuestId int64 `json:"guest_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 要求前端重发渲染消息事件结构
|
||||||
|
type RequestBrowserResendRenderEvent struct {
|
||||||
|
RequestId string `json:"request_id"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user