From 079bc172f30777fc1383459ad3478a40b3d0e6ab Mon Sep 17 00:00:00 2001 From: yumaojun03 <719118794@qq.com> Date: Sun, 1 Dec 2024 17:17:51 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E8=A1=A8=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + vblog/.vscode/settings.json | 3 ++ vblog/README.md | 56 ++++++++++++++++++++ vblog/apps/blog/docs/table.sql | 16 ++++++ vblog/apps/blog/interface.go | 26 +++++++-- vblog/apps/blog/model.go | 10 ++-- vblog/apps/blog/model_test.go | 20 +++++++ vblog/apps/token/docs/table.sql | 14 +++++ vblog/apps/token/model_test.go | 20 +++++++ vblog/apps/user/docs/table.sql | 15 ++++++ vblog/apps/user/enum.go | 8 +++ vblog/apps/user/interface.go | 8 +++ vblog/apps/user/model_test.go | 20 +++++++ vblog/docs/arch.drawio | 93 ++++++++++++++++++--------------- vblog/etc/application.toml | 26 +++++++++ vblog/test/README.md | 1 + vblog/test/setup.go | 19 +++++++ vblog/utils/request.go | 5 ++ 18 files changed, 313 insertions(+), 48 deletions(-) create mode 100644 .gitignore create mode 100644 vblog/.vscode/settings.json create mode 100644 vblog/apps/blog/docs/table.sql create mode 100644 vblog/apps/blog/model_test.go create mode 100644 vblog/apps/token/docs/table.sql create mode 100644 vblog/apps/token/model_test.go create mode 100644 vblog/apps/user/docs/table.sql create mode 100644 vblog/apps/user/enum.go create mode 100644 vblog/apps/user/model_test.go create mode 100644 vblog/etc/application.toml create mode 100644 vblog/test/README.md create mode 100644 vblog/test/setup.go create mode 100644 vblog/utils/request.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a67af1f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +test.env \ No newline at end of file diff --git a/vblog/.vscode/settings.json b/vblog/.vscode/settings.json new file mode 100644 index 0000000..0c2467b --- /dev/null +++ b/vblog/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "go.testEnvFile": "${workspaceFolder}/etc/test.env", +} \ No newline at end of file diff --git a/vblog/README.md b/vblog/README.md index b17cfb7..05bd798 100644 --- a/vblog/README.md +++ b/vblog/README.md @@ -24,3 +24,59 @@ https://gitee.com/infraboard/go-course/blob/master/new.md#%E6%9E%B6%E6%9E%84%E8% ### 业务的详细设计 +直接使用Go的接口 来定义业务 +```go +// 业务域 +type Service interface { + UserService + InnterService +} + +// 1. 外部 +type UserService interface { + // 颁发令牌 登录 + IssueToken(context.Context, *IssueTokenRequest) (*Token, error) + // 撤销令牌 退出 + RevolkToken(context.Context, *RevolkTokenRequest) (*Token, error) +} + +type RevolkTokenRequest struct { + // 访问令牌 + AccessToken string `json:"access_token"` + // 刷新令牌, 构成一对,避免AccessToken 泄露,用户可以直接 revolk + RefreshToken string `json:"refresh_token"` +} + +type IssueTokenRequest struct { + Username string `json:"username"` + Password string `json:"password"` + // 记住我, Token可能1天过期, 过去时间调整为7天 + RememberMe bool `json:"remember_me"` +} + +// 内部 +type InnterService interface { + // 令牌校验 + ValidateToken(context.Context, *ValidateTokenRequest) (*Token, error) +} + +type ValidateTokenRequest struct { + // 访问令牌 + AccessToken string `json:"access_token"` +} +``` + +数据库的设计伴随接口设计已经完成 + +1. 如何基于Vscode 构造单元测试的配置 + +```json +{ + "go.testEnvFile": "${workspaceFolder}/etc/test.env", +} +``` + +添加工作目录环境变量 +``` +WORKSPACE_DIR="/Users/xxxx/Projects/go-course/go17/vblog" +``` \ No newline at end of file diff --git a/vblog/apps/blog/docs/table.sql b/vblog/apps/blog/docs/table.sql new file mode 100644 index 0000000..a9bf065 --- /dev/null +++ b/vblog/apps/blog/docs/table.sql @@ -0,0 +1,16 @@ +CREATE TABLE `blogs` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `created_at` datetime(3) NOT NULL, + `create_by` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, + `updated_at` datetime(3) DEFAULT NULL, + `title` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `summary` text COLLATE utf8mb4_general_ci, + `content` text COLLATE utf8mb4_general_ci, + `category` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL, + `tags` longtext COLLATE utf8mb4_general_ci, + `stage` tinyint(1) DEFAULT NULL, + `change_at` datetime(3) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_blogs_category` (`category`), + KEY `idx_blogs_stage` (`stage`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci \ No newline at end of file diff --git a/vblog/apps/blog/interface.go b/vblog/apps/blog/interface.go index 7599cdd..976b27b 100644 --- a/vblog/apps/blog/interface.go +++ b/vblog/apps/blog/interface.go @@ -12,13 +12,31 @@ type Service interface { // 博客列表查询 QueryBlog(context.Context, *QueryBlogRequest) (*BlogSet, error) // 博客详情查询 - DescribeBlog() + DescribeBlog(context.Context, *DescribeBlogRequest) (*Blog, error) // 博客编辑 - UpdateBlog() + UpdateBlog(context.Context, *UpdateBlogRequest) (*Blog, error) // 发布 - PublishBlog() + PublishBlog(context.Context, *PublishBlogRequest) (*Blog, error) // 删除 - DeleteBlog() + DeleteBlog(context.Context, *DeleteBlogRequest) error +} + +type DeleteBlogRequest struct { + utils.GetRequest +} + +type PublishBlogRequest struct { + utils.GetRequest + StatusSpec +} + +type UpdateBlogRequest struct { + utils.GetRequest + CreateBlogRequest +} + +type DescribeBlogRequest struct { + utils.GetRequest } type QueryBlogRequest struct { diff --git a/vblog/apps/blog/model.go b/vblog/apps/blog/model.go index 9ad229e..764ab56 100644 --- a/vblog/apps/blog/model.go +++ b/vblog/apps/blog/model.go @@ -32,14 +32,18 @@ type CreateBlogRequest struct { // 内容 Content string `json:"content" gorm:"column:content;type:text"` // 分类 - Category string `json:"category" gorm:"column:category;type:text"` + Category string `json:"category" gorm:"column:category;type:varchar(200);index"` // 标签 Tags map[string]string `json:"tags" gorm:"column:tags;serializer:json"` } type Status struct { - // 0: 草稿, 1: 已发布, 2: 审核 ... - Stage STAGE `json:"stage" gorm:"column:stage;type:tinyint(1)"` + StatusSpec // 状态变化的时间, 拿发布时间 ChangeAt *time.Time `json:"change_at" gorm:"column:change_at"` } + +type StatusSpec struct { + // 0: 草稿, 1: 已发布, 2: 审核 ... + Stage STAGE `json:"stage" gorm:"column:stage;type:tinyint(1);index"` +} diff --git a/vblog/apps/blog/model_test.go b/vblog/apps/blog/model_test.go new file mode 100644 index 0000000..9172f03 --- /dev/null +++ b/vblog/apps/blog/model_test.go @@ -0,0 +1,20 @@ +package blog_test + +import ( + "testing" + + "github.com/infraboard/mcube/v2/ioc/config/datasource" + "gitlab.com/go-course-project/go17/vblog/apps/blog" + "gitlab.com/go-course-project/go17/vblog/test" +) + +func TestMigrate(t *testing.T) { + // db 数据库连接对象, migrate + if err := datasource.DB().AutoMigrate(&blog.Blog{}); err != nil { + t.Fatal(err) + } +} + +func init() { + test.DevelopmentSetup() +} diff --git a/vblog/apps/token/docs/table.sql b/vblog/apps/token/docs/table.sql new file mode 100644 index 0000000..243b653 --- /dev/null +++ b/vblog/apps/token/docs/table.sql @@ -0,0 +1,14 @@ +CREATE TABLE `tokens` ( + `id` bigint unsigned AUTO_INCREMENT, + `ref_user_id` longtext, + `access_token` varchar(191), + `access_token_expire_at` datetime(3) NULL, + `issue_at` datetime(3) NULL, + `refresh_token` varchar(191), + `refresh_token_expire_at` datetime(3) NULL, + PRIMARY KEY (`id`), + INDEX `idx_tokens_access_token` (`access_token`), + INDEX `idx_tokens_refresh_token` (`refresh_token`), + CONSTRAINT `uni_tokens_access_token` UNIQUE (`access_token`), + CONSTRAINT `uni_tokens_refresh_token` UNIQUE (`refresh_token`) +) \ No newline at end of file diff --git a/vblog/apps/token/model_test.go b/vblog/apps/token/model_test.go new file mode 100644 index 0000000..a5260ee --- /dev/null +++ b/vblog/apps/token/model_test.go @@ -0,0 +1,20 @@ +package token_test + +import ( + "testing" + + "github.com/infraboard/mcube/v2/ioc/config/datasource" + "gitlab.com/go-course-project/go17/vblog/apps/token" + "gitlab.com/go-course-project/go17/vblog/test" +) + +func TestMigrate(t *testing.T) { + // db 数据库连接对象, migrate + if err := datasource.DB().AutoMigrate(&token.Token{}); err != nil { + t.Fatal(err) + } +} + +func init() { + test.DevelopmentSetup() +} diff --git a/vblog/apps/user/docs/table.sql b/vblog/apps/user/docs/table.sql new file mode 100644 index 0000000..aa982bd --- /dev/null +++ b/vblog/apps/user/docs/table.sql @@ -0,0 +1,15 @@ +CREATE TABLE `users` ( + `id` bigint unsigned AUTO_INCREMENT, + `created_at` datetime(3) NOT NULL, + `create_by` varchar(100), + `updated_at` datetime(3) NULL, + `username` varchar(191), + `avatar` varchar(255), + `nic_name` varchar(100), + `email` varchar(100), + `block_at` datetime(3) NULL, + `block_reason` text, + PRIMARY KEY (`id`), + INDEX `idx_users_username` (`username`), + CONSTRAINT `uni_users_username` UNIQUE (`username`) +) \ No newline at end of file diff --git a/vblog/apps/user/enum.go b/vblog/apps/user/enum.go new file mode 100644 index 0000000..303951d --- /dev/null +++ b/vblog/apps/user/enum.go @@ -0,0 +1,8 @@ +package user + +type DESCRIBE_BY int + +const ( + DESCRIBE_BY_ID DESCRIBE_BY = iota + DESCRIBE_BY_USERNAME +) diff --git a/vblog/apps/user/interface.go b/vblog/apps/user/interface.go index e57b824..a2401cb 100644 --- a/vblog/apps/user/interface.go +++ b/vblog/apps/user/interface.go @@ -10,6 +10,14 @@ type Service interface { type AdminService interface { // 更新用户状态 UpdateUserStatus(context.Context, *UpdateUserStatusRequest) (*User, error) + // 查询某个具体的用户详情 + DescribeUser(context.Context, *DescribeUserRequest) (*User, error) +} + +// UserId Or Username +type DescribeUserRequest struct { + DescribeBy DESCRIBE_BY `json:"describe_by"` + Value string `json:"value"` } type UserService interface { diff --git a/vblog/apps/user/model_test.go b/vblog/apps/user/model_test.go new file mode 100644 index 0000000..cc13700 --- /dev/null +++ b/vblog/apps/user/model_test.go @@ -0,0 +1,20 @@ +package user_test + +import ( + "testing" + + "github.com/infraboard/mcube/v2/ioc/config/datasource" + "gitlab.com/go-course-project/go17/vblog/apps/user" + "gitlab.com/go-course-project/go17/vblog/test" +) + +func TestMigrate(t *testing.T) { + // db 数据库连接对象, migrate + if err := datasource.DB().AutoMigrate(&user.User{}); err != nil { + t.Fatal(err) + } +} + +func init() { + test.DevelopmentSetup() +} diff --git a/vblog/docs/arch.drawio b/vblog/docs/arch.drawio index 8e25d38..40c0889 100644 --- a/vblog/docs/arch.drawio +++ b/vblog/docs/arch.drawio @@ -1,25 +1,25 @@ - + - + - + - + - + - + - + @@ -28,12 +28,12 @@ - + - + @@ -41,104 +41,115 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + + + + diff --git a/vblog/etc/application.toml b/vblog/etc/application.toml new file mode 100644 index 0000000..d40f4fb --- /dev/null +++ b/vblog/etc/application.toml @@ -0,0 +1,26 @@ +[http] + # HTTP服务Host + host = "127.0.0.1" + # HTTP服务端口 + port = 8010 + +[datasource] + provider = "mysql" + host = "127.0.0.1" + port = 3306 + database = "go17_vblog" + username = "root" + password = "123456" + debug = true + +[log] + # 日志的级别, 默认Debug + level = "debug" + +[log.console] + enable = true + no_color = false + +[log.file] + # 是否开启文件记录 + enable = true \ No newline at end of file diff --git a/vblog/test/README.md b/vblog/test/README.md new file mode 100644 index 0000000..cb8fdbe --- /dev/null +++ b/vblog/test/README.md @@ -0,0 +1 @@ +# 构建单元测试环境的工具 \ No newline at end of file diff --git a/vblog/test/setup.go b/vblog/test/setup.go new file mode 100644 index 0000000..d288c17 --- /dev/null +++ b/vblog/test/setup.go @@ -0,0 +1,19 @@ +package test + +import ( + "os" + + "github.com/infraboard/mcube/v2/ioc" +) + +func DevelopmentSetup() { + // 配置单元单元测试的配置, application.toml + req := ioc.NewLoadConfigRequest() + req.ConfigFile.Enabled = true + // 必须配置绝对逻辑, {Workspace} + req.ConfigFile.Path = os.Getenv("WORKSPACE_DIR") + "/etc/application.toml" + err := ioc.ConfigIocObject(req) + if err != nil { + panic(err) + } +} diff --git a/vblog/utils/request.go b/vblog/utils/request.go new file mode 100644 index 0000000..1dbaa17 --- /dev/null +++ b/vblog/utils/request.go @@ -0,0 +1,5 @@ +package utils + +type GetRequest struct { + Id uint `json:"id"` +}