Browse Source

Merge branch 'feature/fastgpt'

* feature/fastgpt:
  增加列表接口
  临时提交
  临时提交
  临时提交
  临时提交

# Conflicts:
#	crontask/init.go
boweniac 1 week ago
parent
commit
d32bcf29b7

+ 37 - 0
desc/wechat/fastgpt.api

@@ -8,6 +8,32 @@ type (
         // Name | 部门名称
         Title *string `json:"title"`
     }
+
+    AppsListReq {
+        Type string `json:"type"`
+
+        Keyword *string `json:"keyword,optional"`
+    }
+
+    AppsListResp {
+        BaseDataInfo
+
+        Data []*AppsListRespInfo `json:"data"`
+    }
+
+    AppsListRespInfo {
+        Id string `json:"_id"`
+
+        TeamId string `json:"teamId"`
+
+        TmbId string `json:"tmbId"`
+
+        Avatar string `json:"avatar"`
+
+        Name string `json:"name"`
+
+        Intro string `json:"intro"`
+    }
 )
 
 @server(
@@ -22,3 +48,14 @@ service Wechat {
     @handler CreateFastgpt
     post /api/fastgpt/create (CreateInfo) returns (BaseMsgResp)
 }
+
+@server(
+    jwt: Auth
+    group: fastgpt
+    middleware: Authority
+)
+
+service Wechat {
+    @handler GetAppsList
+    post /api/fastgpt/apps_list (AppsListReq) returns (AppsListResp)
+}

+ 44 - 0
internal/handler/fastgpt/get_apps_list_handler.go

@@ -0,0 +1,44 @@
+package fastgpt
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/fastgpt"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /api/fastgpt/apps_list fastgpt GetAppsList
+//
+
+//
+
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: AppsListReq
+//
+// Responses:
+//  200: AppsListResp
+
+func GetAppsListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.AppsListReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := fastgpt.NewGetAppsListLogic(r.Context(), svcCtx)
+		resp, err := l.GetAppsList(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 14 - 0
internal/handler/routes.go

@@ -2146,4 +2146,18 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 			},
 		},
 	)
+
+	server.AddRoutes(
+		rest.WithMiddlewares(
+			[]rest.Middleware{serverCtx.Authority},
+			[]rest.Route{
+				{
+					Method:  http.MethodPost,
+					Path:    "/api/fastgpt/apps_list",
+					Handler: fastgpt.GetAppsListHandler(serverCtx),
+				},
+			}...,
+		),
+		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
+	)
 }

+ 258 - 0
internal/logic/department/create_department_logic.go

