补充表结构设计
This commit is contained in:
parent
f2082dec6d
commit
079bc172f3
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test.env
|
3
vblog/.vscode/settings.json
vendored
Normal file
3
vblog/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"go.testEnvFile": "${workspaceFolder}/etc/test.env",
|
||||||
|
}
|
@ -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"
|
||||||
|
```
|
16
vblog/apps/blog/docs/table.sql
Normal file
16
vblog/apps/blog/docs/table.sql
Normal file
@ -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
|
@ -12,13 +12,31 @@ type Service interface {
|
|||||||
// 博客列表查询
|
// 博客列表查询
|
||||||
QueryBlog(context.Context, *QueryBlogRequest) (*BlogSet, error)
|
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 {
|
type QueryBlogRequest struct {
|
||||||
|
@ -32,14 +32,18 @@ type CreateBlogRequest struct {
|
|||||||
// 内容
|
// 内容
|
||||||
Content string `json:"content" gorm:"column:content;type:text"`
|
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"`
|
Tags map[string]string `json:"tags" gorm:"column:tags;serializer:json"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Status struct {
|
type Status struct {
|
||||||
// 0: 草稿, 1: 已发布, 2: 审核 ...
|
StatusSpec
|
||||||
Stage STAGE `json:"stage" gorm:"column:stage;type:tinyint(1)"`
|
|
||||||
// 状态变化的时间, 拿发布时间
|
// 状态变化的时间, 拿发布时间
|
||||||
ChangeAt *time.Time `json:"change_at" gorm:"column:change_at"`
|
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"`
|
||||||
|
}
|
||||||
|
20
vblog/apps/blog/model_test.go
Normal file
20
vblog/apps/blog/model_test.go
Normal file
@ -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()
|
||||||
|
}
|
14
vblog/apps/token/docs/table.sql
Normal file
14
vblog/apps/token/docs/table.sql
Normal file
@ -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`)
|
||||||
|
)
|
20
vblog/apps/token/model_test.go
Normal file
20
vblog/apps/token/model_test.go
Normal file
@ -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()
|
||||||
|
}
|
15
vblog/apps/user/docs/table.sql
Normal file
15
vblog/apps/user/docs/table.sql
Normal file
@ -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`)
|
||||||
|
)
|
8
vblog/apps/user/enum.go
Normal file
8
vblog/apps/user/enum.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
type DESCRIBE_BY int
|
||||||
|
|
||||||
|
const (
|
||||||
|
DESCRIBE_BY_ID DESCRIBE_BY = iota
|
||||||
|
DESCRIBE_BY_USERNAME
|
||||||
|
)
|
@ -10,6 +10,14 @@ type Service interface {
|
|||||||
type AdminService interface {
|
type AdminService interface {
|
||||||
// 更新用户状态
|
// 更新用户状态
|
||||||
UpdateUserStatus(context.Context, *UpdateUserStatusRequest) (*User, error)
|
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 {
|
type UserService interface {
|
||||||
|
20
vblog/apps/user/model_test.go
Normal file
20
vblog/apps/user/model_test.go
Normal file
@ -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()
|
||||||
|
}
|
@ -1,25 +1,25 @@
|
|||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="G4rBrXM05HFn1dIN60R_" name="第 1 页">
|
<diagram id="G4rBrXM05HFn1dIN60R_" name="第 1 页">
|
||||||
<mxGraphModel dx="893" dy="449" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="893" dy="361" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="7" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.625;entryY=0.2;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="2" target="6">
|
<mxCell id="7" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.625;entryY=0.2;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="2" target="6" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="100" y="80" width="640" height="80" as="geometry"/>
|
<mxGeometry x="100" y="80" width="640" height="80" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="3" value="Web:浏览器" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="3" value="Web:浏览器" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="100" y="50" width="110" height="30" as="geometry"/>
|
<mxGeometry x="100" y="50" width="110" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="4" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="4" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="270" y="375" width="520" height="395" as="geometry"/>
|
<mxGeometry x="270" y="375" width="520" height="395" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="5" value="vblog api server" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="5" value="vblog api server" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="310" y="345" width="120" height="30" as="geometry"/>
|
<mxGeometry x="310" y="345" width="120" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="11" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.8;exitY=0.8;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="4">
|
<mxCell id="11" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.8;exitY=0.8;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" parent="1" source="6" target="4" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry">
|
||||||
<mxPoint x="461.20000000000005" y="321" as="sourcePoint"/>
|
<mxPoint x="461.20000000000005" y="321" as="sourcePoint"/>
|
||||||
<Array as="points">
|
<Array as="points">
|
||||||
@ -28,12 +28,12 @@
|
|||||||
</Array>
|
</Array>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="36" value="http: 每个请求是独立,需要带上 用户身份标识符(访问令牌 Token)" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="11">
|
<mxCell id="36" value="http: 每个请求是独立,需要带上 用户身份标识符(访问令牌 Token)" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="11" vertex="1" connectable="0">
|
||||||
<mxGeometry x="0.2492" y="-2" relative="1" as="geometry">
|
<mxGeometry x="0.2492" y="-2" relative="1" as="geometry">
|
||||||
<mxPoint x="21" y="-22" as="offset"/>
|
<mxPoint x="21" y="-22" as="offset"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="16" value="加载Web UI" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.25;exitY=0.25;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="2">
|
<mxCell id="16" value="加载Web UI" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.25;exitY=0.25;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" parent="1" source="6" target="2" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry">
|
||||||
<Array as="points">
|
<Array as="points">
|
||||||
<mxPoint x="376" y="210"/>
|
<mxPoint x="376" y="210"/>
|
||||||
@ -41,104 +41,115 @@
|
|||||||
</Array>
|
</Array>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="6" value="网络" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="6" value="网络" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="346" y="220" width="120" height="80" as="geometry"/>
|
<mxGeometry x="346" y="220" width="120" height="80" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="12" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="12" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="100" y="375" width="120" height="285" as="geometry"/>
|
<mxGeometry x="100" y="375" width="120" height="285" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="14" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.31;entryY=0.8;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="13" target="6">
|
<mxCell id="14" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.31;entryY=0.8;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="13" target="6" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry">
|
||||||
<mxPoint x="354.4000000000001" y="297" as="targetPoint"/>
|
<mxPoint x="354.4000000000001" y="297" as="targetPoint"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="13" value="Web 静态服务" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="13" value="Web 静态服务" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="100" y="345" width="100" height="30" as="geometry"/>
|
<mxGeometry x="100" y="345" width="100" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="17" value="BS 网络架构" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="17" value="BS 网络架构" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="10" y="10" width="90" height="30" as="geometry"/>
|
<mxGeometry x="10" y="10" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="46" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="18" target="43">
|
<mxCell id="46" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="18" target="43" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="18" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="18" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="310" y="420" width="120" height="330" as="geometry"/>
|
<mxGeometry x="310" y="420" width="120" height="330" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="20" value="用户管理" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="20" value="用户管理" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="310" y="390" width="60" height="30" as="geometry"/>
|
<mxGeometry x="310" y="390" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="23" value="注册" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="23" value="注册" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="324" y="440" width="90" height="30" as="geometry"/>
|
<mxGeometry x="324" y="440" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="41" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="24" target="32">
|
<mxCell id="41" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="24" target="32" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="48" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="24" target="45">
|
<mxCell id="48" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="24" target="45" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="24" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="24" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="630" y="420" width="144" height="330" as="geometry"/>
|
<mxGeometry x="630" y="420" width="144" height="330" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="25" value="文章管理(作者 需要登录)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="25" value="文章管理(作者 需要登录)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="630" y="390" width="140" height="30" as="geometry"/>
|
<mxGeometry x="630" y="390" width="140" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="26" value="文章列表" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="26" value="文章列表" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="644" y="440" width="110" height="30" as="geometry"/>
|
<mxGeometry x="644" y="440" width="110" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="27" value="文章编辑" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="27" value="文章编辑" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="644" y="490" width="110" height="30" as="geometry"/>
|
<mxGeometry x="644" y="490" width="110" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="28" value="文章创建" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="28" value="文章创建" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="644" y="540" width="110" height="30" as="geometry"/>
|
<mxGeometry x="644" y="540" width="110" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="29" value="文章发布" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="29" value="文章发布" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="647" y="585" width="110" height="30" as="geometry"/>
|
<mxGeometry x="647" y="585" width="110" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="30" value="文章详情" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="30" value="文章详情" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="647" y="630" width="110" height="30" as="geometry"/>
|
<mxGeometry x="647" y="630" width="110" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="31" value="文章删除" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="31" value="文章删除" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="647" y="680" width="110" height="30" as="geometry"/>
|
<mxGeometry x="647" y="680" width="110" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="47" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="32" target="44">
|
<mxCell id="47" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="32" target="44" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="32" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="49" style="edgeStyle=none;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="32" target="18">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="50" value="确认" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="49">
|
||||||
|
<mxGeometry x="-0.0464" y="3" relative="1" as="geometry">
|
||||||
|
<mxPoint as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="32" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="466" y="420" width="120" height="330" as="geometry"/>
|
<mxGeometry x="466" y="420" width="120" height="330" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="38" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="35" target="37">
|
<mxCell id="38" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="35" target="37" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="35" value="用户/密码" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="35" value="用户/密码" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="620" y="30" width="120" height="30" as="geometry"/>
|
<mxGeometry x="620" y="30" width="120" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="37" value="身份令牌" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="37" value="身份令牌" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="460" y="27.5" width="120" height="35" as="geometry"/>
|
<mxGeometry x="460" y="27.5" width="120" height="35" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="39" value="令牌管理" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
<mxCell id="39" value="令牌管理" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="466" y="390" width="60" height="30" as="geometry"/>
|
<mxGeometry x="466" y="390" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="21" value="登录" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="21" value="登录" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="481" y="440" width="90" height="30" as="geometry"/>
|
<mxGeometry x="481" y="440" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="22" value="退出" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="22" value="退出" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="481" y="490" width="90" height="30" as="geometry"/>
|
<mxGeometry x="481" y="490" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="40" value="注销" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="40" value="注销" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="325" y="490" width="90" height="30" as="geometry"/>
|
<mxGeometry x="325" y="490" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="42" value="令牌校验" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="42" value="令牌校验" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="481" y="600" width="90" height="30" as="geometry"/>
|
<mxGeometry x="481" y="600" width="90" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="43" value="表" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
|
<mxCell id="43" value="表" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" parent="1" vertex="1">
|
||||||
<mxGeometry x="340" y="830" width="60" height="60" as="geometry"/>
|
<mxGeometry x="340" y="830" width="60" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="44" value="表" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
|
<mxCell id="44" value="表" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" parent="1" vertex="1">
|
||||||
<mxGeometry x="496" y="830" width="60" height="60" as="geometry"/>
|
<mxGeometry x="496" y="830" width="60" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="45" value="表" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
|
<mxCell id="45" value="表" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" parent="1" vertex="1">
|
||||||
<mxGeometry x="672" y="830" width="60" height="60" as="geometry"/>
|
<mxGeometry x="672" y="830" width="60" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
|
<mxCell id="51" value="用户查询" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="324" y="600" width="90" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
|
26
vblog/etc/application.toml
Normal file
26
vblog/etc/application.toml
Normal file
@ -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
|
1
vblog/test/README.md
Normal file
1
vblog/test/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# 构建单元测试环境的工具
|
19
vblog/test/setup.go
Normal file
19
vblog/test/setup.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
5
vblog/utils/request.go
Normal file
5
vblog/utils/request.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
type GetRequest struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user