feat(canvas): 绘图工具支持自定义 tldraw License Key (#100)

* feat(canvas): 绘图工具 - 支持自定义 tldraw License Key

* docs(canvas): 绘图工具 - 添加 License Key 页面截图
This commit is contained in:
ahyang
2026-08-03 21:38:04 +08:00
committed by GitHub
parent 9b3ec218e2
commit d83ec033bb
11 changed files with 186 additions and 47 deletions

View File

@@ -11,7 +11,10 @@ import (
"gorm.io/gorm"
)
const drawingEngineSettingKey = "drawing_engine"
const (
drawingEngineSettingKey = "drawing_engine"
tldrawLicenseKeySettingKey = "tldraw_license_key"
)
const (
DrawingEngineTldraw = "tldraw"
@@ -19,7 +22,8 @@ const (
)
type DrawingEngineSetting struct {
DefaultEngine string `json:"defaultEngine"`
DefaultEngine string `json:"defaultEngine"`
TldrawLicenseKey string `json:"tldrawLicenseKey"`
}
type PublicDrawingEngineSetting struct {
@@ -57,11 +61,22 @@ func (s *Service) UpdateDrawingEngineSetting(actor *model.User, value DrawingEng
if err := validateDrawingEngineSetting(value); err != nil {
return nil, err
}
value.TldrawLicenseKey = strings.TrimSpace(value.TldrawLicenseKey)
current, before, err := s.readDrawingEngineSetting()
if err != nil {
return nil, err
}
encoded, err := json.Marshal(value)
currentLicenseSetting, _, err := s.readTldrawLicenseKey()
if err != nil {
return nil, err
}
encoded, err := json.Marshal(struct {
DefaultEngine string `json:"defaultEngine"`
}{DefaultEngine: value.DefaultEngine})
if err != nil {
return nil, err
}
encodedLicenseKey, err := json.Marshal(value.TldrawLicenseKey)
if err != nil {
return nil, err
}
@@ -69,10 +84,14 @@ func (s *Service) UpdateDrawingEngineSetting(actor *model.User, value DrawingEng
if current != nil {
setting.CreatedAt = current.CreatedAt
}
if err := s.repo.SaveSystemSetting(&setting); err != nil {
licenseSetting := model.SystemSetting{Key: tldrawLicenseKeySettingKey, ValueJSON: string(encodedLicenseKey), UpdatedBy: actor.ID}
if currentLicenseSetting != nil {
licenseSetting.CreatedAt = currentLicenseSetting.CreatedAt
}
if err := s.repo.SaveSystemSettings(&setting, &licenseSetting); err != nil {
return nil, err
}
if err := s.appendAdminAudit(actor, "drawing_engine.update", "system_setting", drawingEngineSettingKey, "更新默认绘图工具", map[string]any{"before": before, "after": value}); err != nil {
if err := s.appendAdminAudit(actor, "drawing_engine.update", "system_setting", drawingEngineSettingKey, "更新绘图工具配置", map[string]any{"before": drawingEngineAuditValue(before), "after": drawingEngineAuditValue(value)}); err != nil {
return nil, err
}
return publicDrawingEngineSetting(&setting, value), nil
@@ -80,22 +99,42 @@ func (s *Service) UpdateDrawingEngineSetting(actor *model.User, value DrawingEng
func (s *Service) readDrawingEngineSetting() (*model.SystemSetting, DrawingEngineSetting, error) {
setting, err := s.repo.SystemSetting(drawingEngineSettingKey)
value := defaultDrawingEngineSetting()
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, defaultDrawingEngineSetting(), nil
setting = nil
} else if err != nil {
return nil, DrawingEngineSetting{}, err
} else {
if strings.TrimSpace(setting.ValueJSON) == "" || json.Unmarshal([]byte(setting.ValueJSON), &value) != nil {
return nil, DrawingEngineSetting{}, errors.New("绘图工具配置格式无效")
}
if err := validateDrawingEngineSetting(value); err != nil {
return nil, DrawingEngineSetting{}, err
}
}
_, licenseKey, err := s.readTldrawLicenseKey()
if err != nil {
return nil, DrawingEngineSetting{}, err
}
value := DrawingEngineSetting{}
if strings.TrimSpace(setting.ValueJSON) == "" || json.Unmarshal([]byte(setting.ValueJSON), &value) != nil {
return nil, DrawingEngineSetting{}, errors.New("绘图工具配置格式无效")
}
if err := validateDrawingEngineSetting(value); err != nil {
return nil, DrawingEngineSetting{}, err
}
value.TldrawLicenseKey = licenseKey
return setting, value, nil
}
func (s *Service) readTldrawLicenseKey() (*model.SystemSetting, string, error) {
setting, err := s.repo.SystemSetting(tldrawLicenseKeySettingKey)
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, "", nil
}
if err != nil {
return nil, "", err
}
var value string
if strings.TrimSpace(setting.ValueJSON) == "" || json.Unmarshal([]byte(setting.ValueJSON), &value) != nil {
return nil, "", errors.New("tldraw License Key 配置格式无效")
}
return setting, strings.TrimSpace(value), nil
}
func validateDrawingEngineSetting(value DrawingEngineSetting) error {
if value.DefaultEngine != DrawingEngineTldraw && value.DefaultEngine != DrawingEngineExcalidraw {
return BadAuthRequest("默认绘图工具必须是 tldraw 或 Excalidraw")
@@ -103,6 +142,10 @@ func validateDrawingEngineSetting(value DrawingEngineSetting) error {
return nil
}
func drawingEngineAuditValue(value DrawingEngineSetting) map[string]any {
return map[string]any{"defaultEngine": value.DefaultEngine, "hasTldrawLicenseKey": strings.TrimSpace(value.TldrawLicenseKey) != ""}
}
func publicDrawingEngineSetting(setting *model.SystemSetting, value DrawingEngineSetting) *PublicDrawingEngineSetting {
result := &PublicDrawingEngineSetting{DrawingEngineSetting: value, Configured: setting != nil}
if setting != nil {