liuxiulin 1 ヶ月 前
コミット
1921cb4c51
100 ファイル変更7463 行追加0 行削除
  1. 1 0
      .gitattributes
  2. 20 0
      .gitignore
  3. 26 0
      Dockerfile
  4. 3 0
      README.MD
  5. 22 0
      app/bll/b_chat_assistant.go
  6. 25 0
      app/bll/b_chat_message.go
  7. 22 0
      app/bll/b_chat_session.go
  8. 24 0
      app/bll/b_dataset.go
  9. 28 0
      app/bll/b_dataset_file.go
  10. 14 0
      app/bll/b_file.go
  11. 31 0
      app/bll/b_login.go
  12. 22 0
      app/bll/b_login_history.go
  13. 26 0
      app/bll/b_menu.go
  14. 22 0
      app/bll/b_organization.go
  15. 25 0
      app/bll/b_robot_config.go
  16. 20 0
      app/bll/b_role.go
  17. 22 0
      app/bll/b_role_menu.go
  18. 9 0
      app/bll/b_trans.go
  19. 22 0
      app/bll/b_user.go
  20. 22 0
      app/bll/b_user_role.go
  21. 15 0
      app/bll/b_verify_code.go
  22. 44 0
      app/bll/impl/impl.go
  23. 222 0
      app/bll/impl/internal/b_chat_assistant.go
  24. 385 0
      app/bll/impl/internal/b_chat_message.go
  25. 141 0
      app/bll/impl/internal/b_chat_session.go
  26. 133 0
      app/bll/impl/internal/b_common.go
  27. 184 0
      app/bll/impl/internal/b_dataset.go
  28. 220 0
      app/bll/impl/internal/b_dataset_file.go
  29. 113 0
      app/bll/impl/internal/b_file.go
  30. 218 0
      app/bll/impl/internal/b_login.go
  31. 99 0
      app/bll/impl/internal/b_login_history.go
  32. 155 0
      app/bll/impl/internal/b_menu.go
  33. 164 0
      app/bll/impl/internal/b_organization.go
  34. 282 0
      app/bll/impl/internal/b_robot_config.go
  35. 143 0
      app/bll/impl/internal/b_role.go
  36. 89 0
      app/bll/impl/internal/b_role_menu.go
  37. 23 0
      app/bll/impl/internal/b_trans.go
  38. 234 0
      app/bll/impl/internal/b_user.go
  39. 89 0
      app/bll/impl/internal/b_user_role.go
  40. 163 0
      app/bll/impl/internal/b_verify_code.go
  41. 69 0
      app/context/context.go
  42. 38 0
      app/errors/error.go
  43. 93 0
      app/errors/response.go
  44. 0 0
      app/model/.gitkeep
  45. 68 0
      app/model/entity/e_chat_assistant.go
  46. 58 0
      app/model/entity/e_chat_dataset.go
  47. 71 0
      app/model/entity/e_chat_message.go
  48. 68 0
      app/model/entity/e_chat_session.go
  49. 71 0
      app/model/entity/e_dataset.go
  50. 80 0
      app/model/entity/e_dataset_file.go
  51. 49 0
      app/model/entity/e_login_history.go
  52. 91 0
      app/model/entity/e_menu.go
  53. 62 0
      app/model/entity/e_organization.go
  54. 80 0
      app/model/entity/e_robot_config.go
  55. 55 0
      app/model/entity/e_robot_dataset.go
  56. 61 0
      app/model/entity/e_role.go
  57. 56 0
      app/model/entity/e_role_menu.go
  58. 77 0
      app/model/entity/e_user.go
  59. 58 0
      app/model/entity/e_user_dataset.go
  60. 55 0
      app/model/entity/e_user_role.go
  61. 26 0
      app/model/entity/entity.go
  62. 109 0
      app/model/impl/model/m_chat_assistant.go
  63. 105 0
      app/model/impl/model/m_chat_dataset.go
  64. 113 0
      app/model/impl/model/m_chat_message.go
  65. 105 0
      app/model/impl/model/m_chat_session.go
  66. 149 0
      app/model/impl/model/m_dataset.go
  67. 141 0
      app/model/impl/model/m_dataset_file.go
  68. 113 0
      app/model/impl/model/m_login_history.go
  69. 133 0
      app/model/impl/model/m_menu.go
  70. 118 0
      app/model/impl/model/m_organization.go
  71. 113 0
      app/model/impl/model/m_robot_config.go
  72. 113 0
      app/model/impl/model/m_robot_dataset.go
  73. 104 0
      app/model/impl/model/m_role.go
  74. 113 0
      app/model/impl/model/m_role_menu.go
  75. 54 0
      app/model/impl/model/m_trans.go
  76. 124 0
      app/model/impl/model/m_user.go
  77. 110 0
      app/model/impl/model/m_user_dataset.go
  78. 106 0
      app/model/impl/model/m_user_role.go
  79. 124 0
      app/model/impl/model/model.go
  80. 22 0
      app/model/m_chat_assistant.go
  81. 22 0
      app/model/m_chat_dataset.go
  82. 22 0
      app/model/m_chat_message.go
  83. 22 0
      app/model/m_chat_session.go
  84. 30 0
      app/model/m_dataset.go
  85. 30 0
      app/model/m_dataset_file.go
  86. 22 0
      app/model/m_login_history.go
  87. 28 0
      app/model/m_menu.go
  88. 24 0
      app/model/m_organization.go
  89. 22 0
      app/model/m_robot_config.go
  90. 22 0
      app/model/m_robot_dataset.go
  91. 20 0
      app/model/m_role.go
  92. 24 0
      app/model/m_role_menu.go
  93. 13 0
      app/model/m_trans.go
  94. 25 0
      app/model/m_user.go
  95. 24 0
      app/model/m_user_dataset.go
  96. 22 0
      app/model/m_user_role.go
  97. 81 0
      app/schema/s_chat_assistant.go
  98. 36 0
      app/schema/s_chat_dataset.go
  99. 37 0
      app/schema/s_chat_message.go
  100. 60 0
      app/schema/s_chat_session.go

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
+* linguist-language=GO

+ 20 - 0
.gitignore

@@ -0,0 +1,20 @@
+.buildpath
+.hgignore.swp
+.project
+.orig
+.swp
+.idea/
+.settings/
+.vscode/
+vender/
+composer.lock
+gitpush.sh
+# only ignore /{log,pkg,bin,cbuild}
+/log
+/pkg
+/bin
+/cbuild
+**/.DS_Store
+main
+.vscode
+go.sum

+ 26 - 0
Dockerfile

@@ -0,0 +1,26 @@
+FROM loads/alpine:3.8
+
+LABEL maintainer="john@goframe.org"
+
+###############################################################################
+#                                INSTALLATION
+###############################################################################
+
+# 设置固定的项目路径
+ENV WORKDIR /var/www/yx-dataset-server
+
+# 添加应用可执行文件,并设置执行权限
+ADD ./bin/linux_amd64/main   $WORKDIR/main
+RUN chmod +x $WORKDIR/main
+
+# 添加I18N多语言文件、静态文件、配置文件、模板文件
+ADD i18n     $WORKDIR/i18n
+ADD public   $WORKDIR/public
+ADD config   $WORKDIR/config
+ADD template $WORKDIR/template
+
+###############################################################################
+#                                   START
+###############################################################################
+WORKDIR $WORKDIR
+CMD ./main

+ 3 - 0
README.MD

@@ -0,0 +1,3 @@
+# 永续绿建知识库平台后台
+
+框架文档地址:https://goframe.org/display/gf

+ 22 - 0
app/bll/b_chat_assistant.go

@@ -0,0 +1,22 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IChatAssistant ChatAssistant业务逻辑接口
+type IChatAssistant interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.ChatAssistantQueryParam, opts ...schema.ChatAssistantQueryOptions) (*schema.ChatAssistantQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.ChatAssistantQueryOptions) (*schema.ChatAssistant, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.ChatAssistant) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.ChatAssistant) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 25 - 0
app/bll/b_chat_message.go

@@ -0,0 +1,25 @@
+package bll
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"yx-dataset-server/app/schema"
+)
+
+// IChatMessage ChatMessage业务逻辑接口
+type IChatMessage interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.ChatMessageQueryParam, opts ...schema.ChatMessageQueryOptions) (*schema.ChatMessageQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.ChatMessageQueryOptions) (*schema.ChatMessage, error)
+	// StreamChatMessage 流式对话
+	StreamChatMessage(ctx context.Context, r *ghttp.Request, item schema.ChatMessage)
+	// ChatMessage 非流式对话
+	ChatMessage(ctx context.Context, r *ghttp.Request, item *schema.ChatMessage) (*schema.ChatMessage, error)
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.ChatMessage) (*schema.ChatMessage, error)
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 22 - 0
app/bll/b_chat_session.go

@@ -0,0 +1,22 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IChatSession ChatSession业务逻辑接口
+type IChatSession interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.ChatSessionQueryParam, opts ...schema.ChatSessionQueryOptions) (*schema.ChatSessionQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.ChatSessionQueryOptions) (*schema.ChatSession, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.ChatSession) (*schema.ChatSession, error)
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.ChatSession) (*schema.ChatSession, error)
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 24 - 0
app/bll/b_dataset.go

@@ -0,0 +1,24 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IDataset Dataset业务逻辑接口
+type IDataset interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.DatasetQueryParam, opts ...schema.DatasetQueryOptions) (*schema.DatasetQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.DatasetQueryOptions) (*schema.Dataset, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.Dataset) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.Dataset) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+	// UpdateSequence 更新排序
+	//UpdateSequence(ctx context.Context, recordID string, sequence int) error
+}

+ 28 - 0
app/bll/b_dataset_file.go

@@ -0,0 +1,28 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IDatasetFile DatasetFile业务逻辑接口
+type IDatasetFile interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.DatasetFileQueryParam, opts ...schema.DatasetFileQueryOptions) (*schema.DatasetFileQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.DatasetFileQueryOptions) (*schema.DatasetFile, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.DatasetFile) error
+	// BatchCreate 批量创建数据
+	BatchCreate(ctx context.Context, files schema.DatasetFiles) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.DatasetFile) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// BatchDelete 批量删除
+	BatchDelete(ctx context.Context, fileIDs []string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+	// UpdateEnabled 更新启用状态
+	UpdateEnabled(ctx context.Context, recordID string, status bool) error
+}

+ 14 - 0
app/bll/b_file.go

@@ -0,0 +1,14 @@
+package bll
+
+import (
+	"context"
+	"net/http"
+	"yx-dataset-server/app/schema"
+)
+
+// IFile 文件管理业务逻辑接口
+type IFile interface {
+	// 文件上传
+	Upload(ctx context.Context, r *http.Request, formKey, bucket string) (*schema.FileInfo, error)
+	Download(ctx context.Context, filePath string) ([]byte, string, error)
+}

+ 31 - 0
app/bll/b_login.go

@@ -0,0 +1,31 @@
+package bll
+
+import (
+	"context"
+	"net/http"
+	"yx-dataset-server/app/schema"
+)
+
+// ILogin Login业务逻辑接口
+type ILogin interface {
+	// GetCaptchaID 获取图形验证码信息
+	GetCaptchaID(ctx context.Context, length int) (*schema.LoginCaptcha, error)
+	// ResCaptcha 生成并响应图形验证码
+	ResCaptcha(ctx context.Context, w http.ResponseWriter, captchaID string, width, height int) error
+	// GenerateToken 生成令牌
+	GenerateToken(ctx context.Context, userID string) (*schema.LoginTokenInfo, error)
+	// DestroyToken 销毁令牌
+	DestroyToken(ctx context.Context, tokenString string) error
+	// RefreshToken 刷新令牌
+	RefreshToken(ctx context.Context) (*schema.LoginTokenInfo, error)
+	// Verify 登录验证
+	Verify(ctx context.Context, userName, password string) (*schema.User, error)
+	// GetUserInfo 获取当前用户登录信息
+	GetUserInfo(ctx context.Context) (*schema.UserLoginInfo, error)
+	// UpdatePassword 更新当前用户登录密码
+	UpdatePassword(ctx context.Context, params schema.UpdatePasswordParam) error
+	// Unsubscribe 用户注销
+	Unsubscribe(ctx context.Context, userId, tokenStr string) error
+	// LoginBySms 通过短信验证码登录
+	LoginBySms(ctx context.Context, params schema.SmsLoginParam) error
+}

+ 22 - 0
app/bll/b_login_history.go

@@ -0,0 +1,22 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// ILoginHistory LoginHistory业务逻辑接口
+type ILoginHistory interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.LoginHistoryQueryParam, opts ...schema.LoginHistoryQueryOptions) (*schema.LoginHistoryQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.LoginHistoryQueryOptions) (*schema.LoginHistory, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.LoginHistory) (*schema.LoginHistory, error)
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.LoginHistory) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 26 - 0
app/bll/b_menu.go

@@ -0,0 +1,26 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IMenu Menu业务逻辑接口
+type IMenu interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.MenuQueryParam, opts ...schema.MenuQueryOptions) (*schema.MenuQueryResult, error)
+	// 查询菜单树
+	QueryTree(ctx context.Context, params schema.MenuQueryParam, opts ...schema.MenuQueryOptions) (schema.MenuTrees, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.MenuQueryOptions) (*schema.Menu, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.Menu) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.Menu) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新排序
+	UpdateSequence(ctx context.Context, recordID string, sequence int) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 22 - 0
app/bll/b_organization.go

@@ -0,0 +1,22 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IOrganization Organization业务逻辑接口
+type IOrganization interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.OrganizationQueryParam, opts ...schema.OrganizationQueryOptions) (*schema.OrganizationQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.OrganizationQueryOptions) (*schema.Organization, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.Organization) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.Organization) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 25 - 0
app/bll/b_robot_config.go

@@ -0,0 +1,25 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/robot"
+)
+
+// IRobotConfig RobotConfig业务逻辑接口
+type IRobotConfig interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.RobotConfigQueryParam, opts ...schema.RobotConfigQueryOptions) (*schema.RobotConfigQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.RobotConfigQueryOptions) (*schema.RobotConfig, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.RobotConfig) (*schema.RobotConfig, error)
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.RobotConfig) (*schema.RobotConfig, error)
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+	// 接收消息
+	ReceiveMessage(ctx context.Context, id string, item robot.DingTalkRobotMessage) error
+}

+ 20 - 0
app/bll/b_role.go

@@ -0,0 +1,20 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IRole Role业务逻辑接口
+type IRole interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.RoleQueryParam, opts ...schema.RoleQueryOptions) (*schema.RoleQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.RoleQueryOptions) (*schema.Role, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.Role) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.Role) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+}

+ 22 - 0
app/bll/b_role_menu.go

@@ -0,0 +1,22 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IRoleMenu RoleMenu业务逻辑接口
+type IRoleMenu interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.RoleMenuQueryParam, opts ...schema.RoleMenuQueryOptions) (*schema.RoleMenuQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.RoleMenuQueryOptions) (*schema.RoleMenu, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.RoleMenu) (*schema.RoleMenu, error)
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.RoleMenu) (*schema.RoleMenu, error)
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 9 - 0
app/bll/b_trans.go

@@ -0,0 +1,9 @@
+package bll
+
+import "context"
+
+// ITrans 事务管理接口
+type ITrans interface {
+	// Exec 执行事务
+	Exec(ctx context.Context, fn func(context.Context) error) error
+}

+ 22 - 0
app/bll/b_user.go

@@ -0,0 +1,22 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IUser User业务逻辑接口
+type IUser interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.UserQueryParam, opts ...schema.UserOptions) (*schema.UserQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.UserOptions) (*schema.User, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.User) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.User) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status bool) error
+}

+ 22 - 0
app/bll/b_user_role.go

@@ -0,0 +1,22 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IUserRole UserRole业务逻辑接口
+type IUserRole interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.UserRoleQueryParam, opts ...schema.UserRoleQueryOptions) (*schema.UserRoleQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.UserRoleQueryOptions) (*schema.UserRole, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.UserRole) (*schema.UserRole, error)
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.UserRole) (*schema.UserRole, error)
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 15 - 0
app/bll/b_verify_code.go

@@ -0,0 +1,15 @@
+package bll
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IVerifyCode VerifyCode业务逻辑接口
+type IVerifyCode interface {
+
+	// Check 检查手机号及验证码的有效性
+	Check(ctx context.Context, req schema.VerifyCodeCheck) (bool, error)
+
+	ALiYunSendSms(ctx context.Context, req schema.VerifyCodeRequest) (*schema.VerifyCodeResponse, error)
+}

+ 44 - 0
app/bll/impl/impl.go

@@ -0,0 +1,44 @@
+package impl
+
+import (
+	"go.uber.org/dig"
+	"yx-dataset-server/app/bll"
+	"yx-dataset-server/app/bll/impl/internal"
+)
+
+func Inject(container *dig.Container) {
+	_ = container.Provide(internal.NewTrans)
+	_ = container.Provide(func(b *internal.Trans) bll.ITrans { return b })
+	_ = container.Provide(internal.NewLogin)
+	_ = container.Provide(func(b *internal.Login) bll.ILogin { return b })
+	_ = container.Provide(internal.NewUser)
+	_ = container.Provide(func(b *internal.User) bll.IUser { return b })
+	_ = container.Provide(internal.NewVerifyCode)
+	_ = container.Provide(func(b *internal.VerifyCode) bll.IVerifyCode { return b })
+	_ = container.Provide(internal.NewFile)
+	_ = container.Provide(func(b *internal.File) bll.IFile { return b })
+	_ = container.Provide(internal.NewDataset)
+	_ = container.Provide(func(b *internal.Dataset) bll.IDataset { return b })
+	_ = container.Provide(internal.NewDatasetFile)
+	_ = container.Provide(func(b *internal.DatasetFile) bll.IDatasetFile { return b })
+	_ = container.Provide(internal.NewLoginHistory)
+	_ = container.Provide(func(b *internal.LoginHistory) bll.ILoginHistory { return b })
+	_ = container.Provide(internal.NewOrganization)
+	_ = container.Provide(func(b *internal.Organization) bll.IOrganization { return b })
+
+	_ = container.Provide(internal.NewRole)
+	_ = container.Provide(func(b *internal.Role) bll.IRole { return b })
+	_ = container.Provide(internal.NewMenu)
+	_ = container.Provide(func(b *internal.Menu) bll.IMenu { return b })
+
+	_ = container.Provide(internal.NewChatAssistant)
+	_ = container.Provide(func(b *internal.ChatAssistant) bll.IChatAssistant { return b })
+	_ = container.Provide(internal.NewChatSession)
+	_ = container.Provide(func(b *internal.ChatSession) bll.IChatSession { return b })
+	_ = container.Provide(internal.NewChatMessage)
+	_ = container.Provide(func(b *internal.ChatMessage) bll.IChatMessage { return b })
+
+	_ = container.Provide(internal.NewRobotConfig)
+	_ = container.Provide(func(b *internal.RobotConfig) bll.IRobotConfig { return b })
+
+}

+ 222 - 0
app/bll/impl/internal/b_chat_assistant.go

@@ -0,0 +1,222 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/ragflow"
+)
+
+// NewChatAssistant 创建ChatAssistant
+func NewChatAssistant(
+	mChatAssistant model.IChatAssistant,
+	mChatDataset model.IChatDataset,
+	mTrans model.ITrans,
+	mDataset model.IDataset,
+	mUser model.IUser,
+	mSession model.IChatSession,
+
+) *ChatAssistant {
+	return &ChatAssistant{
+		ChatAssistantModel: mChatAssistant,
+		chatDatasetModel:   mChatDataset,
+		transModel:         mTrans,
+		datasetModel:       mDataset,
+		userModel:          mUser,
+		sessionModel:       mSession,
+	}
+}
+
+// ChatAssistant 创建ChatAssistant对象
+type ChatAssistant struct {
+	ChatAssistantModel model.IChatAssistant
+	chatDatasetModel   model.IChatDataset
+	transModel         model.ITrans
+	datasetModel       model.IDataset
+	userModel          model.IUser
+	sessionModel       model.IChatSession
+}
+
+// Query 查询数据
+func (a *ChatAssistant) Query(ctx context.Context, params schema.ChatAssistantQueryParam, opts ...schema.ChatAssistantQueryOptions) (*schema.ChatAssistantQueryResult, error) {
+	var userQueryParam schema.UserQueryParam
+	userQueryParam.RoleCode = []string{"11", "12"}
+	if !CheckIsRootUser(ctx) {
+		user, err := a.userModel.Get(ctx, GetUserID(ctx))
+		if err != nil {
+			return nil, err
+		}
+		params.OrgId = user.OrgId
+		userQueryParam.OrgId = user.OrgId
+	}
+
+	result, err := a.ChatAssistantModel.Query(ctx, params, opts...)
+	if err != nil {
+		return nil, err
+	}
+	chatDataset, err := a.chatDatasetModel.Query(ctx, schema.ChatDatasetQueryParam{})
+	if err != nil {
+		return nil, err
+	}
+	dataset, err := a.datasetModel.Query(ctx, schema.DatasetQueryParam{})
+	if err != nil {
+		return nil, err
+	}
+	users, err := a.userModel.Query(ctx, userQueryParam)
+	if err != nil {
+		return nil, err
+	}
+	result.Data.FillCreator(users.Data)
+
+	result.Data.FillDatasetId(chatDataset.Data)
+
+	result.Data.FillDataset(dataset.Data)
+
+	return result, nil
+}
+
+// Get 查询指定数据
+func (a *ChatAssistant) Get(ctx context.Context, recordID string, opts ...schema.ChatAssistantQueryOptions) (*schema.ChatAssistant, error) {
+	item, err := a.ChatAssistantModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	user, err := a.userModel.Get(ctx, item.CreatorId)
+	if err != nil {
+		return nil, err
+	}
+	item.CreatorName = user.RealName
+
+	chatDataset, err := a.chatDatasetModel.Query(ctx, schema.ChatDatasetQueryParam{})
+	if err != nil {
+		return nil, err
+	}
+
+	dataset, err := a.datasetModel.Query(ctx, schema.DatasetQueryParam{RecordIds: chatDataset.Data.ToDatasetIds()})
+	if err != nil {
+		return nil, err
+	}
+	users, err := a.userModel.Query(ctx, schema.UserQueryParam{RoleCode: []string{"11", "12"}})
+	if err != nil {
+		return nil, err
+	}
+	dataset.Data.FillCreator(users.Data)
+	item.Datasets = dataset.Data
+
+	sessions, err := a.sessionModel.Query(ctx, schema.ChatSessionQueryParam{AssistantId: item.RecordID})
+	if err != nil {
+		return nil, err
+	}
+	item.Sessions = sessions.Data
+	return item, nil
+}
+
+// Create 创建数据
+func (a *ChatAssistant) Create(ctx context.Context, item schema.ChatAssistant) error {
+	item.RecordID = guid.S()
+	item.CreatorId = GetUserID(ctx)
+	name := "new_chat"
+	if item.Name != "" {
+		name = item.Name
+	}
+	if len(item.Datasets) == 0 {
+		return errors.New400Response("关联知识库不能为空")
+	}
+	if !CheckIsRootUser(ctx) {
+		user, err := a.userModel.Get(ctx, item.CreatorId)
+		if err != nil {
+			return err
+		}
+		item.OrgId = user.OrgId
+	}
+
+	err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		for _, v := range item.Datasets {
+			err := a.chatDatasetModel.Create(ctx, schema.ChatDataset{
+				RecordID:        guid.S(),
+				ChatAssistantId: item.RecordID,
+				DatasetId:       v.RecordID,
+			})
+			if err != nil {
+				return err
+			}
+		}
+
+		resp, err := ragflow.GetHttpClient().CreateChat(ctx, &ragflow.CreateChatReq{
+			Name:       name,
+			DatasetIDs: item.Datasets.ToRagDataIds(),
+		})
+		if err != nil {
+			return err
+		}
+		item.RagChatId = resp.Data.ID
+
+		return a.ChatAssistantModel.Create(ctx, item)
+
+	})
+	return err
+}
+
+// Update 更新数据
+func (a *ChatAssistant) Update(ctx context.Context, recordID string, item schema.ChatAssistant) error {
+	oldItem, err := a.ChatAssistantModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.ChatAssistantModel.Update(ctx, recordID, item)
+		if err != nil {
+			return err
+		}
+		if item.Name != oldItem.Name {
+			_, err = ragflow.GetHttpClient().UpdateChat(ctx, item.RagChatId, &ragflow.UpdateChatReq{
+				Name: item.Name,
+			})
+			if err != nil {
+				return err
+			}
+		}
+		return nil
+	})
+
+	return err
+}
+
+// Delete 删除数据
+func (a *ChatAssistant) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.ChatAssistantModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.ChatAssistantModel.Delete(ctx, recordID)
+		if err != nil {
+			return err
+		}
+		_, err = ragflow.GetHttpClient().DeleteChats(ctx, []string{oldItem.RagChatId})
+		if err != nil {
+			return err
+		}
+		return nil
+	})
+	return err
+}
+
+// UpdateStatus 更新状态
+func (a *ChatAssistant) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.ChatAssistantModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.ChatAssistantModel.UpdateStatus(ctx, recordID, status)
+}

+ 385 - 0
app/bll/impl/internal/b_chat_message.go

