Code Monkey home page Code Monkey logo

iris-admin's Introduction

IrisAdmin

Build Status LICENSE go doc go report Build Status

简体中文 | English

项目地址

GITHUB

简单项目仅供学习,欢迎指点!

相关文档

e9939a7e92f32337871feb22e06bd05a.jpeg e9939a7e92f32337871feb22e06bd05a.jpeg

iris 学习记录分享


简单使用

  • 获取依赖包,注意必须带上 master 版本
 go get github.com/snowlyg/iris-admin@master

项目介绍

项目由多个插件构成,每个插件有不同的功能
  • [viper_server]
    • 插件配置初始化,并生成本地配置文件
    • 使用 github.com/spf13/viper 第三方包实现
    • 需要实现 func getViperConfig() viper_server.ViperConfig 方法
package cache

import (
  "fmt"

  "github.com/fsnotify/fsnotify"
  "github.com/snowlyg/iris-admin/g"
  "github.com/snowlyg/iris-admin/server/viper_server"
  "github.com/spf13/viper"
)

var CONFIG Redis

type Redis struct {
  DB       int    `mapstructure:"db" json:"db" yaml:"db"`
  Addr     string `mapstructure:"addr" json:"addr" yaml:"addr"`
  Password string `mapstructure:"password" json:"password" yaml:"password"`
  PoolSize int    `mapstructure:"pool-size" json:"poolSize" yaml:"pool-size"`
}

// getViperConfig get viper config
func getViperConfig() viper_server.ViperConfig {
  configName := "redis"
  db := fmt.Sprintf("%d", CONFIG.DB)
  poolSize := fmt.Sprintf("%d", CONFIG.PoolSize)
  return viper_server.ViperConfig{
    Directory: g.ConfigDir,
    Name:      configName,
    Type:      g.ConfigType,
    Watch: func(vi *viper.Viper) error {
      if err := vi.Unmarshal(&CONFIG); err != nil {
        return fmt.Errorf("get Unarshal error: %v", err)
      }
      // watch config file change
      vi.SetConfigName(configName)
      return nil
    },
    //
    Default: []byte(`
db: ` + db + `
addr: "` + CONFIG.Addr + `"
password: "` + CONFIG.Password + `"
pool-size: ` + poolSize),
  }
}
  • [zap_server]
    • 插件日志记录
    • 使用 go.uber.org/zap 第三方包实现
    • 通过全局变量 zap_server.ZAPLOG 记录对应级别的日志
  zap_server.ZAPLOG.Info("注册数据表错误", zap.Any("err", err))
  zap_server.ZAPLOG.Debug("注册数据表错误", zap.Any("err", err))
  zap_server.ZAPLOG.Error("注册数据表错误", zap.Any("err", err))
  ...
  • [database]
    • 数据插件 [目前仅支持 mysql]
    • 使用 gorm.io/gorm 第三方包实现
    • 通过单列 database.Instance() 操作数据
  database.Instance().Model(&User{}).Where("name = ?","name").Find(&user)
  ...
  • [casbin]
    • 权限控制管理插件
    • 使用 casbin 第三方包实现
    • 并通过 casbin.Instance() 使用中间件,实现接口权限认证
	_, err := casbin.Instance().AddRoleForUser("1", "999")
	uids, err := casbin.Instance().GetRolesForUser("1")
	_, err := casbin.Instance().RemoveFilteredPolicy(v, p...)
  ...
  	err := cache.Instance().Set(context.Background(), "key", "value", expiration).Err()
    cache.Instance().Del(context.Background(), "key").Result()
    cache.Instance().Get(context.Background(), "key")
  ...
  • [operation]

    • 系统操作日志插件
    • 并通过 index.Use(operation.OperationRecord()) 使用中间件,实现接口自动生成操作日志
  • [cron_server]

    • 任务插件
    • 使用 robfig/cron 第三方包实现
    • 通过单列 cron_server.CronInstance() 操作数据
  cron_server.CronInstance().AddJob("@every 1m",YourJob)
  // 或者
  cron_server.CronInstance().AddFunc("@every 1m",YourFunc)
  ...
  • [web]
    • web_iris Go-Iris web 框架插件
    • web_gin Go-gin web web 框架插件
    • web 框架插件需要实现 type WebFunc interface {} 接口
type WebBaseFunc interface {
  AddWebStatic(staticAbsPath, webPrefix string, paths ...string)
  AddUploadStatic(staticAbsPath, webPrefix string)
  InitRouter() error
  Run()
}

