Coder Social home page Coder Social logo

suyuan32 / simple-admin-core Goto Github PK

View Code? Open in Web Editor NEW
1.5K 17.0 253.0 16.55 MB

Simple Admin是一个基于Go Zero开发面向小型到大型项目的分布式微服务后端管理系统脚手架,提供丰富的后台管理功能,支持k8s快速部署,助力快速开发高并发微服务集群,适合学习和商用。Simple Admin is a powerful microservice framework for large management system. It is based on go-zero and supports several advanced features. It can help you to develop a microservice back-end management system in a short time.

Home Page: http://doc.ryansu.tech/zh

License: MIT License

Go 98.57% Makefile 1.23% Shell 0.21%
go golang backend admin casbin go-zero rbac microservices rocketmq rpc-framework simple-admin ent asynq vue-admin

simple-admin-core's Introduction

Simple Admin

中文 | English

Go-Zero Vben Admin Ent Casbin Release License: MIT 公众号 注意

简介

Simple Admin 是一个强大的、易扩展的后台管理系统,基于 Go-Zero、Vben Admin、Ent、Casbin 等开源项目构建,提供了完整的用户管理、权限管理、角色管理、菜单管理、日志管理、配置管理等功能,支持多语言等特性,适用于小型或大型企业快速搭建分布式后台管理系统。

Simple Admin 有完善的开发部署工具, 十分适合高并发、高可靠、复杂的业务场景,项目可以方便地一键升级,提供了完善的文档视频和示例,让开发者可以快速上手,快速开发。官方提供了 6 大免费基础模块,可以满足 80 % 的常用业务需求。同时提供了模块商店,可以方便的购买和使用更多的模块。

6大免费模块均可免费商用,适合开发者学习、企业内部使用、个人项目使用等,欢迎大家使用和反馈问题,我们会持续更新和维护。

基于 go zero 的加强版工具,针对 simple admin 提供了大量优化,具有大量额外的代码生成功能,全面支持ent,轻松实现三端代码生成,使开发变得简单。

Doge 是 Simple Admin 的模块下载部署的命令行工具,提供模块源码下载,模块 docker , k8s 部署,服务器维护等功能。用户可以上传自己的付费模块获取收益,现已收录 10 + 模块。

模块商店

相关教程

Bilibili 视频教程
关注微信公众号 - 几颗酥 获取更多教程

在线预览

  • 账号 admin
  • 密码 simple-admin
  • 管理员租户账号

    • 企业: admin
    • 账号: admin
    • 密码: simple-admin
  • 租户账号

    • 企业: 测试企业
    • 账号: admin
    • 密码: simple-admin

只读,不可修改和注册

特性

  • 最新技术栈:使用 ent, casbin, kafka 等前沿技术开发
  • 完全支持go-swagger: 直接在api文件内编写注释即可直接生成swagger文档
  • 统一的错误处理: 整个系统拥有国际化的统一错误处理
  • 国际化:内置完善的国际化方案
  • 服务注册发现: 完善的服务注册发现机制,原生支持K8s
  • 权限: 内置完善的动态路由权限生成方案, 集成RBAC权限控制
  • 代码生成: 内置三端 Web, API, RPC 代码生成
  • 多种扩展: 提供多种扩展,同时具有非常简单的接入功能
  • 其他: 流量控制, ES服务
  • ORM: 强大的 Ent 框架支持

支持功能

  • 用户管理:管理系统用户数据
  • 部门管理:管理所属部门
  • 岗位管理:配置系统用户所属担任职务
  • 菜单管理:配置系统菜单,树形展示
  • 角色管理:管理角色权限,支持多角色
  • 字典管理:维护数据字典,方便前端使用
  • 接口文档:根据业务代码自动生成相关的api接口文档
  • 代码生成:自动生成 CRUD 代码,快捷生成自定义逻辑
  • 令牌管理:管理 token 状态,支持拉黑 token

永久免费的官方模块

模块名称 模块介绍 模块地址
Core 核心模块 Core
Backend UI 后端界面 Backend UI
FMS 文件管理 File
Job 定时任务 Job
MMS 会员管理 Member
MCMS 消息中心 Message Center

会员专属的模块

模块名称 模块介绍
CMS 内容管理模块
Simple-Uni 小程序开发脚手架
Simple-Nuxt PC 网页端开发脚手架
Core Tenant 多租户版本

社区模块