@@ -0,0 +1,385 @@
+package internal
+
+import (
+	"bufio"
+	"context"
+	"encoding/json"
+	"fmt"
+	"github.com/gogf/gf/util/guid"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"strings"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/ragflow"
+)
+
+// NewChatMessage 创建ChatMessage
+func NewChatMessage(
+	mSession model.IChatSession,
+	mChatMessage model.IChatMessage,
+	mAssistant model.IChatAssistant,
+) *ChatMessage {
+	return &ChatMessage{
+		ChatMessageModel: mChatMessage,
+		sessionModel:     mSession,
+		assistantModel:   mAssistant,
+	}
+}
+
+// ChatMessage 创建ChatMessage对象
+type ChatMessage struct {
+	ChatMessageModel model.IChatMessage
+	sessionModel     model.IChatSession
+	assistantModel   model.IChatAssistant
+}
+
+// Query 查询数据
+func (a *ChatMessage) Query(ctx context.Context, params schema.ChatMessageQueryParam, opts ...schema.ChatMessageQueryOptions) (*schema.ChatMessageQueryResult, error) {
+	return a.ChatMessageModel.Query(ctx, params, opts...)
+}
+
+// Get 查询指定数据
+func (a *ChatMessage) Get(ctx context.Context, recordID string, opts ...schema.ChatMessageQueryOptions) (*schema.ChatMessage, error) {
+	item, err := a.ChatMessageModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	return item, nil
+}
+
+func (a *ChatMessage) getUpdate(ctx context.Context, recordID string) (*schema.ChatMessage, error) {
+	return a.Get(ctx, recordID)
+}
+
+// StreamChatMessage 流式消息
+func (a *ChatMessage) StreamChatMessage(ctx context.Context, r *ghttp.Request, item schema.ChatMessage) {
+	item.RecordID = guid.S()
+	item.CreatorId = GetUserID(ctx)
+	//var sessionId string
+	if item.SessionId == "" {
+		r.Response.Write("data: {\"code\":500,\"message\":\"会话ID不能为空\"}\n\n")
+		return
+	}
+
+	session, err := a.sessionModel.Get(ctx, item.SessionId)
+	if err != nil {
+		r.Response.Write("data: {\"code\":500,\"message\":\"%s\"}\n\n", err.Error())
+		return
+	}
+	//sessionId = session.RagSessionId
+
+	assistant, err := a.assistantModel.Get(ctx, item.AssistantId)
+	if err != nil {
+		r.Response.Write("data: {\"code\":500,\"message\":\"%s\"}\n\n", err.Error())
+		return
+	}
+
+	stream, err := ragflow.GetHttpClient().ChatCompletionsStream(ctx, assistant.RagChatId, &ragflow.ChatCompletionReq{
+		Question:  item.Question,
+		SessionID: session.RagSessionId,
+	})
+	if err != nil {
+		r.Response.Write("data: {\"code\":500,\"message\":\"%s\"}\n\n", err.Error())
+		return
+	}
+	defer stream.Close() // 关闭流
+	// 用于拼接答案
+	var fullAnswer strings.Builder
+	//err = a.collectStreamDataAndCreate(ctx, stream, &item)
+	//if err != nil {
+	//	r.Response.Write("data: {\"code\":500,\"message\":\"%s\"}\n\n", err.Error())
+	//	return
+	//}
+	// ===================== 5. 设置SSE响应头(必须!) =====================
+	r.Response.Header().Set("Content-Type", "text/event-stream")
+	r.Response.Header().Set("Cache-Control", "no-cache")
+	r.Response.Header().Set("Connection", "keep-alive")
+	r.Response.Header().Set("X-Accel-Buffering", "no") // 禁用Nginx缓冲
+	r.Response.Flush()
+
+	scanner := bufio.NewScanner(stream)
+	buf := make([]byte, 1024*1024*10) // 增大缓冲区
+	scanner.Buffer(buf, 1024*1024*10)
+
+	for scanner.Scan() {
+		line := scanner.Text()
+		// 原封不动写给前端
+		r.Response.Write(line + "\n")
+		r.Response.Flush() // 实时刷新
+
+		//2. 后端收集数据(拼接完整答案)
+		if strings.HasPrefix(line, "data:") {
+			jsonStr := strings.TrimPrefix(line, "data:")
+			jsonStr = strings.TrimSpace(jsonStr)
+
+			if jsonStr != "true" {
+				var chunk ragflow.ChatCompletionResp
+				if err := json.Unmarshal([]byte(jsonStr), &chunk); err == nil {
+					fullAnswer.WriteString(chunk.Data.Answer)
+				}
+			}
+		}
+	}
+
+	// 处理流读取错误
+	if err := scanner.Err(); err != nil {
+		r.Response.Write(fmt.Sprintf("data: {\"code\":500,\"message\":\"读取流失败:%s\"}\n\n", err.Error()))
+		r.Response.Flush()
+		return
+	}
+
+	// ===================== 【业务层:保存完整答案到数据库】 =====================
+	item.Answer = fullAnswer.String()
+	if err := a.ChatMessageModel.Create(ctx, item); err != nil {
+		fmt.Printf("保存聊天记录失败:%v\n", err)
+	}
+
+}
+
+func (a *ChatMessage) ChatMessage(ctx context.Context, r *ghttp.Request, item *schema.ChatMessage) (*schema.ChatMessage, error) {
+	item.RecordID = guid.S()
+	item.CreatorId = GetUserID(ctx)
+	//var sessionId string
+	if item.SessionId == "" {
+		return nil, errors.New400Response("会话ID不能为空")
+	}
+
+	session, err := a.sessionModel.Get(ctx, item.SessionId)
+	if err != nil {
+		return nil, err
+	}
+	//sessionId = session.RagSessionId
+
+	assistant, err := a.assistantModel.Get(ctx, item.AssistantId)
+	if err != nil {
+		return nil, err
+	}
+
+	stream, err := ragflow.GetHttpClient().ChatCompletionsStream(ctx, assistant.RagChatId, &ragflow.ChatCompletionReq{
+		Question:  item.Question,
+		SessionID: session.RagSessionId,
+	})
+	if err != nil {
+		return nil, err
+	}
+	defer stream.Close() // 关闭流
+
+	item, err = CollectStreamDataAndCreate(ctx, stream, item)
+	if err != nil {
+		return nil, err
+	}
+
+	err = a.ChatMessageModel.Create(ctx, *item)
+	if err != nil {
+		return nil, err
+	}
+
+	return item, nil
+}
+
+//func (a *ChatMessage) collectStreamDataAndCreate(ctx context.Context, stream io.ReadCloser, item *schema.ChatMessage) error {
+//	// 解决 token too long 报错:调大缓冲区到 10MB
+//	const maxBufferSize = 10 * 1024 * 1024
+//	scanner := bufio.NewScanner(stream)
+//	buf := make([]byte, maxBufferSize)
+//	scanner.Buffer(buf, maxBufferSize)
+//
+//	// 用于拼接答案
+//	var fullAnswer strings.Builder
+//	// 用于存储最终完整结果
+//	finalResp := &ragflow.ChatCompletionResp{}
+//
+//	// 逐行读取流式返回
+//	for scanner.Scan() {
+//		line := strings.TrimSpace(scanner.Text())
+//		if line == "" {
+//			continue
+//		}
+//
+//		// 只处理 SSE 格式 data: ...
+//		if !strings.HasPrefix(line, "data:") {
+//			continue
+//		}
+//		jsonStr := strings.TrimPrefix(line, "data:")
+//		jsonStr = strings.TrimSpace(jsonStr)
+//
+//		// 流结束标记:data: true
+//		if jsonStr == "true" {
+//			break
+//		}
+//
+//		// 解析当前分片
+//		var chunk ragflow.ChatCompletionResp
+//		if err := json.Unmarshal([]byte(jsonStr), &chunk); err != nil {
+//			continue
+//		}
+//		// 拼接回答内容
+//		if chunk.Data.Answer != "" {
+//			fullAnswer.WriteString(chunk.Data.Answer)
+//		}
+//		// 保存最后一个分片(包含 reference/session_id 等完整信息)
+//		*finalResp = chunk
+//	}
+//
+//	if err := scanner.Err(); err != nil {
+//		return errors.New400Response(fmt.Sprintf("读取流式数据失败: %v", err))
+//	}
+//
+//	item.Answer = fullAnswer.String()
+//
+//	return a.ChatMessageModel.Create(ctx, *item)
+//
+//}
+
+func (a *ChatMessage) CreateV3(ctx context.Context, r *ghttp.Request, item schema.ChatMessage) {
+	item.RecordID = guid.S()
+	item.CreatorId = GetUserID(ctx)
+	//var sessionId string
+	if item.SessionId == "" {
+		//return nil, errors.New400Response("会话ID不能为空")
+		return
+	}
+
+	session, err := a.sessionModel.Get(ctx, item.SessionId)
+	if err != nil {
+		//return nil, err
+		return
+	}
+	//sessionId = session.RagSessionId
+
+	assistant, err := a.assistantModel.Get(ctx, item.AssistantId)
+	if err != nil {
+		//return nil, err
+		return
+	}
+
+	//resp, err := ragflow.GetHttpClient().ChatCompletions(ctx, assistant.RagChatId, &ragflow.ChatCompletionReq{
+	//	Question:  item.Question,
+	//	SessionID: sessionId,
+	//})
+	//if err != nil {
+	//	return nil, err
+	//}
+	//item.Answer = resp.Data.Answer
+	err = a.ChatMessageModel.Create(ctx, item)
+	if err != nil {
+		return
+	}
+	stream, err := ragflow.GetHttpClient().ChatCompletionsStream(ctx, assistant.RagChatId, &ragflow.ChatCompletionReq{
+		Question:  item.Question,
+		SessionID: session.RagSessionId,
+	})
+	if err != nil {
+		return
+	}
+	defer stream.Close() // 关闭流
+
+	// ===================== 5. 设置SSE响应头(必须!) =====================
+	r.Response.Header().Set("Content-Type", "text/event-stream")
+	r.Response.Header().Set("Cache-Control", "no-cache")
+	r.Response.Header().Set("Connection", "keep-alive")
+	r.Response.Header().Set("X-Accel-Buffering", "no") // 禁用Nginx缓冲
+	//r.Response.Flush()
+	//
+	//_, err = io.Copy(r.Response.Writer, stream)
+	//if err != nil {
+	//	// 可自定义错误处理
+	//	r.Response.Write(fmt.Sprintf("data: {\"code\":500,\"message\":\"%s\"}\n\n", err.Error()))
+	//}
+	// 实时刷新
+	//===================== 6. 逐行转发RAG流给前端 =====================
+	scanner := bufio.NewScanner(stream)
+	buf := make([]byte, 1024*1024*10) // 增大缓冲区
+	scanner.Buffer(buf, 1024*1024*10)
+
+	for scanner.Scan() {
+		line := scanner.Text()
+		// 原封不动写给前端
+		r.Response.Write(line + "\n")
+		r.Response.Flush() // 实时刷新
+	}
+
+	//// 处理错误
+	//if err = scanner.Err(); err != nil {
+	//	r.Response.Write(fmt.Sprintf("data: {\"code\":500,\"message\":\"%s\"}\n\n", err.Error()))
+	//	r.Response.Flush() // 实时刷新
+	//}
+
+}
+
+func (a *ChatMessage) CreateV2(ctx context.Context, item schema.ChatMessage) (*schema.ChatMessage, error) {
+	item.RecordID = guid.S()
+	item.CreatorId = GetUserID(ctx)
+
+	if item.SessionId == "" {
+		return nil, errors.New400Response("会话ID不能为空")
+	}
+
+	session, err := a.sessionModel.Get(ctx, item.SessionId)
+	if err != nil {
+		return nil, err
+	}
+	assistant, err := a.assistantModel.Get(ctx, item.AssistantId)
+	if err != nil {
+		return nil, err
+	}
+
+	// 调用非流式接口
+	resp, err := ragflow.GetHttpClient().ChatCompletions(ctx, assistant.RagChatId, &ragflow.ChatCompletionReq{
+		Question:  item.Question,
+		SessionID: session.RagSessionId,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	item.Answer = resp.Data.Answer
+	// 保存数据库
+	err = a.ChatMessageModel.Create(ctx, item)
+	if err != nil {
+		return nil, err
+	}
+
+	return a.getUpdate(ctx, item.RecordID)
+}
+
+// Update 更新数据
+func (a *ChatMessage) Update(ctx context.Context, recordID string, item schema.ChatMessage) (*schema.ChatMessage, error) {
+	oldItem, err := a.ChatMessageModel.Get(ctx, recordID)
+	if err != nil {
+		return nil, err
+	} else if oldItem == nil {
+		return nil, errors.ErrNotFound
+	}
+	err = a.ChatMessageModel.Update(ctx, recordID, item)
+	if err != nil {
+		return nil, err
+	}
+	return a.getUpdate(ctx, recordID)
+}
+
+// Delete 删除数据
+func (a *ChatMessage) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.ChatMessageModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+
+	return a.ChatMessageModel.Delete(ctx, recordID)
+}
+
+// UpdateStatus 更新状态
+func (a *ChatMessage) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.ChatMessageModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.ChatMessageModel.UpdateStatus(ctx, recordID, status)
+}

+ 141 - 0
app/bll/impl/internal/b_chat_session.go

@@ -0,0 +1,141 @@
+package internal
+
+import (
+	"context"
+	"fmt"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/ragflow"
+	"yx-dataset-server/library/redis"
+)
+
+// NewChatSession 创建ChatSession
+func NewChatSession(
+	mChatSession model.IChatSession,
+	mTrans model.ITrans,
+	mAssistant model.IChatAssistant,
+) *ChatSession {
+	return &ChatSession{
+		ChatSessionModel: mChatSession,
+		transModel:       mTrans,
+		assistantModel:   mAssistant,
+	}
+}
+
+// ChatSession 创建ChatSession对象
+type ChatSession struct {
+	ChatSessionModel model.IChatSession
+	transModel       model.ITrans
+	assistantModel   model.IChatAssistant
+}
+
+// Query 查询数据
+func (a *ChatSession) Query(ctx context.Context, params schema.ChatSessionQueryParam, opts ...schema.ChatSessionQueryOptions) (*schema.ChatSessionQueryResult, error) {
+	return a.ChatSessionModel.Query(ctx, params, opts...)
+}
+
+// Get 查询指定数据
+func (a *ChatSession) Get(ctx context.Context, recordID string, opts ...schema.ChatSessionQueryOptions) (*schema.ChatSession, error) {
+	item, err := a.ChatSessionModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	return item, nil
+}
+
+func (a *ChatSession) getUpdate(ctx context.Context, recordID string) (*schema.ChatSession, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *ChatSession) Create(ctx context.Context, item schema.ChatSession) (*schema.ChatSession, error) {
+	item.RecordID = guid.S()
+	item.CreatorId = GetUserID(ctx)
+	name := "new_session"
+	if item.Name != "" {
+		name = item.Name
+	}
+	assistant, err := a.assistantModel.Get(ctx, item.AssistantId)
+	if err != nil {
+		return nil, err
+	}
+
+	s, err := ragflow.GetHttpClient().CreateSession(ctx, assistant.RagChatId, &ragflow.CreateSessionReq{
+		Name: name,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	item.RagSessionId = s.Data.Id
+	err = a.ChatSessionModel.Create(ctx, item)
+	if err != nil {
+		return nil, err
+	}
+	key := fmt.Sprintf("chat:session:%s", item.RecordID)
+	_ = redis.GetClient().Set(ctx, key, item, 8640000)
+
+	return a.getUpdate(ctx, item.RecordID)
+}
+
+// Update 更新数据
+func (a *ChatSession) Update(ctx context.Context, recordID string, item schema.ChatSession) (*schema.ChatSession, error) {
+	oldItem, err := a.ChatSessionModel.Get(ctx, recordID)
+	if err != nil {
+		return nil, err
+	} else if oldItem == nil {
+		return nil, errors.ErrNotFound
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.ChatSessionModel.Update(ctx, recordID, item)
+		if err != nil {
+			return err
+		}
+
+		if oldItem.Name != item.Name {
+			_, err = ragflow.GetHttpClient().UpdateSession(ctx, oldItem.RagChatId, oldItem.RagSessionId, &ragflow.UpdateSessionReq{
+				Name: item.Name,
+			})
+			if err != nil {
+				return err
+			}
+		}
+		return nil
+	})
+
+	return a.getUpdate(ctx, recordID)
+}
+
+// Delete 删除数据
+func (a *ChatSession) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.ChatSessionModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.ChatSessionModel.Delete(ctx, recordID)
+		if err != nil {
+			return err
+		}
+		_, err = ragflow.GetHttpClient().DeleteSessions(ctx, oldItem.RagChatId, []string{oldItem.RagSessionId})
+		return err
+	})
+	return err
+}
+
+// UpdateStatus 更新状态
+func (a *ChatSession) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.ChatSessionModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.ChatSessionModel.UpdateStatus(ctx, recordID, status)
+}

+ 133 - 0
app/bll/impl/internal/b_common.go

@@ -0,0 +1,133 @@
+package internal
+
+import (
+	"bufio"
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"regexp"
+	"strings"
+	iContext "yx-dataset-server/app/context"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/ragflow"
+	"yx-dataset-server/library/utils"
+)
+
+// TransFunc 定义事务执行函数
+type TransFunc func(context.Context) error
+
+// GetRootUser 获取root用户
+func GetRootUser() *schema.User {
+	return &schema.User{
+		RecordID: utils.GetConfig("root.user_name").String(),
+		UserName: utils.GetConfig("root.user_name").String(),
+		RealName: utils.GetConfig("root.real_name").String(),
+		Photo:    utils.GetConfig("root.photo").String(),
+		Password: utils.MD5HashString(utils.GetConfig("root.password").String()),
+	}
+}
+
+// GetUserID 获取用户ID
+func GetUserID(ctx context.Context) string {
+	userID, _ := iContext.FromUserID(ctx)
+	return userID
+}
+
+// CheckIsRootUser 检查是否是root用户
+func CheckIsRootUser(ctx context.Context) bool {
+	userId := GetUserID(ctx)
+	return GetRootUser().RecordID == userId
+}
+
+// ExecTrans 执行事务
+func ExecTrans(ctx context.Context, transModel model.ITrans, fn TransFunc) error {
+	if _, ok := iContext.FromTrans(ctx); ok {
+		return fn(ctx)
+	}
+	trans, err := transModel.Begin(ctx)
+	if err != nil {
+		return err
+	}
+
+	defer func() {
+		if r := recover(); r != nil {
+			_ = transModel.Rollback(ctx, trans)
+			panic(r)
+		}
+	}()
+
+	err = fn(iContext.NewTrans(ctx, trans))
+	if err != nil {
+		_ = transModel.Rollback(ctx, trans)
+		return err
+	}
+	return transModel.Commit(ctx, trans)
+
+}
+
+// ExecTransWithLock 执行事务(加锁)
+func ExecTransWithLock(ctx context.Context, transModel model.ITrans, fn TransFunc) error {
+	if !iContext.FromTransLock(ctx) {
+		ctx = iContext.NewTransLock(ctx)
+	}
+	return ExecTrans(ctx, transModel, fn)
+}
+
+func CollectStreamDataAndCreate(ctx context.Context, stream io.ReadCloser, item *schema.ChatMessage) (*schema.ChatMessage, error) {
+	// 解决 token too long 报错:调大缓冲区到 10MB
+	const maxBufferSize = 10 * 1024 * 1024
+	scanner := bufio.NewScanner(stream)
+	buf := make([]byte, maxBufferSize)
+	scanner.Buffer(buf, maxBufferSize)
+
+	// 用于拼接答案
+	var fullAnswer strings.Builder
+	// 用于存储最终完整结果
+	finalResp := &ragflow.ChatCompletionResp{}
+
+	re := regexp.MustCompile(`\[ID:\d+\]`)
+
+	// 逐行读取流式返回
+	for scanner.Scan() {
+		line := strings.TrimSpace(scanner.Text())
+		if line == "" {
+			continue
+		}
+
+		// 只处理 SSE 格式 data: ...
+		if !strings.HasPrefix(line, "data:") {
+			continue
+		}
+		jsonStr := strings.TrimPrefix(line, "data:")
+		jsonStr = strings.TrimSpace(jsonStr)
+
+		// 流结束标记:data: true
+		if jsonStr == "true" {
+			break
+		}
+
+		// 解析当前分片
+		var chunk ragflow.ChatCompletionResp
+		if err := json.Unmarshal([]byte(jsonStr), &chunk); err != nil {
+			continue
+		}
+		// 拼接回答内容
+		if chunk.Data.Answer != "" {
+			cleanAnswer := re.ReplaceAllString(chunk.Data.Answer, "")
+			fullAnswer.WriteString(cleanAnswer)
+		}
+		// 保存最后一个分片(包含 reference/session_id 等完整信息)
+		*finalResp = chunk
+	}
+
+	if err := scanner.Err(); err != nil {
+		return nil, errors.New400Response(fmt.Sprintf("读取流式数据失败: %v", err))
+	}
+
+	cleanedFullAnswer := re.ReplaceAllString(fullAnswer.String(), "")
+	item.Answer = cleanedFullAnswer
+	return item, nil
+}

+ 184 - 0
app/bll/impl/internal/b_dataset.go

@@ -0,0 +1,184 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/ragflow"
+)
+
+// NewDataset 创建Dataset
+func NewDataset(
+	mDataset model.IDataset,
+	mFile model.IDatasetFile,
+	mTrans model.ITrans,
+	mUser model.IUser,
+) *Dataset {
+	return &Dataset{
+		DatasetModel: mDataset,
+		fileModel:    mFile,
+		transModel:   mTrans,
+		userModel:    mUser,
+	}
+}
+
+// Dataset 创建Dataset对象
+type Dataset struct {
+	DatasetModel model.IDataset
+	fileModel    model.IDatasetFile
+	transModel   model.ITrans
+	userModel    model.IUser
+}
+
+// Query 查询数据
+func (a *Dataset) Query(ctx context.Context, params schema.DatasetQueryParam, opts ...schema.DatasetQueryOptions) (*schema.DatasetQueryResult, error) {
+	result, err := a.DatasetModel.Query(ctx, params, opts...)
+	if err != nil {
+		return nil, err
+	}
+	user, err := a.userModel.Query(ctx, schema.UserQueryParam{RoleCode: []string{"11", "12"}})
+	if err != nil {
+		return nil, err
+	}
+	result.Data.FillCreator(user.Data)
+	return result, nil
+}
+
+// Get 查询指定数据
+func (a *Dataset) Get(ctx context.Context, recordID string, opts ...schema.DatasetQueryOptions) (*schema.Dataset, error) {
+	item, err := a.DatasetModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	file, err := a.fileModel.Query(ctx, schema.DatasetFileQueryParam{DatasetId: recordID})
+	if len(file.Data) > 0 {
+		item.Files = file.Data
+	}
+	return item, nil
+}
+
+func (a *Dataset) getUpdate(ctx context.Context, recordID string) (*schema.Dataset, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *Dataset) Create(ctx context.Context, item schema.Dataset) error {
+	item.RecordID = guid.S()
+	//item.Sequence = 0
+	//sequence, err := a.DatasetModel.GetMaxSequence(ctx)
+	//if err != nil {
+	//	return err
+	//}
+	//if sequence > 0 {
+	//	item.Sequence = sequence + 1
+	//}
+
+	item.CreatorId = GetUserID(ctx)
+	if !CheckIsRootUser(ctx) {
+		user, err := a.userModel.Get(ctx, GetUserID(ctx))
+		if err != nil {
+			return err
+		}
+		item.OrgId = user.OrgId
+	}
+
+	data, err := ragflow.GetHttpClient().CreateDataset(ctx, &ragflow.CreateDatasetReq{
+		Name:           item.Name,
+		ChunkMethod:    "naive",
+		EmbeddingModel: "text-embedding-v4@Tongyi-Qianwen",
+	})
+	if err != nil {
+		return err
+	}
+
+	item.RagDataId = data.Data.ID
+
+	_, err = ragflow.GetHttpClient().UpdateDataset(ctx, item.RagDataId, &ragflow.UpdateDatasetReq{
+		Language: "Chinese",
+	})
+	if err != nil {
+		return err
+	}
+
+	return a.DatasetModel.Create(ctx, item)
+}
+
+// Update 更新数据
+func (a *Dataset) Update(ctx context.Context, recordID string, item schema.Dataset) error {
+	oldItem, err := a.DatasetModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	if item.Name != oldItem.Name {
+		_, err = ragflow.GetHttpClient().UpdateDataset(ctx, item.RagDataId, &ragflow.UpdateDatasetReq{
+			Name:        item.Name,
+			ChunkMethod: "naive",
+		})
+		if err != nil {
+			return err
+		}
+	}
+	err = a.DatasetModel.Update(ctx, recordID, item)
+
+	return err
+}
+
+// Delete 删除数据
+func (a *Dataset) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.DatasetModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.fileModel.DeleteByDatasetIds(ctx, []string{recordID})
+		if err != nil {
+			return err
+		}
+		err = a.DatasetModel.Delete(ctx, recordID)
+		if err != nil {
+			return err
+		}
+		_, err = ragflow.GetHttpClient().DeleteDataset(ctx, []string{oldItem.RagDataId})
+
+		return err
+	})
+	return err
+}
+
+// UpdateStatus 更新状态
+func (a *Dataset) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.DatasetModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.DatasetModel.UpdateStatus(ctx, recordID, status)
+}
+
+// UpdateSequence 更新排序
+//func (a *Dataset) UpdateSequence(ctx context.Context, recordID string, sequence int) error {
+//	item, err := a.DatasetModel.Get(ctx, recordID)
+//	if err != nil {
+//		return err
+//	} else if item == nil {
+//		return errors.ErrNotFound
+//	}
+//	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+//		err = a.DatasetModel.UpdateBatchSequenceMinus(ctx, item.Sequence, sequence)
+//		if err != nil {
+//			return err
+//		}
+//		return a.DatasetModel.UpdateSequence(ctx, recordID, sequence)
+//	})
+//	return err
+//}

+ 220 - 0
app/bll/impl/internal/b_dataset_file.go

