fix
This commit is contained in:
parent
a59557bc85
commit
d42437d63b
@ -1,26 +0,0 @@
|
|||||||
package gmodel
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// fs_feishu_config 飞书app配置表
|
|
||||||
type FsFeishuConfig struct {
|
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // ID
|
|
||||||
AppId *string `gorm:"default:'';" json:"app_id"` //
|
|
||||||
AppName *string `gorm:"default:'';" json:"app_name"` // 项目名称
|
|
||||||
AppSecret *string `gorm:"default:'';" json:"app_secret"` // app密钥
|
|
||||||
EncryptKey *string `gorm:"default:'';" json:"encrypt_key"` //
|
|
||||||
VerificationToken *string `gorm:"default:'';" json:"verification_token"` //
|
|
||||||
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"` //
|
|
||||||
}
|
|
||||||
type FsFeishuConfigModel struct {
|
|
||||||
db *gorm.DB
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFsFeishuConfigModel(db *gorm.DB) *FsFeishuConfigModel {
|
|
||||||
return &FsFeishuConfigModel{db: db, name: "fs_feishu_config"}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
package gmodel
|
|
||||||
// TODO: 使用model的属性做你想做的
|
|
43
model/gmodel/fs_feishu_user_gen.go
Normal file
43
model/gmodel/fs_feishu_user_gen.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fs_feishu_user 飞书用户信息表
|
||||||
|
type FsFeishuUser struct {
|
||||||
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // ID
|
||||||
|
AppId *string `gorm:"default:'';" json:"app_id"` //
|
||||||
|
OpenId *string `gorm:"default:'';" json:"open_id"` //
|
||||||
|
UnionId *string `gorm:"default:'';" json:"union_id"` //
|
||||||
|
Name *string `gorm:"default:'';" json:"name"` //
|
||||||
|
EnName *string `gorm:"default:'';" json:"en_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 *[]byte `gorm:"default:'';" json:"avatar"` //
|
||||||
|
IsFrozen *int64 `gorm:"default:0;" json:"is_frozen"` // 是否冻结
|
||||||
|
IsResigned *int64 `gorm:"default:0;" json:"is_resigned"` // 是否离职
|
||||||
|
IsActivated *int64 `gorm:"default:0;" json:"is_activated"` // 是否激活
|
||||||
|
IsExited *int64 `gorm:"default:0;" json:"is_exited"` // 是否主动退出
|
||||||
|
IsUnjoin *int64 `gorm:"default:0;" json:"is_unjoin"` // 是否未加入
|
||||||
|
DepartmentIds *[]byte `gorm:"default:'';" json:"department_ids"` //
|
||||||
|
WorkStation *string `gorm:"default:'';" json:"work_station"` //
|
||||||
|
EmployeeNo *string `gorm:"default:'';" json:"employee_no"` //
|
||||||
|
EmployeeType *int64 `gorm:"default:0;" json:"employee_type"` // 0:未设置 1:正式员工 2:实习生 3:外包 4:劳务 5:顾问
|
||||||
|
Orders *[]byte `gorm:"default:'';" json:"orders"` //
|
||||||
|
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"` //
|
||||||
|
}
|
||||||
|
type FsFeishuUserModel struct {
|
||||||
|
db *gorm.DB
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFsFeishuUserModel(db *gorm.DB) *FsFeishuUserModel {
|
||||||
|
return &FsFeishuUserModel{db: db, name: "fs_feishu_user"}
|
||||||
|
}
|
30
model/gmodel/fs_feishu_user_logic.go
Normal file
30
model/gmodel/fs_feishu_user_logic.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package gmodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: 使用model的属性做你想做的
|
||||||
|
|
||||||
|
func (u *FsFeishuUserModel) Create(ctx context.Context, data *FsFeishuUser) error {
|
||||||
|
return u.db.WithContext(ctx).Model(&FsFeishuUser{}).Create(&data).Error
|
||||||
|
}
|
||||||
|
func (u *FsFeishuUserModel) Update(ctx context.Context, data *FsFeishuUser) error {
|
||||||
|
return u.db.WithContext(ctx).Model(&FsFeishuUser{}).Where("`app_id` = ? and `open_id` = ?", data.AppId, data.OpenId).Updates(&data).Error
|
||||||
|
}
|
||||||
|
func (u *FsFeishuUserModel) Find(ctx context.Context, appId, openId string) (resp *FsFeishuUser, err error) {
|
||||||
|
err = u.db.WithContext(ctx).Model(&FsFeishuUser{}).Where("`app_id` = ? and `open_id` = ?", appId, openId).Take(&resp).Error
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
func (u *FsFeishuUserModel) CreateOrUpdate(ctx context.Context, appId, openId string, data *FsFeishuUser) error {
|
||||||
|
_, err := u.Find(ctx, appId, openId)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return u.Create(ctx, data)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return u.Update(ctx, data)
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package gmodel
|
package gmodel
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
// TODO: 使用model的属性做你想做的
|
// TODO: 使用model的属性做你想做的
|
||||||
|
|
||||||
func (w *FsFeishuWebhookLogModel) Create(data *FsFeishuWebhookLog) error {
|
func (w *FsFeishuWebhookLogModel) Create(ctx context.Context, data *FsFeishuWebhookLog) error {
|
||||||
return w.db.Model(&FsFeishuWebhookLog{}).Create(&data).Error
|
return w.db.WithContext(ctx).Model(&FsFeishuWebhookLog{}).Create(&data).Error
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ type AllModelsGen struct {
|
|||||||
FsFactoryProduct *FsFactoryProductModel // fs_factory_product 工厂生产表(废弃)
|
FsFactoryProduct *FsFactoryProductModel // fs_factory_product 工厂生产表(废弃)
|
||||||
FsFactoryShipTmp *FsFactoryShipTmpModel // fs_factory_ship_tmp
|
FsFactoryShipTmp *FsFactoryShipTmpModel // fs_factory_ship_tmp
|
||||||
FsFaq *FsFaqModel // fs_faq 常见问题
|
FsFaq *FsFaqModel // fs_faq 常见问题
|
||||||
FsFeishuConfig *FsFeishuConfigModel // fs_feishu_config 飞书app配置表
|
FsFeishuUser *FsFeishuUserModel // fs_feishu_user 飞书用户信息表
|
||||||
FsFeishuWebhookLog *FsFeishuWebhookLogModel // fs_feishu_webhook_log 飞书webhook记录表
|
FsFeishuWebhookLog *FsFeishuWebhookLogModel // fs_feishu_webhook_log 飞书webhook记录表
|
||||||
FsFont *FsFontModel // fs_font 字体配置
|
FsFont *FsFontModel // fs_font 字体配置
|
||||||
FsGerent *FsGerentModel // fs_gerent 管理员表
|
FsGerent *FsGerentModel // fs_gerent 管理员表
|
||||||
@ -169,7 +169,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
|
|||||||
FsFactoryProduct: NewFsFactoryProductModel(gdb),
|
FsFactoryProduct: NewFsFactoryProductModel(gdb),
|
||||||
FsFactoryShipTmp: NewFsFactoryShipTmpModel(gdb),
|
FsFactoryShipTmp: NewFsFactoryShipTmpModel(gdb),
|
||||||
FsFaq: NewFsFaqModel(gdb),
|
FsFaq: NewFsFaqModel(gdb),
|
||||||
FsFeishuConfig: NewFsFeishuConfigModel(gdb),
|
FsFeishuUser: NewFsFeishuUserModel(gdb),
|
||||||
FsFeishuWebhookLog: NewFsFeishuWebhookLogModel(gdb),
|
FsFeishuWebhookLog: NewFsFeishuWebhookLogModel(gdb),
|
||||||
FsFont: NewFsFontModel(gdb),
|
FsFont: NewFsFontModel(gdb),
|
||||||
FsGerent: NewFsGerentModel(gdb),
|
FsGerent: NewFsGerentModel(gdb),
|
||||||
|
144
server/feishu-sync/internal/logic/user_webhook.go
Normal file
144
server/feishu-sync/internal/logic/user_webhook.go
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
}
|
@ -34,7 +34,6 @@ type WebhookMsg struct {
|
|||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Challenge string `json:"challenge"`
|
Challenge string `json:"challenge"`
|
||||||
Header map[string]interface{} `json:"header"`
|
Header map[string]interface{} `json:"header"`
|
||||||
Event map[string]interface{} `json:"event"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// webhook消息事件header(body参数)基础信息
|
// webhook消息事件header(body参数)基础信息
|
||||||
@ -115,7 +114,7 @@ func (l *WebhookLogic) Webhook(w http.ResponseWriter, r *http.Request) {
|
|||||||
feiShuMsgCreateTime := time.UnixMilli(feiShuMsgCreateTimeInt64)
|
feiShuMsgCreateTime := time.UnixMilli(feiShuMsgCreateTimeInt64)
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
//把事件加入日志
|
//把事件加入日志
|
||||||
err = l.svcCtx.AllModels.FsFeishuWebhookLog.Create(&gmodel.FsFeishuWebhookLog{
|
err = l.svcCtx.AllModels.FsFeishuWebhookLog.Create(l.ctx, &gmodel.FsFeishuWebhookLog{
|
||||||
AppId: &msgHeader.AppId,
|
AppId: &msgHeader.AppId,
|
||||||
EventId: &msgHeader.EventId,
|
EventId: &msgHeader.EventId,
|
||||||
EventType: &msgHeader.EventType,
|
EventType: &msgHeader.EventType,
|
||||||
@ -138,9 +137,14 @@ func (l *WebhookLogic) Webhook(w http.ResponseWriter, r *http.Request) {
|
|||||||
case "contact.employee_type_enum.deleted_v3": //删除人员类型事件
|
case "contact.employee_type_enum.deleted_v3": //删除人员类型事件
|
||||||
case "contact.employee_type_enum.updated_v3": //修改人员类型名称事件
|
case "contact.employee_type_enum.updated_v3": //修改人员类型名称事件
|
||||||
case "contact.user.created_v3": //员工入职
|
case "contact.user.created_v3": //员工入职
|
||||||
|
err = l.OnUserChange(realMsgBytes)
|
||||||
case "contact.user.deleted_v3": //员工离职
|
case "contact.user.deleted_v3": //员工离职
|
||||||
|
err = l.OnUserChange(realMsgBytes)
|
||||||
case "contact.user.updated_v3": //员工信息变化
|
case "contact.user.updated_v3": //员工信息变化
|
||||||
|
err = l.OnUserChange(realMsgBytes)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
logx.Error("处理事件错误:", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user