@@ -6,9 +6,11 @@ import (
 	"github.com/suyuan32/simple-admin-common/msg/errormsg"
 	"github.com/suyuan32/simple-admin-core/rpc/types/core"
 	"github.com/zeromicro/go-zero/core/errorx"
+	"go.mongodb.org/mongo-driver/bson/primitive"
 	"time"
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
+	apps "wechat-api/mongo_model/apps"
 	team_members "wechat-api/mongo_model/team_members"
 	teams "wechat-api/mongo_model/teams"
 	users "wechat-api/mongo_model/users"
@@ -92,5 +94,261 @@ func (l *CreateDepartmentLogic) CreateDepartment(req *types.DepartmentInfo) (res
 		return nil, errorx.NewInvalidArgumentError("fastgpt create failed " + err.Error())
 	}
 
+	// 创建默认智能体
+	apps_info := &apps.Apps{
+		ParentID: nil,
+		TeamID:   teams_info.ID,
+		TmbID:    team_members_info.ID,
+		Name:     "默认智能体",
+		Type:     "simple",
+		Version:  "v2",
+		Avatar:   "/imgs/app/avatar/simple.svg",
+		Intro:    "",
+		TeamTags: []string{},
+		Modules: []apps.AppModule{
+			{
+				NodeID:       "userGuide",
+				Name:         "系统配置",
+				Intro:        "",
+				FlowNodeType: "userGuide",
+				Position: apps.Position{
+					X: 531.242273606555,
+					Y: -486.761172954975,
+				},
+				Version: "481",
+				Inputs:  []apps.AppInput{},
+				Outputs: []apps.AppOutput{},
+			},
+			{
+				NodeID:       "workflowStartNodeId",
+				Name:         "流程开始",
+				Intro:        "",
+				Avatar:       "core/workflow/template/workflowStart",
+				FlowNodeType: "workflowStart",
+				Position: apps.Position{
+					X: 558.40823764155,
+					Y: 123.723874291941,
+				},
+				Version: "481",
+				Inputs: []apps.AppInput{
+					{
+						Key:             "userChatInput",
+						RenderTypeList:  []string{"reference", "textarea"},
+						ValueType:       "string",
+						Label:           "workflow:user_question",
+						ToolDescription: "workflow:user_question",
+						Required:        true,
+					},
+				},
+				Outputs: []apps.AppOutput{
+					{
+						ID:        "userChatInput",
+						Key:       "userChatInput",
+						Label:     "common:core.module.input.label.user question",
+						Type:      "static",
+						ValueType: "string",
+					},
+					{
+						ID:          "userFiles",
+						Key:         "userFiles",
+						Label:       "app:workflow.user_file_input",
+						Description: "app:workflow.user_file_input_desc",
+						Type:        "static",
+						ValueType:   "arrayString",
+					},
+				},
+			},
+			{
+				NodeID:       "7BdojPlukIQw",
+				Name:         "AI 对话",
+				Intro:        "AI 大模型对话",
+				Avatar:       "core/workflow/template/aiChat",
+				FlowNodeType: "chatNode",
+				ShowStatus:   true,
+				Position: apps.Position{
+					X: 1106.32383879608,
+					Y: -350.603067468347,
+				},
+				Version: "4813",
+				Inputs: []apps.AppInput{
+					{
+						Key:            "model",
+						RenderTypeList: []string{"settingLLMModel", "reference"},
+						ValueType:      "string",
+						Value:          "DeepSeek-V3",
+					},
+					{
+						Key:            "temperature",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "number",
+						Value:          int32(0),
+						Min:            getInt32(0),
+						Max:            getInt32(10),
+						Step:           getInt32(1),
+					},
+					{
+						Key:            "maxToken",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "number",
+						Value:          int32(2000),
+						Min:            getInt32(100),
+						Max:            getInt32(4000),
+						Step:           getInt32(50),
+					},
+					{
+						Key:            "isResponseAnswerText",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "boolean",
+						Value:          true,
+					},
+					{
+						Key:            "aiChatQuoteRole",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "string",
+						Value:          "system",
+					},
+					{
+						Key:            "quoteTemplate",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "string",
+					},
+					{
+						Key:            "quotePrompt",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "string",
+					},
+					{
+						Key:            "systemPrompt",
+						RenderTypeList: []string{"textarea", "reference"},
+						Max:            getInt32(3000),
+						ValueType:      "string",
+						Label:          "core.ai.Prompt",
+						Description:    "core.app.tip.systemPromptTip",
+						Placeholder:    "core.app.tip.chatNodeSystemPromptTip",
+						Value:          "",
+					},
+					{
+						Key:            "history",
+						RenderTypeList: []string{"numberInput", "reference"},
+						ValueType:      "chatHistory",
+						Label:          "core.module.input.label.chat history",
+						Required:       true,
+						Min:            getInt32(0),
+						Max:            getInt32(30),
+						Value:          int32(6),
+					},
+					{
+						Key:             "userChatInput",
+						RenderTypeList:  []string{"reference", "textarea"},
+						ValueType:       "string",
+						Label:           "common:core.module.input.label.user question",
+						Required:        true,
+						ToolDescription: "common:core.module.input.label.user question",
+						Value:           []interface{}{"workflowStartNodeId", "userChatInput"},
+					},
+					{
+						Key:            "quoteQA",
+						RenderTypeList: []string{"settingDatasetQuotePrompt"},
+						Label:          "",
+						DebugLabel:     "common:core.module.Dataset quote.label",
+						Description:    "",
+						ValueType:      "datasetQuote",
+					},
+					{
+						Key:            "fileUrlList",
+						RenderTypeList: []string{"reference", "input"},
+						Label:          "app:file_quote_link",
+						DebugLabel:     "app:file_quote_link",
+						ValueType:      "arrayString",
+						Value:          [][]interface{}{{"workflowStartNodeId", "userFiles"}},
+					},
+					{
+						Key:            "aiChatVision",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "boolean",
+						Value:          true,
+					},
+				},
+				Outputs: []apps.AppOutput{
+					{
+						ID:          "history",
+						Key:         "history",
+						Required:    true,
+						Label:       "common:core.module.output.label.New context",
+						Description: "common:core.module.output.description.New context",
+						ValueType:   "chatHistory",
+						ValueDesc:   "{\n  obj: System | Human | AI;\n  value: string;\n}[]",
+						Type:        "static",
+					},
+					{
+						ID:          "answerText",
+						Key:         "answerText",
+						Required:    true,
+						Label:       "common:core.module.output.label.Ai response content",
+						Description: "common:core.module.output.description.Ai response content",
+						ValueType:   "string",
+						Type:        "static",
+					},
+				},
+			},
+		},
+		Edges: []apps.Edge{
+			{
+				Source:       "workflowStartNodeId",
+				Target:       "7BdojPlukIQw",
+				SourceHandle: "workflowStartNodeId-source-right",
+				TargetHandle: "7BdojPlukIQw-target-left",
+			},
+		},
+		PluginData: apps.PluginData{
+			ID:          mustParseObjectID("67da46b29667c5bf21203554"),
+			NodeVersion: "67da46d29667c5bf2120361a",
+		},
+		InheritPermission: true,
+		VersionNumber:     int32(0),
+		ChatConfig: apps.ChatConfig{
+			WelcomeText:   "",
+			Variables:     []interface{}{},
+			QuestionGuide: false,
+			TTSConfig: apps.TTSConfig{
+				Type: "web",
+			},
+			WhisperConfig: apps.WhisperConfig{
+				Open:            false,
+				AutoSend:        false,
+				AutoTTSResponse: false,
+			},
+			ScheduledTriggerConfig: nil,
+			ChatInputGuide: apps.ChatInputGuide{
+				Open:      false,
+				TextList:  []string{},
+				CustomUrl: "",
+			},
+			Instruction: "",
+			ID:          mustParseObjectID("67da46d29667c5bf2120361d"),
+		},
+		UpdateTime:               time.Date(2025, 3, 19, 4, 24, 4, 394000000, time.UTC),
+		ScheduledTriggerConfig:   nil,
+		ScheduledTriggerNextTime: nil,
+	}
+
+	err = l.svcCtx.MongoModel.AppsModel.Insert(context.TODO(), apps_info)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt create failed " + err.Error())
+	}
+
 	return &types.BaseMsgResp{Msg: errormsg.Success}, nil
 }