@@ -0,0 +1,220 @@
+package internal
+
+import (
+	"context"
+	"fmt"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/ragflow"
+)
+
+// NewDatasetFile 创建DatasetFile
+func NewDatasetFile(
+	mDatasetFile model.IDatasetFile,
+	mDataset model.IDataset,
+	mTrans model.ITrans,
+	mUser model.IUser,
+) *DatasetFile {
+	return &DatasetFile{
+		DatasetFileModel: mDatasetFile,
+		datasetModel:     mDataset,
+		transModel:       mTrans,
+		userModel:        mUser,
+	}
+}
+
+// DatasetFile 创建DatasetFile对象
+type DatasetFile struct {
+	DatasetFileModel model.IDatasetFile
+	datasetModel     model.IDataset
+	transModel       model.ITrans
+	userModel        model.IUser
+}
+
+// Query 查询数据
+func (a *DatasetFile) Query(ctx context.Context, params schema.DatasetFileQueryParam, opts ...schema.DatasetFileQueryOptions) (*schema.DatasetFileQueryResult, error) {
+	result, err := a.DatasetFileModel.Query(ctx, params, opts...)
+	if err != nil {
+		return nil, err
+	}
+	if len(result.Data) > 0 {
+		user, err := a.userModel.Query(ctx, schema.UserQueryParam{RoleCode: []string{"11", "12"}})
+		if err != nil {
+			return nil, err
+		}
+		result.Data.FillCreator(user.Data)
+	}
+
+	return result, nil
+}
+
+// Get 查询指定数据
+func (a *DatasetFile) Get(ctx context.Context, recordID string, opts ...schema.DatasetFileQueryOptions) (*schema.DatasetFile, error) {
+	item, err := a.DatasetFileModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	return item, nil
+}
+
+func (a *DatasetFile) getUpdate(ctx context.Context, recordID string) (*schema.DatasetFile, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *DatasetFile) Create(ctx context.Context, item schema.DatasetFile) error {
+	item.RecordID = guid.S()
+
+	err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		dataset, err := a.datasetModel.Get(ctx, item.DatasetId)
+		if err != nil {
+			return err
+		}
+
+		err = a.DatasetFileModel.Create(ctx, item)
+		if err != nil {
+			return err
+		}
+
+		dataset.FileCount += 1
+		err = a.datasetModel.Update(ctx, dataset.RecordID, *dataset)
+		if err != nil {
+			return err
+		}
+		fileInfo := ragflow.FileInfo{
+			FileName: item.Name,
+			Url:      fmt.Sprintf("%s%s", "https://app.yongxulvjian.com", item.Url),
+		}
+		req := ragflow.UploadFileReq{
+			File: []*ragflow.FileInfo{&fileInfo},
+		}
+		file, err := ragflow.GetHttpClient().UploadDocument(ctx, dataset.RagDataId, req)
+		if err != nil {
+			return errors.New(fmt.Sprintf("文件上传失败:%s", err.Error()))
+		}
+
+		//go func() {
+		//	_, err = ragflow.GetHttpClient().ParseDocuments(ctx, dataset.RagDataId, []string{file.Data[0].ID})
+		//	if err != nil {
+		//		glog.Errorf(ctx, "文件解析失败:%s", err.Error())
+		//	}
+		//}()
+		item.RagFileId = file.Data[0].ID
+		return a.DatasetFileModel.Update(ctx, item.RecordID, item)
+	})
+
+	return err
+}
+
+// BatchCreate 批量创建数据
+func (a *DatasetFile) BatchCreate(ctx context.Context, files schema.DatasetFiles) error {
+	if len(files) == 0 {
+		return errors.New("文件不能为空")
+	}
+	for _, v := range files {
+		err := a.Create(ctx, *v)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// Update 更新数据
+func (a *DatasetFile) Update(ctx context.Context, recordID string, item schema.DatasetFile) error {
+	oldItem, err := a.DatasetFileModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.DatasetFileModel.Update(ctx, recordID, item)
+}
+
+// Delete 删除数据
+func (a *DatasetFile) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.DatasetFileModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	dataset, err := a.datasetModel.Get(ctx, oldItem.DatasetId)
+	if err != nil {
+		return err
+	}
+	if dataset == nil || dataset.RagDataId == "" {
+		return errors.New("知识库不存在")
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		dataset, err := a.datasetModel.Get(ctx, oldItem.DatasetId)
+		if err != nil {
+			return err
+		}
+		dataset.FileCount -= 1
+		err = a.datasetModel.Update(ctx, dataset.RecordID, *dataset)
+		if err != nil {
+			return err
+		}
+
+		_, err = ragflow.GetHttpClient().DeleteDocuments(ctx, dataset.RagDataId, []string{oldItem.RagFileId})
+		if err != nil {
+			return err
+		}
+		return a.DatasetFileModel.Delete(ctx, recordID)
+	})
+	return err
+}
+
+// UpdateStatus 更新状态
+func (a *DatasetFile) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.DatasetFileModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.DatasetFileModel.UpdateStatus(ctx, recordID, status)
+}
+
+// UpdateEnabled 更新启用状态
+func (a *DatasetFile) UpdateEnabled(ctx context.Context, recordID string, status bool) error {
+	oldItem, err := a.DatasetFileModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.DatasetFileModel.UpdateEnabled(ctx, recordID, status)
+}
+
+// BatchDelete 批量删除
+func (a *DatasetFile) BatchDelete(ctx context.Context, fileIDs []string) error {
+	if len(fileIDs) == 0 {
+		return errors.New("文件不能为空")
+	}
+	file, err := a.DatasetFileModel.Query(ctx, schema.DatasetFileQueryParam{RecordIDs: fileIDs})
+	if err != nil {
+		return err
+	}
+	if len(file.Data) == 0 {
+		return nil
+	}
+
+	dataset, err := a.datasetModel.Get(ctx, file.Data[0].DatasetId)
+	if err != nil {
+		return err
+	}
+
+	_, err = ragflow.GetHttpClient().DeleteDocuments(ctx, dataset.RagDataId, file.Data.ToRagFileIds())
+	if err != nil {
+		return err
+	}
+
+	return a.DatasetFileModel.BatchDelete(ctx, fileIDs)
+}

+ 113 - 0
app/bll/impl/internal/b_file.go

@@ -0,0 +1,113 @@
+package internal
+
+import (
+	"bytes"
+	"context"
+	"filesdk"
+	"fmt"
+	"github.com/gogf/gf/v2/os/glog"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/logger"
+	"yx-dataset-server/library/minio"
+	"yx-dataset-server/library/utils"
+
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+)
+
+// NewFile 创建文件管理实例
+func NewFile() *File {
+	return &File{}
+}
+
+// File 文件管理
+type File struct{}
+
+// Upload 上传文件
+func (a *File) Upload(ctx context.Context, r *http.Request, formKey, bucket string) (*schema.FileInfo, error) {
+	file, header, err := r.FormFile(formKey)
+	if err != nil {
+		return nil, err
+	}
+	buff := new(bytes.Buffer)
+	_, err = io.Copy(buff, file)
+	if err != nil {
+		return nil, err
+	}
+	headers := map[string]string{}
+	headers["FILE-EXPIRE"] = utils.GetConfig("file_server.file-expire").String()
+	result, err := filesdk.GetHandle().Upload(header.Filename, bucket, headers, buff.Bytes())
+	if err != nil {
+		glog.Debugf(ctx, "上传文件失败:%s", err.Error())
+		return nil, err
+	}
+	err = filesdk.GetHandle().HandlePersistent(result.Hash)
+	if err != nil {
+		logger.Printf(ctx, "文件持久化设置失败:%s", err.Error())
+	}
+	//uuid := guid.S()
+	//ctx = fuh.NewFileNameContext(ctx, func(ctx fuh.ContextInfo) string {
+	//	return fmt.Sprintf("%s/%s/%s/%s", ctx.BasePath(), strings.ToLower(bucket), uuid, a.getFileName(ctx.FileName()))
+	//})
+	//infos, err := fuh.Upload(ctx, r, formKey)
+	//if err != nil {
+	//	return nil, err
+	//} else if len(infos) == 0 {
+	//	return nil, nil
+	//}
+	//
+	//fullName := fmt.Sprintf("%s/%s/%s/%s", utils.GetConfig("file_upload.prefix"), strings.ToLower(bucket), uuid, url.PathEscape(a.getFileName(infos[0].Name())))
+	//if fullName[0] != '/' {
+	//	fullName = "/" + fullName
+	//}
+
+	info := &schema.FileInfo{
+		URL:  result.URL,
+		Name: result.Name,
+		Size: result.Size,
+		MD5:  result.Hash,
+	}
+
+	return info, nil
+}
+
+// Download 下载文件
+func (a *File) Download(ctx context.Context, fileUrl string) ([]byte, string, error) {
+	Url, err := url.PathUnescape(fileUrl)
+	if err != nil {
+		return nil, "", err
+	}
+	stat, err := minio.GetClient().Stat(Url)
+	if err != nil {
+		fmt.Println("文件不存在")
+		return nil, "", err
+	}
+	fileData, err := a.getSourceFileData(ctx, Url)
+	if err != nil {
+		return nil, "", err
+	}
+
+	return fileData, stat.ContentType, nil
+
+}
+
+func (a *File) getSourceFileData(ctx context.Context, file string) ([]byte, error) {
+	var fileData []byte
+	obj, err := minio.GetClient().Get(ctx, file)
+	if err != nil {
+		return nil, err
+	}
+	buf := new(bytes.Buffer)
+	_, _ = io.Copy(buf, obj)
+
+	_ = obj.Close()
+	fileData = buf.Bytes()
+	return fileData, nil
+}
+
+// 修正文件名,将半角 % 替换为全角 %(不替换的话文件将无法从浏览器中打开)
+func (a *File) getFileName(fileName string) string {
+	return strings.ReplaceAll(fileName, "%", "%")
+}

+ 218 - 0
app/bll/impl/internal/b_login.go

@@ -0,0 +1,218 @@
+package internal
+
+import (
+	"context"
+	"strings"
+	"yx-dataset-server/app/bll"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/auth"
+	"yx-dataset-server/library/utils"
+
+	"github.com/LyricTian/captcha"
+	"net/http"
+)
+
+// NewLogin 创建Login
+func NewLogin(
+	Auth auth.Auther,
+	user model.IUser,
+	verifyCode bll.IVerifyCode,
+	mTransModel model.ITrans,
+	mLoginHis model.ILoginHistory,
+) *Login {
+	return &Login{
+		auth:          Auth,
+		userModel:     user,
+		verifyCodeBll: verifyCode,
+		transModel:    mTransModel,
+		loginHisModel: mLoginHis,
+	}
+}
+
+// Login 创建Login对象
+type Login struct {
+	auth          auth.Auther
+	userModel     model.IUser
+	verifyCodeBll bll.IVerifyCode
+	transModel    model.ITrans
+	loginHisModel model.ILoginHistory
+}
+
+// GetCaptchaID 获取图形验证码信息
+func (a *Login) GetCaptchaID(ctx context.Context, length int) (*schema.LoginCaptcha, error) {
+	captchaID := captcha.NewLen(length)
+	item := &schema.LoginCaptcha{
+		CaptchaID: captchaID,
+	}
+	return item, nil
+}
+
+// ResCaptcha 生成并响应图形验证码
+func (a *Login) ResCaptcha(ctx context.Context, w http.ResponseWriter, captchaID string, width, height int) error {
+	err := captcha.WriteImage(w, captchaID, width, height)
+	if err != nil {
+		return err
+	}
+	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+	w.Header().Set("Pragma", "no-cache")
+	w.Header().Set("Expires", "0")
+	w.Header().Set("Content-Type", "image/png")
+	return nil
+}
+
+// GenerateToken 生成令牌
+func (a *Login) GenerateToken(ctx context.Context, userID string) (*schema.LoginTokenInfo, error) {
+	tokenInfo, err := a.auth.GenerateToken(userID)
+	if err != nil {
+		return nil, errors.New400Response("生成令牌发生错误")
+	}
+
+	item := &schema.LoginTokenInfo{
+		AccessToken: tokenInfo.GetAccessToken(),
+		TokenType:   tokenInfo.GetTokenType(),
+		ExpiresAt:   tokenInfo.GetExpiresAt(),
+	}
+	return item, nil
+}
+
+// DestroyToken 销毁令牌
+func (a *Login) DestroyToken(ctx context.Context, tokenString string) error {
+	err := a.auth.DestroyToken(tokenString)
+	if err != nil {
+		return errors.WithStack(err)
+	}
+	return nil
+}
+
+// RefreshToken 刷新令牌
+func (a *Login) RefreshToken(ctx context.Context) (*schema.LoginTokenInfo, error) {
+	userid := GetUserID(ctx)
+	if userid == "" {
+		return nil, errors.ErrInvalidToken
+	}
+	token, err := a.GenerateToken(ctx, userid)
+	if err != nil {
+		return nil, errors.New400Response("刷新令牌发生错误")
+	}
+	return token, nil
+}
+
+// Verify 登录验证
+func (a *Login) Verify(ctx context.Context, userName, password string) (*schema.User, error) {
+	// 检查是否是超级用户
+	root := GetRootUser()
+	if userName == root.UserName && root.Password == password {
+		return root, nil
+	}
+
+	result, err := a.userModel.Query(ctx, schema.UserQueryParam{
+		UserName: userName,
+	})
+	if err != nil {
+		return nil, err
+	} else if len(result.Data) == 0 {
+		return nil, errors.ErrInvalidUserName
+	}
+	item := result.Data[0]
+	if item.Password != utils.SHA1HashString(strings.ToUpper(password)) {
+		return nil, errors.ErrInvalidPassword
+	} else if !item.Status {
+		return nil, errors.ErrInvalidUser
+	}
+
+	return item, nil
+}
+
+// GetUserInfo 获取当前用户登录信息
+func (a *Login) GetUserInfo(ctx context.Context) (*schema.UserLoginInfo, error) {
+	userID := GetUserID(ctx)
+	if isRoot := CheckIsRootUser(ctx); isRoot {
+		root := GetRootUser()
+		loginInfo := &schema.UserLoginInfo{
+			UserName: root.UserName,
+			RealName: root.RealName,
+			Photo:    root.Photo,
+		}
+		return loginInfo, nil
+	}
+
+	user, err := a.userModel.Get(ctx, userID)
+	if err != nil {
+		return nil, err
+	} else if user == nil {
+		return nil, errors.ErrInvalidUser
+	} else if user.Status {
+		return nil, errors.ErrUserDisable
+	}
+
+	loginInfo := &schema.UserLoginInfo{
+		UserName: user.UserName,
+		RealName: user.RealName,
+	}
+
+	return loginInfo, nil
+}
+
+func (a *Login) getAndCheckUser(ctx context.Context, userID string, opts ...schema.UserOptions) (*schema.User, error) {
+	user, err := a.userModel.Get(ctx, userID, opts...)
+	if err != nil {
+		return nil, err
+	} else if user == nil {
+		return nil, errors.ErrInvalidUser
+	} else if user.Status {
+		return nil, errors.ErrUserDisable
+	}
+	return user, nil
+}
+
+// UpdatePassword 更新当前用户登录密码
+func (a *Login) UpdatePassword(ctx context.Context, params schema.UpdatePasswordParam) error {
+	userID := GetUserID(ctx)
+	if CheckIsRootUser(ctx) {
+		return errors.New400Response("超级管理员密码只能通过配置文件修改")
+	}
+	if params.OldPassword == "" {
+		return errors.ErrUserNotEmptyPwd
+	}
+	user, err := a.getAndCheckUser(ctx, userID)
+	if err != nil {
+		return err
+	} else if utils.SHA1HashString(strings.ToUpper(params.OldPassword)) != user.Password {
+		return errors.ErrLoginInvalidOldPwd
+	}
+
+	params.NewPassword = utils.SHA1HashString(strings.ToUpper(params.NewPassword))
+	return a.userModel.UpdatePassword(ctx, userID, params.NewPassword)
+}
+
+// Unsubscribe 用户注销
+func (a *Login) Unsubscribe(ctx context.Context, userId, tokenStr string) error {
+	err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err := a.userModel.Delete(ctx, userId)
+		if err != nil {
+			return err
+		}
+
+		return a.DestroyToken(ctx, tokenStr)
+	})
+	return err
+}
+
+// LoginBySms 通过短信验证码登录
+func (a *Login) LoginBySms(ctx context.Context, params schema.SmsLoginParam) error {
+
+	checkResult, err := a.verifyCodeBll.Check(ctx, schema.VerifyCodeCheck{
+		Tel:          params.Phone,
+		BusinessType: params.BusinessType,
+		Code:         params.Code,
+	})
+	if err != nil {
+		return err
+	}
+	if !checkResult {
+		return errors.ErrSmsCode
+	}
+	return nil
+}

+ 99 - 0
app/bll/impl/internal/b_login_history.go

@@ -0,0 +1,99 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+)
+
+// NewLoginHistory 创建LoginHistory
+func NewLoginHistory(mLoginHistory model.ILoginHistory) *LoginHistory {
+	return &LoginHistory{
+		LoginHistoryModel: mLoginHistory,
+	}
+}
+
+// LoginHistory 创建LoginHistory对象
+type LoginHistory struct {
+	LoginHistoryModel model.ILoginHistory
+}
+
+// Query 查询数据
+func (a *LoginHistory) Query(ctx context.Context, params schema.LoginHistoryQueryParam, opts ...schema.LoginHistoryQueryOptions) (*schema.LoginHistoryQueryResult, error) {
+	return a.LoginHistoryModel.Query(ctx, params, opts...)
+}
+
+// Get 查询指定数据
+func (a *LoginHistory) Get(ctx context.Context, recordID string, opts ...schema.LoginHistoryQueryOptions) (*schema.LoginHistory, error) {
+	item, err := a.LoginHistoryModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	return item, nil
+}
+
+func (a *LoginHistory) checkCode(ctx context.Context, code string) error {
+	result, err := a.LoginHistoryModel.Query(ctx, schema.LoginHistoryQueryParam{
+		Code: code,
+	}, schema.LoginHistoryQueryOptions{
+		PageParam: &schema.PaginationParam{PageSize: -1},
+	})
+	if err != nil {
+		return err
+	} else if result.PageResult.Total > 0 {
+		return errors.New400Response("编号已经存在")
+	}
+	return nil
+}
+
+func (a *LoginHistory) getUpdate(ctx context.Context, recordID string) (*schema.LoginHistory, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *LoginHistory) Create(ctx context.Context, item schema.LoginHistory) (*schema.LoginHistory, error) {
+	item.RecordID = guid.S()
+	err := a.LoginHistoryModel.Create(ctx, item)
+	if err != nil {
+		return nil, err
+	}
+	return a.getUpdate(ctx, item.RecordID)
+}
+
+// Update 更新数据
+func (a *LoginHistory) Update(ctx context.Context, recordID string, item schema.LoginHistory) error {
+	oldItem, err := a.LoginHistoryModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.LoginHistoryModel.Update(ctx, recordID, item)
+}
+
+// Delete 删除数据
+func (a *LoginHistory) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.LoginHistoryModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+
+	return a.LoginHistoryModel.Delete(ctx, recordID)
+}
+
+// UpdateStatus 更新状态
+func (a *LoginHistory) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.LoginHistoryModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.LoginHistoryModel.UpdateStatus(ctx, recordID, status)
+}

+ 155 - 0
app/bll/impl/internal/b_menu.go

@@ -0,0 +1,155 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+)
+
+// NewMenu 创建Menu
+func NewMenu(
+	mMenu model.IMenu,
+	mTrans model.ITrans,
+	mRoleMenu model.IRoleMenu,
+	mUser model.IUser,
+) *Menu {
+	return &Menu{
+		MenuModel:     mMenu,
+		transModel:    mTrans,
+		roleMenuModel: mRoleMenu,
+		userModel:     mUser,
+	}
+}
+
+// Menu 创建Menu对象
+type Menu struct {
+	MenuModel     model.IMenu
+	transModel    model.ITrans
+	roleMenuModel model.IRoleMenu
+	userModel     model.IUser
+}
+
+// Query 查询数据
+func (a *Menu) Query(ctx context.Context, params schema.MenuQueryParam, opts ...schema.MenuQueryOptions) (*schema.MenuQueryResult, error) {
+	var menuQueryParam schema.MenuQueryParam
+	userID := GetUserID(ctx)
+	user, err := a.userModel.Get(ctx, userID)
+	if err != nil {
+		return nil, err
+	}
+	if !CheckIsRootUser(ctx) {
+		roleMenu, err := a.roleMenuModel.Query(ctx, schema.RoleMenuQueryParam{RoleId: user.RoleId})
+		if err != nil {
+			return nil, err
+		}
+		menuQueryParam.RecordIDs = roleMenu.Data.ToMenuIds()
+	}
+	menu, err := a.MenuModel.Query(ctx, menuQueryParam)
+	if err != nil {
+		return nil, err
+	}
+	return menu, nil
+}
+
+// QueryTree 查询数据
+func (a *Menu) QueryTree(ctx context.Context, params schema.MenuQueryParam, opts ...schema.MenuQueryOptions) (schema.MenuTrees, error) {
+	var menuQueryParam schema.MenuQueryParam
+	userID := GetUserID(ctx)
+	user, err := a.userModel.Get(ctx, userID)
+	if err != nil {
+		return nil, err
+	}
+	if !CheckIsRootUser(ctx) {
+		roleMenu, err := a.roleMenuModel.Query(ctx, schema.RoleMenuQueryParam{RoleId: user.RoleId})
+		if err != nil {
+			return nil, err
+		}
+		menuQueryParam.RecordIDs = roleMenu.Data.ToMenuIds()
+	}
+	menu, err := a.MenuModel.Query(ctx, menuQueryParam)
+	if err != nil {
+		return nil, err
+	}
+	return schema.ToTree(menu.Data.ToTrees(), ""), nil
+}
+
+// Get 查询指定数据
+func (a *Menu) Get(ctx context.Context, recordID string, opts ...schema.MenuQueryOptions) (*schema.Menu, error) {
+	item, err := a.MenuModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	return item, nil
+}
+
+func (a *Menu) getUpdate(ctx context.Context, recordID string) (*schema.Menu, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *Menu) Create(ctx context.Context, item schema.Menu) error {
+	item.RecordID = guid.S()
+	sequence, err := a.MenuModel.GetMaxSequence(ctx)
+	if err != nil {
+		return err
+	}
+	if sequence > 0 {
+		item.Sequence = sequence + 1
+	}
+	return a.MenuModel.Create(ctx, item)
+}
+
+// Update 更新数据
+func (a *Menu) Update(ctx context.Context, recordID string, item schema.Menu) error {
+	oldItem, err := a.MenuModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.MenuModel.Update(ctx, recordID, item)
+}
+
+// Delete 删除数据
+func (a *Menu) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.MenuModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+
+	return a.MenuModel.Delete(ctx, recordID)
+}
+
+func (a *Menu) UpdateSequence(ctx context.Context, recordID string, sequence int) error {
+	item, err := a.MenuModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if item == nil {
+		return errors.ErrNotFound
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.MenuModel.UpdateBatchSequenceMinus(ctx, item.Sequence, sequence)
+		if err != nil {
+			return err
+		}
+		return a.MenuModel.UpdateSequence(ctx, recordID, sequence)
+	})
+	return err
+}
+
+// UpdateStatus 更新状态
+func (a *Menu) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.MenuModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.MenuModel.UpdateStatus(ctx, recordID, status)
+}

+ 164 - 0
app/bll/impl/internal/b_organization.go

@@ -0,0 +1,164 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/redis"
+)
+
+// NewOrganization 创建Organization
+func NewOrganization(
+	mTrans model.ITrans,
+	mOrganization model.IOrganization,
+	mFile model.IDatasetFile,
+	mDataset model.IDataset,
+	mUser model.IUser,
+	mRole model.IRole,
+) *Organization {
+	return &Organization{
+		transModel:        mTrans,
+		organizationModel: mOrganization,
+		fileModel:         mFile,
+		datasetModel:      mDataset,
+		userModel:         mUser,
+		roleModel:         mRole,
+	}
+}
+
+// Organization 创建Organization对象
+type Organization struct {
+	organizationModel model.IOrganization
+	transModel        model.ITrans
+	fileModel         model.IDatasetFile
+	datasetModel      model.IDataset
+	userModel         model.IUser
+	roleModel         model.IRole
+}
+
+// Query 查询数据
+func (a *Organization) Query(ctx context.Context, params schema.OrganizationQueryParam, opts ...schema.OrganizationQueryOptions) (*schema.OrganizationQueryResult, error) {
+	if !CheckIsRootUser(ctx) {
+		user, err := a.userModel.Get(ctx, GetUserID(ctx))
+		if err != nil {
+			return nil, err
+		}
+		role, err := a.roleModel.Get(ctx, user.RoleId)
+		if err != nil {
+			return nil, err
+		}
+		if role.Code != "11" {
+			params.RecordIds = []string{user.OrgId}
+		}
+	}
+
+	result, err := a.organizationModel.Query(ctx, params, opts...)
+	if err != nil {
+		return nil, err
+	}
+	if len(result.Data) > 0 {
+		user, err := a.userModel.Query(ctx, schema.UserQueryParam{RecordIDs: result.Data.ToUserIds()})
+		if err != nil {
+			return nil, err
+		}
+		result.Data.FillCreator(user.Data)
+	}
+	for _, v := range result.Data {
+		v.Used, _ = redis.GetRedisClient().Get(ctx, "chart:organization:"+v.RecordID).Int()
+		v.Unused = v.ChartNum - v.Used
+
+	}
+
+	return result, nil
+}
+
+// Get 查询指定数据
+func (a *Organization) Get(ctx context.Context, recordID string, opts ...schema.OrganizationQueryOptions) (*schema.Organization, error) {
+	item, err := a.organizationModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	user, err := a.userModel.Get(ctx, item.CreatorId)
+	if err != nil {
+		return nil, err
+	}
+	item.CreatorName = user.RealName
+
+	item.Used, _ = redis.GetRedisClient().Get(ctx, "chart:organization:"+item.RecordID).Int()
+	item.Unused = item.ChartNum - item.Used
+	return item, nil
+}
+
+func (a *Organization) getUpdate(ctx context.Context, recordID string) (*schema.Organization, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *Organization) Create(ctx context.Context, item schema.Organization) error {
+	item.RecordID = guid.S()
+
+	org, err := a.organizationModel.GetByName(ctx, item.Name)
+	if err != nil {
+		return err
+	} else if org != nil {
+		return errors.New("命名重复")
+	}
+	return a.organizationModel.Create(ctx, item)
+}
+
+// Update 更新数据
+func (a *Organization) Update(ctx context.Context, recordID string, item schema.Organization) error {
+	oldItem, err := a.organizationModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.organizationModel.Update(ctx, recordID, item)
+}
+
+// Delete 删除数据
+func (a *Organization) Delete(ctx context.Context, recordID string) error {
+	err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		oldItem, err := a.organizationModel.Get(ctx, recordID)
+		if err != nil {
+			return err
+		} else if oldItem == nil {
+			return errors.ErrNotFound
+		}
+
+		// 删除自建知识库及相关文件
+		dataset, err := a.datasetModel.Query(ctx, schema.DatasetQueryParam{OrgId: recordID})
+		if err != nil {
+			return err
+		}
+		if len(dataset.Data) > 0 {
+			err = a.fileModel.DeleteByDatasetIds(ctx, dataset.Data.ToRecordIds())
+			if err != nil {
+				return err
+			}
+
+			err = a.datasetModel.DeleteByOrgId(ctx, recordID)
+			if err != nil {
+				return err
+			}
+		}
+		return a.organizationModel.Delete(ctx, recordID)
+	})
+	return err
+}
+
+// UpdateStatus 更新状态
+func (a *Organization) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.organizationModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.organizationModel.UpdateStatus(ctx, recordID, status)
+}