// WebFunc 框架插件接口
// - GetTestClient 测试客户端
// - GetTestLogin 测试登录
// - AddWebStatic 添加静态页面
// - AddUploadStatic 上传文件路径
// - Run 启动
type WebFunc interface {
  WebBaseFunc
}
  • [mongodb]
    • mongodb
    • 使用 mongodb 第三方包实现.

数据初始化

简单初始化
  • 使用原生方法 AutoMigrate() 自动迁移初始化数据表
package main

import (
  "github.com/snowlyg/iris-admin/server/web"
  "github.com/snowlyg/iris-admin/server/web/web_iris"
  "github.com/snowlyg/iris-admin-rbac/iris/perm"
  "github.com/snowlyg/iris-admin-rbac/iris/role"
  "github.com/snowlyg/iris-admin/server/database"
  "github.com/snowlyg/iris-admin/server/operation"
)

func main() {
    database.Instance().AutoMigrate(&perm.Permission{},&role.Role{},&user.User{},&operation.Oplog{})
}
自定义迁移工具初始化
  • 使用 gormigrate 第三方依赖包实现数据的迁移控制,方便后续的升级和开发
  • 使用方法详情见 iris-admin-cmd

  • 添加 main.go 文件
package main

import (
  "github.com/snowlyg/iris-admin/server/web"
  "github.com/snowlyg/iris-admin/server/web/web_iris"
)

func main() {
  wi := web_iris.Init()
  web.Start(wi)
}

启动项目

  • 第一次启动项目后,配置文件会自动生成到 config 目录下.
  • 同时会生成一个 rbac_model.conf 文件到项目根目录,该文件用于 casbin 权鉴的规则.
go run main.go

添加模块

  • 如果需要权鉴管理,可以使用 iris-admin-rbac 项目快速集成权鉴功能
  • 可以使用 AddModule() 增加其他 admin 模块
package main

import (
  rbac "github.com/snowlyg/iris-admin-rbac/iris"
  "github.com/snowlyg/iris-admin/server/web"
  "github.com/snowlyg/iris-admin/server/web/web_iris"
)

func main() {
  wi := web_iris.Init()
  rbacParty := web_iris.Party{
    Perfix:    "/api/v1",
    PartyFunc: rbac.Party(),
  }
  wi.AddModule(rbacParty)
  web.Start(web_iris.Init())
}

设置静态文件路径

  • 已经默认内置了一个静态文件访问路径

  • 静态文件将会上传到 /static/upload 目录

  • 可以修改配置项 static-path 修改默认目录

system:
  addr: "127.0.0.1:8085"
  db-type: ""
  level: debug
  static-prefix: /upload
  time-format: "2006-01-02 15:04:05"
  web-prefix: /admin
  web-path: ./dist

配合前端使用

  • 编译前端页面默认 dist 目录

  • 可以修改配置项 web-path 修改默认目录

package main

import (
  "github.com/kataras/iris/v12"
  "github.com/snowlyg/iris-admin/server/web"
)

func main() {
  webServer := web_iris.Init()
  wi.AddUploadStatic("/upload", "/var/static")
  wi.AddWebStatic("/", "/var/static")
  webServer.Run()
}

简单用例

RBAC

接口单元测试和接口文档

接口单元测试需要新建 main_test.go 文件,该文件定义了单元测试的一些通用基础步骤: 建议采用 docker 部署 mysql,否则测试错误失败后会有大量测试数据遗留

  • 1.测试数据库的数据库的创建和摧毁
  • 2.数据表的新建和表数据的填充
    1. PartyFunc , SeedFunc 方法需要根据对应的测试模块自定义 内容如下所示:

main_test.go

package test

import (
  "os"
  "testing"

  "github.com/snowlyg/httptest"
  rbac "github.com/snowlyg/iris-admin-rbac/gin"
  "github.com/snowlyg/iris-admin/server/web/common"
  "github.com/snowlyg/iris-admin/server/web/web_gin"
)

var TestServer *web_gin.WebServer
var TestClient *httptest.Client

func TestMain(m *testing.M) {

  var uuid string
  uuid, TestServer = common.BeforeTestMainGin(rbac.PartyFunc, rbac.SeedFunc)
  code := m.Run()
  common.AfterTestMain(uuid, true)

  os.Exit(code)
}

index_test.go

package test

import (
  "fmt"
  "net/http"
  "path/filepath"
  "testing"

  "github.com/snowlyg/helper/str"
  "github.com/snowlyg/httptest"
  rbac "github.com/snowlyg/iris-admin-rbac/gin"
  "github.com/snowlyg/iris-admin/g"
  "github.com/snowlyg/iris-admin/server/web"
  "github.com/snowlyg/iris-admin/server/web/web_gin/response"
)

