198 lines
5.4 KiB
Go
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
|
|
}
|