点击查看

项目规划进度

RoadMap

预览

pic pic

文档

准备

如何贡献

非常欢迎你的加入!提一个 Issue 或者提交一个 Pull Request。

Pull Request:

  1. Fork 代码!
  2. 创建自己的分支: git checkout -b feat/xxxx
  3. 提交你的修改: git commit -am 'feat(function): add xxxxx'
  4. 推送您的分支: git push origin feat/xxxx
  5. 提交pull request

Git 贡献提交规范

  • 参考 vue 规范 (Angular)

    • feat 增加新功能
    • fix 修复问题/BUG
    • style 代码风格相关无影响运行结果的
    • perf 优化/性能提升
    • refactor 重构
    • revert 撤销修改
    • test 测试相关
    • docs 文档/注释
    • chore 依赖更新/脚手架配置修改等
    • workflow 工作流改进
    • ci 持续集成
    • types 类型定义文件更改
    • wip 开发中

更新日志

CHANGELOG

交流群

Discord

论坛

关注公众号 《几颗酥》 加入微信群

Stars

Star History Chart

维护者

@Ryan Su

License

MIT © Ryan-2022

simple-admin-core's People

Contributors

aoeiuvbpmfdtnl avatar ch3nnn avatar ctra-wang avatar lordlezehaf avatar shaohongwu avatar suyuan32 avatar zhuangpeng 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

simple-admin-core's Issues

源码中的/rpc/ent/pagination.go不会通过gen-ent生成吗

通过goctls创建的RPC 基本项目
在通过go generate生成了/ent下的的文件后
缺少类似pagination.go的还有not_empty_update.go

导致生成的逻辑代码中l.svcCtx.DB.Student.Query().Where(predicates...).Page(l.ctx, in.Page, in.PageSize)用不了
err := l.svcCtx.DB.Student.UpdateOneID(in.Id). SetNotEmptyName(in.Name). SetNotEmptyAge(int(in.Age)). Exec(l.ctx)
中SetNotEmptyName,SetNotEmptyAge方法也没有

项目安排 | RoadMap

项目安排

  • 登录注册
  • 菜单管理
  • 角色管理
  • 角色权限
  • 用户管理
  • 操作日志
  • 服务注册发现
  • 字典功能
  • 三方登录管理
  • 全面支持 K8s
  • 服务监控
  • 日志收集
  • JWT黑名单
  • 定时任务
  • 消息队列
  • Ent
  • 后端 CRUD 代码生成
  • 前端 CRUD 代码生成
  • 一键运行 demo 脚本
  • RPC logic 分组
  • Proto 文件拆分
  • 优化第三方登陆
  • 多角色多职位
  • casbin跨api同步
  • 在线定时任务模块 simple admin job
  • API 单体服务代码生成

Road Map

  • Login and Register
  • Menu Management
  • Role Management
  • Role Authority
  • User Management
  • Operation log
  • Service discovery
  • Dictionary management
  • Oauth management
  • Fully support K8s
  • Service Monitor
  • Log collecting
  • JWT blacklist
  • Job Schedule
  • Message queue
  • Ent
  • Backend CRUD generation
  • Frontend CRUD code generation
  • docker-compose script
  • RPC logic group
  • Proto files divide
  • Enhance oauth
  • Multiple roles and positions
  • Casbin policy synchonize by redis
  • Online job schedule - simple admin job
  • API Single Service Code generation

关于validator的一些优化

一般的accept-language是这样的

accept-language: zh,en;q=0.9,en-US;q=0.8,zh-CN;q=0.7,zh-TW;q=0.6,la;q=0.5,ja;q=0.4,id;q=0.3,fr;q=0.2

下面的这段 在validate时, translate估计只能fallback到en了

https://github.com/suyuan32/simple-admin-tools/blob/f9473c481b9ae1c3f7e3a428314be3fce4760909/rest/httpx/requests.go#L48-L56

建议parse accept-language header时可以参考这里

https://github.com/nicksnyder/go-i18n/blob/639caa7eb5031c3fc275d5b3bf1f44fe3c3f2623/v2/i18n/localizer.go#L30-L51