+
+func mustParseObjectID(hex string) primitive.ObjectID {
+	id, err := primitive.ObjectIDFromHex(hex)
+	if err != nil {
+		panic(err) // 或者根据需要处理错误
+	}
+	return id
+}
+
+func getInt32(n int32) *int32 {
+	num := int32(n)
+	return &num
+}

+ 259 - 0
internal/logic/fastgpt/create_fastgpt_logic.go

@@ -4,7 +4,9 @@ import (
 	"context"
 	"github.com/suyuan32/simple-admin-common/msg/errormsg"
 	"github.com/zeromicro/go-zero/core/errorx"
+	"go.mongodb.org/mongo-driver/bson/primitive"
 	"time"
+	apps "wechat-api/mongo_model/apps"
 	team_members "wechat-api/mongo_model/team_members"
 	teams "wechat-api/mongo_model/teams"
 	users "wechat-api/mongo_model/users"
@@ -76,5 +78,262 @@ func (l *CreateFastgptLogic) CreateFastgpt(req *types.CreateInfo) (resp *types.B
 		return nil, errorx.NewInvalidArgumentError("fastgpt create failed " + err.Error())
 	}
 
+	// 创建app
+	apps_info := &apps.Apps{
+		ParentID: nil,
+		TeamID:   teams_info.ID,
+		TmbID:    team_members_info.ID,
+		Name:     "默认智能体",
+		Type:     "simple",
+		Version:  "v2",
+		Avatar:   "/imgs/app/avatar/simple.svg",
+		Intro:    "",
+		TeamTags: []string{},
+		Modules: []apps.AppModule{
+			{
+				NodeID:       "userGuide",
+				Name:         "系统配置",
+				Intro:        "",
+				FlowNodeType: "userGuide",
+				Position: apps.Position{
+					X: 531.242273606555,
+					Y: -486.761172954975,
+				},
+				Version: "481",
+				Inputs:  []apps.AppInput{},
+				Outputs: []apps.AppOutput{},
+			},
+			{
+				NodeID:       "workflowStartNodeId",
+				Name:         "流程开始",
+				Intro:        "",
+				Avatar:       "core/workflow/template/workflowStart",
+				FlowNodeType: "workflowStart",
+				Position: apps.Position{
+					X: 558.40823764155,
+					Y: 123.723874291941,
+				},
+				Version: "481",
+				Inputs: []apps.AppInput{
+					{
+						Key:             "userChatInput",
+						RenderTypeList:  []string{"reference", "textarea"},
+						ValueType:       "string",
+						Label:           "workflow:user_question",
+						ToolDescription: "workflow:user_question",
+						Required:        true,
+					},
+				},
+				Outputs: []apps.AppOutput{
+					{
+						ID:        "userChatInput",
+						Key:       "userChatInput",
+						Label:     "common:core.module.input.label.user question",
+						Type:      "static",
+						ValueType: "string",
+					},
+					{
+						ID:          "userFiles",
+						Key:         "userFiles",
+						Label:       "app:workflow.user_file_input",
+						Description: "app:workflow.user_file_input_desc",
+						Type:        "static",
+						ValueType:   "arrayString",
+					},
+				},
+			},
+			{
+				NodeID:       "7BdojPlukIQw",
+				Name:         "AI 对话",
+				Intro:        "AI 大模型对话",
+				Avatar:       "core/workflow/template/aiChat",
+				FlowNodeType: "chatNode",
+				ShowStatus:   true,
+				Position: apps.Position{
+					X: 1106.32383879608,
+					Y: -350.603067468347,
+				},
+				Version: "4813",
+				Inputs: []apps.AppInput{
+					{
+						Key:            "model",
+						RenderTypeList: []string{"settingLLMModel", "reference"},
+						ValueType:      "string",
+						Value:          "DeepSeek-V3",
+					},
+					{
+						Key:            "temperature",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "number",
+						Value:          int32(0),
+						Min:            getInt32(0),
+						Max:            getInt32(10),
+						Step:           getInt32(1),
+					},
+					{
+						Key:            "maxToken",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "number",
+						Value:          int32(2000),
+						Min:            getInt32(100),
+						Max:            getInt32(4000),
+						Step:           getInt32(50),
+					},
+					{
+						Key:            "isResponseAnswerText",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "boolean",
+						Value:          true,
+					},
+					{
+						Key:            "aiChatQuoteRole",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "string",
+						Value:          "system",
+					},
+					{
+						Key:            "quoteTemplate",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "string",
+					},
+					{
+						Key:            "quotePrompt",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "string",
+					},
+					{
+						Key:            "systemPrompt",
+						RenderTypeList: []string{"textarea", "reference"},
+						Max:            getInt32(3000),
+						ValueType:      "string",
+						Label:          "core.ai.Prompt",
+						Description:    "core.app.tip.systemPromptTip",
+						Placeholder:    "core.app.tip.chatNodeSystemPromptTip",
+						Value:          "",
+					},
+					{
+						Key:            "history",
+						RenderTypeList: []string{"numberInput", "reference"},
+						ValueType:      "chatHistory",
+						Label:          "core.module.input.label.chat history",
+						Required:       true,
+						Min:            getInt32(0),
+						Max:            getInt32(30),
+						Value:          int32(6),
+					},
+					{
+						Key:             "userChatInput",
+						RenderTypeList:  []string{"reference", "textarea"},
+						ValueType:       "string",
+						Label:           "common:core.module.input.label.user question",
+						Required:        true,
+						ToolDescription: "common:core.module.input.label.user question",
+						Value:           []interface{}{"workflowStartNodeId", "userChatInput"},
+					},
+					{
+						Key:            "quoteQA",
+						RenderTypeList: []string{"settingDatasetQuotePrompt"},
+						Label:          "",
+						DebugLabel:     "common:core.module.Dataset quote.label",
+						Description:    "",
+						ValueType:      "datasetQuote",
+					},
+					{
+						Key:            "fileUrlList",
+						RenderTypeList: []string{"reference", "input"},
+						Label:          "app:file_quote_link",
+						DebugLabel:     "app:file_quote_link",
+						ValueType:      "arrayString",
+						Value:          [][]interface{}{{"workflowStartNodeId", "userFiles"}},
+					},
+					{
+						Key:            "aiChatVision",
+						RenderTypeList: []string{"hidden"},
+						ValueType:      "boolean",
+						Value:          true,
+					},
+				},
+				Outputs: []apps.AppOutput{
+					{
+						ID:          "history",
+						Key:         "history",
+						Required:    true,
+						Label:       "common:core.module.output.label.New context",
+						Description: "common:core.module.output.description.New context",
+						ValueType:   "chatHistory",
+						ValueDesc:   "{\n  obj: System | Human | AI;\n  value: string;\n}[]",
+						Type:        "static",
+					},
+					{
+						ID:          "answerText",
+						Key:         "answerText",
+						Required:    true,
+						Label:       "common:core.module.output.label.Ai response content",
+						Description: "common:core.module.output.description.Ai response content",
+						ValueType:   "string",
+						Type:        "static",
+					},
+				},
+			},
+		},
+		Edges: []apps.Edge{
+			{
+				Source:       "workflowStartNodeId",
+				Target:       "7BdojPlukIQw",
+				SourceHandle: "workflowStartNodeId-source-right",
+				TargetHandle: "7BdojPlukIQw-target-left",
+			},
+		},
+		PluginData: apps.PluginData{
+			ID:          mustParseObjectID("67da46b29667c5bf21203554"),
+			NodeVersion: "67da46d29667c5bf2120361a",
+		},
+		InheritPermission: true,
+		VersionNumber:     int32(0),
+		ChatConfig: apps.ChatConfig{
+			WelcomeText:   "",
+			Variables:     []interface{}{},
+			QuestionGuide: false,
+			TTSConfig: apps.TTSConfig{
+				Type: "web",
+			},
+			WhisperConfig: apps.WhisperConfig{
+				Open:            false,
+				AutoSend:        false,
+				AutoTTSResponse: false,
+			},
+			ScheduledTriggerConfig: nil,
+			ChatInputGuide: apps.ChatInputGuide{
+				Open:      false,
+				TextList:  []string{},
+				CustomUrl: "",
+			},
+			Instruction: "",
+			ID:          mustParseObjectID("67da46d29667c5bf2120361d"),
+		},
+		UpdateTime:               time.Date(2025, 3, 19, 4, 24, 4, 394000000, time.UTC),
+		ScheduledTriggerConfig:   nil,
+		ScheduledTriggerNextTime: nil,
+	}
+
+	err = l.svcCtx.MongoModel.AppsModel.Insert(context.TODO(), apps_info)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt create failed " + err.Error())
+	}
+
 	return &types.BaseMsgResp{Msg: errormsg.Success}, nil
 }