+ 282 - 0
app/bll/impl/internal/b_robot_config.go

@@ -0,0 +1,282 @@
+package internal
+
+import (
+	"context"
+	"fmt"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/ragflow"
+	"yx-dataset-server/library/robot"
+)
+
+// NewRobotConfig 创建RobotConfig
+func NewRobotConfig(
+	mRobotConfig model.IRobotConfig,
+	mRobotDataset model.IRobotDataset,
+	mTrans model.ITrans,
+	mChatMessage model.IChatMessage,
+	mChatAssistant model.IChatAssistant,
+	mChatSession model.IChatSession,
+	mChatDataset model.IChatDataset,
+	mUser model.IUser,
+	mDataset model.IDataset,
+) *RobotConfig {
+	return &RobotConfig{
+		RobotConfigModel:   mRobotConfig,
+		robotDatasetModel:  mRobotDataset,
+		transModel:         mTrans,
+		chatMessageModel:   mChatMessage,
+		chatAssistantModel: mChatAssistant,
+		chatSessionModel:   mChatSession,
+		chatDatasetModel:   mChatDataset,
+		userModel:          mUser,
+		datasetModel:       mDataset,
+	}
+}
+
+// RobotConfig 创建RobotConfig对象
+type RobotConfig struct {
+	RobotConfigModel   model.IRobotConfig
+	robotDatasetModel  model.IRobotDataset
+	transModel         model.ITrans
+	chatMessageModel   model.IChatMessage
+	chatAssistantModel model.IChatAssistant
+	chatSessionModel   model.IChatSession
+	chatDatasetModel   model.IChatDataset
+	userModel          model.IUser
+	datasetModel       model.IDataset
+}
+
+// Query 查询数据
+func (a *RobotConfig) Query(ctx context.Context, params schema.RobotConfigQueryParam, opts ...schema.RobotConfigQueryOptions) (*schema.RobotConfigQueryResult, error) {
+	return a.RobotConfigModel.Query(ctx, params, opts...)
+}
+
+// Get 查询指定数据
+func (a *RobotConfig) Get(ctx context.Context, recordID string, opts ...schema.RobotConfigQueryOptions) (*schema.RobotConfig, error) {
+	item, err := a.RobotConfigModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	return item, nil
+}
+
+func (a *RobotConfig) checkCode(ctx context.Context, code string) error {
+	result, err := a.RobotConfigModel.Query(ctx, schema.RobotConfigQueryParam{
+		Code: code,
+	}, schema.RobotConfigQueryOptions{
+		PageParam: &schema.PaginationParam{PageSize: -1},
+	})
+	if err != nil {
+		return err
+	} else if result.PageResult.Total > 0 {
+		return errors.New400Response("编号已经存在")
+	}
+	return nil
+}
+
+func (a *RobotConfig) getUpdate(ctx context.Context, recordID string) (*schema.RobotConfig, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *RobotConfig) Create(ctx context.Context, item schema.RobotConfig) (*schema.RobotConfig, error) {
+	item.RecordID = guid.S()
+	item.CreatorId = GetUserID(ctx)
+	item.AssistantId = guid.S()
+	item.SessionId = guid.S()
+
+	item.Webhook = fmt.Sprintf("%s%s", "http://113.128.186.214:6666/robot/v1/robots/receive/", item.RecordID)
+	user := GetRootUser()
+	var err error
+	if !CheckIsRootUser(ctx) {
+		user, err = a.userModel.Get(ctx, GetUserID(ctx))
+		if err != nil {
+			return nil, err
+		}
+	}
+	// 创建对话助手及会话
+	err = a.createAssistant(ctx, item.AssistantId, item.SessionId, *user, item)
+	if err != nil {
+		return nil, err
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		if len(item.Datasets) > 0 {
+			for _, dataset := range item.Datasets {
+				err := a.robotDatasetModel.Create(ctx, schema.RobotDataset{
+					RecordID:  guid.S(),
+					RobotId:   item.RecordID,
+					DatasetId: dataset.RecordID,
+				})
+				if err != nil {
+					return err
+				}
+			}
+			return a.RobotConfigModel.Create(ctx, item)
+		}
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+	return a.getUpdate(ctx, item.RecordID)
+}
+
+// Update 更新数据
+func (a *RobotConfig) Update(ctx context.Context, recordID string, item schema.RobotConfig) (*schema.RobotConfig, error) {
+	oldItem, err := a.RobotConfigModel.Get(ctx, recordID)
+	if err != nil {
+		return nil, err
+	} else if oldItem == nil {
+		return nil, errors.ErrNotFound
+	}
+	err = a.RobotConfigModel.Update(ctx, recordID, item)
+	if err != nil {
+		return nil, err
+	}
+	return a.getUpdate(ctx, recordID)
+}
+
+// Delete 删除数据
+func (a *RobotConfig) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.RobotConfigModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+
+	return a.RobotConfigModel.Delete(ctx, recordID)
+}
+
+// UpdateStatus 更新状态
+func (a *RobotConfig) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.RobotConfigModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.RobotConfigModel.UpdateStatus(ctx, recordID, status)
+}
+
+func (a *RobotConfig) ReceiveMessage(ctx context.Context, id string, message robot.DingTalkRobotMessage) error {
+
+	robotConfig, err := a.RobotConfigModel.Get(ctx, id)
+	if err != nil {
+		return err
+	}
+
+	assistant, err := a.chatAssistantModel.Get(ctx, robotConfig.AssistantId)
+	if err != nil {
+		return err
+	}
+
+	session, err := a.chatSessionModel.Get(ctx, robotConfig.SessionId)
+	if err != nil {
+		return err
+	}
+
+	stream, err := ragflow.GetHttpClient().ChatCompletionsStream(ctx, assistant.RagChatId, &ragflow.ChatCompletionReq{
+		Question:  message.Text.Content,
+		SessionID: session.RagSessionId,
+	})
+	if err != nil {
+		return err
+	}
+	defer stream.Close() // 关闭流
+
+	m := new(schema.ChatMessage)
+	m.RecordID = guid.S()
+	m.Question = message.Text.Content
+	m.AssistantId = assistant.RecordID
+	m.SessionId = session.RecordID
+	m.UserId = GetUserID(ctx)
+
+	m, err = CollectStreamDataAndCreate(ctx, stream, m)
+	if err != nil {
+		return err
+	}
+
+	err = a.chatMessageModel.Create(ctx, *m)
+	if err != nil {
+		return err
+	}
+
+	replyMsg := robot.DingReplyMsg{
+		MsgType: "markdown",
+		Markdown: robot.Markdown{
+			Title: m.Question,
+			Text:  m.Answer,
+		},
+	}
+
+	err = robot.SendReplyMsg(message.SessionWebhook, replyMsg)
+	if err != nil {
+		fmt.Println(err)
+		return err
+	}
+	return nil
+}
+
+func (a *RobotConfig) createAssistant(ctx context.Context, assistantId, sessionId string, user schema.User, item schema.RobotConfig) error {
+
+	err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		dataset, err := a.datasetModel.Query(ctx, schema.DatasetQueryParam{RecordIds: item.Datasets.ToRecordIds()})
+		if err != nil {
+			return err
+		}
+
+		c, err := ragflow.GetHttpClient().CreateChat(ctx, &ragflow.CreateChatReq{
+			Name:       fmt.Sprintf("%s%s", item.Name, "助手"),
+			DatasetIDs: dataset.Data.ToRagDataIds(),
+		})
+		if err != nil {
+			return err
+		}
+		err = a.chatAssistantModel.Create(ctx, schema.ChatAssistant{
+			RecordID:  assistantId,
+			OrgId:     user.OrgId,
+			Name:      fmt.Sprintf("%s%s", item.Name, "助手"),
+			RagChatId: c.Data.ID,
+			CreatorId: user.RecordID,
+		})
+		if err != nil {
+			return err
+		}
+
+		if len(item.Datasets) > 0 {
+			for _, v := range item.Datasets {
+				err = a.chatDatasetModel.Create(ctx, schema.ChatDataset{
+					RecordID:        guid.S(),
+					ChatAssistantId: assistantId,
+					DatasetId:       v.RecordID,
+				})
+				if err != nil {
+					return err
+				}
+			}
+		}
+
+		s, err := ragflow.GetHttpClient().CreateSession(ctx, c.Data.ID, &ragflow.CreateSessionReq{
+			Name: fmt.Sprintf("%s%s", item.Name, "会话"),
+		})
+		if err != nil {
+			return err
+		}
+		err = a.chatSessionModel.Create(ctx, schema.ChatSession{
+			RecordID:     sessionId,
+			Name:         fmt.Sprintf("%s%s", item.Name, "会话"),
+			AssistantId:  assistantId,
+			RagSessionId: s.Data.Id,
+			CreatorId:    user.RecordID,
+		})
+
+		return nil
+	})
+	return err
+}

+ 143 - 0
app/bll/impl/internal/b_role.go

@@ -0,0 +1,143 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+)
+
+// NewRole 创建Role
+func NewRole(
+	mRole model.IRole,
+	mRoleMenu model.IRoleMenu,
+	mTrans model.ITrans,
+	mMenu model.IMenu,
+) *Role {
+	return &Role{
+		RoleModel:     mRole,
+		roleMenuModel: mRoleMenu,
+		transModel:    mTrans,
+		menuModel:     mMenu,
+	}
+}
+
+// Role 创建Role对象
+type Role struct {
+	RoleModel     model.IRole
+	roleMenuModel model.IRoleMenu
+	transModel    model.ITrans
+	menuModel     model.IMenu
+}
+
+// Query 查询数据
+func (a *Role) Query(ctx context.Context, params schema.RoleQueryParam, opts ...schema.RoleQueryOptions) (*schema.RoleQueryResult, error) {
+	return a.RoleModel.Query(ctx, params, opts...)
+}
+
+// Get 查询指定数据
+func (a *Role) Get(ctx context.Context, recordID string, opts ...schema.RoleQueryOptions) (*schema.Role, error) {
+	item, err := a.RoleModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	roleMenu, err := a.roleMenuModel.Query(ctx, schema.RoleMenuQueryParam{RoleId: item.RecordID})
+	if err != nil {
+		return nil, err
+	}
+	menu, err := a.menuModel.Query(ctx, schema.MenuQueryParam{RecordIDs: roleMenu.Data.ToMenuIds()})
+	if err != nil {
+		return nil, err
+	}
+	item.Menus = menu.Data
+	return item, nil
+}
+
+func (a *Role) checkCode(ctx context.Context, code string) error {
+	result, err := a.RoleModel.Query(ctx, schema.RoleQueryParam{
+		Code: code,
+	}, schema.RoleQueryOptions{
+		PageParam: &schema.PaginationParam{PageSize: -1},
+	})
+	if err != nil {
+		return err
+	} else if result.PageResult.Total > 0 {
+		return errors.New400Response("编号已经存在")
+	}
+	return nil
+}
+
+func (a *Role) getUpdate(ctx context.Context, recordID string) (*schema.Role, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *Role) Create(ctx context.Context, item schema.Role) error {
+	item.RecordID = guid.S()
+	err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		if len(item.Menus) > 0 {
+			for _, menu := range item.Menus {
+				err := a.roleMenuModel.Create(ctx, schema.RoleMenu{
+					RecordId: guid.S(),
+					RoleId:   item.RecordID,
+					MenuId:   menu.RecordID,
+				})
+				if err != nil {
+					return err
+				}
+			}
+		}
+		return a.RoleModel.Create(ctx, item)
+	})
+	return err
+}
+
+// Update 更新数据
+func (a *Role) Update(ctx context.Context, recordID string, item schema.Role) error {
+	oldItem, err := a.RoleModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.roleMenuModel.DeleteByRoleId(ctx, recordID)
+		if len(item.Menus) > 0 {
+			for _, menu := range item.Menus {
+				err := a.roleMenuModel.Create(ctx, schema.RoleMenu{
+					RecordId: guid.S(),
+					RoleId:   oldItem.RecordID,
+					MenuId:   menu.RecordID,
+				})
+				if err != nil {
+					return err
+				}
+			}
+		}
+		return a.RoleModel.Update(ctx, recordID, item)
+	})
+
+	return err
+}
+
+// Delete 删除数据
+func (a *Role) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.RoleModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.roleMenuModel.DeleteByRoleId(ctx, recordID)
+		if err != nil {
+			return err
+		}
+		return a.RoleModel.Delete(ctx, recordID)
+	})
+	return err
+}

+ 89 - 0
app/bll/impl/internal/b_role_menu.go

@@ -0,0 +1,89 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+)
+
+// NewRoleMenu 创建RoleMenu
+func NewRoleMenu(mRoleMenu model.IRoleMenu) *RoleMenu {
+	return &RoleMenu{
+		RoleMenuModel: mRoleMenu,
+	}
+}
+
+// RoleMenu 创建RoleMenu对象
+type RoleMenu struct {
+	RoleMenuModel model.IRoleMenu
+}
+
+// Query 查询数据
+func (a *RoleMenu) Query(ctx context.Context, params schema.RoleMenuQueryParam, opts ...schema.RoleMenuQueryOptions) (*schema.RoleMenuQueryResult, error) {
+	return a.RoleMenuModel.Query(ctx, params, opts...)
+}
+
+// Get 查询指定数据
+func (a *RoleMenu) Get(ctx context.Context, recordID string, opts ...schema.RoleMenuQueryOptions) (*schema.RoleMenu, error) {
+	item, err := a.RoleMenuModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	return item, nil
+}
+
+func (a *RoleMenu) getUpdate(ctx context.Context, recordID string) (*schema.RoleMenu, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *RoleMenu) Create(ctx context.Context, item schema.RoleMenu) (*schema.RoleMenu, error) {
+	item.RecordId = guid.S()
+	err := a.RoleMenuModel.Create(ctx, item)
+	if err != nil {
+		return nil, err
+	}
+	return a.getUpdate(ctx, item.RecordId)
+}
+
+// Update 更新数据
+func (a *RoleMenu) Update(ctx context.Context, recordID string, item schema.RoleMenu) (*schema.RoleMenu, error) {
+	oldItem, err := a.RoleMenuModel.Get(ctx, recordID)
+	if err != nil {
+		return nil, err
+	} else if oldItem == nil {
+		return nil, errors.ErrNotFound
+	}
+	err = a.RoleMenuModel.Update(ctx, recordID, item)
+	if err != nil {
+		return nil, err
+	}
+	return a.getUpdate(ctx, recordID)
+}
+
+// Delete 删除数据
+func (a *RoleMenu) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.RoleMenuModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+
+	return a.RoleMenuModel.Delete(ctx, recordID)
+}
+
+// UpdateStatus 更新状态
+func (a *RoleMenu) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.RoleMenuModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.RoleMenuModel.UpdateStatus(ctx, recordID, status)
+}

+ 23 - 0
app/bll/impl/internal/b_trans.go

@@ -0,0 +1,23 @@
+package internal
+
+import (
+	"context"
+	"yx-dataset-server/app/model"
+)
+
+// NewTrans 创建事务管理实例
+func NewTrans(trans model.ITrans) *Trans {
+	return &Trans{
+		TransModel: trans,
+	}
+}
+
+// Trans 事务管理
+type Trans struct {
+	TransModel model.ITrans
+}
+
+// Exec 执行事务
+func (a *Trans) Exec(ctx context.Context, fn func(context.Context) error) error {
+	return ExecTrans(ctx, a.TransModel, fn)
+}

+ 234 - 0
app/bll/impl/internal/b_user.go

@@ -0,0 +1,234 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"strings"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/redis"
+	"yx-dataset-server/library/utils"
+)
+
+// NewUser 创建User
+func NewUser(
+	mUser model.IUser,
+	mUserDataset model.IUserDataset,
+	mTrans model.ITrans,
+	mMenu model.IMenu,
+	mRoleMenu model.IRoleMenu,
+	mDataset model.IDataset,
+	mOrganization model.IOrganization,
+	mRole model.IRole,
+) *User {
+	return &User{
+		UserModel:        mUser,
+		userDatasetModel: mUserDataset,
+		transModel:       mTrans,
+		menuModel:        mMenu,
+		roleMenuModel:    mRoleMenu,
+		datasetModel:     mDataset,
+		orgModel:         mOrganization,
+		roleModel:        mRole,
+	}
+}
+
+// User 创建User对象
+type User struct {
+	UserModel        model.IUser
+	userDatasetModel model.IUserDataset
+	transModel       model.ITrans
+	menuModel        model.IMenu
+	roleMenuModel    model.IRoleMenu
+	datasetModel     model.IDataset
+	orgModel         model.IOrganization
+	roleModel        model.IRole
+}
+
+// Query 查询数据
+func (a *User) Query(ctx context.Context, params schema.UserQueryParam, opts ...schema.UserOptions) (*schema.UserQueryResult, error) {
+	result, err := a.UserModel.Query(ctx, params, opts...)
+	if err != nil {
+		return nil, err
+	}
+	result.Data.FillCreator(result.Data)
+	for _, v := range result.Data {
+		v.Used, _ = redis.GetRedisClient().Get(ctx, "chart:user:"+v.RecordID).Int()
+		v.Unused = v.ChartNum - v.Used
+
+	}
+
+	roles, err := a.roleModel.Query(ctx, schema.RoleQueryParam{})
+	if err != nil {
+		return nil, err
+	}
+	result.Data.FillRoleName(roles.Data)
+
+	orgs, err := a.orgModel.Query(ctx, schema.OrganizationQueryParam{})
+	if err != nil {
+		return nil, err
+	}
+	result.Data.FillOrgName(orgs.Data)
+
+	return result, nil
+}
+
+// Get 查询指定数据
+func (a *User) Get(ctx context.Context, recordID string, opts ...schema.UserOptions) (*schema.User, error) {
+	if CheckIsRootUser(ctx) {
+		return a.getRootInfo(ctx)
+	}
+	item, err := a.UserModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+
+	// 查询用户菜单
+	roleMenu, err := a.roleMenuModel.Query(ctx, schema.RoleMenuQueryParam{RoleId: item.RoleId})
+	if err != nil {
+		return nil, err
+	}
+	menus, err := a.menuModel.Query(ctx, schema.MenuQueryParam{RecordIDs: roleMenu.Data.ToMenuIds()})
+	if err != nil {
+		return nil, err
+	}
+	item.Menu = menus.Data.ToTrees()
+
+	role, err := a.roleModel.Get(ctx, item.RoleId)
+	if err != nil {
+		return nil, err
+	}
+	item.RoleName = role.Name
+
+	org, err := a.orgModel.Get(ctx, item.OrgId)
+	if err != nil {
+		return nil, err
+	}
+	item.OrgName = org.Name
+
+	// 查询用户可访问的知识库
+	userDataset, err := a.userDatasetModel.Query(ctx, schema.UserDatasetQueryParam{UserId: recordID})
+	if err != nil {
+		return nil, err
+	}
+	dataset, err := a.datasetModel.Query(ctx, schema.DatasetQueryParam{RecordIds: userDataset.Data.ToDatasetIds()})
+	if err != nil {
+		return nil, err
+	}
+	userDataset.Data.FillDatasetName(dataset.Data)
+
+	item.Datasets = userDataset.Data
+
+	item.Used, _ = redis.GetRedisClient().Get(ctx, "chart:user:"+item.RecordID).Int()
+	item.Unused = item.ChartNum - item.Used
+	return item, nil
+
+}
+
+func (a *User) getUpdate(ctx context.Context, recordID string) (*schema.User, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *User) Create(ctx context.Context, item schema.User) error {
+	item.RecordID = guid.S()
+	item.Status = true
+	item.Password = utils.SHA1HashString(strings.ToUpper(item.Password))
+	err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		if len(item.Datasets) > 0 {
+			for _, v := range item.Datasets {
+				err := a.userDatasetModel.Create(ctx, schema.UserDataset{
+					UserId:    item.RecordID,
+					DatasetId: v.DatasetId,
+					Type:      v.Type,
+				})
+				if err != nil {
+					return err
+				}
+			}
+		}
+
+		return a.UserModel.Create(ctx, item)
+	})
+	return err
+}
+
+// Update 更新数据
+func (a *User) Update(ctx context.Context, recordID string, item schema.User) error {
+	oldItem, err := a.UserModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	if item.Password != "" {
+		item.Password = utils.SHA1HashString(strings.ToUpper(item.Password))
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.userDatasetModel.DeleteByUserId(ctx, recordID)
+		if err != nil {
+			return err
+		}
+		if len(item.Datasets) > 0 {
+			for _, v := range item.Datasets {
+				err := a.userDatasetModel.Create(ctx, schema.UserDataset{
+					UserId:    item.RecordID,
+					DatasetId: v.DatasetId,
+					Type:      v.Type,
+				})
+				if err != nil {
+					return err
+				}
+			}
+		}
+		return nil
+	})
+	err = a.UserModel.Update(ctx, recordID, item)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *User) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.UserModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	err = ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
+		err = a.userDatasetModel.DeleteByUserId(ctx, recordID)
+		if err != nil {
+			return err
+		}
+		return a.UserModel.Delete(ctx, recordID)
+	})
+	return err
+}
+
+// UpdateStatus 更新状态
+func (a *User) UpdateStatus(ctx context.Context, recordID string, status bool) error {
+	oldItem, err := a.UserModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.UserModel.UpdateStatus(ctx, recordID, status)
+}
+
+func (a *User) getRootInfo(ctx context.Context) (*schema.User, error) {
+	user := GetRootUser()
+	user.Password = "******"
+	menu, err := a.menuModel.Query(ctx, schema.MenuQueryParam{})
+	if err != nil {
+		return nil, err
+	}
+	user.Menu = menu.Data.ToTrees()
+	return user, nil
+}

+ 89 - 0
app/bll/impl/internal/b_user_role.go

@@ -0,0 +1,89 @@
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/util/guid"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+)
+
+// NewUserRole 创建UserRole
+func NewUserRole(mUserRole model.IUserRole) *UserRole {
+	return &UserRole{
+		UserRoleModel: mUserRole,
+	}
+}
+
+// UserRole 创建UserRole对象
+type UserRole struct {
+	UserRoleModel model.IUserRole
+}
+
+// Query 查询数据
+func (a *UserRole) Query(ctx context.Context, params schema.UserRoleQueryParam, opts ...schema.UserRoleQueryOptions) (*schema.UserRoleQueryResult, error) {
+	return a.UserRoleModel.Query(ctx, params, opts...)
+}
+
+// Get 查询指定数据
+func (a *UserRole) Get(ctx context.Context, recordID string, opts ...schema.UserRoleQueryOptions) (*schema.UserRole, error) {
+	item, err := a.UserRoleModel.Get(ctx, recordID, opts...)
+	if err != nil {
+		return nil, err
+	} else if item == nil {
+		return nil, errors.ErrNotFound
+	}
+	return item, nil
+}
+
+func (a *UserRole) getUpdate(ctx context.Context, recordID string) (*schema.UserRole, error) {
+	return a.Get(ctx, recordID)
+}
+
+// Create 创建数据
+func (a *UserRole) Create(ctx context.Context, item schema.UserRole) (*schema.UserRole, error) {
+	item.RecordId = guid.S()
+	err := a.UserRoleModel.Create(ctx, item)
+	if err != nil {
+		return nil, err
+	}
+	return a.getUpdate(ctx, item.RecordId)
+}
+
+// Update 更新数据
+func (a *UserRole) Update(ctx context.Context, recordID string, item schema.UserRole) (*schema.UserRole, error) {
+	oldItem, err := a.UserRoleModel.Get(ctx, recordID)
+	if err != nil {
+		return nil, err
+	} else if oldItem == nil {
+		return nil, errors.ErrNotFound
+	}
+	err = a.UserRoleModel.Update(ctx, recordID, item)
+	if err != nil {
+		return nil, err
+	}
+	return a.getUpdate(ctx, recordID)
+}
+
+// Delete 删除数据
+func (a *UserRole) Delete(ctx context.Context, recordID string) error {
+	oldItem, err := a.UserRoleModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+
+	return a.UserRoleModel.Delete(ctx, recordID)
+}
+
+// UpdateStatus 更新状态
+func (a *UserRole) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	oldItem, err := a.UserRoleModel.Get(ctx, recordID)
+	if err != nil {
+		return err
+	} else if oldItem == nil {
+		return errors.ErrNotFound
+	}
+	return a.UserRoleModel.UpdateStatus(ctx, recordID, status)
+}