var (
  url = "/api/v1/admin"
)

func TestList(t *testing.T) {
  TestClient = httptest.Instance(t, str.Join("http://", web.CONFIG.System.Addr), TestServer.GetEngine())
  TestClient.Login(rbac.LoginUrl, nil)
  if TestClient == nil {
    return
  }
  pageKeys := httptest.Responses{
    {Key: "status", Value: http.StatusOK},
    {Key: "message", Value: response.ResponseOkMessage},
    {Key: "data", Value: httptest.Responses{
      {Key: "pageSize", Value: 10},
      {Key: "page", Value: 1},
      {Key: "list", Value: []httptest.Responses{
        {
          {Key: "id", Value: 1, Type: "ge"},
          {Key: "nickName", Value: "超级管理员"},
          {Key: "username", Value: "admin"},
          {Key: "headerImg", Value: "http://xxxx/head.png"},
          {Key: "status", Value: g.StatusTrue},
          {Key: "isShow", Value: g.StatusFalse},
          {Key: "phone", Value: "13800138000"},
          {Key: "email", Value: "[email protected]"},
          {Key: "authorities", Value: []string{"超级管理员"}},
          {Key: "updatedAt", Value: "", Type: "notempty"},
          {Key: "createdAt", Value: "", Type: "notempty"},
        },
      }},
      {Key: "total", Value: 0, Type: "ge"},
    }},
  }
  TestClient.GET(fmt.Sprintf("%s/getAll", url), pageKeys, httptest.RequestParams)
}

func TestCreate(t *testing.T) {
  TestClient = httptest.Instance(t, str.Join("http://", web.CONFIG.System.Addr), TestServer.GetEngine())
  TestClient.Login(rbac.LoginUrl, nil)
  if TestClient == nil {
    return
  }

  data := map[string]interface{}{
    "nickName":     "测试名称",
    "username":     "create_test_username",
    "authorityIds": []uint{web.AdminAuthorityId},
    "email":        "[email protected]",
    "phone":        "13800138001",
    "password":     "123456",
  }
  id := Create(TestClient, data)
  if id == 0 {
    t.Fatalf("测试添加用户失败 id=%d", id)
  }
  defer Delete(TestClient, id)
}

func TestUpdate(t *testing.T) {

  TestClient = httptest.Instance(t, str.Join("http://", web.CONFIG.System.Addr), TestServer.GetEngine())
  TestClient.Login(rbac.LoginUrl, nil)
  if TestClient == nil {
    return
  }
  data := map[string]interface{}{
    "nickName":     "测试名称",
    "username":     "create_test_username_for_update",
    "authorityIds": []uint{web.AdminAuthorityId},
    "email":        "[email protected]",
    "phone":        "13800138001",
    "password":     "123456",
  }
  id := Create(TestClient, data)
  if id == 0 {
    t.Fatalf("测试添加用户失败 id=%d", id)
  }
  defer Delete(TestClient, id)

  update := map[string]interface{}{
    "nickName": "测试名称",
    "email":    "[email protected]",
    "phone":    "13800138003",
    "password": "123456",
  }

  pageKeys := httptest.Responses{
    {Key: "status", Value: http.StatusOK},
    {Key: "message", Value: response.ResponseOkMessage},
  }
  TestClient.PUT(fmt.Sprintf("%s/updateAdmin/%d", url, id), pageKeys, update)
}

func TestGetById(t *testing.T) {
  TestClient = httptest.Instance(t, str.Join("http://", web.CONFIG.System.Addr), TestServer.GetEngine())
  TestClient.Login(rbac.LoginUrl, nil)
  if TestClient == nil {
    return
  }
  data := map[string]interface{}{
    "nickName":     "测试名称",
    "username":     "create_test_username_for_get",
    "email":        "[email protected]",
    "phone":        "13800138001",
    "authorityIds": []uint{web.AdminAuthorityId},
    "password":     "123456",
  }
  id := Create(TestClient, data)
  if id == 0 {
    t.Fatalf("测试添加用户失败 id=%d", id)
  }
  defer Delete(TestClient, id)
  pageKeys := httptest.Responses{
    {Key: "status", Value: http.StatusOK},
    {Key: "message", Value: response.ResponseOkMessage},
    {Key: "data", Value: httptest.Responses{
      {Key: "id", Value: 1, Type: "ge"},
      {Key: "nickName", Value: data["nickName"].(string)},
      {Key: "username", Value: data["username"].(string)},
      {Key: "status", Value: g.StatusTrue},
      {Key: "email", Value: data["email"].(string)},
      {Key: "phone", Value: data["phone"].(string)},
      {Key: "isShow", Value: g.StatusTrue},
      {Key: "headerImg", Value: "http://xxxx/head.png"},
      {Key: "updatedAt", Value: "", Type: "notempty"},
      {Key: "createdAt", Value: "", Type: "notempty"},
      {Key: "createdAt", Value: "", Type: "notempty"},
      {Key: "authorities", Value: []string{"超级管理员"}},
    },
    },
  }
  TestClient.GET(fmt.Sprintf("%s/getAdmin/%d", url, id), pageKeys)
}