还有就是在RegisterDefaultTranslation 失败的error类型不应是类似RegisterDefaultTranslationsError 吗?
为啥要抛出DatabaseError ?
还有作为 gozero 为何要引用回你的core-admin 的error代码?

	err := en_translations.RegisterDefaultTranslations(v.Validator, enTrans)
	if err != nil {
		logx.Errorw(logmessage.DatabaseError, logx.Field("Detail", err.Error()))
		return nil
	}
	err = zh_translations.RegisterDefaultTranslations(v.Validator, zhTrans)
	if err != nil {
		logx.Errorw(logmessage.DatabaseError, logx.Field("Detail", err.Error()))
		return nil
	}

ent版本 postgresql 菜单管理报错

ent版本 postgresql 菜单管理报错!
错误大意:[must appear in the GROUP BY clause or be used in an aggregate function]
忘记保存了 ,可以看看!

/user/update 修改 status 字段成功 实际数据库未修改

func (l *UpdateUserLogic) UpdateUser(in *core.UserInfo) (*core.BaseResp, error) {
	err := entx.WithTx(l.ctx, l.svcCtx.DB, func(tx *ent.Tx) error {
		updateQuery := tx.User.UpdateOneID(uuidx.ParseUUIDString(in.Id)).
			SetNotEmptyUsername(in.Username).
			SetNotEmptyNickname(in.Nickname).
			SetNotEmptyEmail(in.Email).
			SetNotEmptyMobile(in.Mobile).
			SetNotEmptyAvatar(in.Avatar).
			SetNotEmptyHomePath(in.HomePath).
			SetNotEmptyDescription(in.Description).
			SetNotEmptyDepartmentID(in.DepartmentId)

		if in.Password != "" {
			updateQuery = updateQuery.SetNotEmptyPassword(encrypt.BcryptEncrypt(in.Password))
		}

		if in.RoleIds != nil {
			err := l.svcCtx.DB.User.UpdateOneID(uuidx.ParseUUIDString(in.Id)).ClearRoles().Exec(l.ctx)
			if err != nil {
				return err
			}

			updateQuery = updateQuery.AddRoleIDs(in.RoleIds...)
		}

		if in.PositionIds != nil {
			err := l.svcCtx.DB.User.UpdateOneID(uuidx.ParseUUIDString(in.Id)).ClearPositions().Exec(l.ctx)
			if err != nil {
				return err
			}

			_, err = token.NewBlockUserAllTokenLogic(l.ctx, l.svcCtx).BlockUserAllToken(&core.UUIDReq{Id: in.Id})
			if err != nil {
				return err
			}

			updateQuery = updateQuery.AddPositionIDs(in.PositionIds...)
		}

		return updateQuery.Exec(l.ctx)
	})
	if err != nil {
		return nil, errorhandler.DefaultEntError(l.Logger, err, in)
	}

	return &core.BaseResp{
		Msg: i18n.Success,
	}, nil
}

缺少对status的修改操作

error的国际化问题

package errorx

