补充表结构设计

This commit is contained in:
yumaojun03 2024-12-01 17:17:51 +08:00
parent f2082dec6d
commit 079bc172f3
18 changed files with 313 additions and 48 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test.env

3
vblog/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"go.testEnvFile": "${workspaceFolder}/etc/test.env",
}

View File

@ -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"
```

View 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

View File

@ -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 {

View File

@ -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"`
}

View 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()
}

View 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`)
)

View 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()
}

View 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
View File

@ -0,0 +1,8 @@
package user
type DESCRIBE_BY int
const (
DESCRIBE_BY_ID DESCRIBE_BY = iota
DESCRIBE_BY_USERNAME
)

View File

@ -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 {

View 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()
}

View File

@ -1,25 +1,25 @@
<mxfile host="65bd71144e">
<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>
<mxCell id="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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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">
<mxPoint x="461.20000000000005" y="321" as="sourcePoint"/>
<Array as="points">
@ -28,12 +28,12 @@
</Array>
</mxGeometry>
</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">
<mxPoint x="21" y="-22" as="offset"/>
</mxGeometry>
</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">
<Array as="points">
<mxPoint x="376" y="210"/>
@ -41,104 +41,115 @@
</Array>
</mxGeometry>
</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"/>
</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"/>
</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">
<mxPoint x="354.4000000000001" y="297" as="targetPoint"/>
</mxGeometry>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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"/>
</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>
</mxGraphModel>
</diagram>

View 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
View File

@ -0,0 +1 @@
# 构建单元测试环境的工具

19
vblog/test/setup.go Normal file
View 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
View File

@ -0,0 +1,5 @@
package utils
type GetRequest struct {
Id uint `json:"id"`
}