func TestChangeAvatar(t *testing.T) {
  TestClient = httptest.Instance(t, str.Join("http://", web.CONFIG.System.Addr), TestServer.GetEngine())
  TestClient.Login(rbac.LoginUrl, nil)
  if TestClient == nil {
    return
  }
  data := map[string]interface{}{
    "headerImg": "/avatar.png",
  }
  pageKeys := httptest.Responses{
    {Key: "status", Value: http.StatusOK},
    {Key: "message", Value: response.ResponseOkMessage},
  }
  TestClient.POST(fmt.Sprintf("%s/changeAvatar", url), pageKeys, data)

  profile := httptest.Responses{
    {Key: "status", Value: http.StatusOK},
    {Key: "message", Value: response.ResponseOkMessage},
    {Key: "data", Value: httptest.Responses{
      {Key: "id", Value: 1, Type: "ge"},
      {Key: "nickName", Value: "超级管理员"},
      {Key: "username", Value: "admin"},
      {Key: "headerImg", Value: filepath.ToSlash(web.ToStaticUrl("/avatar.png"))},
      {Key: "status", Value: g.StatusTrue},
      {Key: "isShow", Value: g.StatusFalse},
      {Key: "phone", Value: "13800138000"},
      {Key: "email", Value: "[email protected]"},
      {Key: "authorities", Value: []string{"超级管理员"}},
      {Key: "updatedAt", Value: "", Type: "notempty"},
      {Key: "createdAt", Value: "", Type: "notempty"},
    },
    },
  }
  TestClient.GET(fmt.Sprintf("%s/profile", url), profile)
}

func Create(TestClient *httptest.Client, data map[string]interface{}) uint {
  pageKeys := httptest.Responses{
    {Key: "status", Value: http.StatusOK},
    {Key: "message", Value: response.ResponseOkMessage},
    {Key: "data", Value: httptest.Responses{
      {Key: "id", Value: 1, Type: "ge"},
    },
    },
  }
  return TestClient.POST(fmt.Sprintf("%s/createAdmin", url), pageKeys, data).GetId()
}

func Delete(TestClient *httptest.Client, id uint) {
  pageKeys := httptest.Responses{
    {Key: "status", Value: http.StatusOK},
    {Key: "message", Value: response.ResponseOkMessage},
  }
  TestClient.DELETE(fmt.Sprintf("%s/deleteAdmin/%d", url, id), pageKeys)
}

🔋 JetBrains 开源证书支持

JetBrains 对本项目的支持。

打赏

您的打赏将用于支付网站运行,会在项目介绍中特别鸣谢您

469c2727cb1a4f9cc0d819a18059c7ab.jpeg e9939a7e92f32337871feb22e06bd05a.jpeg

iris-admin's People

Contributors

gitter-badger avatar kataras avatar snowlyg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iris-admin's Issues

使用的是 go mod ,运行报错

报错信息:
routes/route.go:21:20: cannot use crs (type "github.com/kataras/iris/v12/context".Handler) as type "github.com/kataras/iris/context".Handler in argument to api.APIBuilder.Party routes/route.go:28:23: cannot use crs (type "github.com/kataras/iris/v12/context".Handler) as type "github.com/kataras/iris/context".Handler in argument to api.APIBuilder.Party routes/route.go:33:18: cannot use crs (type "github.com/kataras/iris/v12/context".Handler) as type "github.com/kataras/iris/context".Handler in argument to api.APIBuilder.Party routes/route.go:38:37: cannot use middleware.JwtHandler().Serve (type func("github.com/kataras/iris/v12/context".Context)) as type "github.com/kataras/iris/context".Handler in argument to admin.Use

我尝试着去把 iris 改成 v12 运行也会报错

  1. clone项目,go.mod没有clone下来,遂执行

go mod init IrisApiProject

  1. copy您的项目里的go.mod 然后执行

go mod tidy

  1. 上面两步都没有问题,然后执行
    go run main.go

然后就报错了

数据库表

hello 我想运行一下,默认里面的是mysql,可是没有数据库的表文件, mysql的数据表能发一份吗?

