cyi-box: Memphis-style toolbox admin platform
Go(fun)+SQLite backend, Vue 3 frontend. Modules: dashboard, pay gateway (Epay-compatible + CDK stock), license/card system (per-app appid, domain binding), AI memory bank with built-in MCP server (/mcp, FTS5 search, signed read links), server SSH monitor + terminal + SFTP, proxy pool with protocol-level alive checks, DB manager (mysql/pg/sqlite + SQL autocomplete + import/export), disk share, vault (AES-GCM + TOTP), bookmarks, dev tools. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cyi-cc/fun"
|
||||
|
||||
"github.com/cyi-cc/cyi-box/backend/internal/dto"
|
||||
"github.com/cyi-cc/cyi-box/backend/internal/store"
|
||||
)
|
||||
|
||||
// ToolSvc 工具箱注册表:List 登录用户可见(驱动侧边导航),管理端点为 admin
|
||||
type ToolSvc struct {
|
||||
fun.Ctx
|
||||
Store *store.Store
|
||||
}
|
||||
|
||||
func (s *ToolSvc) List() ([]dto.ToolView, error) {
|
||||
tools, err := s.Store.ListTools(true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tool: list failed: %w", err)
|
||||
}
|
||||
return toolViews(tools), nil
|
||||
}
|
||||
|
||||
func (s *ToolSvc) AdminList() ([]dto.ToolView, error) {
|
||||
tools, err := s.Store.ListTools(false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tool: list failed: %w", err)
|
||||
}
|
||||
return toolViews(tools), nil
|
||||
}
|
||||
|
||||
func (s *ToolSvc) SaveTool(d dto.SaveToolDto) (dto.ToolView, error) {
|
||||
name := strings.TrimSpace(d.Name)
|
||||
url := strings.TrimSpace(d.Url)
|
||||
if name == "" || len(name) > 32 {
|
||||
return dto.ToolView{}, fun.Error(4001, "工具名必填且不超过 32 字符")
|
||||
}
|
||||
t := store.Tool{
|
||||
Name: name,
|
||||
Url: url,
|
||||
Sort: 0,
|
||||
Enabled: true,
|
||||
}
|
||||
if d.Id != nil {
|
||||
t.Id = *d.Id
|
||||
}
|
||||
if d.Icon != nil {
|
||||
t.Icon = strings.TrimSpace(*d.Icon)
|
||||
}
|
||||
if d.Description != nil {
|
||||
t.Description = strings.TrimSpace(*d.Description)
|
||||
}
|
||||
if d.Sort != nil {
|
||||
t.Sort = *d.Sort
|
||||
}
|
||||
if d.Enabled != nil {
|
||||
t.Enabled = *d.Enabled
|
||||
}
|
||||
if err := s.Store.SaveTool(&t); err != nil {
|
||||
return dto.ToolView{}, fmt.Errorf("tool: save failed: %w", err)
|
||||
}
|
||||
views := toolViews([]store.Tool{t})
|
||||
return views[0], nil
|
||||
}
|
||||
|
||||
func (s *ToolSvc) DeleteTool(d dto.DeleteToolDto) (dto.OkView, error) {
|
||||
if err := s.Store.DeleteTool(d.Id); err != nil {
|
||||
return dto.OkView{}, fmt.Errorf("tool: delete failed: %w", err)
|
||||
}
|
||||
return dto.OkView{Message: "已删除"}, nil
|
||||
}
|
||||
|
||||
func toolViews(tools []store.Tool) []dto.ToolView {
|
||||
views := make([]dto.ToolView, 0, len(tools))
|
||||
for _, t := range tools {
|
||||
views = append(views, dto.ToolView{
|
||||
Id: t.Id,
|
||||
Name: t.Name,
|
||||
Icon: t.Icon,
|
||||
Url: t.Url,
|
||||
Description: t.Description,
|
||||
Sort: t.Sort,
|
||||
Enabled: t.Enabled,
|
||||
})
|
||||
}
|
||||
return views
|
||||
}
|
||||
Reference in New Issue
Block a user