+ 163 - 0
app/bll/impl/internal/b_verify_code.go

@@ -0,0 +1,163 @@
+package internal
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"github.com/gogf/gf/v2/encoding/gjson"
+	"github.com/gogf/gf/v2/os/glog"
+	rand "math/rand"
+	"strings"
+	"sync"
+	"time"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model"
+	"yx-dataset-server/app/schema"
+	"yx-dataset-server/library/logger"
+	"yx-dataset-server/library/redis"
+	"yx-dataset-server/library/sms"
+	"yx-dataset-server/library/utils"
+)
+
+// NewVerifyCode 创建VerifyCode
+func NewVerifyCode(
+	mUser model.IUser,
+) *VerifyCode {
+	return &VerifyCode{
+		userModel: mUser,
+	}
+}
+
+// VerifyCode 创建VerifyCode对象
+type VerifyCode struct {
+	sync.RWMutex
+	userModel model.IUser
+}
+
+func (a *VerifyCode) getKey(businessType int, tel, storeType string) string {
+	return utils.Base64Encode(fmt.Sprintf("%d%s%s", businessType, tel, storeType))
+}
+
+// Check 检查手机号及验证码的有效性
+func (a *VerifyCode) Check(ctx context.Context, req schema.VerifyCodeCheck) (bool, error) {
+	if req.Tel == "" || len(req.Tel) < 11 {
+		return false, errors.New("请输入合法的手机号")
+	}
+
+	var businessType string
+	switch req.BusinessType {
+	case 1:
+		businessType = "login"
+	case 2:
+		businessType = "changePass"
+	default:
+		return false, errors.New("业务类型参数不正确")
+	}
+
+	if req.Token == "" {
+		req.Token = fmt.Sprintf("%s:%s:%s", businessType, "code", req.Tel)
+	}
+
+	val, err := redis.GetClient().Get(ctx, req.Token)
+	if err != nil {
+		return false, errors.ErrBadRequest
+	} else if val == "" {
+		return false, errors.New("验证码已失效,请重新获取验证码")
+	}
+
+	var item schema.VerifyCodeItem
+
+	if err := json.Unmarshal([]byte(val), &item); err != nil {
+		return false, err
+	}
+
+	return item.Code == req.Code && item.BusinessType == req.BusinessType, nil
+}
+
+// SendCode 发送短信验证码
+func (a *VerifyCode) ALiYunSendSms(ctx context.Context, req schema.VerifyCodeRequest) (*schema.VerifyCodeResponse, error) {
+	a.Lock()
+	defer a.Unlock()
+
+	switch req.Bzty {
+	case 1:
+		req.TemplateId = utils.GetConfig("aliyun_sms.loginTemplateCode").String()
+		req.BusinessTypeStr = "login"
+	case 2:
+		req.TemplateId = utils.GetConfig("aliyun_sms.passwordTemplateCode").String()
+		req.BusinessTypeStr = "changePass"
+	}
+
+	telStoreKey := fmt.Sprintf("%s:%s", "telCount", req.Tel)
+	telStoreData, err := redis.GetClient().Get(ctx, telStoreKey)
+	if err != nil {
+		return nil, errors.ErrBadRequest
+	}
+	if telStoreData != "" {
+		var telStoreItem schema.StoreCountItem
+		_ = json.NewDecoder(strings.NewReader(telStoreData)).Decode(&telStoreItem)
+		if telStoreItem.Count >= 50 {
+			return nil, errors.New("该手机号已被限制获取验证码,请于次日重试")
+		}
+		req.TelCount = telStoreItem.Count
+	}
+
+	codeKey := fmt.Sprintf("%s:%s:%s", req.BusinessTypeStr, "code", req.Tel)
+
+	err = a.aliyunSend(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+
+	logger.Printf(ctx, "短信发送成功:[手机号:%s]", req.Tel[7:11])
+	return &schema.VerifyCodeResponse{
+		Token: codeKey,
+	}, nil
+
+}
+
+func (a *VerifyCode) aliyunSend(ctx context.Context, req schema.VerifyCodeRequest) error {
+	if req.Batch {
+		return sms.SendBatchSms(sms.ALiYunSendBatchSmsArgs{
+			TemplateCode:  req.TemplateId,
+			TemplateParam: req.ParamsJson,
+			PhoneNumbers:  req.Tel,
+		})
+	}
+
+	// 随机生成6位验证码
+	code := fmt.Sprintf("%06v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(1000000))
+	paramJson := gjson.New("")
+	_ = paramJson.Set("code", code)
+	glog.Infof(ctx, "验证码发送成功[手机号%s,验证码:%s]", req.Tel, code)
+	//发送短信验证码
+	err := sms.SendSms(sms.ALiYunSendSmsArgs{
+		TemplateCode:  req.TemplateId,
+		TemplateParam: paramJson.MustToJsonString(),
+		PhoneNumbers:  req.Tel,
+	})
+	if err != nil {
+		return err
+	}
+	expired := time.Minute * 5
+	resendLimit := time.Second * 60
+	// 存储重发限制
+	resendLimitKey := fmt.Sprintf("%s:%s:%s", req.BusinessTypeStr, "checkResend", req.Tel)
+	err = redis.GetClient().Set(ctx, resendLimitKey, 1, resendLimit)
+	if err != nil {
+		return errors.ErrBadRequest
+	}
+
+	// 存储验证码
+	codeKey := fmt.Sprintf("%s:%s:%s", req.BusinessTypeStr, "code", req.Tel)
+	codeData := schema.VerifyCodeItem{
+		Code:         code,
+		BusinessType: req.Bzty,
+	}
+	err = redis.GetClient().Set(ctx, codeKey, codeData, expired)
+	if err != nil {
+		return errors.ErrBadRequest
+	}
+
+	return nil
+}

+ 69 - 0
app/context/context.go

@@ -0,0 +1,69 @@
+package context
+
+import (
+	"context"
+)
+
+// 定义全局上下文中的键
+type (
+	transCtx        struct{}
+	transLockCtx    struct{}
+	userIDCtx       struct{}
+	traceIDCtx      struct{}
+)
+
+// NewTrans 创建事务的上下文
+func NewTrans(ctx context.Context, trans interface{}) context.Context {
+	return context.WithValue(ctx, transCtx{}, trans)
+}
+
+// FromTrans 从上下文中获取事务
+func FromTrans(ctx context.Context) (interface{}, bool) {
+	v := ctx.Value(transCtx{})
+	return v, v != nil
+}
+
+// NewTransLock 创建事务锁的上下文
+func NewTransLock(ctx context.Context) context.Context {
+	return context.WithValue(ctx, transLockCtx{}, struct{}{})
+}
+
+// FromTransLock 从上下文中获取事务锁
+func FromTransLock(ctx context.Context) bool {
+	v := ctx.Value(transLockCtx{})
+	return v != nil
+}
+
+// NewUserID 创建用户ID的上下文
+func NewUserID(ctx context.Context, userID string) context.Context {
+	return context.WithValue(ctx, userIDCtx{}, userID)
+}
+
+// FromUserID 从上下文中获取用户ID
+func FromUserID(ctx context.Context) (string, bool) {
+	v := ctx.Value(userIDCtx{})
+	if v != nil {
+		if s, ok := v.(string); ok {
+			return s, s != ""
+		}
+	}
+	return "", false
+}
+
+
+// NewTraceID 创建追踪ID的上下文
+func NewTraceID(ctx context.Context, traceID string) context.Context {
+	return context.WithValue(ctx, traceIDCtx{}, traceID)
+}
+
+// FromTraceID 从上下文中获取追踪ID
+func FromTraceID(ctx context.Context) (string, bool) {
+	v := ctx.Value(traceIDCtx{})
+	if v != nil {
+		if s, ok := v.(string); ok {
+			return s, s != ""
+		}
+	}
+	return "", false
+}
+

+ 38 - 0
app/errors/error.go

@@ -0,0 +1,38 @@
+package errors
+
+import (
+	"github.com/pkg/errors"
+)
+
+// 定义别名
+var (
+	New       = errors.New
+	Wrap      = errors.Wrap
+	Wrapf     = errors.Wrapf
+	WithStack = errors.WithStack
+)
+
+var (
+	ErrBadRequest = New400Response("请求发生错误")
+
+	ErrNoPerm                = NewResponse(401, "无访问权限", 401)
+	ErrInvalidToken          = NewResponse(9999, "令牌失效", 401)
+	ErrNotFound              = NewResponse(404, "资源不存在", 404)
+	ErrTooManyRequests       = NewResponse(429, "请求过于频繁", 429)
+	ErrInternalServer        = NewResponse(500, "服务器发生错误", 500)
+	ErrDBServerInternalError = NewResponse(50001, "数据库发生错误", 500)
+
+	// 用户错误
+	ErrUnauthorized       = New400Response("未授权")
+	ErrUserNotFound       = New400Response("用户不存在")
+	ErrInvalidUserName    = New400Response("无效的用户名")
+	ErrInvalidPassword    = New400Response("无效的密码")
+	ErrInvalidUser        = New400Response("无效的用户")
+	ErrInvalidParams      = New400Response("无效的请求参数")
+	ErrUserDisable        = New400Response("用户被禁用")
+	ErrUserNotEmptyPwd    = New400Response("密码不允许为空")
+	ErrLoginInvalidOldPwd = New400Response("旧密码不正确")
+	ErrUserNameExists     = New400Response("用户名已经存在")
+	ErrUnknownQuery       = New400Response("未知的查询类型")
+	ErrSmsCode            = New400Response("验证码不正确")
+)

+ 93 - 0
app/errors/response.go

@@ -0,0 +1,93 @@
+package errors
+
+import "github.com/gogf/gf/v2/net/ghttp"
+
+// ResponseError 响应错误
+type ResponseError struct {
+	Code       int    // 错误码
+	Message    string // 错误消息
+	StatusCode int    // 响应错误码
+	ERR        error  // 响应错误
+}
+
+func (r *ResponseError) Error() string {
+	if r.ERR != nil {
+		return r.ERR.Error()
+	}
+	return r.Message
+}
+
+// UnWrapResponse 解包响应错误
+func UnWrapResponse(err error) *ResponseError {
+	if v, ok := err.(*ResponseError); ok {
+		return v
+	}
+	return nil
+}
+
+// WrapResponse 包装响应错误
+func WrapResponse(err error, code int, msg string, status ...int) error {
+	res := &ResponseError{
+		Code:    code,
+		Message: msg,
+		ERR:     err,
+	}
+	if len(status) > 0 {
+		res.StatusCode = status[0]
+	}
+	return res
+}
+
+// Wrap400Response 包装错误码为400的响应错误
+func Wrap400Response(err error, msg ...string) error {
+	m := "请求发生错误"
+	if len(msg) > 0 {
+		m = msg[0]
+	}
+	return WrapResponse(err, 400, m, 400)
+}
+
+// Wrap500Response 包装错误码为500的响应错误
+func Wrap500Response(err error, msg ...string) error {
+	m := "服务器发生错误"
+	if len(msg) > 0 {
+		m = msg[0]
+	}
+	return WrapResponse(err, 500, m, 500)
+}
+
+// NewResponse 创建响应错误
+func NewResponse(code int, msg string, status ...int) error {
+	res := &ResponseError{
+		Code:    code,
+		Message: msg,
+	}
+	if len(status) > 0 {
+		res.StatusCode = status[0]
+	}
+	return res
+}
+
+// New400Response 创建错误码为400的响应错误
+func New400Response(msg string) error {
+	return NewResponse(400, msg, 400)
+}
+
+// New500Response 创建错误码为500的响应错误
+func New500Response(msg string) error {
+	return NewResponse(500, msg, 500)
+}
+
+func Json(r *ghttp.Request, code int, v interface{}) {
+	if code == 500 || code == 401 {
+		r.Response.WriteStatus(code)
+		r.Response.ClearBuffer()
+	}
+	r.Response.WriteJson(v)
+}
+
+// JsonExit 返回JSON数据并退出当前HTTP执行函数。
+func JsonExit(r *ghttp.Request, err int, data interface{}) {
+	Json(r, err, data)
+	r.Exit()
+}

+ 0 - 0
app/model/.gitkeep


+ 68 - 0
app/model/entity/e_chat_assistant.go

@@ -0,0 +1,68 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetChatAssistantDB 获取ChatAssistant存储
+func GetChatAssistantDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, ChatAssistant{})
+}
+
+// SchemaChatAssistant ChatAssistant对象
+type SchemaChatAssistant schema.ChatAssistant
+
+// ToChatAssistant 转换为ChatAssistant实体
+func (a SchemaChatAssistant) ToChatAssistant() *ChatAssistant {
+	item := &ChatAssistant{
+		RecordID:  a.RecordID,
+		UserId:    a.UserId,
+		OrgId:     a.OrgId,
+		Name:      a.Name,
+		Desc:      a.Desc,
+		RagChatId: a.RagChatId,
+		CreatorId: a.CreatorId,
+	}
+	return item
+}
+
+// ToSchemaChatAssistant 转换为ChatAssistant对象
+func (a ChatAssistant) ToSchemaChatAssistant() *schema.ChatAssistant {
+	item := &schema.ChatAssistant{
+		RecordID:  a.RecordID,
+		UserId:    a.UserId,
+		OrgId:     a.OrgId,
+		Name:      a.Name,
+		Desc:      a.Desc,
+		RagChatId: a.RagChatId,
+		CreatorId: a.CreatorId,
+		CreatedAt: a.CreatedAt,
+	}
+	return item
+}
+
+// ChatAssistant ChatAssistant实体
+type ChatAssistant struct {
+	gorm.Model
+	RecordID  string `gorm:"column:record_id;size:32;index;"`  // 记录id
+	UserId    string `gorm:"column:user_id;size:32;index;"`    // 所属用户id
+	OrgId     string `gorm:"column:org_id;size:32;index;"`     // 所属组织id
+	Name      string `gorm:"column:name;size:20;"`             // 助手名称
+	Desc      string `gorm:"column:desc;size:30;"`             // 描述
+	RagChatId string `gorm:"column:rag_chat_id;size:32;"`      // rag_chat_id
+	CreatorId string `gorm:"column:creator_id;size:32;index;"` // 创建人id
+}
+
+// ChatAssistants ChatAssistant列表
+type ChatAssistants []*ChatAssistant
+
+// ToSchemaChatAssistants 转换为ChatAssistant对象列表
+func (a ChatAssistants) ToSchemaChatAssistants() []*schema.ChatAssistant {
+	list := make([]*schema.ChatAssistant, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaChatAssistant()
+	}
+	return list
+}

+ 58 - 0
app/model/entity/e_chat_dataset.go

@@ -0,0 +1,58 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetChatDatasetDB 获取ChatDataset存储
+func GetChatDatasetDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, ChatDataset{})
+}
+
+// SchemaChatDataset ChatDataset对象
+type SchemaChatDataset schema.ChatDataset
+
+// ToChatDataset 转换为ChatDataset实体
+func (a SchemaChatDataset) ToChatDataset() *ChatDataset {
+	item := &ChatDataset{
+		RecordID:        a.RecordID,
+		ChatAssistantId: a.ChatAssistantId,
+		DatasetId:       a.DatasetId,
+		RagDataId:       a.RagDataId,
+	}
+	return item
+}
+
+// ToSchemaChatDataset 转换为ChatDataset对象
+func (a ChatDataset) ToSchemaChatDataset() *schema.ChatDataset {
+	item := &schema.ChatDataset{
+		RecordID:        a.RecordID,
+		ChatAssistantId: a.ChatAssistantId,
+		DatasetId:       a.DatasetId,
+		RagDataId:       a.RagDataId,
+	}
+	return item
+}
+
+// ChatDataset ChatDataset实体
+type ChatDataset struct {
+	gorm.Model
+	RecordID        string `gorm:"column:record_id;size:32;index;"`
+	ChatAssistantId string `gorm:"column:chat_assistant_id;size:32;index;"`
+	DatasetId       string `gorm:"column:dataset_id;size:32;index;"`
+	RagDataId       string `gorm:"column:rag_data_id;size:32;"`
+}
+
+// ChatDatasets ChatDataset列表
+type ChatDatasets []*ChatDataset
+
+// ToSchemaChatDatasets 转换为ChatDataset对象列表
+func (a ChatDatasets) ToSchemaChatDatasets() []*schema.ChatDataset {
+	list := make([]*schema.ChatDataset, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaChatDataset()
+	}
+	return list
+}

+ 71 - 0
app/model/entity/e_chat_message.go

@@ -0,0 +1,71 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetChatMessageDB 获取ChatMessage存储
+func GetChatMessageDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, ChatMessage{})
+}
+
+// SchemaChatMessage ChatMessage对象
+type SchemaChatMessage schema.ChatMessage
+
+// ToChatMessage 转换为ChatMessage实体
+func (a SchemaChatMessage) ToChatMessage() *ChatMessage {
+	item := &ChatMessage{
+		RecordID:     a.RecordID,
+		UserId:       a.UserId,
+		AssistantId:  a.AssistantId,
+		SessionId:    a.SessionId,
+		RagSessionId: a.RagSessionId,
+		Question:     a.Question,
+		Answer:       a.Answer,
+		CreatorId:    a.CreatorId,
+	}
+	return item
+}
+
+// ToSchemaChatMessage 转换为ChatMessage对象
+func (a ChatMessage) ToSchemaChatMessage() *schema.ChatMessage {
+	item := &schema.ChatMessage{
+		RecordID:     a.RecordID,
+		UserId:       a.UserId,
+		AssistantId:  a.AssistantId,
+		SessionId:    a.SessionId,
+		RagSessionId: a.RagSessionId,
+		Question:     a.Question,
+		Answer:       a.Answer,
+		CreatorId:    a.CreatorId,
+		CreatedAt:    a.CreatedAt,
+	}
+	return item
+}
+
+// ChatMessage ChatMessage实体
+type ChatMessage struct {
+	gorm.Model
+	RecordID     string `gorm:"column:record_id;size:32;index;"`  //  记录id
+	UserId       string `gorm:"column:user_id;size:32;"`          // 用户id
+	AssistantId  string `gorm:"column:assistant_id;size:32;"`     // 助手id
+	SessionId    string `gorm:"column:session_id;size:32;index;"` // 会话id
+	RagSessionId string `gorm:"column:rag_session_id;size:32;"`   // rag_session_id
+	Question     string `gorm:"column:question;type:longtext;"`   // 对话问题
+	Answer       string `gorm:"column:answer;type:longtext;"`     // 对话答案
+	CreatorId    string `gorm:"column:creator_id;size:32;index;"` // 创建者id
+}
+
+// ChatMessages ChatMessage列表
+type ChatMessages []*ChatMessage
+
+// ToSchemaChatMessages 转换为ChatMessage对象列表
+func (a ChatMessages) ToSchemaChatMessages() []*schema.ChatMessage {
+	list := make([]*schema.ChatMessage, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaChatMessage()
+	}
+	return list
+}

+ 68 - 0
app/model/entity/e_chat_session.go

@@ -0,0 +1,68 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetChatSessionDB 获取ChatSession存储
+func GetChatSessionDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, ChatSession{})
+}
+
+// SchemaChatSession ChatSession对象
+type SchemaChatSession schema.ChatSession
+
+// ToChatSession 转换为ChatSession实体
+func (a SchemaChatSession) ToChatSession() *ChatSession {
+	item := &ChatSession{
+		RecordID:     a.RecordID,
+		Name:         a.Name,
+		UserId:       a.UserId,
+		AssistantId:  a.AssistantId,
+		RagChatId:    a.RagChatId,
+		RagSessionId: a.RagSessionId,
+		CreatorId:    a.CreatorId,
+	}
+	return item
+}
+
+// ToSchemaChatSession 转换为ChatSession对象
+func (a ChatSession) ToSchemaChatSession() *schema.ChatSession {
+	item := &schema.ChatSession{
+		RecordID:     a.RecordID,
+		Name:         a.Name,
+		UserId:       a.UserId,
+		AssistantId:  a.AssistantId,
+		RagChatId:    a.RagChatId,
+		RagSessionId: a.RagSessionId,
+		CreatedAt:    a.CreatedAt,
+		CreatorId:    a.CreatorId,
+	}
+	return item
+}
+
+// ChatSession ChatSession实体
+type ChatSession struct {
+	gorm.Model
+	RecordID     string `gorm:"column:record_id;size:32;index;"`    // 记录id
+	Name         string `gorm:"column:name;size:30;"`               // 名称
+	UserId       string `gorm:"column:user_id;size:32;"`            // 用户id
+	AssistantId  string `gorm:"column:assistant_id;size:32;index;"` // 助手id
+	RagChatId    string `gorm:"column:rag_chat_id;size:32"`         // rag_chat_id
+	RagSessionId string `gorm:"column:rag_session_id;size:32;"`     // rag_session_id
+	CreatorId    string `gorm:"column:creator_id;size:32;index;"`   // 创建人id
+}
+
+// ChatSessions ChatSession列表
+type ChatSessions []*ChatSession
+
+// ToSchemaChatSessions 转换为ChatSession对象列表
+func (a ChatSessions) ToSchemaChatSessions() []*schema.ChatSession {
+	list := make([]*schema.ChatSession, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaChatSession()
+	}
+	return list
+}

+ 71 - 0
app/model/entity/e_dataset.go

@@ -0,0 +1,71 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetDatasetDB 获取Dataset存储
+func GetDatasetDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, Dataset{})
+}
+
+// SchemaDataset Dataset对象
+type SchemaDataset schema.Dataset
+
+// ToDataset 转换为Dataset实体
+func (a SchemaDataset) ToDataset() *Dataset {
+	item := &Dataset{
+		RecordID:  a.RecordID,
+		Name:      a.Name,
+		OrgId:     a.OrgId,
+		FileCount: a.FileCount,
+		Status:    a.Status,
+		CreatorID: a.CreatorId,
+		RagDataId: a.RagDataId,
+		Sequence:  &a.Sequence,
+	}
+	return item
+}
+
+// ToSchemaDataset 转换为Dataset对象
+func (a Dataset) ToSchemaDataset() *schema.Dataset {
+	item := &schema.Dataset{
+		RecordID:  a.RecordID,
+		Name:      a.Name,
+		OrgId:     a.OrgId,
+		FileCount: a.FileCount,
+		Status:    a.Status,
+		CreatorId: a.CreatorID,
+		RagDataId: a.RagDataId,
+		CreatedAt: a.CreatedAt,
+		Sequence:  *a.Sequence,
+	}
+	return item
+}
+
+// Dataset Dataset实体
+type Dataset struct {
+	gorm.Model
+	RecordID  string `gorm:"column:record_id;size:32;index;"`
+	Name      string `gorm:"column:name;size:30;index;"`
+	OrgId     string `gorm:"column:org_id;size:32;index;"`
+	FileCount int    `gorm:"column:file_count;"`
+	Status    bool   `gorm:"column:status;"`
+	CreatorID string `gorm:"column:creator_id;size:32;"`
+	RagDataId string `gorm:"column:rag_data_id;size:32;"`
+	Sequence  *int   `gorm:"column:sequence;auto_increment;"`
+}
+
+// Datasets Dataset列表
+type Datasets []*Dataset
+
+// ToSchemaDatasets 转换为Dataset对象列表
+func (a Datasets) ToSchemaDatasets() []*schema.Dataset {
+	list := make([]*schema.Dataset, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaDataset()
+	}
+	return list
+}

+ 80 - 0
app/model/entity/e_dataset_file.go

@@ -0,0 +1,80 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetDatasetFileDB 获取DatasetFile存储
+func GetDatasetFileDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, DatasetFile{})
+}
+
+// SchemaDatasetFile DatasetFile对象
+type SchemaDatasetFile schema.DatasetFile
+
+// ToDatasetFile 转换为DatasetFile实体
+func (a SchemaDatasetFile) ToDatasetFile() *DatasetFile {
+	item := &DatasetFile{
+		RecordID:    a.RecordID,
+		DatasetId:   a.DatasetId,
+		Name:        a.Name,
+		Url:         a.Url,
+		Size:        a.Size,
+		MD5:         a.MD5,
+		Type:        a.Type,
+		Enabled:     a.Enabled,
+		RagFileId:   a.RagFileId,
+		ParseStatus: a.ParseStatus,
+		CreatorId:   a.CreatorId,
+	}
+	return item
+}
+
+// ToSchemaDatasetFile 转换为DatasetFile对象
+func (a DatasetFile) ToSchemaDatasetFile() *schema.DatasetFile {
+	item := &schema.DatasetFile{
+		RecordID:    a.RecordID,
+		DatasetId:   a.DatasetId,
+		Name:        a.Name,
+		Url:         a.Url,
+		Size:        a.Size,
+		MD5:         a.MD5,
+		Type:        a.Type,
+		Enabled:     a.Enabled,
+		RagFileId:   a.RagFileId,
+		ParseStatus: a.ParseStatus,
+		CreatedAt:   a.CreatedAt,
+		CreatorId:   a.CreatorId,
+	}
+	return item
+}
+
+// DatasetFile DatasetFile实体
+type DatasetFile struct {
+	gorm.Model
+	RecordID    string `gorm:"column:record_id;size:32;index;"`  // 记录id
+	DatasetId   string `gorm:"column:dataset_id;size:32;index;"` // 知识库id
+	Name        string `gorm:"column:name;size:100;"`            // 名称
+	Url         string `gorm:"column:url;size:200;"`             // 文件地址
+	Size        int64  `gorm:"column:size;"`                     // 文件大小
+	MD5         string `gorm:"column:md5;size:50;"`              // md5
+	Type        string `gorm:"column:type;size:10;"`             // 文件类型
+	Enabled     bool   `gorm:"column:enabled;"`                  // 启用状态
+	RagFileId   string `json:"rag_file_id"`                      // rag平台文件id
+	ParseStatus bool   `gorm:"column:parse_status;"`             // 解析状态
+	CreatorId   string `gorm:"column:creator_id;size:32;"`       // 创建人id
+}
+
+// DatasetFiles DatasetFile列表
+type DatasetFiles []*DatasetFile
+
+// ToSchemaDatasetFiles 转换为DatasetFile对象列表
+func (a DatasetFiles) ToSchemaDatasetFiles() []*schema.DatasetFile {
+	list := make([]*schema.DatasetFile, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaDatasetFile()
+	}
+	return list
+}

