Skip to content

purezeroadmin

一步步实现微服务权限管理系统(2)

前言

  • 前端参考了很多框架,可谓百花齐放,但很多封装过剩,不利于学习和应用,最终我选择了 [vue-pure-admin](https://github.com/pure-admin/vue-pure-admin)
  • 后端我将使用 go-zero 来带领大家一步步实现一个权限管理系统
  • 本系列项目存放在 purezeroadmin 中,每一部分我都将打tag,并保证每个tag能正常运行。请多点赞和评论。
  • 后面示例均为 purezeroadmin 项目为例,你们可以根据需要自建工程来进行试验。均采用vscode进行试验。
  • go-zero 常用命令我将放入其对应的 makefile 文件中。

前端相关接口参考

前端模拟的接口在 mock 文件夹中,后端可参照修改

后端修改

登陆接口

  1. 公共api创建 前端返回接口均为 {success: true, data: xxx}, 所以创建公共api `
cat base-api/base.api

api:

type Base {
    Success bool `json:"success"`
}
  1. 依照前章示例,创建 user.api 文件
cat `user-api/api/user.api`

api:

syntax = "v1"

info (
    title: "q9090960bnb3"
    desc:  "haha"
    date:  "2024-10-31"
)

import "../../base-api/base.api"

type UserLoginData {
    Avatar       string   `json:"avatar"`
    Username     string   `json:"username"`
    Nickname     string   `json:"nickname"`
    Roles        []string `json:"roles"`
    Permissions  []string `json:"permissions"`
    AccessToken  string   `json:"accessToken"`
    RefreshToken string   `json:"refreshToken"`
    Expires      string   `json:"expires"`
}

type (
    UserLoginReq {
        UserName string `json:"username"`
        Password string `json:"password"`
    }
    UserLoginResp {
        Base
        Data UserLoginData `json:"data"`
    }
)

service user-api {
    @doc "用户登录"
    @handler userLogin
    post /login (UserLoginReq) returns (UserLoginResp)
}
  1. 生成代码
goctl api go --api user-api/api/user.api --dir user-api
  1. 参考前端mock数据,修改 user-api/internal/logic/userloginlogic.go 中的函数
func (l *UserLoginLogic) UserLogin(req *types.UserLoginReq) (resp *types.UserLoginResp, err error) {
    if req.UserName == "admin" {
        return &types.UserLoginResp{
            Base: types.Base{
                Success: true,
            },
            Data: types.UserLoginData{
                Avatar:       "https://avatars.githubusercontent.com/u/44761321",
                Username:     "admin",
                Nickname:     "小铭",
                Roles:        []string{"admin"},
                Permissions:  []string{"*:*:*"},
                AccessToken:  "eyJhbGciOiJIUzUxMiJ9.admin",
                RefreshToken: "eyJhbGciOiJIUzUxMiJ9.adminRefresh",
                Expires:      "2030/10/30 00:00:00",
            },
        }, nil
    }

    return &types.UserLoginResp{
        Base: types.Base{
            Success: true,
        },
        Data: types.UserLoginData{
            Avatar:       "https://avatars.githubusercontent.com/u/52823142",
            Username:     "common",
            Nickname:     "小林",
            Roles:        []string{"common"},
            Permissions:  []string{"permission:btn:add", "permission:btn:edit"},
            AccessToken:  "eyJhbGciOiJIUzUxMiJ9.common",
            RefreshToken: "eyJhbGciOiJIUzUxMiJ9.commonRefresh",
            Expires:      "2030/10/30 00:00:00",
        },
    }, nil
}

修改刷新token接口

  1. user.api 中添加
type UserRefreshTokenData {
    AccessToken  string `json:"accessToken"`
    RefreshToken string `json:"refreshToken"`
    Expires      string `json:"expires"`
}

type (
    UserRefreshTokenReq {
        RefreshToken string `json:"refreshToken"`
    }
    UserRefreshTokenResp {
        Base
        Data UserRefreshTokenData `json:"data"`
    }
)

service user-api {
    @doc "用户登录"
    @handler UserRefreshToken
    post /refresh-token (UserRefreshTokenReq) returns (UserRefreshTokenResp)
}
  1. 参考前端mock数据,修改 user-api/internal/logic/userrefreshtokenlogic.go 中的函数
func (l *UserRefreshTokenLogic) UserRefreshToken(req *types.UserRefreshTokenReq) (resp *types.UserRefreshTokenResp, err error) {
    if req.RefreshToken != "" {
        return &types.UserRefreshTokenResp{
            Base: types.Base{
                Success: true,
            },
            Data: types.UserRefreshTokenData{
                AccessToken:  "",
                RefreshToken: "",
                Expires:      "",
            },
        }, nil
    }
    return &types.UserRefreshTokenResp{}, nil
}

修改异步获取路由接口

  1. user.api 中添加
type RouterData {
    Path      string       `json:"path"`
    Name      string       `json:"name,omitempty"`
    Component string       `json:"component,omitemty"`
    Meta      Meta         `json:"meta"`
    Children  []RouterData `json:"children,omitempty"`
}

type Meta {
    Title string   `json:"title"`
    Icon  string   `json:"icon,omitempty"`
    Rank  int64    `json:"rank,omitempty"`
    Roles []string `json:"roles,omitempty"`
    Auths []string `json:"auths,omitempty"`
}

type (
    UserRouterReq  {}
    UserRouterResp {
        Base
        Data []RouterData `json:"data"`
    }
)

service user-api {
    @doc "用户登出"
    @handler userRouter
    get /get-async-routes (UserRouterReq) returns (UserRouterResp)
}
  1. 参考前端mock数据,修改 user-api/internal/logic/userrouterlogic.go 中的函数
func (l *UserRouterLogic) UserRouter(req *types.UserRouterReq) (resp *types.UserRouterResp, err error) {
    return &types.UserRouterResp{
        Base: types.Base{
            Success: true,
        },
        Data: []types.RouterData{
            {
                Path: "/permission",
                Meta: types.Meta{
                    Title: "权限管理",
                    Icon:  "ep:lollipop",
                    Rank:  10,
                },
                Children: []types.RouterData{
                    {
                        Path: "/permission/page/index",
                        Name: "PermissionPage",
                        Meta: types.Meta{
                            Title: "页面权限",
                            Roles: []string{"admin", "common"},
                        },
                    },
                    {
                        Path: "/permission/button",
                        Meta: types.Meta{
                            Title: "按钮权限",
                            Roles: []string{"admin", "common"},
                        },
                        Children: []types.RouterData{
                            {
                                Path:      "/permission/button/router",
                                Component: "permission/button/index",
                                Name:      "PermissionButtonRouter",
                                Meta: types.Meta{
                                    Title: "路由返回按钮权限",
                                    Auths: []string{
                                        "permission:btn:add",
                                        "permission:btn:edit",
                                        "permission:btn:delete",
                                    },
                                },
                            },
                            {
                                Path:      "/permission/button/login",
                                Component: "permission/button/perms",
                                Name:      "PermissionButtonLogin",
                                Meta: types.Meta{
                                    Title: "登录返回按钮权限",
                                },
                            },
                        },
                    },
                },
            },
        },
    }, nil
}

前端取消mock

参考 如何关闭mock

前端配置端口转发

vite.config.ts 中配置转发

// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
proxy: {
"^/(login|refresh-token|get-async-routes)": {
    target: "http://localhost:8888",
    changeOrigin: true,
},
},

启动测试

  1. 启动后端服务
# vue-pure-admin工程下执行 cd back-end/user-api
❯ go run user.go
Starting server at 0.0.0.0:8888...
  1. 启动前端服务
# vue-pure-admin工程下执行 cd front-end
❯ pnpm dev

tag版本

purezeroadmin 项目下

git checkout v1.1.0

接下来

目前,前端请求路由太自由了,最好采用统一前缀去访问后端系统

一步步实现微服务权限管理系统(1)

前言

  • 前端参考了很多框架,可谓百花齐放,但很多封装过剩,不利于学习和应用,最终我选择了 [vue-pure-admin](https://github.com/pure-admin/vue-pure-admin)
  • 后端我将使用 go-zero 来带领大家一步步实现一个权限管理系统
  • 本系列项目存放在 purezeroadmin 中,每一部分我都将打tag,并保证每个tag能正常运行。
  • 后面示例均为 purezeroadmin 项目为例,你们可以根据需要自建工程来进行试验。均采用vscode进行试验。
  • go-zero 常用命令我将放入其对应的 makefile 文件中。

搭建环境

前端环境

  1. 参考 vue-pure-admin 官网,下载对应工具包
 cd vue-pure-admin
❯ pure create front-end
? 请输入项目名称 front-end
? 选择一个代码托管平台下载模板 Gitee
? 请选择模板类型 thin
  1. 运行,打开浏览器观测成功
# vue-pure-admin工程下执行 cd front-end
# 删除git仓库,外部工程自己git管理 rm -rf .git  pnpm i
❯ pnpm dev

后端环境

  1. 参考 go-zero 官网,下载对应工具包

  2. 创建工程

# vue-pure-admin工程下执行 mkdir back-end
❯ cd back-end
❯ go mod init backend
  1. 创建测试api
# back-end工程下执行 mkdir -p hello-api/api

创建测试 api 文件 hello.api

syntax = "v1"

info (
    title: "q9090960bnb3"
    desc:  "hello"
    date:  "2024-11-01"
)

type (
    HelloReq {
        World string `form:"world"`
    }
    HelloResp {
        HelloWorld string `json:"hello_world"`
    }
)

service hello-api {
    @doc "你好,世界"
    @handler helloInfo
    get /hello (HelloReq) returns (HelloResp)
}
  1. 生成 api 项目代码
# back-end工程下执行 goctl api go --api hello-api/api/hello.api --dir hello-api
  1. 修改返回逻辑
# back-end工程下执行
cd hello-api/internal/logic

修改 helloinfologic.goHelloInfo 函数

func (l *HelloInfoLogic) HelloInfo(req *types.HelloReq) (resp *types.HelloResp, err error) {
    return &types.HelloResp{
        HelloWorld: "hello " + req.World,
    }, nil
}
  1. 运行查看效果
# back-end工程下执行 cd hello-api
❯ go run hello.go
Starting server at 0.0.0.0:8888...
{"@timestamp":"2024-11-01T11:17:36.574+08:00","caller":"stat/usage.go:61","content":"CPU: 77m, MEMORY: Alloc=1.7Mi, TotalAlloc=3.6Mi, Sys=12.5Mi, NumGC=1","level":"stat"}
...

curl 测试

 curl "http://localhost:8888/hello?world=purezeroadmin"
{"hello_world":"hello purezeroadmin"}#  

tag版本

purezeroadmin 项目下

git checkout v1.0.0

接下来

front-end 中的mock数据替换到 back-end 中了