const (
	// DatabaseError
	// normal database error
	DatabaseError string = "database error occur"

	// RedisError
	// normal redis error
	RedisError string = "redis error occur"

	// request error

	// ApiRequestFailed
	// EN: The interface request failed, please try again later!
	// ZH_CN: 请求出错,请稍候重试
	ApiRequestFailed string = "sys.api.apiRequestFailed"

这部分的message有translate 的支持吗?

swagger 注解的优化

    // swagger:route DELETE /user user deleteUser
    // Delete user information | 删除用户信息
    // Parameters:
    //  + name: body
    //    require: true
    //    in: body
    //    type: IDReq
    // Responses:
    //   200: SimpleMsg
    //   401: SimpleMsg
    //   500: SimpleMsg
    @handler deleteUser
    delete /user (IDReq) returns (SimpleMsg)

现在感觉api文件过于重复显得臃肿。
如果结合 gozero api 已有语法 @doc
可以删减一些重复的定义, 譬如 // swagger:route DELETE /user user deleteUser
在api文件parse的过程中,应该可以推出类似的swagger 路由信息

swagger generated fail!

Describe the bug
I try with the latest version.

To Reproduce
Steps to reproduce the behavior:

  1. run "make gen-api"
  2. See error

Screenshots
image
image

mac M1 使用make docker构建时,一直提示does not match the specified platform: wanted linux/amd64, actual: linux/arm64/v8

Describe the bug
failed to get destination image "sha256:XXX": image with reference sha256:XXX was found but does not match the specified platform: wanted linux/amd64, actual: linux/arm64/v8

To Reproduce
Steps to reproduce the behavior:

  1. 修改dockerfile中FROM --platform=linux/amd64 XXX
  2. 修改makefile中docker build --no-cache --platform linux/amd64 XXX
  3. 执行make docker
  4. 报错如上

Expected behavior
不修改的话打包的镜像无法在服务器端使用,报错:standard_init_linux.go:228: exec user process caused: exec format error

Screenshots
image

desc的merge功能能否添加map支持?

一些接口需使用动态参数,proto可支持map,但使用merge后,map丢失,且生成的文件也有一些问题。

示例:

message SMSCodeReq {
  string phone_number = 1;
  string type = 2;
  string provider_name = 3;
  map<string, string> parameters = 4;
}

看了一下源码,使用了 parser#Parse 方法去逐个parse .proto 文件,然后使用 stringBuilder 构造最终merge后的文件。

在处理 message 时,使用了protox.MessageVisitorprotox.ProtoField.Type 似乎并不能正确取到 map 的类型,这里没有仔细研究应该怎么处理。。。

DictionaryDetail 表结构

// DictionaryDetail table struct
// 字典键值表结构
type DictionaryDetail struct {
	gorm.Model
	Title        string `json:"title,omitempty" yaml:"title" gorm:"comment:the title shown in the UI"` // the title shown in the UI | 展示名
	Key          string `json:"key,omitempty" yaml:"key" gorm:"comment:key"`                           // key | 键
	Value        string `json:"value,omitempty" yaml:"value" gorm:"comment:value"`                     // value | 值
	Status       bool   `json:"status,omitempty" yaml:"status" gorm:"comment:status"`                  // status | 状态
	DictionaryID uint
}

DictionaryID 是不是漏了gorm的相关注解

分页返回的Total有歧义

       var roles []*model.Role
	result := l.svcCtx.DB.Limit(int(in.PageSize)).Offset(int((in.Page - 1) * in.PageSize)).Find(&roles)
	if result.Error != nil {
		logx.Errorw(logmessage.DatabaseError, logx.Field("detail", result.Error.Error()))
		return nil, status.Error(codes.Internal, result.Error.Error())
	}
	resp := &core.RoleListResp{}
	resp.Total = uint64(result.RowsAffected)
	for _, v := range roles {
		resp.Data = append(resp.Data, &core.RoleInfo{
			Id:            uint64(v.ID),
			Name:          v.Name,
			Value:         v.Value,
			DefaultRouter: v.DefaultRouter,
			Status:        v.Status,
			Remark:        v.Remark,
			OrderNo:       v.OrderNo,
			CreateAt:      v.CreatedAt.UnixMilli(),
		})
	}
	return resp, nil

一般的total 应该是所有的数据条数,而不是分页的items的条数

Split proto file

Describe the bug
Can't split core.proto to small file

To Reproduce
Steps to reproduce the behavior:

  1. Try to split core.proto to core_1.proto and core_2.proto then import core_2 into core_1
  2. run command : "make gen-rpc"
  3. throw error : "line xxx, request type must defined in core_1.proto"

Expected behavior
Split file proto like goctl

登录时候显示用户无权限访问此接口

大佬,最新的代码,点击登录后,弹出用户无权限访问此接口,错误是/sys-api/user/info这个接口返回的。
是不是ent schema哪里没有导入数据了?我看casbin admin有权限访问这个接口啊。我是整个项目重新拉了跑了下,应该没有操作问题

适合新手的PR | PR for new contributors

下面列出一些还需要完善的简单功能,适合新手参与项目:

  • 优化 logx 日志格式 | Optimize log data
  • 优化项目文档 | Optimize project documents
  • 增加第三方登陆(在初始化代码里提供,token地址等) | Add other 3rd-party providers for loging in
  • 优化翻译 | Optimize i18n translation
  • #75
  • #74
  • #73

mysql初始化问题

您好,ent是自动生成table吗?有sql文件吗?
我启动rpc以后也没有生成新的表格。有具体初始化数据库的文档吗?

建议贴 | Suggestions

大家可以在该贴提各种建议,点赞高的建议优先处理哦, 注意 simple-admin-core 主要负责所有其他微服务的鉴权、认证等操作,类似于 SSO 单点登录,以及后台的一些基本配置功能,其他拓展功能建议新增 API 服务,类似于 simple-admin-file。

目前规划

整理字符串的常量

redis cache key

	var apis []model.Api
	check := l.svcCtx.DB.Find(&apis)
	if check.RowsAffected != 0 {
		err := l.svcCtx.Redis.Set("database_init_state", "1")
		if err != nil {
			logx.Errorw(logmessage.RedisError, logx.Field("detail", err.Error()))
			return nil, status.Error(codes.Internal, errorx.RedisError)
		}
		return &core.BaseResp{Msg: errorx.AlreadyInit}, nil
	}

	// set default state value
	l.svcCtx.Redis.Setex("database_error_msg", "", 300)
	l.svcCtx.Redis.Set("database_init_state", "0")

roleId

func (l *InitDatabaseLogic) insertRoleMenuAuthorityData() error {
	var menus []model.Menu
	result := l.svcCtx.DB.Find(&menus)
	if result.Error != nil {
		logx.Errorw(logmessage.DatabaseError, logx.Field("detail", result.Error.Error()))
		return status.Error(codes.Internal, result.Error.Error())
	}

	var insertString strings.Builder
	insertString.WriteString("insert into role_menus values ")
	for i := 0; i < len(menus); i++ {
		if i != len(menus)-1 {
			insertString.WriteString(fmt.Sprintf("(%d, %d),", menus[i].ID, 1))
		} else {
			insertString.WriteString(fmt.Sprintf("(%d, %d);", menus[i].ID, 1))
		}
	}

关于postgresql的一点点建议

我看到您将pgsql的链接方式写法改了一下
` //return fmt.Sprintf("postgresql://%s:%s@%s/%s?sslmode=%s", c.Username, c.Password, c.Host, c.DBName, c.SSLMode)

return fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s", c.Host, c.Username, c.Password,
	c.DBName, c.Port, c.SSLMode)`

按照您更改的这种方式,那么在config文件中定义的port字段(如果端口不是5432的话就需要更改host值)就失去了意义!
建议还是维持更新前的写法!

纯属个人建议!

更新请求体限制过于严格

    // The profile request data | 个人信息请求参数
    // swagger:model ProfileReq
    ProfileReq {
        // user's nickname | 用户的昵称
        // Required: true
        // Max length: 10
        Nickname string `json:"nickname" validate:"alphanumunicode,max=10"`

        // The user's avatar path | 用户的头像路径
        // Required: true
        // Max length: 30
        Avatar string `json:"avatar"`

        // User's mobile phone number | 用户的手机号码
        // Required: true
        // Max length: 18
        Mobile string `json:"mobile" validate:"numeric,max=18"`

        // The user's email address | 用户的邮箱
        // Required: true
        // Max length: 100
        Email string `json:"email" validate:"email,max=100"`
    }

更新的的字段不是所有的required的,可能是parital 更新

执行goctls rpc new example生成文件依赖爆红

根目录执行goctls rpc new example --ent=true --port=9015 --desc=true
拉的最新的simple-admin-core和simple-admin-tool
1.生成的/example/internal/config/config.go中
`import (
"github.com/suyuan32/simple-admin-core/pkg/config"

"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/zrpc"

)`
github.com/suyuan32/simple-admin-core/pkg/config爆红
rpc下的相同位置引用的是github.com/suyuan32/simple-admin-common/config

3.文档中说goctls指令的go_zero_version和tool_version参数都是必须的,但是不添加也能执行

怎么运行

能否把源代码运行写的详细一些,谢谢

启动找不到配置文件

1、latest版本
2、run err:
2023/02/02 10:28:22 error: config file etc/core.yaml, open etc/core.yaml: no such file or directory
3、源代码:
var configFile = flag.String("f", "etc/core.yaml", "the config file")
4、修改成:
var configFile = flag.String("f", "api/etc/core.yaml", "the config file")
可以成功启动

pagination的count不支持modifier的情况

在模板中,count的实现方式如下:

count, err := {{ $r }}.Clone().Count(ctx)

一观Clone方法,并未对modifier属性进行复制(ent的问题吧?)

对模板文件进行修改如下即可正常使用

acClone := {{ $r }}.Clone()
acClone.modifiers = {{ $r }}.modifiers
count, err := acClone.Count(ctx)

此方式需要注意modifier的编写,若编写subQuery,必须在最外层套一个 select * from (subquery) AS { $tableName }

这是因为 Count(ctx) 默认的查询语法是

SELECT COUNT(`$tableName`.`id`)

最好是嵌套一层最外层,且将其AStableName

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.