+
+// 添加 mustParseObjectID 函数
+func mustParseObjectID(hex string) primitive.ObjectID {
+	id, err := primitive.ObjectIDFromHex(hex)
+	if err != nil {
+		panic(err) // 或者根据需要处理错误
+	}
+	return id
+}
+
+func getInt32(n int32) *int32 {
+	num := int32(n)
+	return &num
+}

+ 63 - 0
internal/logic/fastgpt/get_apps_list_logic.go

@@ -0,0 +1,63 @@
+package fastgpt
+
+import (
+	"context"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"strconv"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetAppsListLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetAppsListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAppsListLogic {
+	return &GetAppsListLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetAppsListLogic) GetAppsList(req *types.AppsListReq) (resp *types.AppsListResp, err error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+
+	organizationIdStr := strconv.FormatUint(organizationId, 10)
+
+	user, err := l.svcCtx.MongoModel.UsersModel.FindOneByUsername(context.TODO(), organizationIdStr)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt get list failed " + err.Error())
+	}
+
+	teamMember, err := l.svcCtx.MongoModel.TeamMembersModel.FindOneByUserId(context.TODO(), user.ID)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt get list failed " + err.Error())
+	}
+
+	data, err := l.svcCtx.MongoModel.AppsModel.FindAll(context.TODO(), teamMember.TeamID, req.Type, req.Keyword)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt get list failed " + err.Error())
+	}
+
+	var appList []*types.AppsListRespInfo
+
+	if data != nil {
+		for _, app := range data {
+			appList = append(appList, &types.AppsListRespInfo{
+				Id:     app.ID.String(),
+				TeamId: app.TeamID.String(),
+				TmbId:  app.TmbID.String(),
+				Avatar: app.Avatar,
+				Name:   app.Name,
+				Intro:  app.Intro,
+			})
+		}
+	}
+
+	return &types.AppsListResp{Data: appList}, nil
+}