+ 49 - 0
app/model/entity/e_login_history.go

@@ -0,0 +1,49 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetLoginHistoryDB 获取LoginHistory存储
+func GetLoginHistoryDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, LoginHistory{})
+}
+
+// SchemaLoginHistory LoginHistory对象
+type SchemaLoginHistory schema.LoginHistory
+
+// ToLoginHistory 转换为LoginHistory实体
+func (a SchemaLoginHistory) ToLoginHistory() *LoginHistory {
+	item := &LoginHistory{
+		RecordID: a.RecordID,
+	}
+	return item
+}
+
+// ToSchemaLoginHistory 转换为LoginHistory对象
+func (a LoginHistory) ToSchemaLoginHistory() *schema.LoginHistory {
+	item := &schema.LoginHistory{
+		RecordID: a.RecordID,
+	}
+	return item
+}
+
+// LoginHistory LoginHistory实体
+type LoginHistory struct {
+	gorm.Model
+	RecordID string
+}
+
+// LoginHistorys LoginHistory列表
+type LoginHistorys []*LoginHistory
+
+// ToSchemaLoginHistorys 转换为LoginHistory对象列表
+func (a LoginHistorys) ToSchemaLoginHistorys() []*schema.LoginHistory {
+	list := make([]*schema.LoginHistory, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaLoginHistory()
+	}
+	return list
+}

+ 91 - 0
app/model/entity/e_menu.go

@@ -0,0 +1,91 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetMenuDB 获取Menu存储
+func GetMenuDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, Menu{})
+}
+
+// SchemaMenu Menu对象
+type SchemaMenu schema.Menu
+
+// ToMenu 转换为Menu实体
+func (a SchemaMenu) ToMenu() *Menu {
+	item := &Menu{
+		RecordID:    a.RecordID,
+		Name:        a.Name,
+		Path:        a.Path,
+		Component:   a.Component,
+		ParentId:    a.ParentId,
+		Icon:        a.Meta.Icon,
+		Title:       a.Meta.Title,
+		IsLink:      a.Meta.IsLink,
+		IsHide:      a.Meta.IsHide,
+		IsFull:      a.Meta.IsFull,
+		IsAffix:     a.Meta.IsAffix,
+		IsKeepAlive: a.Meta.IsKeepAlive,
+		Sequence:    &a.Sequence,
+		CreatorId:   a.CreatorId,
+	}
+	return item
+}
+
+// ToSchemaMenu 转换为Menu对象
+func (a Menu) ToSchemaMenu() *schema.Menu {
+	item := &schema.Menu{
+		RecordID:  a.RecordID,
+		Name:      a.Name,
+		Path:      a.Path,
+		Component: a.Component,
+		ParentId:  a.ParentId,
+		Sequence:  *a.Sequence,
+		CreatorId: a.CreatorId,
+		CreatedAt: a.CreatedAt,
+		Meta: schema.MenuMeta{
+			Icon:        a.Icon,
+			Title:       a.Title,
+			IsLink:      a.IsLink,
+			IsHide:      a.IsHide,
+			IsFull:      a.IsFull,
+			IsAffix:     a.IsAffix,
+			IsKeepAlive: a.IsKeepAlive,
+		},
+	}
+	return item
+}
+
+// Menu Menu实体
+type Menu struct {
+	gorm.Model
+	RecordID    string `gorm:"column:record_id;size:32;index;comment:'记录内码'"`
+	Name        string `gorm:"column:name;size:50;index;comment:'菜单名称'"`
+	Path        string `gorm:"column:path;size:50;"`            // 路径
+	Component   string `gorm:"column:component;size:50;"`       // 组件
+	ParentId    string `gorm:"column:parent_id;size:32;index;"` // 父级id
+	Icon        string `gorm:"column:icon;size:30;"`            // 图标
+	Title       string `gorm:"column:title;size:50;"`           // 标题
+	IsLink      string `gorm:"column:is_link;size:10;"`         // 是否外链
+	IsHide      bool   `gorm:"column:is_hide;"`                 // 是否隐藏
+	IsFull      bool   `gorm:"column:is_full;"`                 // 是否全屏
+	IsAffix     bool   `gorm:"column:is_affix;"`                // 是否固定
+	IsKeepAlive bool   `gorm:"column:is_keep_alive;"`           // 是否缓存
+	Sequence    *int   `gorm:"column:sequence;auto_increment;"` // 排序值
+	CreatorId   string `gorm:"column:creator_id;size:32;"`      // 创建人
+}
+
+// Menus Menu列表
+type Menus []*Menu
+
+// ToSchemaMenus 转换为Menu对象列表
+func (a Menus) ToSchemaMenus() []*schema.Menu {
+	list := make([]*schema.Menu, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaMenu()
+	}
+	return list
+}

+ 62 - 0
app/model/entity/e_organization.go

@@ -0,0 +1,62 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetOrganizationDB 获取Organization存储
+func GetOrganizationDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, Organization{})
+}
+
+// SchemaOrganization Organization对象
+type SchemaOrganization schema.Organization
+
+// ToOrganization 转换为Organization实体
+func (a SchemaOrganization) ToOrganization() *Organization {
+	item := &Organization{
+		RecordID:  a.RecordID,
+		Name:      a.Name,
+		ChartNum:  a.ChartNum,
+		Sequence:  &a.Sequence,
+		CreatorId: a.CreatorId,
+	}
+	return item
+}
+
+// ToSchemaOrganization 转换为Organization对象
+func (a Organization) ToSchemaOrganization() *schema.Organization {
+	item := &schema.Organization{
+		RecordID:  a.RecordID,
+		Name:      a.Name,
+		ChartNum:  a.ChartNum,
+		Sequence:  *a.Sequence,
+		CreatedAt: a.CreatedAt,
+		CreatorId: a.CreatorId,
+	}
+	return item
+}
+
+// Organization Organization实体
+type Organization struct {
+	gorm.Model
+	RecordID  string `gorm:"column:record_id;size:32;index;"`
+	Name      string `gorm:"column:name;size:30;"`            // 组织名称
+	ChartNum  int    `gorm:"column:chart_num;"`               // 对话轮次/日
+	Sequence  *int   `gorm:"column:sequence;auto_increment;"` // 排序
+	CreatorId string `gorm:"column:creator_id;size:32;"`      // 创建者id
+}
+
+// Organizations Organization列表
+type Organizations []*Organization
+
+// ToSchemaOrganizations 转换为Organization对象列表
+func (a Organizations) ToSchemaOrganizations() []*schema.Organization {
+	list := make([]*schema.Organization, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaOrganization()
+	}
+	return list
+}

+ 80 - 0
app/model/entity/e_robot_config.go

@@ -0,0 +1,80 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetRobotConfigDB 获取RobotConfig存储
+func GetRobotConfigDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, RobotConfig{})
+}
+
+// SchemaRobotConfig RobotConfig对象
+type SchemaRobotConfig schema.RobotConfig
+
+// ToRobotConfig 转换为RobotConfig实体
+func (a SchemaRobotConfig) ToRobotConfig() *RobotConfig {
+	item := &RobotConfig{
+		RecordID:     a.RecordID,
+		OrgId:        a.OrgId,
+		Name:         a.Name,
+		Type:         a.Type,
+		APPID:        a.APPID,
+		ClientId:     a.ClientId,
+		ClientSecret: a.ClientSecret,
+		Webhook:      a.Webhook,
+		AssistantId:  a.AssistantId,
+		SessionId:    a.SessionId,
+		CreatorId:    a.CreatorId,
+	}
+	return item
+}
+
+// ToSchemaRobotConfig 转换为RobotConfig对象
+func (a RobotConfig) ToSchemaRobotConfig() *schema.RobotConfig {
+	item := &schema.RobotConfig{
+		RecordID:     a.RecordID,
+		OrgId:        a.OrgId,
+		Name:         a.Name,
+		Type:         a.Type,
+		APPID:        a.APPID,
+		ClientId:     a.ClientId,
+		ClientSecret: a.ClientSecret,
+		Webhook:      a.Webhook,
+		CreatorId:    a.CreatorId,
+		AssistantId:  a.AssistantId,
+		SessionId:    a.SessionId,
+		CreatedAt:    a.CreatedAt,
+	}
+	return item
+}
+
+// RobotConfig RobotConfig实体
+type RobotConfig struct {
+	gorm.Model
+	RecordID     string `gorm:"column:record_id;size:32;index;"` // 记录id
+	OrgId        string `gorm:"column:org_id;size:32;index;"`    // 组织ID
+	Name         string `gorm:"column:name;size:20;"`            // 机器人名称
+	Type         int    `gorm:"column:type;"`                    // 机器人类型
+	APPID        string `gorm:"column:appid;size:50;"`           // APP ID
+	ClientId     string `gorm:"column:client_id;size:50;"`       // 客户端ID
+	ClientSecret string `gorm:"column:client_secret;size:100;"`  // 客户端密钥
+	Webhook      string `gorm:"column:webhook;size:100;"`        // 消息接收WebHook
+	AssistantId  string `gorm:"column:assistant_id;size:32;"`    // 助手id
+	SessionId    string `gorm:"column:session_id;size:32;"`      // 会话id
+	CreatorId    string `gorm:"column:creator_id;size:32;"`      // 创建人
+}
+
+// RobotConfigs RobotConfig列表
+type RobotConfigs []*RobotConfig
+
+// ToSchemaRobotConfigs 转换为RobotConfig对象列表
+func (a RobotConfigs) ToSchemaRobotConfigs() []*schema.RobotConfig {
+	list := make([]*schema.RobotConfig, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaRobotConfig()
+	}
+	return list
+}

+ 55 - 0
app/model/entity/e_robot_dataset.go

@@ -0,0 +1,55 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetRobotDatasetDB 获取RobotDataset存储
+func GetRobotDatasetDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, RobotDataset{})
+}
+
+// SchemaRobotDataset RobotDataset对象
+type SchemaRobotDataset schema.RobotDataset
+
+// ToRobotDataset 转换为RobotDataset实体
+func (a SchemaRobotDataset) ToRobotDataset() *RobotDataset {
+	item := &RobotDataset{
+		RecordID:  a.RecordID,
+		RobotId:   a.RobotId,
+		DatasetId: a.DatasetId,
+	}
+	return item
+}
+
+// ToSchemaRobotDataset 转换为RobotDataset对象
+func (a RobotDataset) ToSchemaRobotDataset() *schema.RobotDataset {
+	item := &schema.RobotDataset{
+		RecordID:  a.RecordID,
+		RobotId:   a.RobotId,
+		DatasetId: a.DatasetId,
+	}
+	return item
+}
+
+// RobotDataset RobotDataset实体
+type RobotDataset struct {
+	gorm.Model
+	RecordID  string `gorm:"column:record_id;size:32;index;"`
+	RobotId   string `gorm:"column:robot_id;size:32;index;"`
+	DatasetId string `gorm:"column:dataset_id;size:32;index;"`
+}
+
+// RobotDatasets RobotDataset列表
+type RobotDatasets []*RobotDataset
+
+// ToSchemaRobotDatasets 转换为RobotDataset对象列表
+func (a RobotDatasets) ToSchemaRobotDatasets() []*schema.RobotDataset {
+	list := make([]*schema.RobotDataset, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaRobotDataset()
+	}
+	return list
+}

+ 61 - 0
app/model/entity/e_role.go

@@ -0,0 +1,61 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetRoleDB 获取Role存储
+func GetRoleDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, Role{})
+}
+
+// SchemaRole Role对象
+type SchemaRole schema.Role
+
+// ToRole 转换为Role实体
+func (a SchemaRole) ToRole() *Role {
+	item := &Role{
+		RecordID: a.RecordID,
+		Name:     a.Name,
+		Code:     a.Code,
+		ChartNum: a.ChartNum,
+	}
+	return item
+}
+
+// ToSchemaRole 转换为Role对象
+func (a Role) ToSchemaRole() *schema.Role {
+	item := &schema.Role{
+		RecordID:  a.RecordID,
+		Name:      a.Name,
+		Code:      a.Code,
+		ChartNum:  a.ChartNum,
+		Creator:   a.CreatorId,
+		CreatedAt: a.CreatedAt,
+	}
+	return item
+}
+
+// Role Role实体
+type Role struct {
+	gorm.Model
+	RecordID  string `gorm:"column:record_id;size:32;index;"`
+	Name      string `gorm:"column:name;size:30;"` // 角色名称
+	Code      string `gorm:"column:code;size:5;"`  // 角色编码(11 系统管理员 12 企业管理员  99 企业员工)
+	ChartNum  int    `gorm:"column:chart_num;"`    // 对话轮次/日
+	CreatorId string `gorm:"column:creator_id;size:32;"`
+}
+
+// Roles Role列表
+type Roles []*Role
+
+// ToSchemaRoles 转换为Role对象列表
+func (a Roles) ToSchemaRoles() []*schema.Role {
+	list := make([]*schema.Role, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaRole()
+	}
+	return list
+}

+ 56 - 0
app/model/entity/e_role_menu.go

@@ -0,0 +1,56 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetRoleMenuDB 获取RoleMenu存储
+func GetRoleMenuDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, RoleMenu{})
+}
+
+// SchemaRoleMenu RoleMenu对象
+type SchemaRoleMenu schema.RoleMenu
+
+// ToRoleMenu 转换为RoleMenu实体
+func (a SchemaRoleMenu) ToRoleMenu() *RoleMenu {
+	item := &RoleMenu{
+		RecordID: a.RecordId,
+		RoleId:   a.RoleId,
+		MenuId:   a.MenuId,
+	}
+	return item
+}
+
+// ToSchemaRoleMenu 转换为RoleMenu对象
+func (a RoleMenu) ToSchemaRoleMenu() *schema.RoleMenu {
+	item := &schema.RoleMenu{
+		RecordId: a.RecordID,
+		RoleId:   a.RoleId,
+		MenuId:   a.MenuId,
+	}
+	return item
+}
+
+// RoleMenu RoleMenu实体
+type RoleMenu struct {
+	gorm.Model
+	RecordID string `gorm:"column:record_id;size:32;index;"`
+	RoleId   string `gorm:"column:role_id;size:32;index;'"` // 角色id
+	MenuId   string `gorm:"column:menu_id;size:32;index;"`  // 菜单Id
+
+}
+
+// RoleMenus RoleMenu列表
+type RoleMenus []*RoleMenu
+
+// ToSchemaRoleMenus 转换为RoleMenu对象列表
+func (a RoleMenus) ToSchemaRoleMenus() []*schema.RoleMenu {
+	list := make([]*schema.RoleMenu, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaRoleMenu()
+	}
+	return list
+}

+ 77 - 0
app/model/entity/e_user.go

@@ -0,0 +1,77 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetUserDB 获取User存储
+func GetUserDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, User{})
+}
+
+// SchemaUser User对象
+type SchemaUser schema.User
+
+// ToUser 转换为User实体
+func (a SchemaUser) ToUser() *User {
+	item := &User{
+		RecordID:  a.RecordID,
+		UserName:  a.UserName,
+		RealName:  a.RealName,
+		OrgId:     a.OrgId,
+		RoleId:    a.RoleId,
+		Phone:     a.Phone,
+		Password:  a.Password,
+		Photo:     a.Photo,
+		Status:    a.Status,
+		CreatorId: a.CreatorId,
+	}
+	return item
+}
+
+// ToSchemaUser 转换为User对象
+func (a User) ToSchemaUser() *schema.User {
+	item := &schema.User{
+		RecordID:  a.RecordID,
+		UserName:  a.UserName,
+		RealName:  a.RealName,
+		OrgId:     a.OrgId,
+		RoleId:    a.RoleId,
+		Phone:     a.Phone,
+		Password:  a.Password,
+		Photo:     a.Photo,
+		Status:    a.Status,
+		CreatedAt: a.CreatedAt,
+		CreatorId: a.CreatorId,
+	}
+	return item
+}
+
+// User User实体
+type User struct {
+	gorm.Model
+	RecordID  string `gorm:"column:record_id;size:32;index;"`
+	UserName  string `gorm:"column:user_name;size:20;"`
+	RealName  string `gorm:"column:real_name;size:20;"`
+	RoleId    string `gorm:"column:role_id;size:32;index;"`
+	OrgId     string `gorm:"column:org_id;size:32;index;"`
+	Phone     string `gorm:"column:phone;size:20;"`
+	Password  string `gorm:"column:password;size:100;"`
+	Photo     string `gorm:"column:photo;size:200;"`
+	Status    bool   `gorm:"column:status;"`
+	CreatorId string `gorm:"column:creator_id;size:32;"`
+}
+
+// Users User列表
+type Users []*User
+
+// ToSchemaUsers 转换为User对象列表
+func (a Users) ToSchemaUsers() []*schema.User {
+	list := make([]*schema.User, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaUser()
+	}
+	return list
+}

+ 58 - 0
app/model/entity/e_user_dataset.go

@@ -0,0 +1,58 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetUserDatasetDB 获取UserDataset存储
+func GetUserDatasetDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, UserDataset{})
+}
+
+// SchemaUserDataset UserDataset对象
+type SchemaUserDataset schema.UserDataset
+
+// ToUserDataset 转换为UserDataset实体
+func (a SchemaUserDataset) ToUserDataset() *UserDataset {
+	item := &UserDataset{
+		RecordID:  a.RecordID,
+		UserId:    a.UserId,
+		DatasetId: a.DatasetId,
+		Type:      a.Type,
+	}
+	return item
+}
+
+// ToSchemaUserDataset 转换为UserDataset对象
+func (a UserDataset) ToSchemaUserDataset() *schema.UserDataset {
+	item := &schema.UserDataset{
+		RecordID:  a.RecordID,
+		UserId:    a.UserId,
+		DatasetId: a.DatasetId,
+		Type:      a.Type,
+	}
+	return item
+}
+
+// UserDataset UserDataset实体
+type UserDataset struct {
+	gorm.Model
+	RecordID  string `gorm:"column:record_id;size:32;index;"`
+	UserId    string `gorm:"column:user_id;size:32;index;"`   // 用户id
+	DatasetId string `gorm:"column:dataset_id;size:32;index"` // 数据集id
+	Type      int    `gorm:"column:type;"`                    //可用类型  1 只读 2 可编辑
+}
+
+// UserDatasets UserDataset列表
+type UserDatasets []*UserDataset
+
+// ToSchemaUserDatasets 转换为UserDataset对象列表
+func (a UserDatasets) ToSchemaUserDatasets() []*schema.UserDataset {
+	list := make([]*schema.UserDataset, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaUserDataset()
+	}
+	return list
+}

+ 55 - 0
app/model/entity/e_user_role.go

@@ -0,0 +1,55 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/schema"
+)
+
+// GetUserRoleDB 获取User存储
+func GetUserRoleDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	return getDBWithModel(ctx, defDB, UserRole{})
+}
+
+// SchemaUserRole UserRole对象
+type SchemaUserRole schema.UserRole
+
+// ToUserRole 转换为UserRole实体
+func (a SchemaUserRole) ToUserRole() *UserRole {
+	item := &UserRole{
+		RecordId: a.RecordId,
+		UserID:   a.UserId,
+		RoleID:   a.RoleId,
+	}
+	return item
+}
+
+// ToSchemaUserRole 转换为UserRole对象
+func (a UserRole) ToSchemaUserRole() *schema.UserRole {
+	item := &schema.UserRole{
+		RecordId: a.RecordId,
+		UserId:   a.UserID,
+		RoleId:   a.RoleID,
+	}
+	return item
+}
+
+// UserRole 用户角色关联实体
+type UserRole struct {
+	gorm.Model
+	RecordId string `gorm:"column:record_id;size:32;index;"` // 记录id
+	UserID   string `gorm:"column:user_id;size:32;index;"`   // 用户id
+	RoleID   string `gorm:"column:role_id;size:32;index;"`   // 角色id
+}
+
+// UserRoles UserRole列表
+type UserRoles []*UserRole
+
+// ToSchemaUsersRoles 转换为UserRole对象列表
+func (a UserRoles) ToSchemaUserRoles() []*schema.UserRole {
+	list := make([]*schema.UserRole, len(a))
+	for i, item := range a {
+		list[i] = item.ToSchemaUserRole()
+	}
+	return list
+}

+ 26 - 0
app/model/entity/entity.go

@@ -0,0 +1,26 @@
+package entity
+
+import (
+	"context"
+	"gorm.io/gorm"
+	iContext "yx-dataset-server/app/context"
+)
+
+
+func getDB(ctx context.Context, defDB *gorm.DB) *gorm.DB {
+	trans, ok := iContext.FromTrans(ctx)
+	if ok {
+		db, ok := trans.(*gorm.DB)
+		if ok {
+			if iContext.FromTransLock(ctx) {
+				db = db.Set("gorm:query_option", "FOR UPDATE")
+			}
+			return db
+		}
+	}
+	return defDB
+}
+
+func getDBWithModel(ctx context.Context, defDB *gorm.DB, m interface{}) *gorm.DB {
+	return getDB(ctx, defDB).Model(m).WithContext(ctx)
+}

+ 109 - 0
app/model/impl/model/m_chat_assistant.go

