Files
qitongxue-api/internal/logic/tools.go
2026-09-17 14:42:44 +08:00

198 lines
5.4 KiB
Go

package logic
import (
"context"
"encoding/json"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
v1 "tool-api/api/user/v1"
"tool-api/internal/consts"
)
func gcodeUnauthorized() gcode.Code {
return gcode.New(401, "", nil)
}
func gcodeLocked() gcode.Code {
return gcode.New(consts.CodeLocked, "", nil)
}
// ToolsList 工具目录(含模块与工具的锁定态)
func ToolsList(ctx context.Context) (*v1.ToolsListRes, error) {
user, err := getUserById(ctx, CtxUserId(ctx))
if err != nil {
return nil, err
}
level, err := GetLevelByKey(ctx, user.LevelKey)
if err != nil {
return nil, err
}
toolRecords, err := g.Model(consts.TableTools).Where("is_enabled", 1).Order("sort asc").All()
if err != nil {
return nil, err
}
modRecords, err := g.Model(consts.TableModules).Where("is_enabled", 1).Order("sort asc").All()
if err != nil {
return nil, err
}
res := &v1.ToolsListRes{Modules: []v1.ModuleOut{}, List: []v1.ToolOut{}}
countByModule := map[string]int{}
for _, t := range toolRecords {
moduleKey := t["module_key"].String()
countByModule[moduleKey]++
res.List = append(res.List, v1.ToolOut{
ToolKey: t["tool_key"].String(),
ModuleKey: moduleKey,
Name: t["name"].String(),
Icon: t["icon"].String(),
Description: t["description"].String(),
IsHot: t["is_hot"].Int() == 1,
Locked: !slicesContain(level.Modules, moduleKey),
})
}
for _, m := range modRecords {
moduleKey := m["module_key"].String()
res.Modules = append(res.Modules, v1.ModuleOut{
ModuleKey: moduleKey,
Name: m["name"].String(),
Icon: m["icon"].String(),
Locked: !slicesContain(level.Modules, moduleKey),
EnabledToolsCount: countByModule[moduleKey],
})
}
return res, nil
}
func slicesContain(list []string, s string) bool {
for _, v := range list {
if v == s {
return true
}
}
return false
}
// ToolsUsed 工具使用上报(锁定/下架时拒绝)
func ToolsUsed(ctx context.Context, toolKey string) (*v1.ToolsUsedRes, error) {
user, err := getUserById(ctx, CtxUserId(ctx))
if err != nil {
return nil, err
}
level, err := GetLevelByKey(ctx, user.LevelKey)
if err != nil {
return nil, err
}
tool, err := g.Model(consts.TableTools).Where("tool_key", toolKey).Where("is_enabled", 1).One()
if err != nil {
return nil, err
}
if tool.IsEmpty() {
return nil, gerror.New("工具不存在或已下架")
}
if !slicesContain(level.Modules, tool["module_key"].String()) {
return nil, gerror.NewCode(gcodeLocked(), "该功能需要升级等级后使用")
}
if _, err = g.Model(consts.TableUsageLogs).Data(g.Map{
"user_id": user.Id,
"tool_key": toolKey,
"used_at": gtime.Now(),
}).Insert(); err != nil {
return nil, err
}
if _, err = g.Model(consts.TableTools).Where("tool_key", toolKey).
Increment("usage_count", 1); err != nil {
return nil, err
}
return &v1.ToolsUsedRes{}, nil
}
// WorkbenchGet 我的工作台;未配置时返回热推工具作为默认组合
func WorkbenchGet(ctx context.Context) (*v1.WorkbenchGetRes, error) {
user, err := getUserById(ctx, CtxUserId(ctx))
if err != nil {
return nil, err
}
record, err := g.Model(consts.TableWorkbench).Where("user_id", user.Id).One()
if err != nil {
return nil, err
}
if !record.IsEmpty() {
keys := []string{}
_ = json.Unmarshal([]byte(record["tool_keys"].String()), &keys)
return &v1.WorkbenchGetRes{ToolKeys: keys}, nil
}
// 首次进入:预置已授权模块下的热推工具
level, err := GetLevelByKey(ctx, user.LevelKey)
if err != nil {
return nil, err
}
hot, err := g.Model(consts.TableTools).Where("is_enabled", 1).Where("is_hot", 1).Order("sort asc").All()
if err != nil {
return nil, err
}
keys := make([]string, 0, 4)
for _, t := range hot {
if slicesContain(level.Modules, t["module_key"].String()) {
keys = append(keys, t["tool_key"].String())
}
}
return &v1.WorkbenchGetRes{ToolKeys: keys}, nil
}
// WorkbenchSave 保存工作台(校验启用 + 已授权)
func WorkbenchSave(ctx context.Context, toolKeys []string) (*v1.WorkbenchSaveRes, error) {
user, err := getUserById(ctx, CtxUserId(ctx))
if err != nil {
return nil, err
}
level, err := GetLevelByKey(ctx, user.LevelKey)
if err != nil {
return nil, err
}
if len(toolKeys) == 0 {
return nil, gerror.New("工作台至少保留一个工具")
}
for _, key := range toolKeys {
tool, err := g.Model(consts.TableTools).Where("tool_key", key).Where("is_enabled", 1).One()
if err != nil {
return nil, err
}
if tool.IsEmpty() {
return nil, gerror.Newf("工具 %s 不存在或已下架", key)
}
if !slicesContain(level.Modules, tool["module_key"].String()) {
return nil, gerror.NewCode(gcodeLocked(), "包含未解锁的工具,请升级等级")
}
}
jsonStr, err := json.Marshal(toolKeys)
if err != nil {
return nil, err
}
if _, err = g.Model(consts.TableWorkbench).Data(g.Map{
"user_id": user.Id,
"tool_keys": string(jsonStr),
"updated_at": gtime.Now(),
}).Save(); err != nil {
return nil, err
}
return &v1.WorkbenchSaveRes{}, nil
}
// FeedbackSubmit 提交反馈
func FeedbackSubmit(ctx context.Context, content, contact string) (*v1.FeedbackSubmitRes, error) {
if _, err := g.Model(consts.TableFeedbacks).Data(g.Map{
"user_id": CtxUserId(ctx),
"content": content,
"contact": contact,
}).Insert(); err != nil {
return nil, err
}
return &v1.FeedbackSubmitRes{}, nil
}