登录管理员账号报错

重复初始化权限
重复初始化角色
重复初始化账号
Now listening on: http://0.0.0.0:8081
Application started. Press CTRL+C to shut down.
[HTTP Server] http: panic serving [::1]:5203: reflect: call of reflect.Value.Interface on zero Value
image

新手请教

作者您好,我是刚学go不久,算接口仔的程度吧,然后这个东西拿上手不知道应该怎么使用好,文档很精简,但是我可能要写可看着操作的视频之类的东西,请问哪里可以找到啊

yaag module 404 Not Found

when I try install the modules in MAC
I got this error:

go: github.com/betacraft/[email protected] requires
	github.com/flosch/[email protected] requires
	github.com/go-check/[email protected]: reading https://goproxy.io/github.com/go-check/check/@v/v1.0.0-20180628173108-788fd7840127.mod: 404 Not Found

when I try to update the gopm

[GOPM] 12-19 17:10:52 [ INFO] App Version: 0.8.8.0307 Beta
[GOPM] 12-19 17:10:52 [ INFO] Local repository path: /Users/zer0like/.gopm/repos
[GOPM] 12-19 17:10:52 [ INFO] Indicated GOPATH: /Users/zer0like/go
[GOPM] 12-19 17:10:58 [ INFO] Updating pkgname.list...0 > 201409140
[GOPM] 12-19 17:11:08 [ WARN] Fail to update pkgname.list: fail to make request: Get https://raw.githubusercontent.com/gpmgo/docs/master/pkgname.list: dial tcp 151.101.228.133:443: i/o timeout
[GOPM] 12-19 17:11:08 [ INFO] Nothing need to be updated
[GOPM] 12-19 17:11:08 [ INFO] Exit old gopm

maybe it is the problem of the yaag, but I can't fix it

请问如何更名?

你好,我想把IrisApiProject更改成实际的项目名称,请问如何操作呢?

exec: "gcc": executable file not found in %PATH%

我本地下载了tdm-gcc,
如图命令行也能用gcc.exe的命令
image为啥项目启动还是报标题的错误啊
错误如下

# github.com/mattn/go-sqlite3
exec: "gcc": executable file not found in %PATH%

api文档没有

api文档是自动生成的还是本来需要有index.html才行呢

没有使用redis缓存

我看了下代码,好像没有用到redis,实际jwt信息是存在mysql里的,redis里空荡荡的。

mac 下 ,执行run 命令 结果

mac 下 ,执行run 命令 结果

[~/www/dnmp/www/go/IrisApiProject]$ go run main.go                                                                                                                                          *[master]
go: finding github.com/betacraft/yaag v1.0.0
go: downloading github.com/kataras/iris v11.1.1+incompatible
go: downloading github.com/betacraft/yaag v1.0.0
go: extracting github.com/betacraft/yaag v1.0.0
go: extracting github.com/kataras/iris v11.1.1+incompatible
go: github.com/betacraft/[email protected] requires
	github.com/flosch/[email protected] requires
	github.com/go-check/[email protected]: invalid pseudo-version: major version without preceding tag must be v0, not v1

gowatch 后出现问题

2019/03/14 11:17:44 gowatch.go:111: [INFO] Start building...
2019/03/14 11:17:45 gowatch.go:136: [INFO] Build was successful
2019/03/14 11:17:45 gowatch.go:161: [INFO] Restarting ./IrisApiProject ...
2019/03/14 11:17:45 gowatch.go:173: [INFO] ./IrisApiProject is running...
panic: interface conversion: interface {} is nil, not string

goroutine 1 [running]:
IrisApiProject/database.New(0x433d445)
/Users/lucifer/Projects/Go/src/IrisApiProject/database/database.go:37 +0x5ed
IrisApiProject/database.init.ializers()
/Users/lucifer/Projects/Go/src/IrisApiProject/database/database.go:15 +0x22

前端代码请求发起两次

每次发起请求都会发起两次,第一次不带Authorization,第二次带Authorization.

控制台报错:
vue.esm.js:1741 TypeError: Cannot read property 'orders' of undefined
PermissionsMange.vue:155 Uncaught (in promise) TypeError: Cannot read property 'pageSize' of undefined

测试不通过

运行go test -v 没有通过呢, 好像有类型错误的问题

系统macOS
golang版本 1.12

# IrisApiProject [IrisApiProject.test] ./base_test.go:175:30: cannot use testPerms (type []"IrisApiProject/models".Permission) as type []uint in argument to "IrisApiProject/models".CreateRole FAIL IrisApiProject [build failed]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.