+ 23 - 0
internal/types/types.go

@@ -4297,6 +4297,7 @@ type DepartmentInfoResp struct {
 	// Department information | 部门数据
 	Data DepartmentInfo `json:"data"`
 }
+
 // swagger:model CreateInfo
 type CreateInfo struct {
 	// Translated Name | 展示名称
@@ -4304,3 +4305,25 @@ type CreateInfo struct {
 	// Name | 部门名称
 	Title *string `json:"title"`
 }
+
+// swagger:model AppsListReq
+type AppsListReq struct {
+	Type    string  `json:"type"`
+	Keyword *string `json:"keyword,optional"`
+}
+
+// swagger:model AppsListResp
+type AppsListResp struct {
+	BaseDataInfo
+	Data []*AppsListRespInfo `json:"data"`
+}
+
+// swagger:model AppsListRespInfo
+type AppsListRespInfo struct {
+	Id     string `json:"_id"`
+	TeamId string `json:"teamId"`
+	TmbId  string `json:"tmbId"`
+	Avatar string `json:"avatar"`
+	Name   string `json:"name"`
+	Intro  string `json:"intro"`
+}

+ 3 - 0
mongo_model/allmodel.go

@@ -1,6 +1,7 @@
 package mongo_model
 
 import (
+	apps "wechat-api/mongo_model/apps"
 	team_members "wechat-api/mongo_model/team_members"
 	teams "wechat-api/mongo_model/teams"
 	users "wechat-api/mongo_model/users"
@@ -10,6 +11,7 @@ type AllMongoModel struct {
 	UsersModel       users.UsersModel
 	TeamsModel       teams.TeamsModel
 	TeamMembersModel team_members.TeamMembersModel
+	AppsModel        apps.AppsModel
 }
 
 func SetupMongoModel(url, db string) *AllMongoModel {
@@ -17,5 +19,6 @@ func SetupMongoModel(url, db string) *AllMongoModel {
 		UsersModel:       users.NewUsersModel(url, db, "users"),
 		TeamsModel:       teams.NewTeamsModel(url, db, "teams"),
 		TeamMembersModel: team_members.NewTeamMembersModel(url, db, "team_members"),
+		AppsModel:        apps.NewAppsModel(url, db, "apps"),
 	}
 }

+ 25 - 0
mongo_model/apps/appsmodel.go

@@ -0,0 +1,25 @@
+package model
+
+import "github.com/zeromicro/go-zero/core/stores/mon"
+
+var _ AppsModel = (*customAppsModel)(nil)
+
+type (
+	// AppsModel is an interface to be customized, add more methods here,
+	// and implement the added methods in customAppsModel.
+	AppsModel interface {
+		appsModel
+	}
+
+	customAppsModel struct {
+		*defaultAppsModel
+	}
+)
+
+// NewAppsModel returns a model for the mongo.
+func NewAppsModel(url, db, collection string) AppsModel {
+	conn := mon.MustNewModel(url, db, collection)
+	return &customAppsModel{
+		defaultAppsModel: newDefaultAppsModel(conn),
+	}
+}

+ 97 - 0
mongo_model/apps/appsmodelgen.go

@@ -0,0 +1,97 @@
+// Code generated by goctl. DO NOT EDIT.
+// goctl 1.8.1
+
+package model
+
+import (
+	"context"
+	"time"
+
+	"github.com/zeromicro/go-zero/core/stores/mon"
+	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/bson/primitive"
+	"go.mongodb.org/mongo-driver/mongo"
+)
+
+type appsModel interface {
+	Insert(ctx context.Context, data *Apps) error
+	FindOne(ctx context.Context, id string) (*Apps, error)
+	Update(ctx context.Context, data *Apps) (*mongo.UpdateResult, error)
+	Delete(ctx context.Context, id string) (int64, error)
+	FindAll(ctx context.Context, teamId primitive. ObjectID, apptype string, keyword *string) ([]*Apps, error)
+}
+
+type defaultAppsModel struct {
+	conn *mon.Model
+}
+
+func newDefaultAppsModel(conn *mon.Model) *defaultAppsModel {
+	return &defaultAppsModel{conn: conn}
+}
+
+func (m *defaultAppsModel) Insert(ctx context.Context, data *Apps) error {
+	if data.ID.IsZero() {
+		data.ID = primitive.NewObjectID()
+		data.UpdateTime = time.Now()
+	}
+
+	_, err := m.conn.InsertOne(ctx, data)
+	return err
+}
+
+func (m *defaultAppsModel) FindOne(ctx context.Context, id string) (*Apps, error) {
+	oid, err := primitive.ObjectIDFromHex(id)
+	if err != nil {
+		return nil, ErrInvalidObjectId
+	}
+
+	var data Apps
+
+	err = m.conn.FindOne(ctx, &data, bson.M{"_id": oid})
+	switch err {
+	case nil:
+		return &data, nil
+	case mon.ErrNotFound:
+		return nil, ErrNotFound
+	default:
+		return nil, err
+	}
+}
+
+func (m *defaultAppsModel) Update(ctx context.Context, data *Apps) (*mongo.UpdateResult, error) {
+	data.UpdateTime = time.Now()
+
+	res, err := m.conn.UpdateOne(ctx, bson.M{"_id": data.ID}, bson.M{"$set": data})
+	return res, err
+}
+
+func (m *defaultAppsModel) Delete(ctx context.Context, id string) (int64, error) {
+	oid, err := primitive.ObjectIDFromHex(id)
+	if err != nil {
+		return 0, ErrInvalidObjectId
+	}
+
+	res, err := m.conn.DeleteOne(ctx, bson.M{"_id": oid})
+	return res, err
+}
+
+func (m *defaultAppsModel) FindAll(ctx context.Context, teamId primitive. ObjectID, apptype string, keyword *string) ([]*Apps, error) {
+	var data []*Apps
+
+	err := m.conn.Find(ctx, &data, bson.M{
+		"teamId": teamId,
+		"type": apptype,
+		"name": bson.M{
+			"$regex":   keyword, // 用你想要匹配的模式替换 searchPattern
+			"$options": "i",              // 可选:i 表示不区分大小写
+		},
+	})
+	switch err {
+	case nil:
+		return data, nil
+	case mon.ErrNotFound:
+		return nil, ErrNotFound
+	default:
+		return nil, err
+	}
+}

+ 114 - 0
mongo_model/apps/appstypes.go

@@ -0,0 +1,114 @@
+package model
+
+import (
+	"time"
+
+	"go.mongodb.org/mongo-driver/bson/primitive"
+)
+
+type AppModule struct {
+	NodeID       string      `bson:"nodeId" json:"nodeId"`
+	Name         string      `bson:"name" json:"name"`
+	Intro        string      `bson:"intro" json:"intro"`
+	Avatar       string      `bson:"avatar,omitempty" json:"avatar,omitempty"`
+	FlowNodeType string      `bson:"flowNodeType" json:"flowNodeType"`
+	ShowStatus   bool        `bson:"showStatus,omitempty" json:"showStatus,omitempty"`
+	Position     Position    `bson:"position" json:"position"`
+	Version      string      `bson:"version" json:"version"`
+	Inputs       []AppInput  `bson:"inputs" json:"inputs"`
+	Outputs      []AppOutput `bson:"outputs" json:"outputs"`
+}
+
+type Position struct {
+	X float64 `bson:"x" json:"x"`
+	Y float64 `bson:"y" json:"y"`
+}
+
+type AppInput struct {
+	Key             string      `bson:"key" json:"key"`
+	RenderTypeList  []string    `bson:"renderTypeList" json:"renderTypeList"`
+	ValueType       string      `bson:"valueType" json:"valueType"`
+	Label           string      `bson:"label" json:"label"`
+	ToolDescription string      `bson:"toolDescription,omitempty" json:"toolDescription,omitempty"`
+	Required        bool        `bson:"required,omitempty" json:"required,omitempty"`
+	Value           interface{} `bson:"value,omitempty" json:"value,omitempty"`
+	Min             *int32      `bson:"min,omitempty" json:"min,omitempty"`
+	Max             *int32      `bson:"max,omitempty" json:"max,omitempty"`
+	Step            *int32      `bson:"step,omitempty" json:"step,omitempty"`
+	Description     string      `bson:"description,omitempty" json:"description,omitempty"`
+	DebugLabel      string      `bson:"debugLabel,omitempty" json:"debugLabel,omitempty"`
+	Placeholder     string      `bson:"placeholder,omitempty" json:"placeholder,omitempty"`
+}
+
+type AppOutput struct {
+	ID          string `bson:"id" json:"id"`
+	Key         string `bson:"key" json:"key"`
+	Label       string `bson:"label" json:"label"`
+	Required    bool   `bson:"required,omitempty" json:"required,omitempty"`
+	Description string `bson:"description,omitempty" json:"description,omitempty"`
+	ValueType   string `bson:"valueType" json:"valueType"`
+	ValueDesc   string `bson:"valueDesc,omitempty" json:"valueDesc,omitempty"`
+	Type        string `bson:"type" json:"type"`
+}
+
+type Edge struct {
+	Source       string `bson:"source" json:"source"`
+	Target       string `bson:"target" json:"target"`
+	SourceHandle string `bson:"sourceHandle" json:"sourceHandle"`
+	TargetHandle string `bson:"targetHandle" json:"targetHandle"`
+}
+
+type PluginData struct {
+	ID          primitive.ObjectID `bson:"_id" json:"id"`
+	NodeVersion string             `bson:"nodeVersion" json:"nodeVersion"`
+}
+
+type TTSConfig struct {
+	Type string `bson:"type" json:"type"`
+}
+
+type WhisperConfig struct {
+	Open            bool `bson:"open" json:"open"`
+	AutoSend        bool `bson:"autoSend" json:"autoSend"`
+	AutoTTSResponse bool `bson:"autoTTSResponse" json:"autoTTSResponse"`
+}
+
+type ChatInputGuide struct {
+	Open      bool     `bson:"open" json:"open"`
+	TextList  []string `bson:"textList" json:"textList"`
+	CustomUrl string   `bson:"customUrl" json:"customUrl"`
+}
+
+type ChatConfig struct {
+	WelcomeText            string             `bson:"welcomeText" json:"welcomeText"`
+	Variables              []interface{}      `bson:"variables" json:"variables"`
+	QuestionGuide          bool               `bson:"questionGuide" json:"questionGuide"`
+	TTSConfig              TTSConfig          `bson:"ttsConfig" json:"ttsConfig"`
+	WhisperConfig          WhisperConfig      `bson:"whisperConfig" json:"whisperConfig"`
+	ScheduledTriggerConfig interface{}        `bson:"scheduledTriggerConfig" json:"scheduledTriggerConfig"`
+	ChatInputGuide         ChatInputGuide     `bson:"chatInputGuide" json:"chatInputGuide"`
+	Instruction            string             `bson:"instruction" json:"instruction"`
+	ID                     primitive.ObjectID `bson:"_id" json:"id"`
+}
+
+type Apps struct {
+	ID                       primitive.ObjectID  `bson:"_id,omitempty" json:"id,omitempty"`
+	ParentID                 *primitive.ObjectID `bson:"parentId,omitempty" json:"parentId,omitempty"`
+	TeamID                   primitive.ObjectID  `bson:"teamId" json:"teamId"`
+	TmbID                    primitive.ObjectID  `bson:"tmbId" json:"tmbId"`
+	Name                     string              `bson:"name" json:"name"`
+	Type                     string              `bson:"type" json:"type"`
+	Version                  string              `bson:"version" json:"version"`
+	Avatar                   string              `bson:"avatar" json:"avatar"`
+	Intro                    string              `bson:"intro" json:"intro"`
+	TeamTags                 []string            `bson:"teamTags" json:"teamTags"`
+	Modules                  []AppModule         `bson:"modules" json:"modules"`
+	Edges                    []Edge              `bson:"edges" json:"edges"`
+	PluginData               PluginData          `bson:"pluginData" json:"pluginData"`
+	InheritPermission        bool                `bson:"inheritPermission" json:"inheritPermission"`
+	UpdateTime               time.Time           `bson:"updateTime" json:"updateTime"`
+	VersionNumber            int32               `bson:"__v" json:"versionNumber"`
+	ChatConfig               ChatConfig          `bson:"chatConfig" json:"chatConfig"`
+	ScheduledTriggerConfig   interface{}         `bson:"scheduledTriggerConfig" json:"scheduledTriggerConfig"`
+	ScheduledTriggerNextTime interface{}         `bson:"scheduledTriggerNextTime" json:"scheduledTriggerNextTime"`
+}

+ 12 - 0
mongo_model/apps/error.go

@@ -0,0 +1,12 @@
+package model
+
+import (
+	"errors"
+
+	"github.com/zeromicro/go-zero/core/stores/mon"
+)
+
+var (
+	ErrNotFound        = mon.ErrNotFound
+	ErrInvalidObjectId = errors.New("invalid objectId")
+)

+ 15 - 0
mongo_model/team_members/teammembersmodelgen.go

@@ -16,6 +16,7 @@ import (
 type teamMembersModel interface {
 	Insert(ctx context.Context, data *TeamMembers) error
 	FindOne(ctx context.Context, id string) (*TeamMembers, error)
+	FindOneByUserId(ctx context.Context, userId primitive. ObjectID) (*TeamMembers, error)
 	Update(ctx context.Context, data *TeamMembers) (*mongo.UpdateResult, error)
 	Delete(ctx context.Context, id string) (int64, error)
 }
@@ -57,6 +58,20 @@ func (m *defaultTeamMembersModel) FindOne(ctx context.Context, id string) (*Team
 	}
 }
 
+func (m *defaultTeamMembersModel) FindOneByUserId(ctx context.Context, userId primitive. ObjectID) (*TeamMembers, error) {
+	var data TeamMembers
+
+	err := m.conn.FindOne(ctx, &data, bson.M{"userId": userId})
+	switch err {
+	case nil:
+		return &data, nil
+	case mon.ErrNotFound:
+		return nil, ErrNotFound
+	default:
+		return nil, err
+	}
+}
+
 func (m *defaultTeamMembersModel) Update(ctx context.Context, data *TeamMembers) (*mongo.UpdateResult, error) {
 	res, err := m.conn.UpdateOne(ctx, bson.M{"_id": data.ID}, bson.M{"$set": data})
 	return res, err

+ 15 - 0
mongo_model/users/usersmodelgen.go

@@ -14,6 +14,7 @@ import (
 type usersModel interface {
 	Insert(ctx context.Context, data *Users) error
 	FindOne(ctx context.Context, id string) (*Users, error)
+	FindOneByUsername(ctx context.Context, username string) (*Users, error)
 	Update(ctx context.Context, data *Users) (*mongo.UpdateResult, error)
 	Delete(ctx context.Context, id string) (int64, error)
 }
@@ -54,6 +55,20 @@ func (m *defaultUsersModel) FindOne(ctx context.Context, id string) (*Users, err
 	}
 }
 
+func (m *defaultUsersModel) FindOneByUsername(ctx context.Context, username string) (*Users, error) {
+	var data Users
+
+	err := m.conn.FindOne(ctx, &data, bson.M{"username": username})
+	switch err {
+	case nil:
+		return &data, nil
+	case mon.ErrNotFound:
+		return nil, ErrNotFound
+	default:
+		return nil, err
+	}
+}
+
 func (m *defaultUsersModel) Update(ctx context.Context, data *Users) (*mongo.UpdateResult, error) {
 	res, err := m.conn.UpdateOne(ctx, bson.M{"_id": data.ID}, bson.M{"$set": data})
 	return res, err