@@ -0,0 +1,109 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewChatAssistant 创建ChatAssistant存储实例
+func NewChatAssistant(db *gorm.DB) *ChatAssistant {
+	return &ChatAssistant{db}
+}
+
+// ChatAssistant ChatAssistant存储
+type ChatAssistant struct {
+	db *gorm.DB
+}
+
+func (a *ChatAssistant) getQueryOption(opts ...schema.ChatAssistantQueryOptions) schema.ChatAssistantQueryOptions {
+	var opt schema.ChatAssistantQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *ChatAssistant) Query(ctx context.Context, params schema.ChatAssistantQueryParam, opts ...schema.ChatAssistantQueryOptions) (*schema.ChatAssistantQueryResult, error) {
+	db := entity.GetChatAssistantDB(ctx, a.db)
+	if v := params.OrgId; v != "" {
+		db = db.Where("org_id=?", v)
+	}
+
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.ChatAssistants
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.ChatAssistantQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaChatAssistants(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *ChatAssistant) Get(ctx context.Context, recordID string, opts ...schema.ChatAssistantQueryOptions) (*schema.ChatAssistant, error) {
+	db := entity.GetChatAssistantDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.ChatAssistant
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaChatAssistant(), nil
+}
+
+// Create 创建数据
+func (a *ChatAssistant) Create(ctx context.Context, item schema.ChatAssistant) error {
+	ChatAssistant := entity.SchemaChatAssistant(item).ToChatAssistant()
+	result := entity.GetChatAssistantDB(ctx, a.db).Create(ChatAssistant)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *ChatAssistant) Update(ctx context.Context, recordID string, item schema.ChatAssistant) error {
+	ChatAssistant := entity.SchemaChatAssistant(item).ToChatAssistant()
+	result := entity.GetChatAssistantDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(ChatAssistant)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *ChatAssistant) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetChatAssistantDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.ChatAssistant{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *ChatAssistant) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetChatAssistantDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 105 - 0
app/model/impl/model/m_chat_dataset.go

@@ -0,0 +1,105 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewChatDataset 创建ChatDataset存储实例
+func NewChatDataset(db *gorm.DB) *ChatDataset {
+	return &ChatDataset{db}
+}
+
+// ChatDataset ChatDataset存储
+type ChatDataset struct {
+	db *gorm.DB
+}
+
+func (a *ChatDataset) getQueryOption(opts ...schema.ChatDatasetQueryOptions) schema.ChatDatasetQueryOptions {
+	var opt schema.ChatDatasetQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *ChatDataset) Query(ctx context.Context, params schema.ChatDatasetQueryParam, opts ...schema.ChatDatasetQueryOptions) (*schema.ChatDatasetQueryResult, error) {
+	db := entity.GetChatDatasetDB(ctx, a.db)
+	if v := params.ChatId; v != "" {
+		db = db.Where("chat_id=?", v)
+	}
+
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.ChatDatasets
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.ChatDatasetQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaChatDatasets(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *ChatDataset) Get(ctx context.Context, recordID string, opts ...schema.ChatDatasetQueryOptions) (*schema.ChatDataset, error) {
+	db := entity.GetChatDatasetDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.ChatDataset
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaChatDataset(), nil
+}
+
+// Create 创建数据
+func (a *ChatDataset) Create(ctx context.Context, item schema.ChatDataset) error {
+	ChatDataset := entity.SchemaChatDataset(item).ToChatDataset()
+	result := entity.GetChatDatasetDB(ctx, a.db).Create(ChatDataset)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *ChatDataset) Update(ctx context.Context, recordID string, item schema.ChatDataset) error {
+	ChatDataset := entity.SchemaChatDataset(item).ToChatDataset()
+	result := entity.GetChatDatasetDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(ChatDataset)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *ChatDataset) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetChatDatasetDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.ChatDataset{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *ChatDataset) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetChatDatasetDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 113 - 0
app/model/impl/model/m_chat_message.go

@@ -0,0 +1,113 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewChatMessage 创建ChatMessage存储实例
+func NewChatMessage(db *gorm.DB) *ChatMessage {
+	return &ChatMessage{db}
+}
+
+// ChatMessage ChatMessage存储
+type ChatMessage struct {
+	db *gorm.DB
+}
+
+func (a *ChatMessage) getQueryOption(opts ...schema.ChatMessageQueryOptions) schema.ChatMessageQueryOptions {
+	var opt schema.ChatMessageQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *ChatMessage) Query(ctx context.Context, params schema.ChatMessageQueryParam, opts ...schema.ChatMessageQueryOptions) (*schema.ChatMessageQueryResult, error) {
+	db := entity.GetChatMessageDB(ctx, a.db)
+	if v := params.AssistantId; v != "" {
+		db = db.Where("assistant_id = ?", v)
+	}
+
+	if v := params.SessionId; v != "" {
+		db = db.Where("session_id = ?", v)
+	}
+
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.ChatMessages
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.ChatMessageQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaChatMessages(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *ChatMessage) Get(ctx context.Context, recordID string, opts ...schema.ChatMessageQueryOptions) (*schema.ChatMessage, error) {
+	db := entity.GetChatMessageDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.ChatMessage
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaChatMessage(), nil
+}
+
+// Create 创建数据
+func (a *ChatMessage) Create(ctx context.Context, item schema.ChatMessage) error {
+	ChatMessage := entity.SchemaChatMessage(item).ToChatMessage()
+	result := entity.GetChatMessageDB(ctx, a.db).Create(ChatMessage)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *ChatMessage) Update(ctx context.Context, recordID string, item schema.ChatMessage) error {
+	ChatMessage := entity.SchemaChatMessage(item).ToChatMessage()
+	result := entity.GetChatMessageDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(ChatMessage)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *ChatMessage) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetChatMessageDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.ChatMessage{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *ChatMessage) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetChatMessageDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 105 - 0
app/model/impl/model/m_chat_session.go

@@ -0,0 +1,105 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewChatSession 创建ChatSession存储实例
+func NewChatSession(db *gorm.DB) *ChatSession {
+	return &ChatSession{db}
+}
+
+// ChatSession ChatSession存储
+type ChatSession struct {
+	db *gorm.DB
+}
+
+func (a *ChatSession) getQueryOption(opts ...schema.ChatSessionQueryOptions) schema.ChatSessionQueryOptions {
+	var opt schema.ChatSessionQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *ChatSession) Query(ctx context.Context, params schema.ChatSessionQueryParam, opts ...schema.ChatSessionQueryOptions) (*schema.ChatSessionQueryResult, error) {
+	db := entity.GetChatSessionDB(ctx, a.db)
+	if v := params.AssistantId; v != "" {
+		db = db.Where("assistant_id=?", v)
+	}
+
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.ChatSessions
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.ChatSessionQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaChatSessions(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *ChatSession) Get(ctx context.Context, recordID string, opts ...schema.ChatSessionQueryOptions) (*schema.ChatSession, error) {
+	db := entity.GetChatSessionDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.ChatSession
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaChatSession(), nil
+}
+
+// Create 创建数据
+func (a *ChatSession) Create(ctx context.Context, item schema.ChatSession) error {
+	ChatSession := entity.SchemaChatSession(item).ToChatSession()
+	result := entity.GetChatSessionDB(ctx, a.db).Create(ChatSession)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *ChatSession) Update(ctx context.Context, recordID string, item schema.ChatSession) error {
+	ChatSession := entity.SchemaChatSession(item).ToChatSession()
+	result := entity.GetChatSessionDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(ChatSession)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *ChatSession) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetChatSessionDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.ChatSession{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *ChatSession) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetChatSessionDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 149 - 0
app/model/impl/model/m_dataset.go

@@ -0,0 +1,149 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewDataset 创建Dataset存储实例
+func NewDataset(db *gorm.DB) *Dataset {
+	return &Dataset{db}
+}
+
+// Dataset Dataset存储
+type Dataset struct {
+	db *gorm.DB
+}
+
+func (a *Dataset) getQueryOption(opts ...schema.DatasetQueryOptions) schema.DatasetQueryOptions {
+	var opt schema.DatasetQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *Dataset) Query(ctx context.Context, params schema.DatasetQueryParam, opts ...schema.DatasetQueryOptions) (*schema.DatasetQueryResult, error) {
+	db := entity.GetDatasetDB(ctx, a.db)
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+	if v := params.OrgId; v != "" {
+		db = db.Where("org_id=?", v)
+	}
+	if v := params.RecordIds; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+
+	db = db.Order("sequence ASC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.Datasets
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.DatasetQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaDatasets(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *Dataset) Get(ctx context.Context, recordID string, opts ...schema.DatasetQueryOptions) (*schema.Dataset, error) {
+	db := entity.GetDatasetDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.Dataset
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaDataset(), nil
+}
+
+// Create 创建数据
+func (a *Dataset) Create(ctx context.Context, item schema.Dataset) error {
+	Dataset := entity.SchemaDataset(item).ToDataset()
+	result := entity.GetDatasetDB(ctx, a.db).Create(Dataset)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *Dataset) Update(ctx context.Context, recordID string, item schema.Dataset) error {
+	Dataset := entity.SchemaDataset(item).ToDataset()
+	result := entity.GetDatasetDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(Dataset)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *Dataset) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetDatasetDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.Dataset{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// DeleteByOrgId 删除数据
+func (a *Dataset) DeleteByOrgId(ctx context.Context, orgId string) error {
+	result := entity.GetDatasetDB(ctx, a.db).Where("org_id=?", orgId).Delete(entity.Dataset{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *Dataset) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetDatasetDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+//// UpdateSequence 更新排序
+//func (a *Dataset) UpdateSequence(ctx context.Context, recordID string, sequence int) error {
+//	result := entity.GetDatasetDB(ctx, a.db).Where("record_id=?", recordID).Update("sequence", sequence)
+//	if err := result.Error; err != nil {
+//		return errors.ErrDBServerInternalError
+//	}
+//	return nil
+//}
+//
+//// UpdateBatchSequenceMinus 批量排序-1
+//func (a *Dataset) UpdateBatchSequenceMinus(ctx context.Context, oldSequence, sequence int) error {
+//	result := entity.GetDatasetDB(ctx, a.db).Where("sequence <= ? and sequence > ?", sequence, oldSequence).Update("sequence", gorm.Expr("sequence - 1"))
+//	if err := result.Error; err != nil {
+//		return errors.ErrDBServerInternalError
+//	}
+//	return nil
+//}
+//
+//// GetMaxSequence 查询最大排序值
+//func (a *Dataset) GetMaxSequence(ctx context.Context) (int, error) {
+//	var maxSeq int
+//	result := entity.GetDatasetDB(ctx, a.db).Select("MAX(sequence) as sequence")
+//	if result == nil {
+//		return maxSeq, nil
+//	}
+//	if err := result.Error; err != nil {
+//		return 0, errors.ErrDBServerInternalError
+//	}
+//	result.Scan(&maxSeq)
+//	return maxSeq, nil
+//}

+ 141 - 0
app/model/impl/model/m_dataset_file.go

@@ -0,0 +1,141 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewDatasetFile 创建DatasetFile存储实例
+func NewDatasetFile(db *gorm.DB) *DatasetFile {
+	return &DatasetFile{db}
+}
+
+// DatasetFile DatasetFile存储
+type DatasetFile struct {
+	db *gorm.DB
+}
+
+func (a *DatasetFile) getQueryOption(opts ...schema.DatasetFileQueryOptions) schema.DatasetFileQueryOptions {
+	var opt schema.DatasetFileQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *DatasetFile) Query(ctx context.Context, params schema.DatasetFileQueryParam, opts ...schema.DatasetFileQueryOptions) (*schema.DatasetFileQueryResult, error) {
+	db := entity.GetDatasetFileDB(ctx, a.db)
+	if v := params.DatasetId; v != "" {
+		db = db.Where("dataset_id=?", v)
+	}
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.DatasetFiles
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.DatasetFileQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaDatasetFiles(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *DatasetFile) Get(ctx context.Context, recordID string, opts ...schema.DatasetFileQueryOptions) (*schema.DatasetFile, error) {
+	db := entity.GetDatasetFileDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.DatasetFile
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaDatasetFile(), nil
+}
+
+// Create 创建数据
+func (a *DatasetFile) Create(ctx context.Context, item schema.DatasetFile) error {
+	DatasetFile := entity.SchemaDatasetFile(item).ToDatasetFile()
+	result := entity.GetDatasetFileDB(ctx, a.db).Create(DatasetFile)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *DatasetFile) Update(ctx context.Context, recordID string, item schema.DatasetFile) error {
+	DatasetFile := entity.SchemaDatasetFile(item).ToDatasetFile()
+	result := entity.GetDatasetFileDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(DatasetFile)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *DatasetFile) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetDatasetFileDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.DatasetFile{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// BatchDelete 删除数据
+func (a *DatasetFile) BatchDelete(ctx context.Context, recordIDs []string) error {
+	result := entity.GetDatasetFileDB(ctx, a.db).Where("record_id in (?)", recordIDs).Delete(entity.DatasetFile{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// DeleteByDatasetId 删除数据
+func (a *DatasetFile) DeleteByDatasetIds(ctx context.Context, datasetIds []string) error {
+	result := entity.GetDatasetFileDB(ctx, a.db).Where("dataset_id in (?)", datasetIds).Delete(entity.DatasetFile{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *DatasetFile) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetDatasetFileDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateParseStatus 更新解析状态
+func (a *DatasetFile) UpdateParseStatus(ctx context.Context, recordID string, status bool) error {
+	result := entity.GetDatasetFileDB(ctx, a.db).Where("record_id = ?", recordID).Update("parse_status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateEnabled 更新启用状态
+func (a *DatasetFile) UpdateEnabled(ctx context.Context, recordID string, status bool) error {
+	result := entity.GetDatasetFileDB(ctx, a.db).Where("record_id=?", recordID).Update("enabled", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 113 - 0
app/model/impl/model/m_login_history.go

@@ -0,0 +1,113 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewLoginHistory 创建LoginHistory存储实例
+func NewLoginHistory(db *gorm.DB) *LoginHistory {
+	return &LoginHistory{db}
+}
+
+// LoginHistory LoginHistory存储
+type LoginHistory struct {
+	db *gorm.DB
+}
+
+func (a *LoginHistory) getQueryOption(opts ...schema.LoginHistoryQueryOptions) schema.LoginHistoryQueryOptions {
+	var opt schema.LoginHistoryQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *LoginHistory) Query(ctx context.Context, params schema.LoginHistoryQueryParam, opts ...schema.LoginHistoryQueryOptions) (*schema.LoginHistoryQueryResult, error) {
+	db := entity.GetLoginHistoryDB(ctx, a.db)
+	if v := params.Code; v != "" {
+		db = db.Where("code=?", v)
+	}
+	if v := params.LikeCode; v != "" {
+		db = db.Where("code LIKE ?", "%"+v+"%")
+	}
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+	if v := params.Status; v > 0 {
+		db = db.Where("status=?", v)
+	}
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.LoginHistorys
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.LoginHistoryQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaLoginHistorys(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *LoginHistory) Get(ctx context.Context, recordID string, opts ...schema.LoginHistoryQueryOptions) (*schema.LoginHistory, error) {
+	db := entity.GetLoginHistoryDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.LoginHistory
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaLoginHistory(), nil
+}
+
+// Create 创建数据
+func (a *LoginHistory) Create(ctx context.Context, item schema.LoginHistory) error {
+	LoginHistory := entity.SchemaLoginHistory(item).ToLoginHistory()
+	result := entity.GetLoginHistoryDB(ctx, a.db).Create(LoginHistory)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *LoginHistory) Update(ctx context.Context, recordID string, item schema.LoginHistory) error {
+	LoginHistory := entity.SchemaLoginHistory(item).ToLoginHistory()
+	result := entity.GetLoginHistoryDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(LoginHistory)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *LoginHistory) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetLoginHistoryDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.LoginHistory{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *LoginHistory) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetLoginHistoryDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 133 - 0
app/model/impl/model/m_menu.go

@@ -0,0 +1,133 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewMenu 创建Menu存储实例
+func NewMenu(db *gorm.DB) *Menu {
+	return &Menu{db}
+}
+
+// Menu Menu存储
+type Menu struct {
+	db *gorm.DB
+}
+
+func (a *Menu) getQueryOption(opts ...schema.MenuQueryOptions) schema.MenuQueryOptions {
+	var opt schema.MenuQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *Menu) Query(ctx context.Context, params schema.MenuQueryParam, opts ...schema.MenuQueryOptions) (*schema.MenuQueryResult, error) {
+	db := entity.GetMenuDB(ctx, a.db)
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("sequence ASC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.Menus
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.MenuQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaMenus(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *Menu) Get(ctx context.Context, recordID string, opts ...schema.MenuQueryOptions) (*schema.Menu, error) {
+	db := entity.GetMenuDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.Menu
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaMenu(), nil
+}
+
+// Create 创建数据
+func (a *Menu) Create(ctx context.Context, item schema.Menu) error {
+	Menu := entity.SchemaMenu(item).ToMenu()
+	result := entity.GetMenuDB(ctx, a.db).Create(Menu)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *Menu) Update(ctx context.Context, recordID string, item schema.Menu) error {
+	Menu := entity.SchemaMenu(item).ToMenu()
+	result := entity.GetMenuDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(Menu)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *Menu) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetMenuDB(ctx, a.db).Where("record_id=? or parent_id = ?", recordID, recordID).Delete(entity.Menu{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *Menu) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetMenuDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateSequence 更新排序
+func (a *Menu) UpdateSequence(ctx context.Context, recordID string, sequence int) error {
+	// 严格按照你的 UpdateStatus 格式编写
+	result := entity.GetMenuDB(ctx, a.db).Where("record_id=?", recordID).Update("sequence", sequence)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateBatchSequenceMinus 批量排序-1
+func (a *Menu) UpdateBatchSequenceMinus(ctx context.Context, oldSequence, sequence int) error {
+	result := entity.GetMenuDB(ctx, a.db).Where("sequence <= ? and sequence > ?", sequence, oldSequence).Update("sequence", gorm.Expr("sequence - 1"))
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// GetMaxSequence 查询菜单 sequence 排序字段的最大值
+func (a *Menu) GetMaxSequence(ctx context.Context) (int, error) {
+	var maxSeq int
+	result := entity.GetMenuDB(ctx, a.db).Select("MAX(sequence)").Scan(&maxSeq)
+	if err := result.Error; err != nil {
+		return 0, errors.ErrDBServerInternalError
+	}
+	return maxSeq, nil
+}

+ 118 - 0
app/model/impl/model/m_organization.go

@@ -0,0 +1,118 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewOrganization 创建Organization存储实例
+func NewOrganization(db *gorm.DB) *Organization {
+	return &Organization{db}
+}
+
+// Organization Organization存储
+type Organization struct {
+	db *gorm.DB
+}
+
+func (a *Organization) getQueryOption(opts ...schema.OrganizationQueryOptions) schema.OrganizationQueryOptions {
+	var opt schema.OrganizationQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *Organization) Query(ctx context.Context, params schema.OrganizationQueryParam, opts ...schema.OrganizationQueryOptions) (*schema.OrganizationQueryResult, error) {
+	db := entity.GetOrganizationDB(ctx, a.db)
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+	if v := params.RecordIds; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("Sequence ASC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.Organizations
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.OrganizationQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaOrganizations(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *Organization) Get(ctx context.Context, recordID string, opts ...schema.OrganizationQueryOptions) (*schema.Organization, error) {
+	db := entity.GetOrganizationDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.Organization
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaOrganization(), nil
+}
+
+// Get 查询指定数据
+func (a *Organization) GetByName(ctx context.Context, name string, opts ...schema.OrganizationQueryOptions) (*schema.Organization, error) {
+	db := entity.GetOrganizationDB(ctx, a.db).Where("name=?", name)
+	var item entity.Organization
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaOrganization(), nil
+}
+
+// Create 创建数据
+func (a *Organization) Create(ctx context.Context, item schema.Organization) error {
+	Organization := entity.SchemaOrganization(item).ToOrganization()
+	result := entity.GetOrganizationDB(ctx, a.db).Create(Organization)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *Organization) Update(ctx context.Context, recordID string, item schema.Organization) error {
+	Organization := entity.SchemaOrganization(item).ToOrganization()
+	result := entity.GetOrganizationDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(Organization)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *Organization) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetOrganizationDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.Organization{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *Organization) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetOrganizationDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 113 - 0
app/model/impl/model/m_robot_config.go

@@ -0,0 +1,113 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewRobotConfig 创建RobotConfig存储实例
+func NewRobotConfig(db *gorm.DB) *RobotConfig {
+	return &RobotConfig{db}
+}
+
+// RobotConfig RobotConfig存储
+type RobotConfig struct {
+	db *gorm.DB
+}
+
+func (a *RobotConfig) getQueryOption(opts ...schema.RobotConfigQueryOptions) schema.RobotConfigQueryOptions {
+	var opt schema.RobotConfigQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *RobotConfig) Query(ctx context.Context, params schema.RobotConfigQueryParam, opts ...schema.RobotConfigQueryOptions) (*schema.RobotConfigQueryResult, error) {
+	db := entity.GetRobotConfigDB(ctx, a.db)
+	if v := params.Code; v != "" {
+		db = db.Where("code=?", v)
+	}
+	if v := params.LikeCode; v != "" {
+		db = db.Where("code LIKE ?", "%"+v+"%")
+	}
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+	if v := params.Status; v > 0 {
+		db = db.Where("status=?", v)
+	}
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.RobotConfigs
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.RobotConfigQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaRobotConfigs(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *RobotConfig) Get(ctx context.Context, recordID string, opts ...schema.RobotConfigQueryOptions) (*schema.RobotConfig, error) {
+	db := entity.GetRobotConfigDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.RobotConfig
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaRobotConfig(), nil
+}
+
+// Create 创建数据
+func (a *RobotConfig) Create(ctx context.Context, item schema.RobotConfig) error {
+	RobotConfig := entity.SchemaRobotConfig(item).ToRobotConfig()
+	result := entity.GetRobotConfigDB(ctx, a.db).Create(RobotConfig)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *RobotConfig) Update(ctx context.Context, recordID string, item schema.RobotConfig) error {
+	RobotConfig := entity.SchemaRobotConfig(item).ToRobotConfig()
+	result := entity.GetRobotConfigDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(RobotConfig)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *RobotConfig) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetRobotConfigDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.RobotConfig{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *RobotConfig) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetRobotConfigDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 113 - 0
app/model/impl/model/m_robot_dataset.go

@@ -0,0 +1,113 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewRobotDataset 创建RobotDataset存储实例
+func NewRobotDataset(db *gorm.DB) *RobotDataset {
+	return &RobotDataset{db}
+}
+
+// RobotDataset RobotDataset存储
+type RobotDataset struct {
+	db *gorm.DB
+}
+
+func (a *RobotDataset) getQueryOption(opts ...schema.RobotDatasetQueryOptions) schema.RobotDatasetQueryOptions {
+	var opt schema.RobotDatasetQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *RobotDataset) Query(ctx context.Context, params schema.RobotDatasetQueryParam, opts ...schema.RobotDatasetQueryOptions) (*schema.RobotDatasetQueryResult, error) {
+	db := entity.GetRobotDatasetDB(ctx, a.db)
+	if v := params.Code; v != "" {
+		db = db.Where("code=?", v)
+	}
+	if v := params.LikeCode; v != "" {
+		db = db.Where("code LIKE ?", "%"+v+"%")
+	}
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+	if v := params.Status; v > 0 {
+		db = db.Where("status=?", v)
+	}
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.RobotDatasets
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.RobotDatasetQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaRobotDatasets(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *RobotDataset) Get(ctx context.Context, recordID string, opts ...schema.RobotDatasetQueryOptions) (*schema.RobotDataset, error) {
+	db := entity.GetRobotDatasetDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.RobotDataset
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaRobotDataset(), nil
+}
+
+// Create 创建数据
+func (a *RobotDataset) Create(ctx context.Context, item schema.RobotDataset) error {
+	RobotDataset := entity.SchemaRobotDataset(item).ToRobotDataset()
+	result := entity.GetRobotDatasetDB(ctx, a.db).Create(RobotDataset)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *RobotDataset) Update(ctx context.Context, recordID string, item schema.RobotDataset) error {
+	RobotDataset := entity.SchemaRobotDataset(item).ToRobotDataset()
+	result := entity.GetRobotDatasetDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(RobotDataset)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *RobotDataset) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetRobotDatasetDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.RobotDataset{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *RobotDataset) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetRobotDatasetDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 104 - 0
app/model/impl/model/m_role.go

@@ -0,0 +1,104 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewRole 创建Role存储实例
+func NewRole(db *gorm.DB) *Role {
+	return &Role{db}
+}
+
+// Role Role存储
+type Role struct {
+	db *gorm.DB
+}
+
+func (a *Role) getQueryOption(opts ...schema.RoleQueryOptions) schema.RoleQueryOptions {
+	var opt schema.RoleQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *Role) Query(ctx context.Context, params schema.RoleQueryParam, opts ...schema.RoleQueryOptions) (*schema.RoleQueryResult, error) {
+	db := entity.GetRoleDB(ctx, a.db)
+	if v := params.Code; v != "" {
+		db = db.Where("code=?", v)
+	}
+	if v := params.LikeCode; v != "" {
+		db = db.Where("code LIKE ?", "%"+v+"%")
+	}
+	if v := params.LikeName; v != "" {
+		db = db.Where("name LIKE ?", "%"+v+"%")
+	}
+	if v := params.Status; v > 0 {
+		db = db.Where("status=?", v)
+	}
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.Roles
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.RoleQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaRoles(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *Role) Get(ctx context.Context, recordID string, opts ...schema.RoleQueryOptions) (*schema.Role, error) {
+	db := entity.GetRoleDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.Role
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaRole(), nil
+}
+
+// Create 创建数据
+func (a *Role) Create(ctx context.Context, item schema.Role) error {
+	Role := entity.SchemaRole(item).ToRole()
+	result := entity.GetRoleDB(ctx, a.db).Create(Role)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *Role) Update(ctx context.Context, recordID string, item schema.Role) error {
+	Role := entity.SchemaRole(item).ToRole()
+	result := entity.GetRoleDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(Role)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *Role) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetRoleDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.Role{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 113 - 0
app/model/impl/model/m_role_menu.go

@@ -0,0 +1,113 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewRoleMenu 创建RoleMenu存储实例
+func NewRoleMenu(db *gorm.DB) *RoleMenu {
+	return &RoleMenu{db}
+}
+
+// RoleMenu RoleMenu存储
+type RoleMenu struct {
+	db *gorm.DB
+}
+
+func (a *RoleMenu) getQueryOption(opts ...schema.RoleMenuQueryOptions) schema.RoleMenuQueryOptions {
+	var opt schema.RoleMenuQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *RoleMenu) Query(ctx context.Context, params schema.RoleMenuQueryParam, opts ...schema.RoleMenuQueryOptions) (*schema.RoleMenuQueryResult, error) {
+	db := entity.GetRoleMenuDB(ctx, a.db)
+	if v := params.RoleId; v != "" {
+		db = db.Where("role_id=?", v)
+	}
+	if v := params.RoleIds; len(v) > 0 {
+		db = db.Where("role_id in (?)", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.RoleMenus
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.RoleMenuQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaRoleMenus(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *RoleMenu) Get(ctx context.Context, recordID string, opts ...schema.RoleMenuQueryOptions) (*schema.RoleMenu, error) {
+	db := entity.GetRoleMenuDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.RoleMenu
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaRoleMenu(), nil
+}
+
+// Create 创建数据
+func (a *RoleMenu) Create(ctx context.Context, item schema.RoleMenu) error {
+	RoleMenu := entity.SchemaRoleMenu(item).ToRoleMenu()
+	result := entity.GetRoleMenuDB(ctx, a.db).Create(RoleMenu)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *RoleMenu) Update(ctx context.Context, recordID string, item schema.RoleMenu) error {
+	RoleMenu := entity.SchemaRoleMenu(item).ToRoleMenu()
+	result := entity.GetRoleMenuDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(RoleMenu)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// DeleteByRoleId 删除数据
+func (a *RoleMenu) DeleteByRoleId(ctx context.Context, roleId string) error {
+	result := entity.GetRoleMenuDB(ctx, a.db).Where("role_id=?", roleId).Delete(entity.RoleMenu{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *RoleMenu) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetRoleMenuDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.RoleMenu{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *RoleMenu) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetRoleMenuDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 54 - 0
app/model/impl/model/m_trans.go

@@ -0,0 +1,54 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+)
+
+// NewTrans 创建事务管理实例
+func NewTrans(db *gorm.DB) *Trans {
+	return &Trans{db}
+}
+
+// Trans 事务管理
+type Trans struct {
+	db *gorm.DB
+}
+
+// Begin 开启事务
+func (a *Trans) Begin(ctx context.Context) (interface{}, error) {
+	result := a.db.Begin()
+	if err := result.Error; err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	return result, nil
+}
+
+// Commit 提交事务
+func (a *Trans) Commit(ctx context.Context, trans interface{}) error {
+	db, ok := trans.(*gorm.DB)
+	if !ok {
+		return errors.New("unknow trans")
+	}
+
+	result := db.Commit()
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Rollback 回滚事务
+func (a *Trans) Rollback(ctx context.Context, trans interface{}) error {
+	db, ok := trans.(*gorm.DB)
+	if !ok {
+		return errors.New("unknow trans")
+	}
+
+	result := db.Rollback()
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 124 - 0
app/model/impl/model/m_user.go

@@ -0,0 +1,124 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewUser 创建User存储实例
+func NewUser(db *gorm.DB) *User {
+	return &User{db}
+}
+
+// User User存储
+type User struct {
+	db *gorm.DB
+}
+
+func (a *User) getQueryOption(opts ...schema.UserOptions) schema.UserOptions {
+	var opt schema.UserOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *User) Query(ctx context.Context, params schema.UserQueryParam, opts ...schema.UserOptions) (*schema.UserQueryResult, error) {
+	db := entity.GetUserDB(ctx, a.db)
+
+	if v := params.LikeName; v != "" {
+		db = db.Where("real_name LIKE ?", "%"+v+"%")
+	}
+
+	if v := params.RecordIDs; len(v) > 0 {
+		db = db.Where("record_id in (?)", v)
+	}
+
+	if v := params.OrgId; v != "" {
+		db = db.Where("org_id=?", v)
+	}
+	if v := params.RoleCode; len(v) > 0 {
+		subQuery := entity.GetRoleDB(ctx, a.db).Where("code in (?)", v).Select("role_id")
+		db = db.Where("role_id in (?)", subQuery)
+	}
+
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.Users
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.UserQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaUsers(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *User) Get(ctx context.Context, recordID string, opts ...schema.UserOptions) (*schema.User, error) {
+	db := entity.GetUserDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.User
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaUser(), nil
+}
+
+// Create 创建数据
+func (a *User) Create(ctx context.Context, item schema.User) error {
+	User := entity.SchemaUser(item).ToUser()
+	result := entity.GetUserDB(ctx, a.db).Create(User)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *User) Update(ctx context.Context, recordID string, item schema.User) error {
+	User := entity.SchemaUser(item).ToUser()
+	result := entity.GetUserDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(User)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *User) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetUserDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.User{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *User) UpdateStatus(ctx context.Context, recordID string, status bool) error {
+	result := entity.GetUserDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdatePassword 更新密码
+func (a *User) UpdatePassword(ctx context.Context, recordID, password string) error {
+	result := entity.GetUserDB(ctx, a.db).Where("record_id=?", recordID).Update("password", password)
+	if err := result.Error; err != nil {
+		return errors.WithStack(err)
+	}
+	return nil
+}

+ 110 - 0
app/model/impl/model/m_user_dataset.go

@@ -0,0 +1,110 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewUserDataset 创建UserDataset存储实例
+func NewUserDataset(db *gorm.DB) *UserDataset {
+	return &UserDataset{db}
+}
+
+// UserDataset UserDataset存储
+type UserDataset struct {
+	db *gorm.DB
+}
+
+func (a *UserDataset) getQueryOption(opts ...schema.UserDatasetQueryOptions) schema.UserDatasetQueryOptions {
+	var opt schema.UserDatasetQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *UserDataset) Query(ctx context.Context, params schema.UserDatasetQueryParam, opts ...schema.UserDatasetQueryOptions) (*schema.UserDatasetQueryResult, error) {
+	db := entity.GetUserDatasetDB(ctx, a.db)
+	if v := params.UserId; v != "" {
+		db = db.Where("user_id = ?", v)
+	}
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.UserDatasets
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.UserDatasetQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaUserDatasets(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *UserDataset) Get(ctx context.Context, recordID string, opts ...schema.UserDatasetQueryOptions) (*schema.UserDataset, error) {
+	db := entity.GetUserDatasetDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.UserDataset
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaUserDataset(), nil
+}
+
+// Create 创建数据
+func (a *UserDataset) Create(ctx context.Context, item schema.UserDataset) error {
+	UserDataset := entity.SchemaUserDataset(item).ToUserDataset()
+	result := entity.GetUserDatasetDB(ctx, a.db).Create(UserDataset)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *UserDataset) Update(ctx context.Context, recordID string, item schema.UserDataset) error {
+	UserDataset := entity.SchemaUserDataset(item).ToUserDataset()
+	result := entity.GetUserDatasetDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(UserDataset)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *UserDataset) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetUserDatasetDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.UserDataset{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// DeleteByUserId 删除数据
+func (a *UserDataset) DeleteByUserId(ctx context.Context, recordID string) error {
+	result := entity.GetUserDatasetDB(ctx, a.db).Where("user_id=?", recordID).Delete(entity.UserDataset{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *UserDataset) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetUserDatasetDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 106 - 0
app/model/impl/model/m_user_role.go

@@ -0,0 +1,106 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"yx-dataset-server/app/errors"
+	"yx-dataset-server/app/model/entity"
+	"yx-dataset-server/app/schema"
+)
+
+// NewUserRole 创建UserRole存储实例
+func NewUserRole(db *gorm.DB) *UserRole {
+	return &UserRole{db}
+}
+
+// UserRole UserRole存储
+type UserRole struct {
+	db *gorm.DB
+}
+
+func (a *UserRole) getQueryOption(opts ...schema.UserRoleQueryOptions) schema.UserRoleQueryOptions {
+	var opt schema.UserRoleQueryOptions
+	if len(opts) > 0 {
+		opt = opts[0]
+	}
+	return opt
+}
+
+// Query 查询数据
+func (a *UserRole) Query(ctx context.Context, params schema.UserRoleQueryParam, opts ...schema.UserRoleQueryOptions) (*schema.UserRoleQueryResult, error) {
+	db := entity.GetUserRoleDB(ctx, a.db)
+
+	if v := params.UserId; v != "" {
+		db = db.Where("user_id = ?", v)
+	}
+	if v := params.RoleId; v != "" {
+		db = db.Where("role_id = ?", v)
+	}
+
+	db = db.Order("id DESC")
+
+	opt := a.getQueryOption(opts...)
+	var list entity.UserRoles
+	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	}
+	qr := &schema.UserRoleQueryResult{
+		PageResult: pr,
+		Data:       list.ToSchemaUserRoles(),
+	}
+
+	return qr, nil
+}
+
+// Get 查询指定数据
+func (a *UserRole) Get(ctx context.Context, recordID string, opts ...schema.UserRoleQueryOptions) (*schema.UserRole, error) {
+	db := entity.GetUserRoleDB(ctx, a.db).Where("record_id=?", recordID)
+	var item entity.UserRole
+	ok, err := FindOne(ctx, db, &item)
+	if err != nil {
+		return nil, errors.ErrDBServerInternalError
+	} else if !ok {
+		return nil, nil
+	}
+
+	return item.ToSchemaUserRole(), nil
+}
+
+// Create 创建数据
+func (a *UserRole) Create(ctx context.Context, item schema.UserRole) error {
+	UserRole := entity.SchemaUserRole(item).ToUserRole()
+	result := entity.GetUserRoleDB(ctx, a.db).Create(UserRole)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Update 更新数据
+func (a *UserRole) Update(ctx context.Context, recordID string, item schema.UserRole) error {
+	UserRole := entity.SchemaUserRole(item).ToUserRole()
+	result := entity.GetUserRoleDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(UserRole)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// Delete 删除数据
+func (a *UserRole) Delete(ctx context.Context, recordID string) error {
+	result := entity.GetUserRoleDB(ctx, a.db).Where("record_id=?", recordID).Delete(entity.UserRole{})
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}
+
+// UpdateStatus 更新状态
+func (a *UserRole) UpdateStatus(ctx context.Context, recordID string, status int) error {
+	result := entity.GetUserRoleDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
+	if err := result.Error; err != nil {
+		return errors.ErrDBServerInternalError
+	}
+	return nil
+}

+ 124 - 0
app/model/impl/model/model.go

@@ -0,0 +1,124 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	iContext "yx-dataset-server/app/context"
+	"yx-dataset-server/app/schema"
+)
+
+// TransFunc 定义事务执行函数
+type TransFunc func(context.Context) error
+
+// ExecTrans 执行事务
+func ExecTrans(ctx context.Context, db *gorm.DB, fn TransFunc) error {
+	if _, ok := iContext.FromTrans(ctx); ok {
+		return fn(ctx)
+	}
+
+	transModel := NewTrans(db)
+	trans, err := transModel.Begin(ctx)
+	if err != nil {
+		return err
+	}
+
+	defer func() {
+		if r := recover(); r != nil {
+			_ = transModel.Rollback(ctx, trans)
+			panic(r)
+		}
+	}()
+
+	ctx = iContext.NewTrans(ctx, trans)
+	err = fn(ctx)
+	if err != nil {
+		_ = transModel.Rollback(ctx, trans)
+		return err
+	}
+	return transModel.Commit(ctx, trans)
+}
+
+// ExecTransWithLock 执行事务(加锁)
+func ExecTransWithLock(ctx context.Context, db *gorm.DB, fn TransFunc) error {
+	if !iContext.FromTransLock(ctx) {
+		ctx = iContext.NewTransLock(ctx)
+	}
+	return ExecTrans(ctx, db, fn)
+}
+
+// WrapPageQuery 包装带有分页的查询
+func WrapPageQuery(ctx context.Context, db *gorm.DB, pp *schema.PaginationParam, out interface{}) (*schema.PaginationResult, error) {
+	if pp != nil {
+		total, err := FindPage(ctx, db, pp.PageIndex, pp.PageSize, out)
+		if err != nil {
+			return nil, err
+		}
+		return &schema.PaginationResult{
+			Total: total,
+		}, nil
+	}
+
+	result := db.Find(out)
+	return nil, result.Error
+}
+
+// FindPage 查询分页数据
+func FindPage(ctx context.Context, db *gorm.DB, pageIndex, pageSize int, out interface{}) (int, error) {
+	selectTmp := db.Statement.Clauses["SELECT"]
+	var count int64
+	result := db.Count(&count)
+	db.Statement.Clauses["SELECT"] = selectTmp
+	if err := result.Error; err != nil {
+		return 0, err
+	} else if count == 0 {
+		return 0, nil
+	}
+
+	// 如果分页大小小于0或者分页索引小于0,则不查询数据
+	if pageSize < 0 || pageIndex < 0 {
+		return int(count), nil
+	}
+
+	if pageIndex > 0 && pageSize > 0 {
+		db = db.Offset((pageIndex - 1) * pageSize)
+	}
+	if pageSize > 0 {
+		db = db.Limit(pageSize)
+	}
+	result = db.Find(out)
+	if err := result.Error; err != nil {
+		return 0, err
+	}
+
+	return int(count), nil
+}
+
+// FindOne 查询单条数据
+func FindOne(ctx context.Context, db *gorm.DB, out interface{}) (bool, error) {
+	result := db.First(out)
+	if err := result.Error; err != nil {
+		if err == gorm.ErrRecordNotFound {
+			return false, nil
+		}
+		return false, err
+	}
+	return true, nil
+}
+
+// Check 检查数据是否存在
+func Check(ctx context.Context, db *gorm.DB) (bool, error) {
+	var count int64
+	result := db.Count(&count)
+	if err := result.Error; err != nil {
+		return false, err
+	}
+	return count > 0, nil
+}
+
+const maxNumberOfBatchParameters = 65535
+
+// OwnDb 实例化DB
+type OwnDb struct {
+	*gorm.DB
+}
+

+ 22 - 0
app/model/m_chat_assistant.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IChatAssistant ChatAssistant存储接口
+type IChatAssistant interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.ChatAssistantQueryParam, opts ...schema.ChatAssistantQueryOptions) (*schema.ChatAssistantQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.ChatAssistantQueryOptions) (*schema.ChatAssistant, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.ChatAssistant) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.ChatAssistant) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 22 - 0
app/model/m_chat_dataset.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IChatDataset ChatDataset存储接口
+type IChatDataset interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.ChatDatasetQueryParam, opts ...schema.ChatDatasetQueryOptions) (*schema.ChatDatasetQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.ChatDatasetQueryOptions) (*schema.ChatDataset, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.ChatDataset) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.ChatDataset) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 22 - 0
app/model/m_chat_message.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IChatMessage ChatMessage存储接口
+type IChatMessage interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.ChatMessageQueryParam, opts ...schema.ChatMessageQueryOptions) (*schema.ChatMessageQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.ChatMessageQueryOptions) (*schema.ChatMessage, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.ChatMessage) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.ChatMessage) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 22 - 0
app/model/m_chat_session.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IChatSession ChatSession存储接口
+type IChatSession interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.ChatSessionQueryParam, opts ...schema.ChatSessionQueryOptions) (*schema.ChatSessionQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.ChatSessionQueryOptions) (*schema.ChatSession, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.ChatSession) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.ChatSession) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 30 - 0
app/model/m_dataset.go

@@ -0,0 +1,30 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IDataset Dataset存储接口
+type IDataset interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.DatasetQueryParam, opts ...schema.DatasetQueryOptions) (*schema.DatasetQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.DatasetQueryOptions) (*schema.Dataset, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.Dataset) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.Dataset) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// DeleteByOrgId 删除数据
+	DeleteByOrgId(ctx context.Context, orgId string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+	//// UpdateSequence 更新排序
+	//UpdateSequence(ctx context.Context, recordID string, sequence int) error
+	//// UpdateBatchSequenceMinus 批量排序-1
+	//UpdateBatchSequenceMinus(ctx context.Context, oldSequence, sequence int) error
+	//// GetMaxSequence 查询最大排序值
+	//GetMaxSequence(ctx context.Context) (int, error)
+}

+ 30 - 0
app/model/m_dataset_file.go

@@ -0,0 +1,30 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IDatasetFile DatasetFile存储接口
+type IDatasetFile interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.DatasetFileQueryParam, opts ...schema.DatasetFileQueryOptions) (*schema.DatasetFileQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.DatasetFileQueryOptions) (*schema.DatasetFile, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.DatasetFile) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.DatasetFile) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// BatchDelete 删除数据
+	BatchDelete(ctx context.Context, recordIDs []string) error
+	// DeleteByDatasetId 删除数据
+	DeleteByDatasetIds(ctx context.Context, datasetIds []string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+	// UpdateParseStatus 更新解析状态
+	UpdateParseStatus(ctx context.Context, recordID string, status bool) error
+	// UpdateEnabled 更新启用状态
+	UpdateEnabled(ctx context.Context, recordID string, status bool) error
+}

+ 22 - 0
app/model/m_login_history.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// ILoginHistory LoginHistory存储接口
+type ILoginHistory interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.LoginHistoryQueryParam, opts ...schema.LoginHistoryQueryOptions) (*schema.LoginHistoryQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.LoginHistoryQueryOptions) (*schema.LoginHistory, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.LoginHistory) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.LoginHistory) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 28 - 0
app/model/m_menu.go

@@ -0,0 +1,28 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IMenu Menu存储接口
+type IMenu interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.MenuQueryParam, opts ...schema.MenuQueryOptions) (*schema.MenuQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.MenuQueryOptions) (*schema.Menu, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.Menu) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.Menu) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+	// UpdateSequence 更新排序
+	UpdateSequence(ctx context.Context, recordID string, sequence int) error
+	// UpdateBatchSequenceMinus 批量排序-1
+	UpdateBatchSequenceMinus(ctx context.Context, oldSequence, sequence int) error
+	// GetMaxSequence 查询菜单 sequence 排序字段的最大值
+	GetMaxSequence(ctx context.Context) (int, error)
+}

+ 24 - 0
app/model/m_organization.go

@@ -0,0 +1,24 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IOrganization Organization存储接口
+type IOrganization interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.OrganizationQueryParam, opts ...schema.OrganizationQueryOptions) (*schema.OrganizationQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.OrganizationQueryOptions) (*schema.Organization, error)
+	// 通过名称查询企业
+	GetByName(ctx context.Context, name string, opts ...schema.OrganizationQueryOptions) (*schema.Organization, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.Organization) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.Organization) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 22 - 0
app/model/m_robot_config.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IRobotConfig RobotConfig存储接口
+type IRobotConfig interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.RobotConfigQueryParam, opts ...schema.RobotConfigQueryOptions) (*schema.RobotConfigQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.RobotConfigQueryOptions) (*schema.RobotConfig, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.RobotConfig) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.RobotConfig) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 22 - 0
app/model/m_robot_dataset.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IRobotDataset RobotDataset存储接口
+type IRobotDataset interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.RobotDatasetQueryParam, opts ...schema.RobotDatasetQueryOptions) (*schema.RobotDatasetQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.RobotDatasetQueryOptions) (*schema.RobotDataset, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.RobotDataset) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.RobotDataset) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 20 - 0
app/model/m_role.go

@@ -0,0 +1,20 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IRole Role存储接口
+type IRole interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.RoleQueryParam, opts ...schema.RoleQueryOptions) (*schema.RoleQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.RoleQueryOptions) (*schema.Role, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.Role) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.Role) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+}

+ 24 - 0
app/model/m_role_menu.go

@@ -0,0 +1,24 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IRoleMenu RoleMenu存储接口
+type IRoleMenu interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.RoleMenuQueryParam, opts ...schema.RoleMenuQueryOptions) (*schema.RoleMenuQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.RoleMenuQueryOptions) (*schema.RoleMenu, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.RoleMenu) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.RoleMenu) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// DeleteByRoleId 删除数据
+	DeleteByRoleId(ctx context.Context, roleId string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 13 - 0
app/model/m_trans.go

@@ -0,0 +1,13 @@
+package model
+
+import "context"
+
+// ITrans 事务管理接口
+type ITrans interface {
+	// Begin 开始事务
+	Begin(ctx context.Context) (interface{}, error)
+	// Commit 提交事务
+	Commit(ctx context.Context, trans interface{}) error
+	// Rollback 回滚事务
+	Rollback(ctx context.Context, trans interface{}) error
+}

+ 25 - 0
app/model/m_user.go

@@ -0,0 +1,25 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IUser User存储接口
+//goland:noinspection ALL
+type IUser interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.UserQueryParam, opts ...schema.UserOptions) (*schema.UserQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.UserOptions) (*schema.User, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.User) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.User) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status bool) error
+	// UpdatePassword 更新密码
+	UpdatePassword(ctx context.Context, recordID, password string) error
+}

+ 24 - 0
app/model/m_user_dataset.go

@@ -0,0 +1,24 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IUserDataset UserDataset存储接口
+type IUserDataset interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.UserDatasetQueryParam, opts ...schema.UserDatasetQueryOptions) (*schema.UserDatasetQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.UserDatasetQueryOptions) (*schema.UserDataset, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.UserDataset) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.UserDataset) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// DeleteByUserId 删除数据
+	DeleteByUserId(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 22 - 0
app/model/m_user_role.go

@@ -0,0 +1,22 @@
+package model
+
+import (
+	"context"
+	"yx-dataset-server/app/schema"
+)
+
+// IUserRole UserRole存储接口
+type IUserRole interface {
+	// 查询数据
+	Query(ctx context.Context, params schema.UserRoleQueryParam, opts ...schema.UserRoleQueryOptions) (*schema.UserRoleQueryResult, error)
+	// 查询指定数据
+	Get(ctx context.Context, recordID string, opts ...schema.UserRoleQueryOptions) (*schema.UserRole, error)
+	// 创建数据
+	Create(ctx context.Context, item schema.UserRole) error
+	// 更新数据
+	Update(ctx context.Context, recordID string, item schema.UserRole) error
+	// 删除数据
+	Delete(ctx context.Context, recordID string) error
+	// 更新状态
+	UpdateStatus(ctx context.Context, recordID string, status int) error
+}

+ 81 - 0
app/schema/s_chat_assistant.go

@@ -0,0 +1,81 @@
+package schema
+
+import (
+	"time"
+)
+
+// ChatAssistant ChatAssistant对象
+type ChatAssistant struct {
+	RecordID    string       `json:"record_id"`    // 记录id
+	OrgId       string       `json:"org_id"`       // 组织id
+	UserId      string       `json:"user_id"`      // 所属用户id
+	Name        string       `json:"name"`         // 助手名称
+	Desc        string       `json:"desc"`         // 描述
+	RagChatId   string       `json:"rag_chat_id"`  // rag_chat_id
+	Datasets    Datasets     `json:"datasets"`     // 绑定的知识库id
+	CreatedAt   time.Time    `json:"created_at"`   // 创建时间
+	CreatorId   string       `json:"creator_id"`   // 创建人id
+	CreatorName string       `json:"creator_name"` // 创建人名称
+	Sessions    ChatSessions `json:"sessions"`     // 会话列表
+}
+
+// ChatAssistantQueryParam 查询条件
+type ChatAssistantQueryParam struct {
+	OrgId     string
+	LikeName  string
+	RecordIDs []string
+}
+
+// ChatAssistantQueryOptions ChatAssistant对象查询可选参数项
+type ChatAssistantQueryOptions struct {
+	PageParam *PaginationParam // 分页参数
+}
+
+type ChatAssistants []*ChatAssistant
+
+// ChatAssistantQueryResult ChatAssistant对象查询结果
+type ChatAssistantQueryResult struct {
+	Data       ChatAssistants
+	PageResult *PaginationResult
+}
+
+// FillCreator 填充创建者信息
+func (a ChatAssistants) FillCreator(users Users) {
+	for _, v := range a {
+		for _, u := range users {
+			if v.CreatorId == u.RecordID {
+				v.CreatorName = u.RealName
+				continue
+			}
+		}
+	}
+}
+
+// FillDatasetId 填充知识库id
+func (a ChatAssistants) FillDatasetId(data ChatDatasets) {
+	for _, v := range a {
+		for _, d := range data {
+			if v.RecordID == d.ChatAssistantId {
+				v.Datasets = append(v.Datasets, &Dataset{RecordID: d.DatasetId})
+				continue
+			}
+		}
+	}
+}
+
+// FillDatasetId 填充知识库id
+func (a ChatAssistants) FillDataset(data Datasets) {
+	for _, v := range a {
+		for _, d := range v.Datasets {
+			for _, d2 := range data {
+				if d.RecordID == d2.RecordID {
+					d.Name = d2.Name
+					d.OrgId = d2.OrgId
+					d.RagDataId = d2.RagDataId
+					d.FileCount = d2.FileCount
+					continue
+				}
+			}
+		}
+	}
+}

+ 36 - 0
app/schema/s_chat_dataset.go

@@ -0,0 +1,36 @@
+package schema
+
+// ChatDataset ChatDataset对象
+type ChatDataset struct {
+	RecordID        string `json:"record_id"`         // 记录id
+	ChatAssistantId string `json:"chat_assistant_id"` // 聊天助手id
+	DatasetId       string `json:"dataset_id"`        // 知识库id
+	RagDataId       string `json:"rag_data_id"`       // rag_dataset_id
+}
+
+// ChatDatasetQueryParam 查询条件
+type ChatDatasetQueryParam struct {
+	ChatId    string
+	RecordIDs []string
+}
+
+// ChatDatasetQueryOptions ChatDataset对象查询可选参数项
+type ChatDatasetQueryOptions struct {
+	PageParam *PaginationParam // 分页参数
+}
+
+type ChatDatasets []*ChatDataset
+
+// ChatDatasetQueryResult ChatDataset对象查询结果
+type ChatDatasetQueryResult struct {
+	Data       ChatDatasets
+	PageResult *PaginationResult
+}
+
+func (a ChatDatasets) ToDatasetIds() []string {
+	Ids := make([]string, len(a))
+	for k, v := range a {
+		Ids[k] = v.DatasetId
+	}
+	return Ids
+}

+ 37 - 0
app/schema/s_chat_message.go

@@ -0,0 +1,37 @@
+package schema
+
+import "time"
+
+// ChatMessage ChatMessage对象
+type ChatMessage struct {
+	RecordID     string    `json:"record_id"`      // 记录id
+	UserId       string    `json:"user_id"`        // 用户id
+	AssistantId  string    `json:"assistant_id"`   // 助手id
+	SessionId    string    `json:"session_id"`     // 会话id
+	RagSessionId string    `json:"rag_session_id"` // rag_session_id
+	Question     string    `json:"question"`       // 对话问题
+	Answer       string    `json:"answer"`         // 对话答案
+	CreatedAt    time.Time `json:"created_at"`     // 创建时间
+	CreatorId    string    `json:"creator_id"`     // 创建人id
+}
+
+// ChatMessageQueryParam 查询条件
+type ChatMessageQueryParam struct {
+	AssistantId string
+	SessionId   string
+	LikeName    string
+	RecordIDs   []string
+}
+
+// ChatMessageQueryOptions ChatMessage对象查询可选参数项
+type ChatMessageQueryOptions struct {
+	PageParam *PaginationParam // 分页参数
+}
+
+type ChatMessages []*ChatMessage
+
+// ChatMessageQueryResult ChatMessage对象查询结果
+type ChatMessageQueryResult struct {
+	Data       ChatMessages
+	PageResult *PaginationResult
+}

+ 60 - 0
app/schema/s_chat_session.go

@@ -0,0 +1,60 @@
+package schema
+
+import "time"
+
+// ChatSession ChatSession对象
+type ChatSession struct {
+	RecordID     string       `json:"record_id"`      // 记录id
+	Name         string       `json:"name"`           // 名称
+	UserId       string       `json:"user_id"`        // 用户id
+	AssistantId  string       `json:"assistant_id"`   // 助手id
+	RagChatId    string       `json:"rag_chat_id"`    // rag_chat_id
+	RagSessionId string       `json:"rag_session_id"` // rag_session_id
+	CreatedAt    time.Time    `json:"created_at"`     // 创建时间
+	CreatorId    string       `json:"creator_id"`     // 创建人id
+	CreatorName  string       `json:"creator_name"`   // 创建人名称
+	Messages     ChatMessages `json:"messages"`       // 聊天记录
+}
+
+// ChatSessionQueryParam 查询条件
+type ChatSessionQueryParam struct {
+	AssistantId string
+	RecordIDs   []string
+}
+
+// ChatSessionQueryOptions ChatSession对象查询可选参数项
+type ChatSessionQueryOptions struct {
+	PageParam *PaginationParam // 分页参数
+}
+
+type ChatSessions []*ChatSession
+
+// ChatSessionQueryResult ChatSession对象查询结果
+type ChatSessionQueryResult struct {
+	Data       ChatSessions
+	PageResult *PaginationResult
+}
+
+// FillCreator 填充创建者信息
+func (a ChatSessions) FillCreator(users Users) {
+	for _, v := range a {
+		for _, u := range users {
+			if v.CreatorId == u.RecordID {
+				v.CreatorName = u.RealName
+				continue
+			}
+		}
+	}
+}
+
+// FillMessages 填充聊天记录
+func (a ChatSessions) FillMessages(Messages ChatMessages) {
+	for _, v := range a {
+		for _, m := range Messages {
+			if v.RecordID == m.SessionId {
+				v.Messages = append(v.Messages, m)
+				continue
+			}
+		}
+	}
+}

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません