feat: 完善数据库信息保存以及项目、redis相关操作

This commit is contained in:
meilin.huang
2021-07-28 18:03:19 +08:00
parent 3ebc3ee14d
commit bda3920c1e
153 changed files with 5527 additions and 1017 deletions

Binary file not shown.

View File

@@ -1,5 +1,5 @@
app:
name: devops
name: mayfly-go
version: 1.0.0
server:
@@ -7,6 +7,10 @@ server:
model: release
port: 8888
cors: true
tls:
enable: false
key-file: ./default.key
cert-file: ./default.pem
# 静态资源
static:
- relative-path: /assets
@@ -18,6 +22,11 @@ server:
- relative-path: /favicon.ico
filepath: ./static/favicon.ico
jwt:
key: mykey
# 过期时间单位分钟
expire-time: 1440
redis:
host: 127.0.0.1
port: 6379
@@ -27,4 +36,11 @@ mysql:
username: root
password: 111049
db-name: mayfly-job
config: charset=utf8&loc=Local&parseTime=true
config: charset=utf8&loc=Local&parseTime=true
log:
# 日志等级, trace, debug, info, warn, error, fatal
level: info
# file:
# path: ./
# name: mayfly.log

27
server/default.key Normal file
View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEA0CsawvEZl42Vf+0BlTuZ3Dp10yW8Oty1tjimxUj3s0WPeKil
6+TehnQELS8vGJfek+yT99nyrt+bkRmg1kxZ57FtQFEuthG4OQZoaMDUz6Ab+8P1
PQ9VH0XimnnYabxztJiQjl8HdJt6N4WP35kGlcul7qQ+Qc7iwjhSadfAhXVycqVI
cGQyHiPPfbmYRjueAIC4czmMUxwFKCwjepGYkwzWuGkpMD0hg/SIXpFJE2dcqYPR
2nCah1gxZZG00lHU1X2pehNmmgeHRkB5S7mrsCdyyV/33SAYk6T6PT7dOqY54bfn
h3C0k+T7IzvKTXKG76eG63STmxVa6luVoKMvxwIDAQABAoIBAQCI2Y2CUpYMd9us
edbskH4ZtaT35nrUB3y+Cog4cjvE8xnarKRHa/KOWX7VZYuEk3KTtJeh/Pn51K6k
uUBvIUqJcq7r9XLL5uJBOuEw3HQK+qrq3GxAc+/12y+Zdji7alR2iUWfEwIHup6i
GX/38tXNbE/tjrQO9z9Dh1tGkbvS/66tPn/T/oMxsRvZB6mCjB7yuOlEIwYTomYB
pUFemELt8T5RtfxRa8T1VoITbfuj7zvecqlThW0H8UizsFxvrOCUaga7jtsJOCHo
bcW5WvWwazoOfQ2BGpksKkBDf1N6pj85e4kOoYcVG9UN03ZwDvAGfQPWUlHB4YzW
PybMwIQBAoGBAPfuOQ+ukVmkiEKj6wCBe3Z0pYeNqBGec9aj62bKFh79BCE3ZopS
7JtGs8VfBKkBAaOy+MDuvJ2fvRNRtHT4BYe1U6ZRsmVFqHScACOaO/7TR0tz0ihL
0QLCkbSwsXExG6bYbwP4jMHkhHArT7Hy8WXvup8PffjSiEs1A1uGvYSBAoGBANbx
lHo+39nsc1OO8TUAWZChIQUib2hFIwzQYngSzINdfXQaGFT/omOsudAtfdjvp+qO
Tr7WpwgFEFveDFsdJfZ2Kc2x9a3ty7IYIWaAjK2ghkAKz3Tt4gClreB6qG2SBycP
4C2ImbY6hMaFHz3ENtTEzzTMdD1ByxQVMvoem3BHAoGBAJdaTmtMXl8jGivUdXnx
kbVWsFZ4G8nluUGm/+XYKHjybLr6XxbCWL7SApzSzL1/Z8jPURw2od53za0li8x8
PKQEBfTamtVIGPZW5Z7WYRnHURa2tezzm7zbmqd71lcLa54HMn5yFTuojVEMn7I6
ZTOdjYfcpUJpA9slmc8eCkQBAoGBAJEIbxRRaoBEQMkH8Y++zbB+WKZ7RssHo4/Y
6Ch3HtIg+i6mEPcBitRQzww+NeV0SExHe7Dfa9NIf3JNkO7F60CzGJ/3zXtvsftY
tujQIpxhbVS3NqaCgPXI1VtbyFwupW7hEnYG7xj7wW2mk578z7afmeTZdDGFPH8v
krccgeuvAoGBAPAwiqbZlXNx+ueI1B3T8VpXnG0ozKxG+l5B71kssZWa7xcv9yRd
c15l2PSXNtnoT/mBID7+dqQOmfYxsDHAkUdd/BrxhXtdi9FR3AfHSEQz+VKsogAD
uLyRd7jWTYqqGa2UToF/CBV+c6QyMB+6pzFNk5DmUEm4Gd6jcHDITYeI
-----END RSA PRIVATE KEY-----

21
server/default.pem Normal file
View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDejCCAmICCQDQU4ZRt2G46TANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJ6
aDEPMA0GA1UECAwGbWF5Zmx5MQswCQYDVQQHDAJ4bTEPMA0GA1UECgwGbWF5Zmx5
MQ8wDQYDVQQLDAZtYXlmbHkxDzANBgNVBAMMBm1heWZseTEfMB0GCSqGSIb3DQEJ
ARYQOTU0NTM3NDczQHFxLmNvbTAeFw0yMTA2MjQwMzI2MzBaFw0zMTA2MjIwMzI2
MzBaMH8xCzAJBgNVBAYTAnpoMQ8wDQYDVQQIDAZtYXlmbHkxCzAJBgNVBAcMAnht
MQ8wDQYDVQQKDAZtYXlmbHkxDzANBgNVBAsMBm1heWZseTEPMA0GA1UEAwwGbWF5
Zmx5MR8wHQYJKoZIhvcNAQkBFhA5NTQ1Mzc0NzNAcXEuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0CsawvEZl42Vf+0BlTuZ3Dp10yW8Oty1tjim
xUj3s0WPeKil6+TehnQELS8vGJfek+yT99nyrt+bkRmg1kxZ57FtQFEuthG4OQZo
aMDUz6Ab+8P1PQ9VH0XimnnYabxztJiQjl8HdJt6N4WP35kGlcul7qQ+Qc7iwjhS
adfAhXVycqVIcGQyHiPPfbmYRjueAIC4czmMUxwFKCwjepGYkwzWuGkpMD0hg/SI
XpFJE2dcqYPR2nCah1gxZZG00lHU1X2pehNmmgeHRkB5S7mrsCdyyV/33SAYk6T6
PT7dOqY54bfnh3C0k+T7IzvKTXKG76eG63STmxVa6luVoKMvxwIDAQABMA0GCSqG
SIb3DQEBCwUAA4IBAQB/e8EO2XEtkYBxebR1w6i50vaegLsxQJR3l5qm7rsHu3Cr
smJXGsc56axKCAqJ4XvSI65BT51FghAoGn62QNyiQgc0YoS99nwCCGFtnhZ2lmSe
pfhUHegN/Qo4I8FemEMD+o9kGeAzwrnaIVIT/cNOEQgm+RzrgHHJh5QBn2XgJalU
NeFTWaimyefwSezSa/vPbyMoAl9HkT6kdvnms/yOth4AOle6+5pM2StWjmMi4yx4
16y3NvLTku6nAUazaHTOOu/MCqLWL2/qYTk3r7OCop2jr9Rp+HLbg5AfKLUIVXjG
/1fnXJIuD+2u9qgDLN5PZNgz4MlU86ugtmYPFkVt
-----END CERTIFICATE-----

View File

@@ -6,6 +6,7 @@ import (
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/model"
"mayfly-go/base/utils"
"mayfly-go/server/devops/apis/form"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/application"
@@ -17,45 +18,73 @@ import (
)
type Db struct {
DbApp application.IDb
DbApp application.Db
}
// @router /api/dbs [get]
func (d *Db) Dbs(rc *ctx.ReqCtx) {
m := new(entity.Db)
g := rc.GinCtx
m := &entity.Db{EnvId: uint64(ginx.QueryInt(g, "envId", 0)),
ProjectId: uint64(ginx.QueryInt(g, "projectId", 0)),
Database: g.Query("database"),
}
ginx.BindQuery(g, m)
rc.ResData = d.DbApp.GetPageList(m, ginx.GetPageParam(rc.GinCtx), new([]vo.SelectDataDbVO))
}
// @router /api/db/:dbId/select [get]
func (d *Db) SelectData(rc *ctx.ReqCtx) {
func (d *Db) Save(rc *ctx.ReqCtx) {
form := &form.DbForm{}
ginx.BindJsonAndValid(rc.GinCtx, form)
rc.ReqParam = form
db := new(entity.Db)
utils.Copy(db, form)
db.SetBaseInfo(rc.LoginAccount)
d.DbApp.Save(db)
}
func (d *Db) DeleteDb(rc *ctx.ReqCtx) {
d.DbApp.Delete(uint64(ginx.PathParamInt(rc.GinCtx, "id")))
}
// @router /api/db/:dbId/exec-sql [get]
func (d *Db) ExecSql(rc *ctx.ReqCtx) {
g := rc.GinCtx
// 去除前后空格及换行符
selectSql := strings.TrimFunc(g.Query("selectSql"), func(r rune) bool {
sql := strings.TrimFunc(g.Query("sql"), func(r rune) bool {
s := string(r)
return s == " " || s == "\n"
})
rc.ReqParam = selectSql
rc.ReqParam = sql
biz.NotEmpty(selectSql, "selectSql不能为空")
res, err := d.DbApp.GetDbInstance(GetDbId(g)).SelectData(selectSql)
if err != nil {
panic(biz.NewBizErr(fmt.Sprintf("查询失败: %s", err.Error())))
}
rc.ResData = res
}
// @router /api/db/:dbId/exec-sql [post]
func (d *Db) ExecSql(g *gin.Context) {
rc := ctx.NewReqCtxWithGin(g).WithLog(ctx.NewLogInfo("sql执行"))
rc.Handle(func(rc *ctx.ReqCtx) {
selectSql := g.Query("sql")
biz.NotEmpty(selectSql, "sql不能为空")
num, err := d.DbApp.GetDbInstance(GetDbId(rc.GinCtx)).Exec(selectSql)
biz.NotEmpty(sql, "sql不能为空")
if strings.HasPrefix(sql, "SELECT") || strings.HasPrefix(sql, "select") {
colNames, res, err := d.DbApp.GetDbInstance(GetDbId(g)).SelectData(sql)
if err != nil {
panic(biz.NewBizErr(fmt.Sprintf("查询失败: %s", err.Error())))
}
colAndRes := make(map[string]interface{})
colAndRes["colNames"] = colNames
colAndRes["res"] = res
rc.ResData = colAndRes
} else {
rowsAffected, err := d.DbApp.GetDbInstance(GetDbId(g)).Exec(sql)
if err != nil {
panic(biz.NewBizErr(fmt.Sprintf("执行失败: %s", err.Error())))
}
rc.ResData = num
})
res := make([]map[string]string, 0)
resData := make(map[string]string)
resData["影响条数"] = fmt.Sprintf("%d", rowsAffected)
res = append(res, resData)
colAndRes := make(map[string]interface{})
colAndRes["colNames"] = []string{"影响条数"}
colAndRes["res"] = res
rc.ResData = colAndRes
}
}
// @router /api/db/:dbId/t-metadata [get]
@@ -74,21 +103,32 @@ func (d *Db) ColumnMA(rc *ctx.ReqCtx) {
// @router /api/db/:dbId/hint-tables [get]
func (d *Db) HintTables(rc *ctx.ReqCtx) {
dbi := d.DbApp.GetDbInstance(GetDbId(rc.GinCtx))
// 获取所有表
tables := dbi.GetTableMetedatas()
res := make(map[string][]string)
tableNames := make([]string, 0)
for _, v := range tables {
tableName := v["tableName"]
columnMds := dbi.GetColumnMetadatas(tableName)
columnNames := make([]string, len(columnMds))
for i, v := range columnMds {
comment := v["columnComment"]
if comment != "" {
columnNames[i] = v["columnName"] + " [" + comment + "]"
} else {
columnNames[i] = v["columnName"]
}
tableNames = append(tableNames, v["tableName"])
}
// 获取所有表下的所有列信息
columnMds := dbi.GetColumnMetadatas(tableNames...)
// key = 表名value = 列名数组
res := make(map[string][]string)
for _, v := range columnMds {
tName := v["tableName"]
if res[tName] == nil {
res[tName] = make([]string, 0)
}
res[tableName] = columnNames
columnName := fmt.Sprintf("%s [%s]", v["columnName"], v["columnType"])
comment := v["columnComment"]
// 如果字段备注不为空,则加上备注信息
if comment != "" {
columnName = fmt.Sprintf("%s[%s]", columnName, comment)
}
res[tName] = append(res[tName], columnName)
}
rc.ResData = res
}

View File

@@ -0,0 +1,16 @@
package form
type DbForm struct {
Id uint64
Name string `binding:"required" json:"name"`
Type string `binding:"required" json:"type"` // 类型mysql oracle等
Host string `binding:"required" json:"host"`
Port int `binding:"required" json:"port"`
Username string `binding:"required" json:"username"`
Password string `binding:"required" json:"password"`
Database string `binding:"required" json:"database"`
ProjectId uint64 `binding:"required" json:"projectId"`
Project string `json:"project"`
Env string `json:"env"`
EnvId uint64 `binding:"required" json:"envId"`
}

View File

@@ -2,45 +2,46 @@ package form
type MachineForm struct {
Id uint64 `json:"id"`
Name string `json:"name" valid:"Required"`
Name string `json:"name" binding:"required"`
// IP地址
Ip string `json:"ip" valid:"Required"`
Ip string `json:"ip" binding:"required"`
// 用户名
Username string `json:"username" valid:"Required"`
Password string `json:"password" valid:"Required"`
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
// 端口号
Port int `json:"port" valid:"Required"`
Port int `json:"port" binding:"required"`
}
type MachineRunForm struct {
MachineId int64 `valid:"Required"`
Cmd string `valid:"Required"`
MachineId int64 `binding:"required"`
Cmd string `binding:"required"`
}
type MachineFileForm struct {
Id uint64
Name string `valid:"Required"`
MachineId uint64 `valid:"Required"`
Type int `valid:"Required"`
Path string `valid:"Required"`
Name string `binding:"required"`
MachineId uint64 `binding:"required"`
Type int `binding:"required"`
Path string `binding:"required"`
}
type MachineScriptForm struct {
Id uint64
Name string `valid:"Required"`
MachineId uint64 `valid:"Required"`
Type int `valid:"Required"`
Description string `valid:"Required"`
Script string `valid:"Required"`
Name string `binding:"required"`
MachineId uint64 `binding:"required"`
Type int `binding:"required"`
Description string `binding:"required"`
Params string
Script string `binding:"required"`
}
type DbSqlSaveForm struct {
Sql string `valid:"Required"`
Type int `valid:"Required"`
Sql string `binding:"required"`
Type int `binding:"required"`
}
type MachineFileUpdateForm struct {
Content string `valid:"Required"`
Id uint64 `valid:"Required"`
Path string `valid:"Required"`
Content string `binding:"required"`
Id uint64 `binding:"required"`
Path string `binding:"required"`
}

View File

@@ -0,0 +1,18 @@
package form
type Redis struct {
Id uint64
Host string `binding:"required" json:"host"`
Password string `json:"password"`
Db int `json:"db"`
ProjectId uint64 `binding:"required" json:"projectId"`
Project string `json:"project"`
Env string `json:"env"`
EnvId uint64 `binding:"required" json:"envId"`
}
type KeyValue struct {
Key string `binding:"required" json:"key"`
Value interface{} `binding:"required" json:"value"`
Timed uint64
}

View File

@@ -26,7 +26,7 @@ var WsUpgrader = websocket.Upgrader{
}
type Machine struct {
MachineApp application.IMachine
MachineApp application.Machine
}
func (m *Machine) Machines(rc *ctx.ReqCtx) {
@@ -45,6 +45,12 @@ func (m *Machine) SaveMachine(rc *ctx.ReqCtx) {
m.MachineApp.Save(entity)
}
func (m *Machine) DeleteMachine(rc *ctx.ReqCtx) {
id := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
rc.ReqParam = id
m.MachineApp.Delete(id)
}
// top命令信息
func (m *Machine) Top(rc *ctx.ReqCtx) {
rc.ResData = m.MachineApp.GetCli(GetMachineId(rc.GinCtx)).GetTop()

View File

@@ -19,8 +19,8 @@ import (
)
type MachineFile struct {
MachineFileApp application.IMachineFile
MachineApp application.IMachine
MachineFileApp application.MachineFile
MachineApp application.Machine
}
const (

View File

@@ -16,8 +16,8 @@ import (
)
type MachineScript struct {
MachineScriptApp application.IMachineScript
MachineApp application.IMachine
MachineScriptApp application.MachineScript
MachineApp application.Machine
}
func (m *MachineScript) MachineScripts(rc *ctx.ReqCtx) {
@@ -57,8 +57,12 @@ func (m *MachineScript) RunMachineScript(rc *ctx.ReqCtx) {
biz.NotNil(ms, "该脚本不存在")
biz.IsTrue(ms.MachineId == application.Common_Script_Machine_Id || ms.MachineId == machineId, "该脚本不属于该机器")
vars := g.QueryMap("params")
res, err := m.MachineApp.GetCli(machineId).Run(utils.TemplateParse(ms.Script, vars))
script := ms.Script
// 如果有脚本参数,则用脚本参数替换脚本中的模板占位符参数
if params := g.Query("params"); params != "" {
script = utils.TemplateParse(ms.Script, utils.Json2Map(params))
}
res, err := m.MachineApp.GetCli(machineId).Run(script)
// 记录请求参数
rc.ReqParam = fmt.Sprintf("[machineId: %d, scriptId: %d, name: %s]", machineId, scriptId, ms.Name)
if err != nil {

View File

@@ -0,0 +1,100 @@
package apis
import (
"fmt"
"mayfly-go/base/biz"
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
sys_applicaiton "mayfly-go/server/sys/application"
sys_entity "mayfly-go/server/sys/domain/entity"
)
type Project struct {
ProjectApp application.Project
AccountApp sys_applicaiton.Account
}
// 获取当前登录用户可以访问的项目列表
func (p *Project) GetProjectsByLoginAccount(rc *ctx.ReqCtx) {
// 获取登录用户拥有的项目ids
projectMembers := &[]entity.ProjectMember{}
p.ProjectApp.ListMember(&entity.ProjectMember{AccountId: rc.LoginAccount.Id}, projectMembers)
var pids []uint64
for _, pm := range *projectMembers {
pids = append(pids, pm.ProjectId)
}
// 获取项目信息
projects := &vo.AccountProjects{}
p.ProjectApp.ListProjectByIds(pids, projects)
rc.ResData = projects
}
func (p *Project) GetProjects(rc *ctx.ReqCtx) {
condition := &entity.Project{}
ginx.BindQuery(rc.GinCtx, condition)
// condition.Name = rc.GinCtx.Query("name")
rc.ResData = p.ProjectApp.GetPageList(condition, ginx.GetPageParam(rc.GinCtx), new([]entity.Project))
}
func (p *Project) SaveProject(rc *ctx.ReqCtx) {
project := &entity.Project{}
ginx.BindJsonAndValid(rc.GinCtx, project)
rc.ReqParam = project
project.SetBaseInfo(rc.LoginAccount)
p.ProjectApp.SaveProject(project)
}
// 获取项目下的环境信息
func (p *Project) GetProjectEnvs(rc *ctx.ReqCtx) {
projectEnvs := &[]entity.ProjectEnv{}
p.ProjectApp.ListEnvByProjectId(uint64(ginx.PathParamInt(rc.GinCtx, "projectId")), projectEnvs)
rc.ResData = projectEnvs
}
//保存项目下的环境信息
func (p *Project) SaveProjectEnvs(rc *ctx.ReqCtx) {
projectEnv := &entity.ProjectEnv{}
ginx.BindJsonAndValid(rc.GinCtx, projectEnv)
rc.ReqParam = projectEnv
projectEnv.SetBaseInfo(rc.LoginAccount)
p.ProjectApp.SaveProjectEnv(projectEnv)
}
// 获取项目下的成员信息
func (p *Project) GetProjectMembers(rc *ctx.ReqCtx) {
projectMems := &[]entity.ProjectMember{}
rc.ResData = p.ProjectApp.GetMemberPage(&entity.ProjectMember{ProjectId: uint64(ginx.PathParamInt(rc.GinCtx, "projectId"))},
ginx.GetPageParam(rc.GinCtx), projectMems)
}
//保存项目的成员信息
func (p *Project) SaveProjectMember(rc *ctx.ReqCtx) {
projectMem := &entity.ProjectMember{}
ginx.BindJsonAndValid(rc.GinCtx, projectMem)
rc.ReqParam = projectMem
// 校验账号并赋值username
account := &sys_entity.Account{}
account.Id = projectMem.AccountId
biz.ErrIsNil(p.AccountApp.GetAccount(account, "Id", "Username"), "账号不存在")
projectMem.Username = account.Username
projectMem.SetBaseInfo(rc.LoginAccount)
p.ProjectApp.SaveProjectMember(projectMem)
}
//删除项目成员
func (p *Project) DelProjectMember(rc *ctx.ReqCtx) {
g := rc.GinCtx
pid := ginx.PathParamInt(g, "projectId")
aid := ginx.PathParamInt(g, "accountId")
rc.ReqParam = fmt.Sprintf("projectId: %d, accountId: %d", pid, aid)
p.ProjectApp.DeleteMember(uint64(pid), uint64(aid))
}

203
server/devops/apis/redis.go Normal file
View File

@@ -0,0 +1,203 @@
package apis
import (
"mayfly-go/base/biz"
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/utils"
"mayfly-go/server/devops/apis/form"
"mayfly-go/server/devops/apis/vo"
"mayfly-go/server/devops/application"
"mayfly-go/server/devops/domain/entity"
"strconv"
"strings"
"time"
)
type Redis struct {
RedisApp application.Redis
}
func (r *Redis) RedisList(rc *ctx.ReqCtx) {
g := rc.GinCtx
m := &entity.Redis{EnvId: uint64(ginx.QueryInt(g, "envId", 0)),
ProjectId: uint64(ginx.QueryInt(g, "projectId", 0)),
}
ginx.BindQuery(g, m)
rc.ResData = r.RedisApp.GetPageList(m, ginx.GetPageParam(rc.GinCtx), new([]vo.Redis))
}
func (r *Redis) Save(rc *ctx.ReqCtx) {
form := &form.Redis{}
ginx.BindJsonAndValid(rc.GinCtx, form)
rc.ReqParam = form
redis := new(entity.Redis)
utils.Copy(redis, form)
redis.SetBaseInfo(rc.LoginAccount)
r.RedisApp.Save(redis)
}
func (r *Redis) DeleteRedis(rc *ctx.ReqCtx) {
r.RedisApp.Delete(uint64(ginx.PathParamInt(rc.GinCtx, "id")))
}
func (r *Redis) RedisInfo(rc *ctx.ReqCtx) {
res, _ := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(rc.GinCtx, "id"))).Cli.Info().Result()
datas := strings.Split(res, "\r\n")
i := 0
length := len(datas)
parseMap := make(map[string]map[string]string, 0)
for {
if i >= length {
break
}
if strings.Contains(datas[i], "#") {
key := utils.SubString(datas[i], strings.Index(datas[i], "#")+1, utils.StrLen(datas[i]))
i++
key = strings.Trim(key, " ")
sectionMap := make(map[string]string, 0)
for {
if i >= length || !strings.Contains(datas[i], ":") {
break
}
pair := strings.Split(datas[i], ":")
i++
if len(pair) != 2 {
continue
}
sectionMap[pair[0]] = pair[1]
}
parseMap[key] = sectionMap
} else {
i++
}
}
rc.ResData = parseMap
}
// scan获取redis的key列表信息
func (r *Redis) Scan(rc *ctx.ReqCtx) {
g := rc.GinCtx
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")))
keys, cursor := ri.Scan(uint64(ginx.PathParamInt(g, "cursor")), g.Query("match"), int64(ginx.PathParamInt(g, "count")))
var keyInfoSplit []string
if len(keys) > 0 {
keyInfoLua := `
local result = {}
-- KEYS[1]为第1个参数lua数组下标从1开始
local ttl = redis.call('ttl', KEYS[1]);
local keyType = redis.call('type', KEYS[1]);
for i = 1, #KEYS do
local ttl = redis.call('ttl', KEYS[i]);
local keyType = redis.call('type', KEYS[i]);
table.insert(result, string.format("%d,%s", ttl, keyType['ok']));
end;
return table.concat(result, ".");`
// 通过lua获取 ttl,type.ttl2,type2格式以便下面切割获取ttl和type。避免多次调用ttl和type函数
keyInfos, _ := ri.Cli.Eval(keyInfoLua, keys).Result()
keyInfoSplit = strings.Split(keyInfos.(string), ".")
}
kis := make([]*vo.KeyInfo, 0)
for i, k := range keys {
ttlType := strings.Split(keyInfoSplit[i], ",")
ttl, _ := strconv.Atoi(ttlType[0])
ki := &vo.KeyInfo{Key: k, Type: ttlType[1], Ttl: uint64(ttl)}
kis = append(kis, ki)
}
size, _ := ri.Cli.DBSize().Result()
rc.ResData = &vo.Keys{Cursor: cursor, Keys: kis, DbSize: size}
}
func (r *Redis) DeleteKey(rc *ctx.ReqCtx) {
g := rc.GinCtx
key := g.Query("key")
biz.NotEmpty(key, "key不能为空")
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")))
rc.ReqParam = key
ri.Cli.Del(key)
}
func (r *Redis) checkKey(rc *ctx.ReqCtx) (*application.RedisInstance, string) {
g := rc.GinCtx
key := g.Query("key")
biz.NotEmpty(key, "key不能为空")
return r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id"))), key
}
func (r *Redis) GetStringValue(rc *ctx.ReqCtx) {
ri, key := r.checkKey(rc)
str, err := ri.Cli.Get(key).Result()
biz.ErrIsNilAppendErr(err, "获取字符串值失败: %s")
rc.ResData = str
}
func (r *Redis) GetHashValue(rc *ctx.ReqCtx) {
ri, key := r.checkKey(rc)
res, err := ri.Cli.HGetAll(key).Result()
biz.ErrIsNilAppendErr(err, "获取hash值失败: %s")
rc.ResData = res
}
func (r *Redis) GetSetValue(rc *ctx.ReqCtx) {
ri, key := r.checkKey(rc)
res, err := ri.Cli.SMembers(key).Result()
biz.ErrIsNilAppendErr(err, "获取set值失败: %s")
rc.ResData = res
}
func (r *Redis) Test(rc *ctx.ReqCtx) {
schema := `{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "integer"
},
"name": {
"description": "Name of the product",
"type": "string"
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
}
},
"required": ["id", "name", "price"]
}
`
// 获取请求报文的内容长度
len := rc.GinCtx.Request.ContentLength
// 新建一个字节切片,长度与请求报文的内容长度相同
body := make([]byte, len)
// 读取 r 的请求主体,并将具体内容读入 body 中
rc.GinCtx.Request.Body.Read(body)
err := utils.ValidJsonString(schema, string(body))
biz.ErrIsNilAppendErr(err, "%s")
}
func (r *Redis) SetStringValue(rc *ctx.ReqCtx) {
g := rc.GinCtx
keyValue := new(form.KeyValue)
ginx.BindJsonAndValid(g, keyValue)
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")))
str, err := ri.Cli.Set(keyValue.Key, keyValue.Value, time.Second*time.Duration(keyValue.Timed)).Result()
biz.ErrIsNilAppendErr(err, "保存字符串值失败: %s")
rc.ResData = str
}

View File

@@ -10,6 +10,11 @@ type SelectDataDbVO struct {
Port *int `json:"port"`
Type *string `json:"type"`
Database *string `json:"database"`
Username *string `json:"username"`
ProjectId *int64 `json:"projectId"`
Project *string `json:"project"`
Env *string `json:"env"`
EnvId *int64 `json:"envId"`
CreateTime *time.Time `json:"createTime"`
Creator *string `json:"creator"`
CreatorId *int64 `json:"creatorId"`

View File

@@ -0,0 +1,10 @@
package vo
// 用户选择项目
type AccountProject struct {
Id uint64 `json:"id"`
Name string `json:"name"`
Remark string `json:"remark"`
}
type AccountProjects []AccountProject

View File

@@ -0,0 +1,29 @@
package vo
import "time"
type Redis struct {
Id *int64 `json:"id"`
// Name *string `json:"name"`
Host *string `json:"host"`
Db int `json:"db"`
ProjectId *int64 `json:"projectId"`
Project *string `json:"project"`
Env *string `json:"env"`
EnvId *int64 `json:"envId"`
CreateTime *time.Time `json:"createTime"`
Creator *string `json:"creator"`
CreatorId *int64 `json:"creatorId"`
}
type Keys struct {
Cursor uint64 `json:"cursor"`
Keys []*KeyInfo `json:"keys"`
DbSize int64 `json:"dbSize"`
}
type KeyInfo struct {
Key string `json:"key"`
Ttl uint64 `json:"ttl"`
Type string `json:"type"`
}

View File

@@ -34,6 +34,7 @@ type MachineScriptVO struct {
Script *string `json:"script"`
Type *int `json:"type"`
Description *string `json:"description"`
Params *string `json:"params"`
MachineId *uint64 `json:"machineId"`
}

View File

@@ -1,16 +1,22 @@
package application
import (
"database/sql"
"errors"
"fmt"
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
"mayfly-go/server/devops/infrastructure/db"
"mayfly-go/server/devops/infrastructure/persistence"
"strings"
"sync"
"time"
)
type IDb interface {
type Db interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetPageList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据条件获取
GetDbBy(condition *entity.Db, cols ...string) error
@@ -20,36 +26,260 @@ type IDb interface {
Save(entity *entity.Db)
GetDbInstance(id uint64) *db.DbInstance
// 删除数据库信息
Delete(id uint64)
// 获取数据库连接实例
GetDbInstance(id uint64) *DbInstance
}
type dbApp struct {
dbRepo repository.Db
type dbAppImpl struct {
dbRepo repository.Db
dbSqlRepo repository.DbSql
}
var Db IDb = &dbApp{dbRepo: persistence.DbDao}
var DbApp Db = &dbAppImpl{
dbRepo: persistence.DbDao,
dbSqlRepo: persistence.DbSqlDao,
}
// 分页获取数据库信息列表
func (d *dbApp) GetPageList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (d *dbAppImpl) GetPageList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return d.dbRepo.GetDbList(condition, pageParam, toEntity, orderBy...)
}
// 根据条件获取
func (d *dbApp) GetDbBy(condition *entity.Db, cols ...string) error {
func (d *dbAppImpl) GetDbBy(condition *entity.Db, cols ...string) error {
return d.dbRepo.GetDb(condition, cols...)
}
// 根据id获取
func (d *dbApp) GetById(id uint64, cols ...string) *entity.Db {
func (d *dbAppImpl) GetById(id uint64, cols ...string) *entity.Db {
return d.dbRepo.GetById(id, cols...)
}
func (d *dbApp) Save(entity *entity.Db) {
func (d *dbAppImpl) Save(dbEntity *entity.Db) {
// 默认tcp连接
dbEntity.Network = "tcp"
// 测试连接
TestConnection(dbEntity)
// 查找是否存在该库
oldDb := &entity.Db{Host: dbEntity.Host, Port: dbEntity.Port, Database: dbEntity.Database}
err := d.GetDbBy(oldDb)
if dbEntity.Id == 0 {
biz.IsTrue(err != nil, "该库已存在")
d.dbRepo.Insert(dbEntity)
} else {
// 如果存在该库,则校验修改的库是否为该库
if err == nil {
biz.IsTrue(oldDb.Id == dbEntity.Id, "该库已存在")
}
// 先关闭数据库连接
CloseDb(dbEntity.Id)
d.dbRepo.Update(dbEntity)
}
}
func (d *dbApp) GetDbInstance(id uint64) *db.DbInstance {
return db.GetDbInstance(id, func(id uint64) *entity.Db {
return d.dbRepo.GetById(id)
})
func (d *dbAppImpl) Delete(id uint64) {
// 关闭连接
CloseDb(id)
d.dbRepo.Delete(id)
// 删除该库下用户保存的所有sql信息
d.dbSqlRepo.DeleteBy(&entity.DbSql{DbId: id})
}
func (da *dbAppImpl) GetDbInstance(id uint64) *DbInstance {
// Id不为0则为需要缓存
needCache := id != 0
if needCache {
load, ok := dbCache.Load(id)
if ok {
return load.(*DbInstance)
}
}
d := da.GetById(id)
biz.NotNil(d, "数据库信息不存在")
DB, err := sql.Open(d.Type, getDsn(d))
biz.ErrIsNil(err, fmt.Sprintf("Open %s failed, err:%v\n", d.Type, err))
perr := DB.Ping()
if perr != nil {
panic(biz.NewBizErr(fmt.Sprintf("数据库连接失败: %s", perr.Error())))
}
// 最大连接周期超过时间的连接就close
DB.SetConnMaxLifetime(100 * time.Second)
// 设置最大连接数
DB.SetMaxOpenConns(2)
// 设置闲置连接数
DB.SetMaxIdleConns(1)
dbi := &DbInstance{Id: id, Type: d.Type, db: DB}
if needCache {
dbCache.LoadOrStore(d.Id, dbi)
}
return dbi
}
//------------------------------------------------------------------------------
var dbCache sync.Map
func GetDbInstanceByCache(id uint64) *DbInstance {
if load, ok := dbCache.Load(id); ok {
return load.(*DbInstance)
}
return nil
}
func TestConnection(d *entity.Db) {
biz.NotNil(d, "数据库信息不存在")
DB, err := sql.Open(d.Type, getDsn(d))
biz.ErrIsNil(err, "Open %s failed, err:%v\n", d.Type, err)
defer DB.Close()
perr := DB.Ping()
biz.ErrIsNilAppendErr(perr, "数据库连接失败: %s")
}
// db实例
type DbInstance struct {
Id uint64
Type string
db *sql.DB
}
// 执行查询语句
// 依次返回 列名数组结果map错误
func (d *DbInstance) SelectData(sql string) ([]string, []map[string]string, error) {
sql = strings.Trim(sql, " ")
if !strings.HasPrefix(sql, "SELECT") && !strings.HasPrefix(sql, "select") {
return nil, nil, errors.New("该sql非查询语句")
}
// 没加limit则默认限制50条
if !strings.Contains(sql, "limit") && !strings.Contains(sql, "LIMIT") {
sql = sql + " LIMIT 50"
}
rows, err := d.db.Query(sql)
if err != nil {
return nil, nil, err
}
// rows对象一定要close掉如果出错不关掉则会很迅速的达到设置最大连接数
// 后面的链接过来直接报错或拒绝,实际上也没有起效果
defer func() {
if rows != nil {
rows.Close()
}
}()
cols, _ := rows.Columns()
// 这里表示一行填充数据
scans := make([]interface{}, len(cols))
// 这里表示一行所有列的值,用[]byte表示
vals := make([][]byte, len(cols))
// 这里scans引用vals把数据填充到[]byte里
for k := range vals {
scans[k] = &vals[k]
}
result := make([]map[string]string, 0)
// 列名
colNames := make([]string, 0)
// 是否第一次遍历,列名数组只需第一次遍历时加入
isFirst := true
for rows.Next() {
// 不Scan也会导致等待该链接实际处于未工作的状态然后也会导致连接数迅速达到最大
err := rows.Scan(scans...)
if err != nil {
return nil, nil, err
}
// 每行数据
rowData := make(map[string]string)
// 把vals中的数据复制到row中
for k, v := range vals {
key := cols[k]
// 如果是密码字段,则脱敏显示
if key == "password" {
v = []byte("******")
}
if isFirst {
colNames = append(colNames, key)
}
// 这里把[]byte数据转成string
rowData[key] = string(v)
}
//放入结果集
result = append(result, rowData)
isFirst = false
}
return colNames, result, nil
}
// 执行 update, insert, delete建表等sql
// 返回影响条数和错误
func (d *DbInstance) Exec(sql string) (int64, error) {
res, err := d.db.Exec(sql)
if err != nil {
return 0, err
}
return res.RowsAffected()
}
// 关闭连接,并从缓存中移除
func (d *DbInstance) Close() {
d.db.Close()
dbCache.Delete(d.Id)
}
// 获取dataSourceName
func getDsn(d *entity.Db) string {
if d.Type == "mysql" {
return fmt.Sprintf("%s:%s@%s(%s:%d)/%s", d.Username, d.Password, d.Network, d.Host, d.Port, d.Database)
}
return ""
}
func CloseDb(id uint64) {
if di := GetDbInstanceByCache(id); di != nil {
di.Close()
}
}
//-----------------------------------元数据-------------------------------------------
const (
// mysql 表信息元数据
MYSQL_TABLE_MA = `SELECT table_name tableName, engine, table_comment tableComment,
create_time createTime from information_schema.tables
WHERE table_schema = (SELECT database())`
// mysql 列信息元数据
MYSQL_COLOUMN_MA = `SELECT table_name tableName, column_name columnName, column_type columnType,
column_comment columnComment, column_key columnKey, extra from information_schema.columns
WHERE table_name in (%s) AND table_schema = (SELECT database()) ORDER BY ordinal_position limit 15000`
)
func (d *DbInstance) GetTableMetedatas() []map[string]string {
var sql string
if d.Type == "mysql" {
sql = MYSQL_TABLE_MA
}
_, res, _ := d.SelectData(sql)
return res
}
func (d *DbInstance) GetColumnMetadatas(tableNames ...string) []map[string]string {
var sql, tableName string
for i := 0; i < len(tableNames); i++ {
if i != 0 {
tableName = tableName + ", "
}
tableName = tableName + "'" + tableNames[i] + "'"
}
if d.Type == "mysql" {
sql = fmt.Sprintf(MYSQL_COLOUMN_MA, tableName)
}
_, res, err := d.SelectData(sql)
biz.ErrIsNilAppendErr(err, "获取数据库列信息失败: %s")
return res
}

View File

@@ -7,58 +7,95 @@ import (
"mayfly-go/server/devops/domain/repository"
"mayfly-go/server/devops/infrastructure/machine"
"mayfly-go/server/devops/infrastructure/persistence"
"gorm.io/gorm"
)
type IMachine interface {
type Machine interface {
// 根据条件获取账号信息
GetMachine(condition *entity.Machine, cols ...string) error
Save(entity *entity.Machine)
Delete(id uint64)
// 根据id获取
GetById(id uint64, cols ...string) *entity.Machine
// 分页获取机器信息列表
GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 获取机器连接
GetCli(id uint64) *machine.Cli
}
type machineApp struct {
type machineAppImpl struct {
machineRepo repository.Machine
}
var Machine IMachine = &machineApp{machineRepo: persistence.MachineDao}
var MachineApp Machine = &machineAppImpl{machineRepo: persistence.MachineDao}
// 分页获取机器信息列表
func (m *machineApp) GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (m *machineAppImpl) GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return m.machineRepo.GetMachineList(condition, pageParam, toEntity, orderBy...)
}
// 根据条件获取机器信息
func (m *machineApp) Save(entity *entity.Machine) {
biz.ErrIsNil(machine.TestConn(entity), "该机器无法连接")
if entity.Id != 0 {
m.machineRepo.UpdateById(entity)
func (m *machineAppImpl) Save(me *entity.Machine) {
biz.ErrIsNilAppendErr(machine.TestConn(me), "该机器无法连接: %s")
oldMachine := &entity.Machine{Ip: me.Ip, Port: me.Port, Username: me.Username}
err := m.GetMachine(oldMachine)
if me.Id != 0 {
// 如果存在该库,则校验修改的库是否为该库
if err == nil {
biz.IsTrue(oldMachine.Id == me.Id, "该机器信息已存在")
}
// 关闭连接
machine.Close(me.Id)
m.machineRepo.UpdateById(me)
} else {
m.machineRepo.Create(entity)
biz.IsTrue(err != nil, "该机器信息已存在")
m.machineRepo.Create(me)
}
}
// 根据条件获取机器信息
func (m *machineApp) GetMachine(condition *entity.Machine, cols ...string) error {
func (m *machineAppImpl) Delete(id uint64) {
// 关闭连接
machine.Close(id)
model.Tx(
func(db *gorm.DB) error {
// 删除machine表信息
return db.Delete(new(entity.Machine), "id = ?", id).Error
},
func(db *gorm.DB) error {
// 删除machine_file
machineFile := &entity.MachineFile{MachineId: id}
return db.Where(machineFile).Delete(machineFile).Error
},
func(db *gorm.DB) error {
// 删除machine_script
machineScript := &entity.MachineScript{MachineId: id}
return db.Where(machineScript).Delete(machineScript).Error
},
)
}
// 根据条件获取机器信息
func (m *machineAppImpl) GetMachine(condition *entity.Machine, cols ...string) error {
return m.machineRepo.GetMachine(condition, cols...)
}
func (m *machineApp) GetById(id uint64, cols ...string) *entity.Machine {
func (m *machineAppImpl) GetById(id uint64, cols ...string) *entity.Machine {
return m.machineRepo.GetById(id, cols...)
}
func (m *machineApp) GetCli(id uint64) *machine.Cli {
func (m *machineAppImpl) GetCli(id uint64) *machine.Cli {
cli, err := machine.GetCli(id, func(machineId uint64) *entity.Machine {
return m.GetById(machineId)
})
biz.ErrIsNil(err, "获取客户端错误")
biz.ErrIsNilAppendErr(err, "获取客户端错误: %s")
return cli
}

View File

@@ -15,9 +15,9 @@ import (
"github.com/pkg/sftp"
)
type IMachineFile interface {
type MachineFile interface {
// 分页获取机器文件信息列表
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据条件获取
GetMachineFile(condition *entity.MachineFile, cols ...string) error
@@ -47,34 +47,34 @@ type IMachineFile interface {
RemoveFile(fileId uint64, path string)
}
type machineFileApp struct {
type machineFileAppImpl struct {
machineFileRepo repository.MachineFile
machineRepo repository.Machine
}
// 实现类单例
var MachineFile IMachineFile = &machineFileApp{
var MachineFileApp MachineFile = &machineFileAppImpl{
machineRepo: persistence.MachineDao,
machineFileRepo: persistence.MachineFileDao,
}
// 分页获取机器脚本信息列表
func (m *machineFileApp) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (m *machineFileAppImpl) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return m.machineFileRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
// 根据条件获取
func (m *machineFileApp) GetMachineFile(condition *entity.MachineFile, cols ...string) error {
func (m *machineFileAppImpl) GetMachineFile(condition *entity.MachineFile, cols ...string) error {
return m.machineFileRepo.GetMachineFile(condition, cols...)
}
// 根据id获取
func (m *machineFileApp) GetById(id uint64, cols ...string) *entity.MachineFile {
func (m *machineFileAppImpl) GetById(id uint64, cols ...string) *entity.MachineFile {
return m.machineFileRepo.GetById(id, cols...)
}
// 保存机器文件配置
func (m *machineFileApp) Save(entity *entity.MachineFile) {
func (m *machineFileAppImpl) Save(entity *entity.MachineFile) {
biz.NotNil(m.machineRepo.GetById(entity.MachineId, "Name"), "该机器不存在")
if entity.Id != 0 {
@@ -85,11 +85,11 @@ func (m *machineFileApp) Save(entity *entity.MachineFile) {
}
// 根据id删除
func (m *machineFileApp) Delete(id uint64) {
func (m *machineFileAppImpl) Delete(id uint64) {
m.machineFileRepo.Delete(id)
}
func (m *machineFileApp) ReadDir(fid uint64, path string) []fs.FileInfo {
func (m *machineFileAppImpl) ReadDir(fid uint64, path string) []fs.FileInfo {
path, machineId := m.checkAndReturnPathMid(fid, path)
if !strings.HasSuffix(path, "/") {
path = path + "/"
@@ -101,7 +101,7 @@ func (m *machineFileApp) ReadDir(fid uint64, path string) []fs.FileInfo {
return fis
}
func (m *machineFileApp) ReadFile(fileId uint64, path string) ([]byte, fs.FileInfo) {
func (m *machineFileAppImpl) ReadFile(fileId uint64, path string) ([]byte, fs.FileInfo) {
path, machineId := m.checkAndReturnPathMid(fileId, path)
sftpCli := m.getSftpCli(machineId)
// 读取文件内容
@@ -119,7 +119,7 @@ func (m *machineFileApp) ReadFile(fileId uint64, path string) ([]byte, fs.FileIn
}
// 写文件内容
func (m *machineFileApp) WriteFileContent(fileId uint64, path string, content []byte) {
func (m *machineFileAppImpl) WriteFileContent(fileId uint64, path string, content []byte) {
_, machineId := m.checkAndReturnPathMid(fileId, path)
sftpCli := m.getSftpCli(machineId)
@@ -133,7 +133,7 @@ func (m *machineFileApp) WriteFileContent(fileId uint64, path string, content []
}
// 上传文件
func (m *machineFileApp) UploadFile(fileId uint64, path, filename string, content []byte) {
func (m *machineFileAppImpl) UploadFile(fileId uint64, path, filename string, content []byte) {
path, machineId := m.checkAndReturnPathMid(fileId, path)
if !strings.HasSuffix(path, "/") {
path = path + "/"
@@ -148,7 +148,7 @@ func (m *machineFileApp) UploadFile(fileId uint64, path, filename string, conten
}
// 删除文件
func (m *machineFileApp) RemoveFile(fileId uint64, path string) {
func (m *machineFileAppImpl) RemoveFile(fileId uint64, path string) {
path, machineId := m.checkAndReturnPathMid(fileId, path)
sftpCli := m.getSftpCli(machineId)
@@ -164,12 +164,12 @@ func (m *machineFileApp) RemoveFile(fileId uint64, path string) {
}
// 获取sftp client
func (m *machineFileApp) getSftpCli(machineId uint64) *sftp.Client {
return Machine.GetCli(machineId).GetSftpCli()
func (m *machineFileAppImpl) getSftpCli(machineId uint64) *sftp.Client {
return MachineApp.GetCli(machineId).GetSftpCli()
}
// 校验并返回实际可访问的文件path
func (m *machineFileApp) checkAndReturnPathMid(fid uint64, inputPath string) (string, uint64) {
func (m *machineFileAppImpl) checkAndReturnPathMid(fid uint64, inputPath string) (string, uint64) {
biz.IsTrue(fid != 0, "文件id不能为空")
mf := m.GetById(uint64(fid))
biz.NotNil(mf, "文件不存在")

View File

@@ -8,9 +8,9 @@ import (
"mayfly-go/server/devops/infrastructure/persistence"
)
type IMachineScript interface {
type MachineScript interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据条件获取
GetMachineScript(condition *entity.MachineScript, cols ...string) error
@@ -23,7 +23,7 @@ type IMachineScript interface {
Delete(id uint64)
}
type machineScriptApp struct {
type machineScriptAppImpl struct {
machineScriptRepo repository.MachineScript
machineRepo repository.Machine
}
@@ -31,27 +31,27 @@ type machineScriptApp struct {
const Common_Script_Machine_Id = 9999999
// 实现类单例
var MachineScript IMachineScript = &machineScriptApp{
var MachineScriptApp MachineScript = &machineScriptAppImpl{
machineRepo: persistence.MachineDao,
machineScriptRepo: persistence.MachineScriptDao}
// 分页获取机器脚本信息列表
func (m *machineScriptApp) GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (m *machineScriptAppImpl) GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return m.machineScriptRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
// 根据条件获取
func (m *machineScriptApp) GetMachineScript(condition *entity.MachineScript, cols ...string) error {
func (m *machineScriptAppImpl) GetMachineScript(condition *entity.MachineScript, cols ...string) error {
return m.machineScriptRepo.GetMachineScript(condition, cols...)
}
// 根据id获取
func (m *machineScriptApp) GetById(id uint64, cols ...string) *entity.MachineScript {
func (m *machineScriptAppImpl) GetById(id uint64, cols ...string) *entity.MachineScript {
return m.machineScriptRepo.GetById(id, cols...)
}
// 保存机器脚本
func (m *machineScriptApp) Save(entity *entity.MachineScript) {
func (m *machineScriptAppImpl) Save(entity *entity.MachineScript) {
// 如果机器id不为公共脚本id则校验机器是否存在
if machineId := entity.MachineId; machineId != Common_Script_Machine_Id {
biz.NotNil(m.machineRepo.GetById(machineId, "Name"), "该机器不存在")
@@ -65,6 +65,6 @@ func (m *machineScriptApp) Save(entity *entity.MachineScript) {
}
// 根据id删除
func (m *machineScriptApp) Delete(id uint64) {
func (m *machineScriptAppImpl) Delete(id uint64) {
m.machineScriptRepo.Delete(id)
}

View File

@@ -0,0 +1,95 @@
package application
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
"mayfly-go/server/devops/infrastructure/persistence"
)
type Project interface {
// 分页获取项目信息列表
GetPageList(condition *entity.Project, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
ListProjectByIds(ids []uint64, toEntity interface{}, orderBy ...string)
SaveProject(project *entity.Project)
// 根据项目id获取所有该项目下的环境信息列表
ListEnvByProjectId(projectId uint64, listPtr interface{})
// 保存项目环境信息
SaveProjectEnv(projectEnv *entity.ProjectEnv)
// 根据条件获取项目成员信息
ListMember(condition *entity.ProjectMember, toEntity interface{}, orderBy ...string)
SaveProjectMember(pm *entity.ProjectMember)
// 根据条件获取项目成员信息
GetMemberPage(condition *entity.ProjectMember, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
DeleteMember(projectId, accountId uint64)
}
type projectAppImpl struct {
projectRepo repository.Project
projectEnvRepo repository.ProjectEnv
projectMemberRepo repository.ProjectMemeber
}
var ProjectApp Project = &projectAppImpl{
projectRepo: persistence.ProjectRepo,
projectEnvRepo: persistence.ProjectEnvRepo,
projectMemberRepo: persistence.ProjectMemberRepo,
}
// 分页获取项目信息列表
func (p *projectAppImpl) GetPageList(condition *entity.Project, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return p.projectRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
func (p *projectAppImpl) ListProjectByIds(ids []uint64, toEntity interface{}, orderBy ...string) {
p.projectRepo.GetByIdIn(ids, toEntity, orderBy...)
}
func (p *projectAppImpl) SaveProject(project *entity.Project) {
if project.Id == 0 {
p.projectRepo.Save(project)
} else {
// 防止误传导致项目名更新
project.Name = ""
p.projectRepo.Update(project)
}
}
// 根据项目id获取所有该项目下的环境信息列表
func (p *projectAppImpl) ListEnvByProjectId(projectId uint64, listPtr interface{}) {
p.projectEnvRepo.ListEnv(&entity.ProjectEnv{ProjectId: projectId}, listPtr)
}
// 保存项目环境信息
func (p *projectAppImpl) SaveProjectEnv(projectEnv *entity.ProjectEnv) {
p.projectEnvRepo.Save(projectEnv)
}
// 根据条件获取项目成员信息
func (p *projectAppImpl) ListMember(condition *entity.ProjectMember, toEntity interface{}, orderBy ...string) {
p.projectMemberRepo.ListMemeber(condition, toEntity, orderBy...)
}
func (p *projectAppImpl) SaveProjectMember(pm *entity.ProjectMember) {
pms := new([]entity.ProjectMember)
p.ListMember(&entity.ProjectMember{ProjectId: pm.ProjectId, AccountId: pm.AccountId}, pms)
biz.IsTrue(len(*pms) == 0, "该成员已存在")
p.projectMemberRepo.Save(pm)
}
func (p *projectAppImpl) GetMemberPage(condition *entity.ProjectMember, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return p.projectMemberRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
func (p *projectAppImpl) DeleteMember(projectId, accountId uint64) {
p.projectMemberRepo.DeleteByPidMid(projectId, accountId)
}

View File

@@ -0,0 +1,146 @@
package application
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
"mayfly-go/server/devops/infrastructure/persistence"
"sync"
"github.com/go-redis/redis"
)
type Redis interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.Redis, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据id获取
GetById(id uint64, cols ...string) *entity.Redis
// 根据条件获取
GetRedisBy(condition *entity.Redis, cols ...string) error
Save(entity *entity.Redis)
// 删除数据库信息
Delete(id uint64)
// 获取数据库连接实例
GetRedisInstance(id uint64) *RedisInstance
}
type redisAppImpl struct {
redisRepo repository.Redis
}
var RedisApp Redis = &redisAppImpl{
redisRepo: persistence.RedisDao,
}
// 分页获取机器脚本信息列表
func (r *redisAppImpl) GetPageList(condition *entity.Redis, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return r.redisRepo.GetRedisList(condition, pageParam, toEntity, orderBy...)
}
// 根据id获取
func (r *redisAppImpl) GetById(id uint64, cols ...string) *entity.Redis {
return r.redisRepo.GetById(id, cols...)
}
// 根据条件获取
func (r *redisAppImpl) GetRedisBy(condition *entity.Redis, cols ...string) error {
return r.redisRepo.GetRedis(condition, cols...)
}
func (r *redisAppImpl) Save(re *entity.Redis) {
TestRedisConnection(re)
// 查找是否存在该库
oldRedis := &entity.Redis{Host: re.Host, Db: re.Db}
err := r.GetRedisBy(oldRedis)
if re.Id == 0 {
biz.IsTrue(err != nil, "该库已存在")
r.redisRepo.Insert(re)
} else {
// 如果存在该库,则校验修改的库是否为该库
if err == nil {
biz.IsTrue(re.Id == re.Id, "该库已存在")
}
// 先关闭数据库连接
CloseRedis(re.Id)
r.redisRepo.Update(re)
}
}
// 删除Redis信息
func (r *redisAppImpl) Delete(id uint64) {
CloseRedis(id)
r.redisRepo.Delete(id)
}
// 获取数据库连接实例
func (r *redisAppImpl) GetRedisInstance(id uint64) *RedisInstance {
// Id不为0则为需要缓存
needCache := id != 0
if needCache {
load, ok := redisCache.Load(id)
if ok {
return load.(*RedisInstance)
}
}
// 缓存不存在则回调获取redis信息
re := r.GetById(id)
biz.NotNil(re, "redis信息不存在")
rcli := redis.NewClient(&redis.Options{
Addr: re.Host,
Password: re.Password, // no password set
DB: re.Db, // use default DB
})
// 测试连接
_, e := rcli.Ping().Result()
biz.ErrIsNilAppendErr(e, "redis连接失败: %s")
ri := &RedisInstance{Id: id, Cli: rcli}
if needCache {
redisCache.LoadOrStore(re.Id, ri)
}
return ri
}
//------------------------------------------------------------------------------
var redisCache sync.Map
// redis实例
type RedisInstance struct {
Id uint64
Cli *redis.Client
}
// 关闭redis连接
func CloseRedis(id uint64) {
if load, ok := redisCache.Load(id); ok {
load.(*RedisInstance).Cli.Close()
redisCache.Delete(id)
}
}
func TestRedisConnection(re *entity.Redis) {
rcli := redis.NewClient(&redis.Options{
Addr: re.Host,
Password: re.Password, // no password set
DB: re.Db, // use default DB
})
defer rcli.Close()
// 测试连接
_, e := rcli.Ping().Result()
biz.ErrIsNilAppendErr(e, "Redis连接失败: %s")
}
func (r *RedisInstance) Scan(cursor uint64, match string, count int64) ([]string, uint64) {
keys, newcursor, err := r.Cli.Scan(cursor, match, count).Result()
biz.ErrIsNilAppendErr(err, "scan失败: %s")
return keys, newcursor
}

View File

@@ -7,12 +7,16 @@ import (
type Db struct {
model.Model
Name string `orm:"column(name)" json:"name"`
Type string `orm:"column(type)" json:"type"` // 类型mysql oracle等
Host string `orm:"column(host)" json:"host"`
Port int `orm:"column(port)" json:"port"`
Network string `orm:"column(network)" json:"network"`
Username string `orm:"column(username)" json:"username"`
Password string `orm:"column(password)" json:"-"`
Database string `orm:"column(database)" json:"database"`
Name string `orm:"column(name)" json:"name"`
Type string `orm:"column(type)" json:"type"` // 类型mysql oracle等
Host string `orm:"column(host)" json:"host"`
Port int `orm:"column(port)" json:"port"`
Network string `orm:"column(network)" json:"network"`
Username string `orm:"column(username)" json:"username"`
Password string `orm:"column(password)" json:"-"`
Database string `orm:"column(database)" json:"database"`
ProjectId uint64
Project string
EnvId uint64
Env string
}

View File

@@ -4,12 +4,10 @@ import "mayfly-go/base/model"
type MachineScript struct {
model.Model
Name string `json:"name"`
// 机器id
MachineId uint64 `json:"machineId"`
Type int `json:"type"`
// 脚本内容
Description string `json:"description"`
// 脚本内容
Script string `json:"script"`
Name string `json:"name"`
MachineId uint64 `json:"machineId"` // 机器id
Type int `json:"type"`
Description string `json:"description"` // 脚本描述
Params string `json:"params"` // 参数列表json
Script string `json:"script"` // 脚本内容
}

View File

@@ -0,0 +1,10 @@
package entity
import "mayfly-go/base/model"
// 项目
type Project struct {
model.Model
Name string `json:"name"` // 项目名
Remark string `json:"remark"` // 备注说明
}

View File

@@ -0,0 +1,11 @@
package entity
import "mayfly-go/base/model"
// 项目环境
type ProjectEnv struct {
model.Model
Name string `json:"name"` // 环境名
ProjectId uint64 `json:"projectId"` // 项目id
Remark string `json:"remark"` // 备注说明
}

View File

@@ -0,0 +1,11 @@
package entity
import "mayfly-go/base/model"
// 项目成员,用于对项目下组件的访问控制
type ProjectMember struct {
model.Model
AccountId uint64 `json:"accountId"` // 账号
Username string `json:"username"` // 账号用户名
ProjectId uint64 `json:"projectId"` // 项目id
}

View File

@@ -0,0 +1,17 @@
package entity
import (
"mayfly-go/base/model"
)
type Redis struct {
model.Model
Host string `orm:"column(host)" json:"host"`
Password string `orm:"column(password)" json:"-"`
Db int `orm:"column(database)" json:"db"`
ProjectId uint64
Project string
EnvId uint64
Env string
}

View File

@@ -7,11 +7,17 @@ import (
type Db interface {
// 分页获取机器信息列表
GetDbList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetDbList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据条件获取账号信息
GetDb(condition *entity.Db, cols ...string) error
// 根据id获取
GetById(id uint64, cols ...string) *entity.Db
Insert(db *entity.Db)
Update(db *entity.Db)
Delete(id uint64)
}

View File

@@ -0,0 +1,7 @@
package repository
import "mayfly-go/server/devops/domain/entity"
type DbSql interface {
DeleteBy(condition *entity.DbSql)
}

View File

@@ -7,7 +7,7 @@ import (
type Machine interface {
// 分页获取机器信息列表
GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据条件获取账号信息
GetMachine(condition *entity.Machine, cols ...string) error

View File

@@ -7,7 +7,7 @@ import (
type MachineFile interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据条件获取
GetMachineFile(condition *entity.MachineFile, cols ...string) error

View File

@@ -7,7 +7,7 @@ import (
type MachineScript interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据条件获取
GetMachineScript(condition *entity.MachineScript, cols ...string) error

View File

@@ -0,0 +1,16 @@
package repository
import (
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
)
type Project interface {
GetPageList(condition *entity.Project, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string)
Save(p *entity.Project)
Update(project *entity.Project)
}

View File

@@ -0,0 +1,10 @@
package repository
import "mayfly-go/server/devops/domain/entity"
type ProjectEnv interface {
// 获取项目环境列表
ListEnv(condition *entity.ProjectEnv, toEntity interface{}, orderBy ...string)
Save(entity *entity.ProjectEnv)
}

View File

@@ -0,0 +1,19 @@
package repository
import (
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
)
type ProjectMemeber interface {
// 获取项目成员列表
ListMemeber(condition *entity.ProjectMember, toEntity interface{}, orderBy ...string)
Save(mp *entity.ProjectMember)
GetPageList(condition *entity.ProjectMember, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据成员id和项目id删除关联关系
DeleteByPidMid(projectId, accountId uint64)
}

View File

@@ -0,0 +1,22 @@
package repository
import (
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
)
type Redis interface {
// 分页获取机器信息列表
GetRedisList(condition *entity.Redis, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
// 根据id获取
GetById(id uint64, cols ...string) *entity.Redis
GetRedis(condition *entity.Redis, cols ...string) error
Insert(redis *entity.Redis)
Update(redis *entity.Redis)
Delete(id uint64)
}

View File

@@ -1,131 +0,0 @@
package db
import (
"database/sql"
"errors"
"fmt"
"mayfly-go/base/biz"
"mayfly-go/server/devops/domain/entity"
"strings"
"sync"
"time"
_ "github.com/go-sql-driver/mysql"
)
var dbCache sync.Map
// db实例
type DbInstance struct {
Id uint64
Type string
db *sql.DB
}
// 执行查询语句
func (d *DbInstance) SelectData(sql string) ([]map[string]string, error) {
sql = strings.Trim(sql, " ")
if !strings.HasPrefix(sql, "SELECT") && !strings.HasPrefix(sql, "select") {
return nil, errors.New("该sql非查询语句")
}
rows, err := d.db.Query(sql)
if err != nil {
return nil, err
}
// rows对象一定要close掉如果出错不关掉则会很迅速的达到设置最大连接数
// 后面的链接过来直接报错或拒绝,实际上也没有起效果
defer func() {
if rows != nil {
rows.Close()
}
}()
cols, _ := rows.Columns()
// 这里表示一行填充数据
scans := make([]interface{}, len(cols))
// 这里表示一行所有列的值,用[]byte表示
vals := make([][]byte, len(cols))
// 这里scans引用vals把数据填充到[]byte里
for k := range vals {
scans[k] = &vals[k]
}
result := make([]map[string]string, 0)
for rows.Next() {
// 不Scan也会导致等待该链接实际处于未工作的状态然后也会导致连接数迅速达到最大
err := rows.Scan(scans...)
if err != nil {
return nil, err
}
// 每行数据
rowData := make(map[string]string)
// 把vals中的数据复制到row中
for k, v := range vals {
key := cols[k]
// 如果是密码字段,则脱敏显示
if key == "password" {
v = []byte("******")
}
// 这里把[]byte数据转成string
rowData[key] = string(v)
}
//放入结果集
result = append(result, rowData)
}
return result, nil
}
// 执行 update, insert, delete建表等sql
//
// 返回影响条数和错误
func (d *DbInstance) Exec(sql string) (int64, error) {
res, err := d.db.Exec(sql)
if err != nil {
return 0, err
}
return res.RowsAffected()
}
// 关闭连接,并从缓存中移除
func (d *DbInstance) Close() {
d.db.Close()
dbCache.Delete(d.Id)
}
// 获取dataSourceName
func getDsn(d *entity.Db) string {
if d.Type == "mysql" {
return fmt.Sprintf("%s:%s@%s(%s:%d)/%s", d.Username, d.Password, d.Network, d.Host, d.Port, d.Database)
}
return ""
}
func GetDbInstance(id uint64, getDbInfo func(uint64) *entity.Db) *DbInstance {
// Id不为0则为需要缓存
needCache := id != 0
if needCache {
load, ok := dbCache.Load(id)
if ok {
return load.(*DbInstance)
}
}
d := getDbInfo(id)
biz.NotNil(d, "数据库信息不存在")
DB, err := sql.Open(d.Type, getDsn(d))
biz.ErrIsNil(err, fmt.Sprintf("Open %s failed, err:%v\n", d.Type, err))
perr := DB.Ping()
if perr != nil {
panic(biz.NewBizErr(fmt.Sprintf("数据库连接失败: %s", perr.Error())))
}
// 最大连接周期超过时间的连接就close
DB.SetConnMaxLifetime(100 * time.Second)
// 设置最大连接数
DB.SetMaxOpenConns(5)
// 设置闲置连接数
DB.SetMaxIdleConns(1)
dbi := &DbInstance{Id: id, Type: d.Type, db: DB}
if needCache {
dbCache.LoadOrStore(d.Id, dbi)
}
return dbi
}

View File

@@ -1,33 +0,0 @@
package db
import "fmt"
const (
// mysql 表信息元数据
MYSQL_TABLE_MA = `SELECT table_name tableName, engine, table_comment tableComment,
create_time createTime from information_schema.tables
WHERE table_schema = (SELECT database())`
// mysql 列信息元数据
MYSQL_COLOUMN_MA = `SELECT column_name columnName, column_type columnType,
column_comment columnComment, column_key columnKey, extra from information_schema.columns
WHERE table_name = '%s' AND table_schema = (SELECT database()) ORDER BY ordinal_position`
)
func (d *DbInstance) GetTableMetedatas() []map[string]string {
var sql string
if d.Type == "mysql" {
sql = MYSQL_TABLE_MA
}
res, _ := d.SelectData(sql)
return res
}
func (d *DbInstance) GetColumnMetadatas(tableName string) []map[string]string {
var sql string
if d.Type == "mysql" {
sql = fmt.Sprintf(MYSQL_COLOUMN_MA, tableName)
}
res, _ := d.SelectData(sql)
return res
}

View File

@@ -42,7 +42,10 @@ func GetCli(machineId uint64, getMachine func(uint64) *entity.Machine) (*Cli, er
}
return c, nil
})
return cli.(*Cli), err
if cli != nil {
return cli.(*Cli), err
}
return nil, err
}
//根据机器信息创建客户端对象
@@ -204,3 +207,10 @@ func (c *Cli) RunTerminal(shell string, stdout, stderr io.Writer) error {
session.Run(shell)
return nil
}
// 关闭指定机器的连接
func Close(id uint64) {
if cli, ok := cliCache.Get(fmt.Sprint(id)); ok {
cli.(*Cli).Close()
}
}

View File

@@ -1,6 +1,7 @@
package persistence
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
@@ -11,7 +12,7 @@ type dbRepo struct{}
var DbDao repository.Db = &dbRepo{}
// 分页获取数据库信息列表
func (d *dbRepo) GetDbList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (d *dbRepo) GetDbList(condition *entity.Db, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
@@ -29,3 +30,15 @@ func (d *dbRepo) GetById(id uint64, cols ...string) *entity.Db {
}
return db
}
func (d *dbRepo) Insert(db *entity.Db) {
biz.ErrIsNil(model.Insert(db), "新增数据库信息失败")
}
func (d *dbRepo) Update(db *entity.Db) {
biz.ErrIsNil(model.UpdateById(db), "更新数据库信息失败")
}
func (d *dbRepo) Delete(id uint64) {
model.DeleteById(new(entity.Db), id)
}

View File

@@ -0,0 +1,17 @@
package persistence
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
)
type dbSqlRepo struct{}
var DbSqlDao repository.DbSql = &dbSqlRepo{}
// 分页获取数据库信息列表
func (d *dbSqlRepo) DeleteBy(condition *entity.DbSql) {
biz.ErrIsNil(model.DeleteByCondition(condition), "删除sql失败")
}

View File

@@ -12,7 +12,7 @@ type machineFileRepo struct{}
var MachineFileDao repository.MachineFile = &machineFileRepo{}
// 分页获取机器文件信息列表
func (m *machineFileRepo) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (m *machineFileRepo) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}

View File

@@ -11,7 +11,7 @@ type machineRepo struct{}
var MachineDao repository.Machine = &machineRepo{}
// 分页获取机器信息列表
func (m *machineRepo) GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (m *machineRepo) GetMachineList(condition *entity.Machine, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}

View File

@@ -12,7 +12,7 @@ type machineScriptRepo struct{}
var MachineScriptDao repository.MachineScript = &machineScriptRepo{}
// 分页获取机器信息列表
func (m *machineScriptRepo) GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (m *machineScriptRepo) GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}

View File

@@ -0,0 +1,20 @@
package persistence
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
)
type projectEnvRepo struct{}
var ProjectEnvRepo repository.ProjectEnv = &projectEnvRepo{}
func (p *projectEnvRepo) ListEnv(condition *entity.ProjectEnv, toEntity interface{}, orderBy ...string) {
model.ListByOrder(condition, toEntity, orderBy...)
}
func (p *projectEnvRepo) Save(entity *entity.ProjectEnv) {
biz.ErrIsNilAppendErr(model.Insert(entity), "保存环境失败:%s")
}

View File

@@ -0,0 +1,28 @@
package persistence
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
)
type projectMemeberRepo struct{}
var ProjectMemberRepo repository.ProjectMemeber = &projectMemeberRepo{}
func (p *projectMemeberRepo) ListMemeber(condition *entity.ProjectMember, toEntity interface{}, orderBy ...string) {
model.ListByOrder(condition, toEntity, orderBy...)
}
func (p *projectMemeberRepo) Save(pm *entity.ProjectMember) {
biz.ErrIsNilAppendErr(model.Insert(pm), "保存项目成员失败:%s")
}
func (p *projectMemeberRepo) GetPageList(condition *entity.ProjectMember, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
func (p *projectMemeberRepo) DeleteByPidMid(projectId, accountId uint64) {
model.DeleteByCondition(&entity.ProjectMember{ProjectId: projectId, AccountId: accountId})
}

View File

@@ -0,0 +1,28 @@
package persistence
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
)
type projectRepo struct{}
var ProjectRepo repository.Project = &projectRepo{}
func (p *projectRepo) GetPageList(condition *entity.Project, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
func (p *projectRepo) GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string) {
model.GetByIdIn(new(entity.Project), toEntity, ids, orderBy...)
}
func (p *projectRepo) Save(project *entity.Project) {
biz.ErrIsNil(model.Insert(project), "保存项目失败")
}
func (p *projectRepo) Update(project *entity.Project) {
biz.ErrIsNil(model.UpdateById(project), "更新项目信息")
}

View File

@@ -0,0 +1,42 @@
package persistence
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/devops/domain/entity"
"mayfly-go/server/devops/domain/repository"
)
type redisRepo struct{}
var RedisDao repository.Redis = &redisRepo{}
// 分页获取机器信息列表
func (r *redisRepo) GetRedisList(condition *entity.Redis, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
// 根据id获取
func (r *redisRepo) GetById(id uint64, cols ...string) *entity.Redis {
rd := new(entity.Redis)
if err := model.GetById(rd, id, cols...); err != nil {
return nil
}
return rd
}
func (r *redisRepo) GetRedis(condition *entity.Redis, cols ...string) error {
return model.GetBy(condition, cols...)
}
func (r *redisRepo) Insert(redis *entity.Redis) {
biz.ErrIsNilAppendErr(model.Insert(redis), "新增失败: %s")
}
func (r *redisRepo) Update(redis *entity.Redis) {
biz.ErrIsNilAppendErr(model.UpdateById(redis), "更新失败: %s")
}
func (r *redisRepo) Delete(id uint64) {
biz.ErrIsNilAppendErr(model.DeleteById(new(entity.Redis), id), "删除失败: %s")
}

View File

@@ -11,16 +11,31 @@ import (
func InitDbRouter(router *gin.RouterGroup) {
db := router.Group("dbs")
{
d := &apis.Db{DbApp: application.Db}
d := &apis.Db{DbApp: application.DbApp}
// 获取所有数据库列表
db.GET("", func(c *gin.Context) {
rc := ctx.NewReqCtxWithGin(c)
rc.Handle(d.Dbs)
})
// db.GET(":dbId/select", controllers.SelectData)
db.GET(":dbId/select", func(g *gin.Context) {
rc := ctx.NewReqCtxWithGin(g).WithLog(ctx.NewLogInfo("执行数据库查询语句"))
rc.Handle(d.SelectData)
saveDb := ctx.NewLogInfo("保存数据库信息")
db.POST("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).
WithLog(saveDb).
Handle(d.Save)
})
deleteDb := ctx.NewLogInfo("删除数据库信息")
db.DELETE(":id", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).
WithLog(deleteDb).
Handle(d.DeleteDb)
})
// db.GET(":dbId/exec-sql", controllers.SelectData)
db.GET(":dbId/exec-sql", func(g *gin.Context) {
rc := ctx.NewReqCtxWithGin(g).WithLog(ctx.NewLogInfo("执行Sql语句"))
rc.Handle(d.ExecSql)
})
db.GET(":dbId/t-metadata", func(c *gin.Context) {
@@ -35,7 +50,7 @@ func InitDbRouter(router *gin.RouterGroup) {
})
db.POST(":dbId/sql", func(c *gin.Context) {
rc := ctx.NewReqCtxWithGin(c).WithLog(ctx.NewLogInfo("保存sql内容"))
rc := ctx.NewReqCtxWithGin(c)
rc.Handle(d.SaveSql)
})

View File

@@ -9,15 +9,25 @@ import (
)
func InitMachineRouter(router *gin.RouterGroup) {
m := &apis.Machine{MachineApp: application.Machine}
m := &apis.Machine{MachineApp: application.MachineApp}
db := router.Group("machines")
{
db.GET("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(m.Machines)
})
saveMachine := ctx.NewLogInfo("保存机器信息")
db.POST("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(m.SaveMachine)
ctx.NewReqCtxWithGin(c).
WithLog(saveMachine).
Handle(m.SaveMachine)
})
delMachine := ctx.NewLogInfo("删除机器")
db.DELETE("/delete/:id", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).
WithLog(delMachine).
Handle(m.DeleteMachine)
})
db.GET(":machineId/top", func(c *gin.Context) {

View File

@@ -12,8 +12,8 @@ func InitMachineFileRouter(router *gin.RouterGroup) {
machineFile := router.Group("machines")
{
mf := &apis.MachineFile{
MachineFileApp: application.MachineFile,
MachineApp: application.Machine}
MachineFileApp: application.MachineFileApp,
MachineApp: application.MachineApp}
// 获取指定机器文件列表
machineFile.GET(":machineId/files", func(c *gin.Context) {

View File

@@ -12,12 +12,12 @@ func InitMachineScriptRouter(router *gin.RouterGroup) {
machines := router.Group("machines")
{
ms := &apis.MachineScript{
MachineScriptApp: application.MachineScript,
MachineApp: application.Machine}
MachineScriptApp: application.MachineScriptApp,
MachineApp: application.MachineApp}
// 获取指定机器脚本列表
machines.GET(":machineId/scripts", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithNeedToken(false).Handle(ms.MachineScripts)
ctx.NewReqCtxWithGin(c).Handle(ms.MachineScripts)
})
saveMachienScriptLog := ctx.NewLogInfo("保存脚本")

View File

@@ -0,0 +1,74 @@
package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/apis"
"mayfly-go/server/devops/application"
sys_applicaiton "mayfly-go/server/sys/application"
"github.com/gin-gonic/gin"
)
func InitProjectRouter(router *gin.RouterGroup) {
m := &apis.Project{
ProjectApp: application.ProjectApp,
AccountApp: sys_applicaiton.AccountApp}
project := router.Group("/projects")
{
router.GET("/accounts/projects", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(m.GetProjectsByLoginAccount)
})
// 获取项目列表
project.GET("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(m.GetProjects)
})
saveProjectLog := ctx.NewLogInfo("保存项目信息")
savePP := ctx.NewPermission("project:save")
// 保存项目下的环境信息
project.POST("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(saveProjectLog).
WithRequiredPermission(savePP).
Handle(m.SaveProject)
})
// 获取项目下的环境信息列表
project.GET("/:projectId/envs", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(m.GetProjectEnvs)
})
saveProjectEnvLog := ctx.NewLogInfo("新增项目环境信息")
savePeP := ctx.NewPermission("project:env:save")
// 保存项目下的环境信息
project.POST("/:projectId/envs", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(saveProjectEnvLog).
WithRequiredPermission(savePeP).
Handle(m.SaveProjectEnvs)
})
// 获取项目下的成员信息列表
project.GET("/:projectId/members", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(m.GetProjectMembers)
})
// 保存项目成员
saveProjectMemLog := ctx.NewLogInfo("新增项目成员")
savePmP := ctx.NewPermission("project:member:add")
project.POST("/:projectId/members", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(saveProjectMemLog).
WithRequiredPermission(savePmP).
Handle(m.SaveProjectMember)
})
// 删除项目成员
delProjectMemLog := ctx.NewLogInfo("删除项目成员")
savePmdP := ctx.NewPermission("project:member:del")
project.DELETE("/:projectId/members/:accountId", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(delProjectMemLog).
WithRequiredPermission(savePmdP).
Handle(m.DelProjectMember)
})
}
}

View File

@@ -0,0 +1,79 @@
package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/devops/apis"
"mayfly-go/server/devops/application"
"github.com/gin-gonic/gin"
)
func InitRedisRouter(router *gin.RouterGroup) {
redis := router.Group("redis")
{
rs := &apis.Redis{
RedisApp: application.RedisApp,
}
// 获取redis list
redis.GET("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(rs.RedisList)
})
save := ctx.NewLogInfo("保存redis信息")
redis.POST("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(save).Handle(rs.Save)
})
delRedis := ctx.NewLogInfo("删除redis信息")
redis.DELETE(":id", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(delRedis).Handle(rs.DeleteRedis)
})
redis.GET(":id/info", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(rs.RedisInfo)
})
// 获取指定redis keys
redis.GET(":id/scan/:cursor/:count", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(rs.Scan)
})
// 删除key
deleteKeyL := ctx.NewLogInfo("redis删除key")
// deleteKey := ctx.NewPermission("project:save")
redis.DELETE(":id/key", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(deleteKeyL).Handle(rs.DeleteKey)
})
// 获取string类型值
redis.GET(":id/string-value", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(rs.GetStringValue)
})
// 设置string类型值
redis.POST(":id/string-value", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(rs.SetStringValue)
})
// 获取hash类型值
redis.GET(":id/hash-value", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(rs.GetHashValue)
})
// 获取set类型值
redis.GET(":id/set-value", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(rs.GetSetValue)
})
// 设置hash类型值
redis.POST(":id/hash-value", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(rs.SetStringValue)
})
// 设置hash类型值
redis.POST("test", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithNeedToken(false).Handle(rs.Test)
})
}
}

View File

@@ -1,21 +1,29 @@
package initialize
import (
"mayfly-go/base/global"
"fmt"
"mayfly-go/base/config"
"mayfly-go/base/middleware"
devops_routers "mayfly-go/server/devops/routers"
sys_routers "mayfly-go/server/sys/routers"
"net/http"
"github.com/gin-gonic/gin"
)
func InitRouter() *gin.Engine {
// server配置
serverConfig := global.Config.Server
serverConfig := config.Conf.Server
gin.SetMode(serverConfig.Model)
var router = gin.New()
router.MaxMultipartMemory = 8 << 20
// 没有路由即 404返回
router.NoRoute(func(g *gin.Context) {
g.JSON(http.StatusNotFound, gin.H{"code": 404, "msg": fmt.Sprintf("not found '%s:%s'", g.Request.Method, g.Request.URL.Path)})
})
// 设置静态资源
if staticConfs := serverConfig.Static; staticConfs != nil {
for _, scs := range *staticConfs {
@@ -37,11 +45,15 @@ func InitRouter() *gin.Engine {
// 设置路由组
api := router.Group("/api")
{
sys_routers.InitCaptchaRouter(api)
sys_routers.InitAccountRouter(api) // 注册account路由
sys_routers.InitResourceRouter(api)
sys_routers.InitRoleRouter(api)
devops_routers.InitProjectRouter(api)
devops_routers.InitDbRouter(api)
devops_routers.InitRedisRouter(api)
devops_routers.InitMachineRouter(api)
devops_routers.InitMachineScriptRouter(api)
devops_routers.InitMachineFileRouter(api)

Binary file not shown.

View File

@@ -5,69 +5,18 @@
Source Server Type : MySQL
Source Server Version : 80018
Source Host : localhost:3306
Source Schema : mayfly-go
Source Schema : mayfly-job
Target Server Type : MySQL
Target Server Version : 80018
File Encoding : 65001
Date: 08/06/2021 14:52:42
Date: 28/07/2021 17:30:54
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_account
-- ----------------------------
DROP TABLE IF EXISTS `t_account`;
CREATE TABLE `t_account` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(12) NOT NULL,
`password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`status` tinyint(4) DEFAULT NULL,
`create_time` datetime NOT NULL,
`creator_id` bigint(255) NOT NULL,
`creator` varchar(12) NOT NULL,
`update_time` datetime NOT NULL,
`modifier_id` bigint(255) NOT NULL,
`modifier` varchar(12) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of t_account
-- ----------------------------
BEGIN;
INSERT INTO `t_account` VALUES (1, 'admin', '7b116d117002fad3f6dde6c718b885b9', 1, '2020-01-01 19:00:00', 1, 'admin', '2020-01-01 19:00:00', 1, 'admin');
INSERT INTO `t_account` VALUES (2, 'admin2', 'e10adc3949ba59abbe56e057f20f883e', -1, '2020-09-09 12:00:09', 2, 'haha', '2020-09-09 12:00:09', 2, 'haha');
COMMIT;
-- ----------------------------
-- Table structure for t_account_role
-- ----------------------------
DROP TABLE IF EXISTS `t_account_role`;
CREATE TABLE `t_account_role` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id',
`account_id` bigint(20) NOT NULL COMMENT '账号id',
`role_id` bigint(20) NOT NULL COMMENT '角色id',
`creator` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`creator_id` bigint(20) unsigned DEFAULT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_account_role
-- ----------------------------
BEGIN;
INSERT INTO `t_account_role` VALUES (23, 3, 6, 'admin', 1, '2021-05-28 16:19:21');
INSERT INTO `t_account_role` VALUES (24, 2, 1, 'admin', 1, '2021-05-28 16:21:38');
INSERT INTO `t_account_role` VALUES (25, 1, 1, 'admin', 1, '2021-05-28 16:21:45');
INSERT INTO `t_account_role` VALUES (26, 4, 6, 'admin', 1, '2021-05-28 17:04:48');
INSERT INTO `t_account_role` VALUES (29, 1, 6, 'admin', 1, '2021-06-02 16:07:44');
COMMIT;
-- ----------------------------
-- Table structure for t_db
-- ----------------------------
@@ -82,6 +31,10 @@ CREATE TABLE `t_db` (
`type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '数据库类型(mysql...)',
`database` varchar(32) DEFAULT NULL,
`network` varchar(8) DEFAULT NULL,
`project_id` bigint(20) DEFAULT NULL,
`project` varchar(64) DEFAULT NULL,
`env_id` bigint(20) DEFAULT NULL COMMENT '环境id',
`env` varchar(255) DEFAULT NULL COMMENT '环境描述',
`remark` varchar(125) DEFAULT NULL COMMENT '备注,描述等',
`create_time` datetime DEFAULT NULL,
`creator_id` bigint(20) DEFAULT NULL,
@@ -90,16 +43,11 @@ CREATE TABLE `t_db` (
`modifier_id` bigint(20) DEFAULT NULL,
`modifier` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据库信息表';
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据库信息表';
-- ----------------------------
-- Records of t_db
-- ----------------------------
BEGIN;
INSERT INTO `t_db` VALUES (1, 'mayfly-go', 'localhost', 3306, 'root', '******', 'mysql', 'mayfly-job', 'tcp', NULL, '2020-12-14 15:04:43', NULL, NULL, '2020-12-14 15:04:48', NULL, NULL);
INSERT INTO `t_db` VALUES (2, 'maylfy', '114.67.67.10', 3306, 'root', '******', 'mysql', 'mayfly', 'tcp', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `t_db` VALUES (3, 'mayfly-oracle', 'localhost', 1521, 'TEST', '******', 'godror', 'xe', 'tcp', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
COMMIT;
-- ----------------------------
-- Table structure for t_db_sql
@@ -117,14 +65,67 @@ CREATE TABLE `t_db_sql` (
`modifier_id` bigint(20) DEFAULT NULL,
`modifier` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据库sql信息';
-- ----------------------------
-- Records of t_db_sql
-- ----------------------------
BEGIN;
INSERT INTO `t_db_sql` VALUES (2, 1, 'SELECT\n *\nFROM\n t_account\n \nSELECT\n *\nFROM\n t_db\n \nSELECT\n *\nFROM\n t_db_sql', 1, 1, 'admin', '2020-12-18 15:27:53', '2021-04-25 11:09:04', 1, 'admin');
INSERT INTO `t_db_sql` VALUES (2, 1, 'SELECT\n *\nFROM\n t_sys_resource sr \n \nSELECT COUNT(*) FROM t_sys_account\n \nSELECT\n *\nFROM\n t_db td\n \nSELECT\n *\nFROM\n t_db_sql\n \nUPDATE t_sys_account t SET t.creator = \"admin\"', 1, 1, 'admin', '2020-12-18 15:27:53', '2021-07-22 10:10:25', 1, 'admin');
INSERT INTO `t_db_sql` VALUES (3, 2, 'SELECT\n *\nFROM\n t_account\n \nSELECT\n *\nFROM\n t_resource\n \nSELECT\n *\nFROM\n t_sys_operation_log\nORDER BY\n id DESC\nLIMIT\n 20', 1, 1, 'admin', '2020-12-18 17:13:36', '2021-04-21 10:16:21', 1, 'admin');
INSERT INTO `t_db_sql` VALUES (4, 4, 'SELECT\n *\nFROM\n t_ci_corp_auth t WHERE t.fk_corp = \'1212\'\n \nSELECT * FROM t_ci_corp\n \nSELECT\n *\nFROM\n t_activity_user_record r\n LEFT JOIN t_activity a ON r.sequence_no = a.update_time\nWHERE\n r.channel_source = 1\n AND a.sequence_no = 12', 1, 1, 'admin', '2021-06-28 15:25:03', '2021-07-05 17:07:08', 1, 'admin');
INSERT INTO `t_db_sql` VALUES (5, 5, 'SELECT * FROM t_sys_code\n\nSELECT * FROM t_sys_dict_data', 1, 1, 'admin', '2021-06-28 17:27:56', '2021-06-28 17:27:56', 1, 'admin');
INSERT INTO `t_db_sql` VALUES (7, 10, 'SELECT * FROM t_account', 1, 1, 'admin', '2021-07-08 17:07:47', '2021-07-08 17:08:03', 1, 'admin');
COMMIT;
-- ----------------------------
-- Table structure for t_gw_service
-- ----------------------------
DROP TABLE IF EXISTS `t_gw_service`;
CREATE TABLE `t_gw_service` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`service_name` varchar(36) NOT NULL COMMENT '服务名',
`urls` varchar(125) DEFAULT NULL COMMENT 'urls'',''分割',
`create_time` datetime DEFAULT NULL,
`creator` varchar(36) DEFAULT NULL,
`creator_id` bigint(20) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`modifier_id` bigint(20) DEFAULT NULL,
`modifier` varchar(36) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='网关服务';
-- ----------------------------
-- Records of t_gw_service
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Table structure for t_gw_service_api
-- ----------------------------
DROP TABLE IF EXISTS `t_gw_service_api`;
CREATE TABLE `t_gw_service_api` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`service_id` int(11) NOT NULL COMMENT '服务id',
`service_name` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`uri` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'uri地址',
`json_schemal` text COMMENT 'json schemal校验参数',
`enable_mock` tinyint(2) DEFAULT NULL COMMENT '是否启用mock',
`create_time` datetime DEFAULT NULL,
`creator_id` bigint(20) DEFAULT NULL,
`creator` varchar(36) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`modifier_id` bigint(20) DEFAULT NULL,
`modifier` varchar(36) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='网关服务api';
-- ----------------------------
-- Records of t_gw_service_api
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
@@ -146,16 +147,11 @@ CREATE TABLE `t_machine` (
`modifier` varchar(12) DEFAULT NULL,
`modifier_id` bigint(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='机器信息';
-- ----------------------------
-- Records of t_machine
-- ----------------------------
BEGIN;
INSERT INTO `t_machine` VALUES (1, 'eatlife', '148.70.36.197', 22, 'root', '******', 1, '2020-01-01 10:10:10', NULL, NULL, '2020-01-01 10:10:10', NULL, NULL);
INSERT INTO `t_machine` VALUES (2, 'JD云', '114.67.67.10', 22, 'root', '******', 1, '2020-08-18 10:00:00', NULL, NULL, '2020-08-18 10:00:00', NULL, NULL);
INSERT INTO `t_machine` VALUES (4, '腾讯云', '118.24.26.101', 22, 'root', '******', NULL, '2021-05-10 15:57:49', 'admin', 1, '2021-05-10 15:57:49', 'admin', 1);
COMMIT;
-- ----------------------------
-- Table structure for t_machine_file
@@ -174,25 +170,11 @@ CREATE TABLE `t_machine_file` (
`create_time` datetime NOT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8 COMMENT='机器文件';
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8 COMMENT='机器文件';
-- ----------------------------
-- Records of t_machine_file
-- ----------------------------
BEGIN;
INSERT INTO `t_machine_file` VALUES (1, 1, 'redis配置文件', '/etc/my.cnf', '2', 1, 'admin', NULL, NULL, '2019-08-21 11:30:33', NULL);
INSERT INTO `t_machine_file` VALUES (10, 2, 'java-dockerfile', '/usr/local/java/Dockerfile', '2', 1, 'admin', NULL, NULL, '2019-11-06 15:16:12', NULL);
INSERT INTO `t_machine_file` VALUES (11, 1, 'usr', '/usr', '1', 1, 'admin', NULL, NULL, '2019-11-06 15:16:12', NULL);
INSERT INTO `t_machine_file` VALUES (12, 1, 'opt', '/opt', '1', 1, 'admin', NULL, NULL, '2019-11-06 15:16:12', NULL);
INSERT INTO `t_machine_file` VALUES (13, 3, '根目录', '/', '1', 1, 'admin', NULL, NULL, '2019-11-18 05:19:28', NULL);
INSERT INTO `t_machine_file` VALUES (14, 1, 'usr', '/usr/local', '1', 1, 'admin', NULL, NULL, '2019-11-19 05:52:28', NULL);
INSERT INTO `t_machine_file` VALUES (15, 2, 'usr', '/usr/', '1', 1, 'admin', NULL, NULL, '2019-11-19 08:35:19', NULL);
INSERT INTO `t_machine_file` VALUES (16, 3, '软件安装目录', '/usr/local', '1', 1, 'admin', NULL, NULL, '2019-11-19 08:40:55', NULL);
INSERT INTO `t_machine_file` VALUES (23, 4, '根目录', '/', '1', 1, 'admin', NULL, NULL, '2019-12-11 07:54:04', NULL);
INSERT INTO `t_machine_file` VALUES (24, 4, '项目目录', '/usr/local/java', '1', 1, 'admin', NULL, NULL, '2020-03-07 07:12:20', NULL);
INSERT INTO `t_machine_file` VALUES (25, 8, '软件安装位置', '/usr/local', '1', 1, 'admin', NULL, NULL, '2020-08-28 09:41:56', NULL);
INSERT INTO `t_machine_file` VALUES (28, 2, 'java目录', '/usr/local/java', '1', 1, 'admin', 1, 'admin', '2021-05-08 17:32:25', '2021-05-08 17:32:25');
COMMIT;
-- ----------------------------
-- Table structure for t_machine_monitor
@@ -221,6 +203,7 @@ CREATE TABLE `t_machine_script` (
`name` varchar(255) NOT NULL COMMENT '脚本名',
`machine_id` bigint(64) NOT NULL COMMENT '机器id[0:公共]',
`script` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '脚本内容',
`params` varchar(512) DEFAULT NULL COMMENT '脚本入参',
`description` varchar(255) DEFAULT NULL COMMENT '脚本描述',
`type` tinyint(8) DEFAULT NULL COMMENT '脚本类型[1: 有结果2无结果3实时交互]',
`creator_id` bigint(20) DEFAULT NULL,
@@ -230,36 +213,175 @@ CREATE TABLE `t_machine_script` (
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='机器脚本';
-- ----------------------------
-- Records of t_machine_script
-- ----------------------------
BEGIN;
INSERT INTO `t_machine_script` VALUES (1, 'sys_info', 9999999, '# 获取系统cpu信息\nfunction get_cpu_info() {\n Physical_CPUs=$(grep \"physical id\" /proc/cpuinfo | sort | uniq | wc -l)\n Virt_CPUs=$(grep \"processor\" /proc/cpuinfo | wc -l)\n CPU_Kernels=$(grep \"cores\" /proc/cpuinfo | uniq | awk -F \': \' \'{print $2}\')\n CPU_Type=$(grep \"model name\" /proc/cpuinfo | awk -F \': \' \'{print $2}\' | sort | uniq)\n CPU_Arch=$(uname -m)\n echo -e \'\\n-------------------------- CPU信息 --------------------------\'\n cat <<EOF | column -t\n物理CPU个数: $Physical_CPUs\n逻辑CPU个数: $Virt_CPUs\n每CPU核心数: $CPU_Kernels\nCPU型号: $CPU_Type\nCPU架构: $CPU_Arch\nEOF\n}\n\n# 获取系统信息\nfunction get_systatus_info() {\n sys_os=$(uname -o)\n sys_release=$(cat /etc/redhat-release)\n sys_kernel=$(uname -r)\n sys_hostname=$(hostname)\n sys_selinux=$(getenforce)\n sys_lang=$(echo $LANG)\n sys_lastreboot=$(who -b | awk \'{print $3,$4}\')\n echo -e \'-------------------------- 系统信息 --------------------------\'\n cat <<EOF | column -t\n系统: ${sys_os}\n发行版本: ${sys_release}\n系统内核: ${sys_kernel}\n主机名: ${sys_hostname}\nselinux状态: ${sys_selinux}\n系统语言: ${sys_lang}\n系统最后重启时间: ${sys_lastreboot}\nEOF\n}\n\nget_systatus_info\n#echo -e \"\\n\"\nget_cpu_info', '获取系统信息', 1, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `t_machine_script` VALUES (2, 'get_process_by_name', 9999999, '#! /bin/bash\n# Function: 根据输入的程序的名字过滤出所对应的PID并显示出详细信息如果有几个PID则全部显示\nNAME=java\nN=`ps -aux | grep $NAME | grep -v grep | wc -l` ##统计进程总数\nif [ $N -le 0 ];then\n echo \"无该进程!\"\nfi\ni=1\nwhile [ $N -gt 0 ]\ndo\n echo \"进程PID: `ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $2}\'`\"\n echo \"进程命令:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $11}\'`\"\n echo \"进程所属用户: `ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $1}\'`\"\n echo \"CPU占用率`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $3}\'`%\"\n echo \"内存占用率:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $4}\'`%\"\n echo \"进程开始运行的时刻:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $9}\'`\"\n echo \"进程运行的时间:` ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $11}\'`\"\n echo \"进程状态:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $8}\'`\"\n echo \"进程虚拟内存:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $5}\'`\"\n echo \"进程共享内存:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $6}\'`\"\n echo \"***************************************************************\"\n let N-- i++\ndone', '获取进程运行状态', 1, NULL, NULL, 1, 'admin', NULL, '2021-05-05 16:52:54');
INSERT INTO `t_machine_script` VALUES (3, 'sys_run_info', 9999999, '#!/bin/bash\n# 获取要监控的本地服务器IP地址\nIP=`ifconfig | grep inet | grep -vE \'inet6|127.0.0.1\' | awk \'{print $2}\'`\necho \"IP地址\"$IP\n \n# 获取cpu总核数\ncpu_num=`grep -c \"model name\" /proc/cpuinfo`\necho \"cpu总核数\"$cpu_num\n \n# 1、获取CPU利用率\n################################################\n#us 用户空间占用CPU百分比\n#sy 内核空间占用CPU百分比\n#ni 用户进程空间内改变过优先级的进程占用CPU百分比\n#id 空闲CPU百分比\n#wa 等待输入输出的CPU时间百分比\n#hi 硬件中断\n#si 软件中断\n#################################################\n# 获取用户空间占用CPU百分比\ncpu_user=`top -b -n 1 | grep Cpu | awk \'{print $2}\' | cut -f 1 -d \"%\"`\necho \"用户空间占用CPU百分比\"$cpu_user\n \n# 获取内核空间占用CPU百分比\ncpu_system=`top -b -n 1 | grep Cpu | awk \'{print $4}\' | cut -f 1 -d \"%\"`\necho \"内核空间占用CPU百分比\"$cpu_system\n \n# 获取空闲CPU百分比\ncpu_idle=`top -b -n 1 | grep Cpu | awk \'{print $8}\' | cut -f 1 -d \"%\"`\necho \"空闲CPU百分比\"$cpu_idle\n \n# 获取等待输入输出占CPU百分比\ncpu_iowait=`top -b -n 1 | grep Cpu | awk \'{print $10}\' | cut -f 1 -d \"%\"`\necho \"等待输入输出占CPU百分比\"$cpu_iowait\n \n#2、获取CPU上下文切换和中断次数\n# 获取CPU中断次数\ncpu_interrupt=`vmstat -n 1 1 | sed -n 3p | awk \'{print $11}\'`\necho \"CPU中断次数\"$cpu_interrupt\n \n# 获取CPU上下文切换次数\ncpu_context_switch=`vmstat -n 1 1 | sed -n 3p | awk \'{print $12}\'`\necho \"CPU上下文切换次数\"$cpu_context_switch\n \n#3、获取CPU负载信息\n# 获取CPU15分钟前到现在的负载平均值\ncpu_load_15min=`uptime | awk \'{print $11}\' | cut -f 1 -d \',\'`\necho \"CPU 15分钟前到现在的负载平均值\"$cpu_load_15min\n \n# 获取CPU5分钟前到现在的负载平均值\ncpu_load_5min=`uptime | awk \'{print $10}\' | cut -f 1 -d \',\'`\necho \"CPU 5分钟前到现在的负载平均值\"$cpu_load_5min\n \n# 获取CPU1分钟前到现在的负载平均值\ncpu_load_1min=`uptime | awk \'{print $9}\' | cut -f 1 -d \',\'`\necho \"CPU 1分钟前到现在的负载平均值\"$cpu_load_1min\n \n# 获取任务队列(就绪状态等待的进程数)\ncpu_task_length=`vmstat -n 1 1 | sed -n 3p | awk \'{print $1}\'`\necho \"CPU任务队列长度\"$cpu_task_length\n \n#4、获取内存信息\n# 获取物理内存总量\nmem_total=`free -h | grep Mem | awk \'{print $2}\'`\necho \"物理内存总量:\"$mem_total\n \n# 获取操作系统已使用内存总量\nmem_sys_used=`free -h | grep Mem | awk \'{print $3}\'`\necho \"已使用内存总量(操作系统)\"$mem_sys_used\n \n# 获取操作系统未使用内存总量\nmem_sys_free=`free -h | grep Mem | awk \'{print $4}\'`\necho \"剩余内存总量(操作系统)\"$mem_sys_free\n \n# 获取应用程序已使用的内存总量\nmem_user_used=`free | sed -n 3p | awk \'{print $3}\'`\necho \"已使用内存总量(应用程序)\"$mem_user_used\n \n# 获取应用程序未使用内存总量\nmem_user_free=`free | sed -n 3p | awk \'{print $4}\'`\necho \"剩余内存总量(应用程序)\"$mem_user_free\n \n# 获取交换分区总大小\nmem_swap_total=`free | grep Swap | awk \'{print $2}\'`\necho \"交换分区总大小:\"$mem_swap_total\n \n# 获取已使用交换分区大小\nmem_swap_used=`free | grep Swap | awk \'{print $3}\'`\necho \"已使用交换分区大小:\"$mem_swap_used\n \n# 获取剩余交换分区大小\nmem_swap_free=`free | grep Swap | awk \'{print $4}\'`\necho \"剩余交换分区大小:\"$mem_swap_free', '获取cpu、内存等系统运行状态', 1, NULL, NULL, NULL, NULL, NULL, '2021-04-25 15:07:16');
INSERT INTO `t_machine_script` VALUES (4, 'top', 9999999, 'top', '实时获取系统运行状态', 3, NULL, NULL, 1, 'admin', NULL, '2021-05-24 15:58:20');
INSERT INTO `t_machine_script` VALUES (9, 'fasf', 0, 'fafsd', 'fasdfa', 2, 1, 'admin', 1, 'admin', '2021-04-25 15:55:25', '2021-04-25 15:55:25');
INSERT INTO `t_machine_script` VALUES (10, 'fas', 0, 'd', 'f', 2, 1, 'admin', 1, 'admin', '2021-04-25 15:58:14', '2021-04-25 15:58:14');
INSERT INTO `t_machine_script` VALUES (11, 'tests', 0, 'fsfsdf', 'fsdfs', 2, 1, 'admin', 1, 'admin', '2021-04-25 16:13:06', '2021-04-25 16:13:06');
INSERT INTO `t_machine_script` VALUES (12, 'fafas', 0, 'sdsd', 'fsfsd', 2, 1, 'admin', 1, 'admin', '2021-04-25 16:14:41', '2021-04-25 16:14:41');
INSERT INTO `t_machine_script` VALUES (15, 'mvn_install', 4, 'mvn clean -Dmaven.test.skip=true install', 'mvn打包', 3, 1, 'admin', 1, 'admin', '2021-05-10 15:58:34', '2021-06-03 11:12:25');
INSERT INTO `t_machine_script` VALUES (1, 'sys_info', 9999999, '# 获取系统cpu信息\nfunction get_cpu_info() {\n Physical_CPUs=$(grep \"physical id\" /proc/cpuinfo | sort | uniq | wc -l)\n Virt_CPUs=$(grep \"processor\" /proc/cpuinfo | wc -l)\n CPU_Kernels=$(grep \"cores\" /proc/cpuinfo | uniq | awk -F \': \' \'{print $2}\')\n CPU_Type=$(grep \"model name\" /proc/cpuinfo | awk -F \': \' \'{print $2}\' | sort | uniq)\n CPU_Arch=$(uname -m)\n echo -e \'\\n-------------------------- CPU信息 --------------------------\'\n cat <<EOF | column -t\n物理CPU个数: $Physical_CPUs\n逻辑CPU个数: $Virt_CPUs\n每CPU核心数: $CPU_Kernels\nCPU型号: $CPU_Type\nCPU架构: $CPU_Arch\nEOF\n}\n\n# 获取系统信息\nfunction get_systatus_info() {\n sys_os=$(uname -o)\n sys_release=$(cat /etc/redhat-release)\n sys_kernel=$(uname -r)\n sys_hostname=$(hostname)\n sys_selinux=$(getenforce)\n sys_lang=$(echo $LANG)\n sys_lastreboot=$(who -b | awk \'{print $3,$4}\')\n echo -e \'-------------------------- 系统信息 --------------------------\'\n cat <<EOF | column -t\n系统: ${sys_os}\n发行版本: ${sys_release}\n系统内核: ${sys_kernel}\n主机名: ${sys_hostname}\nselinux状态: ${sys_selinux}\n系统语言: ${sys_lang}\n系统最后重启时间: ${sys_lastreboot}\nEOF\n}\n\nget_systatus_info\n#echo -e \"\\n\"\nget_cpu_info', NULL, '获取系统信息', 1, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `t_machine_script` VALUES (2, 'get_process_by_name', 9999999, '#! /bin/bash\n# Function: 根据输入的程序的名字过滤出所对应的PID并显示出详细信息如果有几个PID则全部显示\nNAME={{.processName}}\nN=`ps -aux | grep $NAME | grep -v grep | wc -l` ##统计进程总数\nif [ $N -le 0 ];then\n echo \"无该进程!\"\nfi\ni=1\nwhile [ $N -gt 0 ]\ndo\n echo \"进程PID: `ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $2}\'`\"\n echo \"进程命令:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $11}\'`\"\n echo \"进程所属用户: `ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $1}\'`\"\n echo \"CPU占用率`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $3}\'`%\"\n echo \"内存占用率:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $4}\'`%\"\n echo \"进程开始运行的时刻:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $9}\'`\"\n echo \"进程运行的时间:` ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $11}\'`\"\n echo \"进程状态:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $8}\'`\"\n echo \"进程虚拟内存:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $5}\'`\"\n echo \"进程共享内存:`ps -aux | grep $NAME | grep -v grep | awk \'NR==\'$i\'{print $0}\'| awk \'{print $6}\'`\"\n echo \"***************************************************************\"\n let N-- i++\ndone', '[{\"name\": \"进程名\",\"model\": \"processName\", \"placeholder\": \"请输入进程名\"}]', '获取进程运行状态', 1, NULL, NULL, 1, 'admin', NULL, '2021-07-12 15:33:41');
INSERT INTO `t_machine_script` VALUES (3, 'sys_run_info', 9999999, '#!/bin/bash\n# 获取要监控的本地服务器IP地址\nIP=`ifconfig | grep inet | grep -vE \'inet6|127.0.0.1\' | awk \'{print $2}\'`\necho \"IP地址\"$IP\n \n# 获取cpu总核数\ncpu_num=`grep -c \"model name\" /proc/cpuinfo`\necho \"cpu总核数\"$cpu_num\n \n# 1、获取CPU利用率\n################################################\n#us 用户空间占用CPU百分比\n#sy 内核空间占用CPU百分比\n#ni 用户进程空间内改变过优先级的进程占用CPU百分比\n#id 空闲CPU百分比\n#wa 等待输入输出的CPU时间百分比\n#hi 硬件中断\n#si 软件中断\n#################################################\n# 获取用户空间占用CPU百分比\ncpu_user=`top -b -n 1 | grep Cpu | awk \'{print $2}\' | cut -f 1 -d \"%\"`\necho \"用户空间占用CPU百分比\"$cpu_user\n \n# 获取内核空间占用CPU百分比\ncpu_system=`top -b -n 1 | grep Cpu | awk \'{print $4}\' | cut -f 1 -d \"%\"`\necho \"内核空间占用CPU百分比\"$cpu_system\n \n# 获取空闲CPU百分比\ncpu_idle=`top -b -n 1 | grep Cpu | awk \'{print $8}\' | cut -f 1 -d \"%\"`\necho \"空闲CPU百分比\"$cpu_idle\n \n# 获取等待输入输出占CPU百分比\ncpu_iowait=`top -b -n 1 | grep Cpu | awk \'{print $10}\' | cut -f 1 -d \"%\"`\necho \"等待输入输出占CPU百分比\"$cpu_iowait\n \n#2、获取CPU上下文切换和中断次数\n# 获取CPU中断次数\ncpu_interrupt=`vmstat -n 1 1 | sed -n 3p | awk \'{print $11}\'`\necho \"CPU中断次数\"$cpu_interrupt\n \n# 获取CPU上下文切换次数\ncpu_context_switch=`vmstat -n 1 1 | sed -n 3p | awk \'{print $12}\'`\necho \"CPU上下文切换次数\"$cpu_context_switch\n \n#3、获取CPU负载信息\n# 获取CPU15分钟前到现在的负载平均值\ncpu_load_15min=`uptime | awk \'{print $11}\' | cut -f 1 -d \',\'`\necho \"CPU 15分钟前到现在的负载平均值\"$cpu_load_15min\n \n# 获取CPU5分钟前到现在的负载平均值\ncpu_load_5min=`uptime | awk \'{print $10}\' | cut -f 1 -d \',\'`\necho \"CPU 5分钟前到现在的负载平均值\"$cpu_load_5min\n \n# 获取CPU1分钟前到现在的负载平均值\ncpu_load_1min=`uptime | awk \'{print $9}\' | cut -f 1 -d \',\'`\necho \"CPU 1分钟前到现在的负载平均值\"$cpu_load_1min\n \n# 获取任务队列(就绪状态等待的进程数)\ncpu_task_length=`vmstat -n 1 1 | sed -n 3p | awk \'{print $1}\'`\necho \"CPU任务队列长度\"$cpu_task_length\n \n#4、获取内存信息\n# 获取物理内存总量\nmem_total=`free -h | grep Mem | awk \'{print $2}\'`\necho \"物理内存总量:\"$mem_total\n \n# 获取操作系统已使用内存总量\nmem_sys_used=`free -h | grep Mem | awk \'{print $3}\'`\necho \"已使用内存总量(操作系统)\"$mem_sys_used\n \n# 获取操作系统未使用内存总量\nmem_sys_free=`free -h | grep Mem | awk \'{print $4}\'`\necho \"剩余内存总量(操作系统)\"$mem_sys_free\n \n# 获取应用程序已使用的内存总量\nmem_user_used=`free | sed -n 3p | awk \'{print $3}\'`\necho \"已使用内存总量(应用程序)\"$mem_user_used\n \n# 获取应用程序未使用内存总量\nmem_user_free=`free | sed -n 3p | awk \'{print $4}\'`\necho \"剩余内存总量(应用程序)\"$mem_user_free\n \n# 获取交换分区总大小\nmem_swap_total=`free | grep Swap | awk \'{print $2}\'`\necho \"交换分区总大小:\"$mem_swap_total\n \n# 获取已使用交换分区大小\nmem_swap_used=`free | grep Swap | awk \'{print $3}\'`\necho \"已使用交换分区大小:\"$mem_swap_used\n \n# 获取剩余交换分区大小\nmem_swap_free=`free | grep Swap | awk \'{print $4}\'`\necho \"剩余交换分区大小:\"$mem_swap_free', NULL, '获取cpu、内存等系统运行状态', 1, NULL, NULL, NULL, NULL, NULL, '2021-04-25 15:07:16');
INSERT INTO `t_machine_script` VALUES (4, 'top', 9999999, 'top', NULL, '实时获取系统运行状态', 3, NULL, NULL, 1, 'admin', NULL, '2021-05-24 15:58:20');
INSERT INTO `t_machine_script` VALUES (17, 'nginx启动', 2, 'docker run -itd --name nginx -v /usr/local/nginx/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/nginx/log:/var/log/nginx -v /usr/local/nginx/nginx.conf:/etc/nginx/conf.d/default.conf -v /usr/local/nginx/html:/usr/share/nginx/html -p 80:80 nginx', NULL, '启动nginx', 1, 1, 'admin', 1, 'admin', '2021-06-24 16:38:47', '2021-07-05 14:36:49');
INSERT INTO `t_machine_script` VALUES (18, 'disk-mem', 9999999, 'df -h', '', '磁盘空间查看', 1, 1, 'admin', 1, 'admin', '2021-07-16 10:49:53', '2021-07-16 10:49:53');
COMMIT;
-- ----------------------------
-- Table structure for t_resource
-- Table structure for t_project
-- ----------------------------
DROP TABLE IF EXISTS `t_resource`;
CREATE TABLE `t_resource` (
DROP TABLE IF EXISTS `t_project`;
CREATE TABLE `t_project` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL,
`name` varchar(255) NOT NULL COMMENT '项目名',
`remark` varchar(255) DEFAULT NULL COMMENT '备注说明',
`create_time` datetime DEFAULT NULL,
`creator_id` bigint(20) DEFAULT NULL,
`creator` varchar(255) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`modifier_id` bigint(20) DEFAULT NULL,
`modifier` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='项目信息表';
-- ----------------------------
-- Records of t_project
-- ----------------------------
-- ----------------------------
-- Table structure for t_project_env
-- ----------------------------
DROP TABLE IF EXISTS `t_project_env`;
CREATE TABLE `t_project_env` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`project_id` bigint(20) NOT NULL COMMENT '关联的项目id',
`name` varchar(255) NOT NULL COMMENT '环境名',
`remark` varchar(255) DEFAULT NULL COMMENT '说明备注',
`create_time` datetime DEFAULT NULL,
`creator_id` bigint(20) DEFAULT NULL,
`creator` varchar(255) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`modifier_id` bigint(20) DEFAULT NULL,
`modifier` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='项目环境';
-- ----------------------------
-- Records of t_project_env
-- ----------------------------
-- ----------------------------
-- Table structure for t_project_member
-- ----------------------------
DROP TABLE IF EXISTS `t_project_member`;
CREATE TABLE `t_project_member` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`project_id` bigint(20) NOT NULL COMMENT '项目id',
`account_id` bigint(20) NOT NULL COMMENT '账号id',
`username` varchar(36) DEFAULT NULL COMMENT '账号用户名冗余',
`create_time` datetime DEFAULT NULL,
`creator_id` bigint(20) DEFAULT NULL,
`creator` varchar(36) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`modifier_id` bigint(20) DEFAULT NULL,
`modifier` varchar(36) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='项目成员关联表';
-- ----------------------------
-- Records of t_project_member
-- ----------------------------
-- ----------------------------
-- Table structure for t_redis
-- ----------------------------
DROP TABLE IF EXISTS `t_redis`;
CREATE TABLE `t_redis` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`host` varchar(32) NOT NULL,
`password` varchar(32) DEFAULT NULL,
`db` int(32) DEFAULT NULL,
`project_id` bigint(20) DEFAULT NULL,
`project` varchar(32) DEFAULT NULL,
`env_id` bigint(20) DEFAULT NULL,
`env` varchar(32) DEFAULT NULL,
`creator` varchar(32) DEFAULT NULL,
`creator_id` bigint(32) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`modifier` varchar(32) DEFAULT NULL,
`modifier_id` bigint(20) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='redis信息';
-- ----------------------------
-- Records of t_redis
-- ----------------------------
-- ----------------------------
-- Table structure for t_sys_account
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_account`;
CREATE TABLE `t_sys_account` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(12) NOT NULL,
`password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`status` tinyint(4) DEFAULT NULL,
`last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
`create_time` datetime NOT NULL,
`creator_id` bigint(255) NOT NULL,
`creator` varchar(12) NOT NULL,
`update_time` datetime NOT NULL,
`modifier_id` bigint(255) NOT NULL,
`modifier` varchar(12) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='账号信息表';
-- ----------------------------
-- Records of t_sys_account
-- ----------------------------
BEGIN;
INSERT INTO `t_sys_account` VALUES (1, 'admin', '1f9c9c5cc9cdd1efda2064ce0ade8e66', 1, '2021-07-28 15:53:00', '2020-01-01 19:00:00', 1, 'admin', '2020-01-01 19:00:00', 1, 'admin');
INSERT INTO `t_sys_account` VALUES (7, 'huangmeilin', '1f9c9c5cc9cdd1efda2064ce0ade8e66', 1, '2021-07-09 17:56:12', '2021-07-06 16:15:36', 1, 'admin', '2021-07-06 16:15:36', 1, 'admin');
INSERT INTO `t_sys_account` VALUES (8, 'test', '098f6bcd4621d373cade4e832627b4f6', 1, '2021-07-12 16:40:28', '2021-07-09 17:58:10', 1, 'admin', '2021-07-09 17:58:10', 1, 'admin');
COMMIT;
-- ----------------------------
-- Table structure for t_sys_account_role
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_account_role`;
CREATE TABLE `t_sys_account_role` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id',
`account_id` bigint(20) NOT NULL COMMENT '账号id',
`role_id` bigint(20) NOT NULL COMMENT '角色id',
`creator` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`creator_id` bigint(20) unsigned DEFAULT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8 COMMENT='账号角色关联表';
-- ----------------------------
-- Records of t_sys_account_role
-- ----------------------------
BEGIN;
INSERT INTO `t_sys_account_role` VALUES (25, 1, 1, 'admin', 1, '2021-05-28 16:21:45');
INSERT INTO `t_sys_account_role` VALUES (34, 7, 8, 'admin', 1, '2021-07-09 10:50:43');
INSERT INTO `t_sys_account_role` VALUES (35, 8, 8, 'admin', 1, '2021-07-09 17:58:25');
COMMIT;
-- ----------------------------
-- Table structure for t_sys_resource
-- ----------------------------
DROP TABLE IF EXISTS `t_sys_resource`;
CREATE TABLE `t_sys_resource` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL COMMENT '父节点id',
`type` tinyint(255) NOT NULL COMMENT '1菜单路由2资源按钮等',
`status` int(255) NOT NULL,
`name` varchar(255) NOT NULL,
`code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '主要用于按钮等资源',
`weight` int(11) DEFAULT NULL,
`meta` varchar(255) DEFAULT NULL COMMENT '数据',
`status` int(255) NOT NULL COMMENT '状态1:可用,-1:禁用',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '名称',
`code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '菜单路由为path其他为唯一标识',
`weight` int(11) DEFAULT NULL COMMENT '权重顺序',
`meta` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '数据',
`creator_id` bigint(20) NOT NULL,
`creator` varchar(255) NOT NULL,
`modifier_id` bigint(20) NOT NULL,
@@ -267,64 +389,83 @@ CREATE TABLE `t_resource` (
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='资源表';
-- ----------------------------
-- Records of t_resource
-- Records of t_sys_resource
-- ----------------------------
BEGIN;
INSERT INTO `t_resource` VALUES (1, 0, 1, 1, '首页', '/home', 1, '{\"component\":\"Home\",\"icon\":\"el-icon-s-home\",\"isAffix\":true,\"isKeepAlive\":true,\"routeName\":\"Home\"}', 1, 'admin', 1, 'admin', '2021-05-25 16:44:41', '2021-05-27 09:12:56');
INSERT INTO `t_resource` VALUES (2, 0, 1, 1, '运维', '/ops', 3, '{\"icon\":\"el-icon-monitor\",\"isKeepAlive\":true,\"redirect\":\"machine/list\",\"routeName\":\"Ops\"}', 1, 'admin', 1, 'admin', '2021-05-25 16:48:16', '2021-06-08 14:20:24');
INSERT INTO `t_resource` VALUES (3, 2, 1, 1, '机器列表', 'machines', 1, '{\"component\":\"MachineList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"MachineList\"}', 2, 'admin', 1, 'admin', '2021-05-25 16:50:04', '2021-06-03 10:03:29');
INSERT INTO `t_resource` VALUES (4, 0, 1, 1, '系统管理', '/sys', 4, '{\"icon\":\"el-icon-setting\",\"isKeepAlive\":true,\"redirect\":\"/sys/resources\",\"routeName\":\"sys\"}', 1, 'admin', 1, 'admin', '2021-05-26 15:20:20', '2021-06-08 14:20:34');
INSERT INTO `t_resource` VALUES (5, 4, 1, 1, '资源管理', 'resources', 3, '{\"component\":\"ResourceList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"ResourceList\"}', 1, 'admin', 1, 'admin', '2021-05-26 15:23:07', '2021-06-08 11:27:55');
INSERT INTO `t_resource` VALUES (9, 0, 1, 1, 'iframes', '/iframes', 4, '{\"component\":\"RouterParent\",\"icon\":\"el-icon-pear\",\"isIframe\":true,\"isKeepAlive\":true,\"link\":\"https://www.baidu.com\",\"routeName\":\"Iframe\"}', 1, 'admin', 1, 'admin', '2021-05-27 09:58:37', '2021-06-02 11:23:23');
INSERT INTO `t_resource` VALUES (11, 4, 1, 1, '角色管理', 'roles', 2, '{\"component\":\"RoleList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"RoleList\"}', 1, 'admin', 1, 'admin', '2021-05-27 11:15:35', '2021-06-03 09:59:41');
INSERT INTO `t_resource` VALUES (12, 3, 2, 1, '机器终端按钮', 'machine:terminal', 4, '', 1, 'admin', 1, 'admin', '2021-05-28 14:06:02', '2021-05-31 17:47:59');
INSERT INTO `t_resource` VALUES (14, 4, 1, 1, '账号管理', 'accounts', 1, '{\"component\":\"AccountList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"AccountList\"}', 1, 'admin', 1, 'admin', '2021-05-28 14:56:25', '2021-06-03 09:39:22');
INSERT INTO `t_resource` VALUES (15, 3, 2, 1, '文件管理按钮', 'machine:file', 5, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:44:37', '2021-05-31 17:48:07');
INSERT INTO `t_resource` VALUES (16, 3, 2, 1, '机器添加按钮', 'machine:add', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:11', '2021-05-31 19:34:15');
INSERT INTO `t_resource` VALUES (17, 3, 2, 1, '机器编辑按钮', 'machine:update', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:23', '2021-05-31 19:34:18');
INSERT INTO `t_resource` VALUES (18, 3, 2, 1, '机器删除按钮', 'machine:del', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:36', '2021-05-31 19:34:17');
INSERT INTO `t_resource` VALUES (19, 14, 2, 1, '角色分配按钮', 'account:saveRoles', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:50:51', '2021-05-31 19:19:30');
INSERT INTO `t_resource` VALUES (20, 11, 2, 1, '分配菜单&权限按钮', 'role:saveResources', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:51:41', '2021-05-31 19:33:37');
INSERT INTO `t_resource` VALUES (21, 14, 2, 1, '账号删除按钮', 'account:del', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:01', '2021-05-31 18:02:01');
INSERT INTO `t_resource` VALUES (22, 11, 2, 1, '角色删除按钮', 'role:del', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:29', '2021-05-31 19:33:38');
INSERT INTO `t_resource` VALUES (23, 11, 2, 1, '角色新增按钮', 'role:add', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:44', '2021-05-31 19:33:39');
INSERT INTO `t_resource` VALUES (24, 11, 2, 1, '角色编辑按钮', 'role:update', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:57', '2021-05-31 19:33:40');
INSERT INTO `t_resource` VALUES (25, 5, 2, 1, '资源新增按钮', 'resource:add', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:03:33', '2021-05-31 19:31:47');
INSERT INTO `t_resource` VALUES (26, 5, 2, 1, '资源删除按钮', 'resource:del', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:03:47', '2021-05-31 19:29:40');
INSERT INTO `t_resource` VALUES (27, 5, 2, 1, '资源编辑按钮', 'resource:update', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:04:03', '2021-05-31 19:29:40');
INSERT INTO `t_resource` VALUES (28, 5, 2, 1, '资源禁用启用按钮', 'resource:changeStatus', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:04:33', '2021-05-31 18:04:33');
INSERT INTO `t_resource` VALUES (29, 14, 2, 1, '账号添加按钮', 'account:add', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 19:23:42', '2021-05-31 19:23:42');
INSERT INTO `t_resource` VALUES (30, 14, 2, 1, '账号编辑修改按钮', 'account:update', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 19:23:58', '2021-05-31 19:23:58');
INSERT INTO `t_resource` VALUES (31, 14, 2, 1, '账号管理基本权限', 'account', 0, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:25:06', '2021-05-31 21:25:06');
INSERT INTO `t_resource` VALUES (32, 5, 2, 1, '资源管理基本权限', 'resource', 0, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:25:25', '2021-05-31 21:25:25');
INSERT INTO `t_resource` VALUES (33, 11, 2, 1, '角色管理基本权限', 'role', 0, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:25:40', '2021-05-31 21:25:40');
INSERT INTO `t_resource` VALUES (34, 14, 2, 1, '账号启用禁用按钮', 'account:changeStatus', 5, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:29:48', '2021-05-31 21:29:48');
INSERT INTO `t_resource` VALUES (36, 2, 1, 1, 'DBMS', 'dbms', 2, '{\"icon\":\"el-icon-date\",\"isKeepAlive\":true,\"routeName\":\"DBMS\"}', 1, 'admin', 1, 'admin', '2021-06-01 14:01:33', '2021-06-03 09:58:54');
INSERT INTO `t_resource` VALUES (37, 3, 2, 1, '添加文件配置', 'machine:addFile', 6, 'null', 1, 'admin', 1, 'admin', '2021-06-01 19:54:23', '2021-06-01 19:54:23');
INSERT INTO `t_resource` VALUES (38, 36, 1, 1, '数据查询', 'select-data', 1, '{\"component\":\"SelectData\",\"icon\":\"el-icon-search\",\"isKeepAlive\":true,\"routeName\":\"SelectData\"}', 1, 'admin', 1, 'admin', '2021-06-03 09:09:29', '2021-06-03 14:34:01');
INSERT INTO `t_resource` VALUES (39, 0, 1, 1, '个人中心', '/personal', 2, '{\"component\":\"Personal\",\"icon\":\"el-icon-menu\",\"isHide\":true,\"isKeepAlive\":true,\"routeName\":\"Personal\"}', 1, 'admin', 1, 'admin', '2021-06-03 14:25:35', '2021-06-03 14:26:03');
INSERT INTO `t_resource` VALUES (40, 3, 2, 1, '文件管理-新增按钮', 'machine:file:add', 7, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:06:26', '2021-06-08 11:12:28');
INSERT INTO `t_resource` VALUES (41, 3, 2, 1, '文件管理-删除按钮', 'machine:file:del', 8, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:06:49', '2021-06-08 11:06:49');
INSERT INTO `t_resource` VALUES (42, 3, 2, 1, '文件管理-写入or下载文件权限', 'machine:file:write', 9, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:07:27', '2021-06-08 11:07:27');
INSERT INTO `t_resource` VALUES (43, 3, 2, 1, '文件管理-文件上传按钮', 'machine:file:upload', 10, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:07:42', '2021-06-08 11:07:42');
INSERT INTO `t_resource` VALUES (44, 3, 2, 1, '文件管理-删除文件按钮', 'machine:file:rm', 11, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:08:12', '2021-06-08 11:08:12');
INSERT INTO `t_resource` VALUES (45, 3, 2, 1, '脚本管理-保存脚本按钮', 'machine:script:save', 12, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:01', '2021-06-08 11:09:01');
INSERT INTO `t_resource` VALUES (46, 3, 2, 1, '脚本管理-删除按钮', 'machine:script:del', 13, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:27', '2021-06-08 11:09:27');
INSERT INTO `t_resource` VALUES (47, 3, 2, 1, '脚本管理-执行按钮', 'machine:script:run', 14, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:50', '2021-06-08 11:09:50');
INSERT INTO `t_sys_resource` VALUES (1, 0, 1, 1, '首页', '/home', 1, '{\"component\":\"Home\",\"icon\":\"el-icon-s-home\",\"isAffix\":true,\"isKeepAlive\":true,\"routeName\":\"Home\"}', 1, 'admin', 1, 'admin', '2021-05-25 16:44:41', '2021-05-27 09:12:56');
INSERT INTO `t_sys_resource` VALUES (2, 0, 1, 1, '运维', '/ops', 3, '{\"icon\":\"el-icon-monitor\",\"isKeepAlive\":true,\"redirect\":\"machine/list\",\"routeName\":\"Ops\"}', 1, 'admin', 1, 'admin', '2021-05-25 16:48:16', '2021-06-08 14:20:24');
INSERT INTO `t_sys_resource` VALUES (3, 2, 1, 1, '机器列表', 'machines', 2, '{\"component\":\"MachineList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"MachineList\"}', 2, 'admin', 1, 'admin', '2021-05-25 16:50:04', '2021-06-30 16:20:08');
INSERT INTO `t_sys_resource` VALUES (4, 0, 1, 1, '系统管理', '/sys', 4, '{\"icon\":\"el-icon-setting\",\"isKeepAlive\":true,\"redirect\":\"/sys/resources\",\"routeName\":\"sys\"}', 1, 'admin', 1, 'admin', '2021-05-26 15:20:20', '2021-06-08 14:20:34');
INSERT INTO `t_sys_resource` VALUES (5, 4, 1, 1, '资源管理', 'resources', 3, '{\"component\":\"ResourceList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"ResourceList\"}', 1, 'admin', 1, 'admin', '2021-05-26 15:23:07', '2021-06-08 11:27:55');
INSERT INTO `t_sys_resource` VALUES (9, 0, 1, 1, 'iframes', '/iframes', 4, '{\"component\":\"RouterParent\",\"icon\":\"el-icon-pear\",\"isIframe\":true,\"isKeepAlive\":true,\"link\":\"https://www.baidu.com\",\"routeName\":\"Iframe\"}', 1, 'admin', 1, 'admin', '2021-05-27 09:58:37', '2021-06-22 11:19:27');
INSERT INTO `t_sys_resource` VALUES (11, 4, 1, 1, '角色管理', 'roles', 2, '{\"component\":\"RoleList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"RoleList\"}', 1, 'admin', 1, 'admin', '2021-05-27 11:15:35', '2021-06-03 09:59:41');
INSERT INTO `t_sys_resource` VALUES (12, 3, 2, 1, '机器终端按钮', 'machine:terminal', 4, '', 1, 'admin', 1, 'admin', '2021-05-28 14:06:02', '2021-05-31 17:47:59');
INSERT INTO `t_sys_resource` VALUES (14, 4, 1, 1, '账号管理', 'accounts', 1, '{\"component\":\"AccountList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"AccountList\"}', 1, 'admin', 1, 'admin', '2021-05-28 14:56:25', '2021-06-03 09:39:22');
INSERT INTO `t_sys_resource` VALUES (15, 3, 2, 1, '文件管理按钮', 'machine:file', 5, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:44:37', '2021-05-31 17:48:07');
INSERT INTO `t_sys_resource` VALUES (16, 3, 2, 1, '机器添加按钮', 'machine:add', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:11', '2021-05-31 19:34:15');
INSERT INTO `t_sys_resource` VALUES (17, 3, 2, 1, '机器编辑按钮', 'machine:update', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:23', '2021-05-31 19:34:18');
INSERT INTO `t_sys_resource` VALUES (18, 3, 2, 1, '机器删除按钮', 'machine:del', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:36', '2021-05-31 19:34:17');
INSERT INTO `t_sys_resource` VALUES (19, 14, 2, 1, '角色分配按钮', 'account:saveRoles', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:50:51', '2021-05-31 19:19:30');
INSERT INTO `t_sys_resource` VALUES (20, 11, 2, 1, '分配菜单&权限按钮', 'role:saveResources', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:51:41', '2021-05-31 19:33:37');
INSERT INTO `t_sys_resource` VALUES (21, 14, 2, 1, '账号删除按钮', 'account:del', 2, 'null', 1, 'admin', 1, 'admin', '2021-05-31 18:02:01', '2021-06-10 17:12:17');
INSERT INTO `t_sys_resource` VALUES (22, 11, 2, 1, '角色删除按钮', 'role:del', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:29', '2021-05-31 19:33:38');
INSERT INTO `t_sys_resource` VALUES (23, 11, 2, 1, '角色新增按钮', 'role:add', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:44', '2021-05-31 19:33:39');
INSERT INTO `t_sys_resource` VALUES (24, 11, 2, 1, '角色编辑按钮', 'role:update', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:57', '2021-05-31 19:33:40');
INSERT INTO `t_sys_resource` VALUES (25, 5, 2, 1, '资源新增按钮', 'resource:add', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:03:33', '2021-05-31 19:31:47');
INSERT INTO `t_sys_resource` VALUES (26, 5, 2, 1, '资源删除按钮', 'resource:del', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:03:47', '2021-05-31 19:29:40');
INSERT INTO `t_sys_resource` VALUES (27, 5, 2, 1, '资源编辑按钮', 'resource:update', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:04:03', '2021-05-31 19:29:40');
INSERT INTO `t_sys_resource` VALUES (28, 5, 2, 1, '资源禁用启用按钮', 'resource:changeStatus', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:04:33', '2021-05-31 18:04:33');
INSERT INTO `t_sys_resource` VALUES (29, 14, 2, 1, '账号添加按钮', 'account:add', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 19:23:42', '2021-05-31 19:23:42');
INSERT INTO `t_sys_resource` VALUES (30, 14, 2, 1, '账号编辑修改按钮', 'account:update', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 19:23:58', '2021-05-31 19:23:58');
INSERT INTO `t_sys_resource` VALUES (31, 14, 2, 1, '账号管理基本权限', 'account', 0, 'null', 1, 'admin', 1, 'admin', '2021-05-31 21:25:06', '2021-06-22 11:20:34');
INSERT INTO `t_sys_resource` VALUES (32, 5, 2, 1, '资源管理基本权限', 'resource', 0, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:25:25', '2021-05-31 21:25:25');
INSERT INTO `t_sys_resource` VALUES (33, 11, 2, 1, '角色管理基本权限', 'role', 0, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:25:40', '2021-05-31 21:25:40');
INSERT INTO `t_sys_resource` VALUES (34, 14, 2, 1, '账号启用禁用按钮', 'account:changeStatus', 5, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:29:48', '2021-05-31 21:29:48');
INSERT INTO `t_sys_resource` VALUES (36, 2, 1, 1, 'DBMS', 'dbms', 3, '{\"icon\":\"el-icon-date\",\"isKeepAlive\":true,\"routeName\":\"DBMS\"}', 1, 'admin', 1, 'admin', '2021-06-01 14:01:33', '2021-07-07 15:26:54');
INSERT INTO `t_sys_resource` VALUES (37, 3, 2, 1, '添加文件配置', 'machine:addFile', 6, 'null', 1, 'admin', 1, 'admin', '2021-06-01 19:54:23', '2021-06-01 19:54:23');
INSERT INTO `t_sys_resource` VALUES (38, 36, 1, 1, '数据操作', 'sql-exec', 1, '{\"component\":\"SqlExec\",\"icon\":\"el-icon-search\",\"isKeepAlive\":true,\"routeName\":\"SqlExec\"}', 1, 'admin', 1, 'admin', '2021-06-03 09:09:29', '2021-07-05 14:05:37');
INSERT INTO `t_sys_resource` VALUES (39, 0, 1, 1, '个人中心', '/personal', 2, '{\"component\":\"Personal\",\"icon\":\"el-icon-user\",\"isKeepAlive\":true,\"routeName\":\"Personal\"}', 1, 'admin', 1, 'admin', '2021-06-03 14:25:35', '2021-06-11 10:50:45');
INSERT INTO `t_sys_resource` VALUES (40, 3, 2, 1, '文件管理-新增按钮', 'machine:file:add', 7, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:06:26', '2021-06-08 11:12:28');
INSERT INTO `t_sys_resource` VALUES (41, 3, 2, 1, '文件管理-删除按钮', 'machine:file:del', 8, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:06:49', '2021-06-08 11:06:49');
INSERT INTO `t_sys_resource` VALUES (42, 3, 2, 1, '文件管理-写入or下载文件权限', 'machine:file:write', 9, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:07:27', '2021-06-08 11:07:27');
INSERT INTO `t_sys_resource` VALUES (43, 3, 2, 1, '文件管理-文件上传按钮', 'machine:file:upload', 10, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:07:42', '2021-06-08 11:07:42');
INSERT INTO `t_sys_resource` VALUES (44, 3, 2, 1, '文件管理-删除文件按钮', 'machine:file:rm', 11, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:08:12', '2021-06-08 11:08:12');
INSERT INTO `t_sys_resource` VALUES (45, 3, 2, 1, '脚本管理-保存脚本按钮', 'machine:script:save', 12, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:01', '2021-06-08 11:09:01');
INSERT INTO `t_sys_resource` VALUES (46, 3, 2, 1, '脚本管理-删除按钮', 'machine:script:del', 13, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:27', '2021-06-08 11:09:27');
INSERT INTO `t_sys_resource` VALUES (47, 3, 2, 1, '脚本管理-执行按钮', 'machine:script:run', 14, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:50', '2021-06-08 11:09:50');
INSERT INTO `t_sys_resource` VALUES (48, 2, 1, 1, '项目管理', 'projects', 1, '{\"component\":\"ProjectList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"ProjectList\"}', 1, 'admin', 1, 'admin', '2021-06-30 16:19:49', '2021-06-30 16:20:12');
INSERT INTO `t_sys_resource` VALUES (49, 36, 1, 1, '数据库管理', 'dbs', 2, '{\"component\":\"DbList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"DbList\"}', 1, 'admin', 1, 'admin', '2021-07-07 15:13:55', '2021-07-07 15:13:55');
INSERT INTO `t_sys_resource` VALUES (50, 48, 2, 1, '项目保存', 'project:save', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-08 17:27:28', '2021-07-08 17:35:07');
INSERT INTO `t_sys_resource` VALUES (51, 48, 2, 1, '成员分配', 'project:member:add', 2, 'null', 1, 'admin', 1, 'admin', '2021-07-08 17:29:25', '2021-07-08 17:29:25');
INSERT INTO `t_sys_resource` VALUES (52, 48, 2, 1, '成员移除', 'project:member:del', 3, 'null', 1, 'admin', 1, 'admin', '2021-07-08 17:30:01', '2021-07-08 17:30:01');
INSERT INTO `t_sys_resource` VALUES (53, 48, 2, 1, '环境新增', 'project:env:add', 4, 'null', 1, 'admin', 1, 'admin', '2021-07-08 17:30:17', '2021-07-08 17:30:17');
INSERT INTO `t_sys_resource` VALUES (54, 49, 2, 1, '数据库保存', 'db:save', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-08 17:30:36', '2021-07-08 17:31:05');
INSERT INTO `t_sys_resource` VALUES (55, 49, 2, 1, '数据库删除', 'db:del', 2, 'null', 1, 'admin', 1, 'admin', '2021-07-08 17:30:48', '2021-07-08 17:30:48');
INSERT INTO `t_sys_resource` VALUES (56, 48, 2, 1, '项目基本权限', 'project', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-09 10:47:19', '2021-07-09 11:09:20');
INSERT INTO `t_sys_resource` VALUES (57, 3, 2, 1, '基本权限', 'machine', 0, 'null', 1, 'admin', 1, 'admin', '2021-07-09 10:48:02', '2021-07-09 10:48:02');
INSERT INTO `t_sys_resource` VALUES (58, 49, 2, 1, '基本权限', 'db', 0, 'null', 1, 'admin', 1, 'admin', '2021-07-09 10:48:22', '2021-07-09 10:48:22');
INSERT INTO `t_sys_resource` VALUES (59, 38, 2, 1, '基本权限', 'db:exec', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-09 10:50:13', '2021-07-09 10:50:13');
INSERT INTO `t_sys_resource` VALUES (60, 2, 1, 1, 'Redis', 'redis', 4, '{\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"RDS\"}', 1, 'admin', 1, 'admin', '2021-07-19 20:15:41', '2021-07-19 20:19:20');
INSERT INTO `t_sys_resource` VALUES (61, 60, 1, 1, '数据操作', 'data-operation', 1, '{\"component\":\"DataOperation\",\"icon\":\"el-icon-search\",\"isKeepAlive\":true,\"routeName\":\"DataOperation\"}', 1, 'admin', 1, 'admin', '2021-07-19 20:17:29', '2021-07-20 10:45:28');
INSERT INTO `t_sys_resource` VALUES (62, 61, 2, 1, '基本权限', 'redis:data', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-19 20:18:54', '2021-07-19 20:18:54');
INSERT INTO `t_sys_resource` VALUES (63, 60, 1, 1, 'redis管理', 'manage', 2, '{\"component\":\"RedisList\",\"icon\":\"el-icon-menu\",\"isKeepAlive\":true,\"routeName\":\"RedisList\"}', 1, 'admin', 1, 'admin', '2021-07-20 10:48:04', '2021-07-20 10:48:04');
INSERT INTO `t_sys_resource` VALUES (64, 63, 2, 1, '基本权限', 'redis:manage', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-20 10:48:26', '2021-07-20 10:48:26');
COMMIT;
-- ----------------------------
-- Table structure for t_role
-- Table structure for t_sys_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` (
DROP TABLE IF EXISTS `t_sys_role`;
CREATE TABLE `t_sys_role` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(16) NOT NULL,
`code` varchar(64) NOT NULL COMMENT '角色code',
`status` tinyint(255) DEFAULT NULL,
`remark` varchar(255) DEFAULT NULL,
`type` tinyint(2) NOT NULL COMMENT '类型1:公共角色2:特殊角色',
`create_time` datetime DEFAULT NULL,
`creator_id` bigint(20) DEFAULT NULL,
`creator` varchar(16) DEFAULT NULL,
@@ -332,21 +473,23 @@ CREATE TABLE `t_role` (
`modifier_id` bigint(20) DEFAULT NULL,
`modifier` varchar(16) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='角色表';
-- ----------------------------
-- Records of t_role
-- Records of t_sys_role
-- ----------------------------
BEGIN;
INSERT INTO `t_role` VALUES (1, '超级管理员', 1, '权限超级大,拥有所有权限', '2021-05-27 14:09:50', 1, 'admin', '2021-05-28 10:26:28', 1, 'admin');
INSERT INTO `t_role` VALUES (6, '普通管理员', 1, '只拥有部分管理权限', '2021-05-28 15:55:36', 1, 'admin', '2021-05-28 15:55:36', 1, 'admin');
INSERT INTO `t_sys_role` VALUES (1, '超级管理员', 'SUPBER_ADMIN', 1, '权限超级大,拥有所有权限', 2, '2021-05-27 14:09:50', 1, 'admin', '2021-05-28 10:26:28', 1, 'admin');
INSERT INTO `t_sys_role` VALUES (6, '普通管理员', 'ADMIN', 1, '只拥有部分管理权限', 2, '2021-05-28 15:55:36', 1, 'admin', '2021-05-28 15:55:36', 1, 'admin');
INSERT INTO `t_sys_role` VALUES (7, '公共角色', 'COMMON', 1, '所有账号基础角色', 1, '2021-07-06 15:05:47', 1, 'admin', '2021-07-06 15:05:47', 1, 'admin');
INSERT INTO `t_sys_role` VALUES (8, '开发', 'DEV', 1, '研发人员', 0, '2021-07-09 10:46:10', 1, 'admin', '2021-07-09 10:46:10', 1, 'admin');
COMMIT;
-- ----------------------------
-- Table structure for t_role_resource
-- Table structure for t_sys_role_resource
-- ----------------------------
DROP TABLE IF EXISTS `t_role_resource`;
CREATE TABLE `t_role_resource` (
DROP TABLE IF EXISTS `t_sys_role_resource`;
CREATE TABLE `t_sys_role_resource` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id` bigint(20) NOT NULL,
`resource_id` bigint(20) NOT NULL,
@@ -354,64 +497,108 @@ CREATE TABLE `t_role_resource` (
`creator` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=391 DEFAULT CHARSET=utf8 COMMENT='角色资源表';
) ENGINE=InnoDB AUTO_INCREMENT=438 DEFAULT CHARSET=utf8 COMMENT='角色资源关联';
-- ----------------------------
-- Records of t_role_resource
-- Records of t_sys_role_resource
-- ----------------------------
BEGIN;
INSERT INTO `t_role_resource` VALUES (1, 1, 1, 1, 'admin', '2021-05-27 15:07:39');
INSERT INTO `t_role_resource` VALUES (323, 1, 2, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_role_resource` VALUES (326, 1, 4, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_role_resource` VALUES (327, 1, 5, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_role_resource` VALUES (328, 1, 11, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_role_resource` VALUES (335, 1, 14, 1, 'admin', '2021-05-28 17:42:21');
INSERT INTO `t_role_resource` VALUES (336, 1, 3, 1, 'admin', '2021-05-28 17:42:43');
INSERT INTO `t_role_resource` VALUES (337, 1, 12, 1, 'admin', '2021-05-28 17:42:43');
INSERT INTO `t_role_resource` VALUES (338, 6, 2, 1, 'admin', '2021-05-28 19:19:38');
INSERT INTO `t_role_resource` VALUES (339, 6, 3, 1, 'admin', '2021-05-28 19:19:38');
INSERT INTO `t_role_resource` VALUES (340, 6, 12, 1, 'admin', '2021-05-28 19:19:38');
INSERT INTO `t_role_resource` VALUES (342, 6, 1, 1, 'admin', '2021-05-29 01:31:22');
INSERT INTO `t_role_resource` VALUES (343, 5, 1, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_role_resource` VALUES (344, 5, 4, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_role_resource` VALUES (345, 5, 14, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_role_resource` VALUES (346, 5, 5, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_role_resource` VALUES (347, 5, 11, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_role_resource` VALUES (348, 5, 3, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_role_resource` VALUES (349, 5, 12, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_role_resource` VALUES (350, 5, 2, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_role_resource` VALUES (353, 1, 15, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_role_resource` VALUES (354, 1, 16, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_role_resource` VALUES (355, 1, 17, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_role_resource` VALUES (356, 1, 18, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_role_resource` VALUES (358, 1, 20, 1, 'admin', '2021-05-31 17:52:08');
INSERT INTO `t_role_resource` VALUES (360, 1, 22, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_role_resource` VALUES (361, 1, 23, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_role_resource` VALUES (362, 1, 24, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_role_resource` VALUES (363, 1, 25, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_role_resource` VALUES (364, 1, 26, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_role_resource` VALUES (365, 1, 27, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_role_resource` VALUES (366, 1, 28, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_role_resource` VALUES (369, 1, 31, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_role_resource` VALUES (370, 1, 32, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_role_resource` VALUES (371, 1, 33, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_role_resource` VALUES (374, 1, 36, 1, 'admin', '2021-06-01 14:01:57');
INSERT INTO `t_role_resource` VALUES (375, 1, 19, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_role_resource` VALUES (376, 1, 21, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_role_resource` VALUES (377, 1, 29, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_role_resource` VALUES (378, 1, 30, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_role_resource` VALUES (379, 1, 34, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_role_resource` VALUES (380, 1, 37, 1, 'admin', '2021-06-03 09:09:42');
INSERT INTO `t_role_resource` VALUES (381, 1, 38, 1, 'admin', '2021-06-03 09:09:42');
INSERT INTO `t_role_resource` VALUES (382, 1, 39, 1, 'admin', '2021-06-03 14:26:42');
INSERT INTO `t_role_resource` VALUES (383, 1, 40, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_role_resource` VALUES (384, 1, 41, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_role_resource` VALUES (385, 1, 42, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_role_resource` VALUES (386, 1, 43, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_role_resource` VALUES (387, 1, 44, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_role_resource` VALUES (388, 1, 45, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_role_resource` VALUES (389, 1, 46, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_role_resource` VALUES (390, 1, 47, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (1, 1, 1, 1, 'admin', '2021-05-27 15:07:39');
INSERT INTO `t_sys_role_resource` VALUES (323, 1, 2, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_sys_role_resource` VALUES (326, 1, 4, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_sys_role_resource` VALUES (327, 1, 5, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_sys_role_resource` VALUES (328, 1, 11, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_sys_role_resource` VALUES (335, 1, 14, 1, 'admin', '2021-05-28 17:42:21');
INSERT INTO `t_sys_role_resource` VALUES (336, 1, 3, 1, 'admin', '2021-05-28 17:42:43');
INSERT INTO `t_sys_role_resource` VALUES (337, 1, 12, 1, 'admin', '2021-05-28 17:42:43');
INSERT INTO `t_sys_role_resource` VALUES (338, 6, 2, 1, 'admin', '2021-05-28 19:19:38');
INSERT INTO `t_sys_role_resource` VALUES (339, 6, 3, 1, 'admin', '2021-05-28 19:19:38');
INSERT INTO `t_sys_role_resource` VALUES (342, 6, 1, 1, 'admin', '2021-05-29 01:31:22');
INSERT INTO `t_sys_role_resource` VALUES (343, 5, 1, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (344, 5, 4, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (345, 5, 14, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (346, 5, 5, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (347, 5, 11, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (348, 5, 3, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_sys_role_resource` VALUES (349, 5, 12, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_sys_role_resource` VALUES (350, 5, 2, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_sys_role_resource` VALUES (353, 1, 15, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_sys_role_resource` VALUES (354, 1, 16, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_sys_role_resource` VALUES (355, 1, 17, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_sys_role_resource` VALUES (356, 1, 18, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_sys_role_resource` VALUES (358, 1, 20, 1, 'admin', '2021-05-31 17:52:08');
INSERT INTO `t_sys_role_resource` VALUES (360, 1, 22, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (361, 1, 23, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (362, 1, 24, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (363, 1, 25, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (364, 1, 26, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (365, 1, 27, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (366, 1, 28, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (369, 1, 31, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_sys_role_resource` VALUES (370, 1, 32, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_sys_role_resource` VALUES (371, 1, 33, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_sys_role_resource` VALUES (374, 1, 36, 1, 'admin', '2021-06-01 14:01:57');
INSERT INTO `t_sys_role_resource` VALUES (375, 1, 19, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (376, 1, 21, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (377, 1, 29, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (378, 1, 30, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (379, 1, 34, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (380, 1, 37, 1, 'admin', '2021-06-03 09:09:42');
INSERT INTO `t_sys_role_resource` VALUES (381, 1, 38, 1, 'admin', '2021-06-03 09:09:42');
INSERT INTO `t_sys_role_resource` VALUES (382, 1, 39, 1, 'admin', '2021-06-03 14:26:42');
INSERT INTO `t_sys_role_resource` VALUES (383, 1, 40, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (384, 1, 41, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (385, 1, 42, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (386, 1, 43, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (387, 1, 44, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (388, 1, 45, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (389, 1, 46, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (390, 1, 47, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (391, 6, 39, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (392, 6, 15, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (395, 6, 31, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (396, 6, 33, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (397, 6, 32, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (398, 6, 4, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (399, 6, 14, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (400, 6, 11, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (401, 6, 5, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (402, 1, 48, 1, 'admin', '2021-06-30 16:22:35');
INSERT INTO `t_sys_role_resource` VALUES (403, 7, 1, 1, 'admin', '2021-07-06 15:07:09');
INSERT INTO `t_sys_role_resource` VALUES (404, 7, 39, 1, 'admin', '2021-07-06 15:07:09');
INSERT INTO `t_sys_role_resource` VALUES (405, 1, 49, 1, 'admin', '2021-07-07 15:14:17');
INSERT INTO `t_sys_role_resource` VALUES (406, 1, 50, 1, 'admin', '2021-07-08 17:32:19');
INSERT INTO `t_sys_role_resource` VALUES (407, 1, 51, 1, 'admin', '2021-07-08 17:32:19');
INSERT INTO `t_sys_role_resource` VALUES (408, 1, 52, 1, 'admin', '2021-07-08 17:32:19');
INSERT INTO `t_sys_role_resource` VALUES (409, 1, 53, 1, 'admin', '2021-07-08 17:32:19');
INSERT INTO `t_sys_role_resource` VALUES (410, 1, 54, 1, 'admin', '2021-07-08 17:32:19');
INSERT INTO `t_sys_role_resource` VALUES (411, 1, 55, 1, 'admin', '2021-07-08 17:32:19');
INSERT INTO `t_sys_role_resource` VALUES (412, 1, 56, 1, 'admin', '2021-07-09 10:48:50');
INSERT INTO `t_sys_role_resource` VALUES (413, 1, 57, 1, 'admin', '2021-07-09 10:48:50');
INSERT INTO `t_sys_role_resource` VALUES (414, 1, 58, 1, 'admin', '2021-07-09 10:48:50');
INSERT INTO `t_sys_role_resource` VALUES (415, 8, 1, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (416, 8, 39, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (417, 8, 56, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (418, 8, 57, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (419, 8, 12, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (420, 8, 15, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (421, 8, 38, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (422, 8, 58, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (423, 8, 2, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (424, 8, 48, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (425, 8, 3, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (426, 8, 36, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (427, 8, 49, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (428, 1, 59, 1, 'admin', '2021-07-09 10:50:20');
INSERT INTO `t_sys_role_resource` VALUES (429, 8, 59, 1, 'admin', '2021-07-09 10:50:32');
INSERT INTO `t_sys_role_resource` VALUES (430, 6, 56, 1, 'admin', '2021-07-12 16:44:12');
INSERT INTO `t_sys_role_resource` VALUES (431, 6, 57, 1, 'admin', '2021-07-12 16:44:12');
INSERT INTO `t_sys_role_resource` VALUES (432, 6, 48, 1, 'admin', '2021-07-12 16:44:12');
INSERT INTO `t_sys_role_resource` VALUES (433, 1, 60, 1, 'admin', '2021-07-19 20:19:29');
INSERT INTO `t_sys_role_resource` VALUES (434, 1, 61, 1, 'admin', '2021-07-19 20:19:29');
INSERT INTO `t_sys_role_resource` VALUES (435, 1, 62, 1, 'admin', '2021-07-19 20:19:29');
INSERT INTO `t_sys_role_resource` VALUES (436, 1, 63, 1, 'admin', '2021-07-20 10:48:39');
INSERT INTO `t_sys_role_resource` VALUES (437, 1, 64, 1, 'admin', '2021-07-20 10:48:39');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -1,9 +1,13 @@
package apis
import (
"fmt"
"mayfly-go/base/biz"
"mayfly-go/base/captcha"
"mayfly-go/base/ctx"
"mayfly-go/base/ginx"
"mayfly-go/base/global"
"mayfly-go/base/httpclient"
"mayfly-go/base/utils"
"mayfly-go/server/sys/apis/form"
"mayfly-go/server/sys/apis/vo"
@@ -15,9 +19,9 @@ import (
)
type Account struct {
AccountApp application.IAccount
ResourceApp application.IResource
RoleApp application.IRole
AccountApp application.Account
ResourceApp application.Resource
RoleApp application.Role
}
// @router /accounts/login [post]
@@ -26,6 +30,9 @@ func (a *Account) Login(rc *ctx.ReqCtx) {
ginx.BindJsonAndValid(rc.GinCtx, loginForm)
rc.ReqParam = loginForm.Username
// 校验验证码
biz.IsTrue(captcha.Verify(loginForm.Cid, loginForm.Captcha), "验证码错误")
account := &entity.Account{Username: loginForm.Username, Password: utils.Md5(loginForm.Password)}
biz.ErrIsNil(a.AccountApp.GetAccount(account, "Id", "Username", "Password", "Status"), "用户名或密码错误")
biz.IsTrue(account.IsEnable(), "该账号不可用")
@@ -46,6 +53,9 @@ func (a *Account) Login(rc *ctx.ReqCtx) {
// 保存该账号的权限codes
ctx.SavePermissionCodes(account.Id, permissions)
// 保存登录消息
go a.saveLogin(account, rc.GinCtx.ClientIP())
rc.ResData = map[string]interface{}{
"token": ctx.CreateToken(account.Id, account.Username),
"username": account.Username,
@@ -54,12 +64,61 @@ func (a *Account) Login(rc *ctx.ReqCtx) {
}
}
// 保存更新账号登录信息
func (a *Account) saveLogin(account *entity.Account, ip string) {
// 更新账号最后登录时间
now := time.Now()
updateAccount := &entity.Account{LastLoginTime: &now}
updateAccount.Id = account.Id
a.AccountApp.Update(updateAccount)
bodyMap, err := httpclient.NewRequest(fmt.Sprintf("http://ip-api.com/json/%s?lang=zh-CN", ip)).Get().BodyToMap()
if err != nil {
global.Log.Errorf("获取客户端ip地址信息失败%s", err.Error())
return
}
if bodyMap["status"].(string) == "fail" {
return
}
msg := fmt.Sprintf("%s-%s登录", bodyMap["regionName"], bodyMap["city"])
fmt.Printf(msg)
}
// @router /accounts [get]
func (a *Account) Accounts(rc *ctx.ReqCtx) {
condition := &entity.Account{}
condition.Username = rc.GinCtx.Query("username")
rc.ResData = a.AccountApp.GetPageList(condition, ginx.GetPageParam(rc.GinCtx), new([]vo.AccountManageVO))
}
// @router /accounts [get]
func (a *Account) CreateAccount(rc *ctx.ReqCtx) {
form := &form.AccountCreateForm{}
ginx.BindJsonAndValid(rc.GinCtx, form)
rc.ReqParam = form
account := &entity.Account{}
utils.Copy(account, form)
account.SetBaseInfo(rc.LoginAccount)
a.AccountApp.Create(account)
}
func (a *Account) ChangeStatus(rc *ctx.ReqCtx) {
g := rc.GinCtx
account := &entity.Account{}
account.Id = uint64(ginx.PathParamInt(g, "id"))
account.Status = int8(ginx.PathParamInt(g, "status"))
rc.ReqParam = fmt.Sprintf("accountId: %d, status: %d", account.Id, account.Status)
a.AccountApp.Update(account)
}
func (a *Account) DeleteAccount(rc *ctx.ReqCtx) {
id := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
rc.ReqParam = id
a.AccountApp.Delete(id)
}
// 获取账号角色id列表用户回显角色分配
func (a *Account) AccountRoleIds(rc *ctx.ReqCtx) {
rc.ResData = a.RoleApp.GetAccountRoleIds(uint64(ginx.PathParamInt(rc.GinCtx, "id")))

View File

@@ -0,0 +1,11 @@
package apis
import (
"mayfly-go/base/captcha"
"mayfly-go/base/ctx"
)
func GenerateCaptcha(rc *ctx.ReqCtx) {
id, image := captcha.Generate()
rc.ResData = map[string]interface{}{"base64Captcha": image, "cid": id}
}

View File

@@ -0,0 +1,11 @@
package form
type AccountCreateForm struct {
Username *string `json:"username" binding:"required,min=4,max=16"`
}
type AccountUpdateForm struct {
Password *string `json:"password" binding:"required,min=6,max=16"`
RePassword *string `json:"rePassword" binding:"required,min=4,max=16"`
}

View File

@@ -2,6 +2,8 @@ package form
// 登录表单
type LoginForm struct {
Username string `valid:"Required"`
Password string `valid:"Required"`
Username string `json:"username" binding:"required"`
Password string `binding:"required"`
Captcha string `binding:"required"`
Cid string `binding:"required"`
}

View File

@@ -1,20 +1,20 @@
package form
type ResourceForm struct {
Pid int `valid:"Required"`
Id int `valid:"Required"`
Code string `valid:"Required"`
Name string `valid:"Required"`
Type int `valid:"Required"`
Weight int `valid:"Required"`
Meta map[string]interface{} `valid:"Required"`
Pid int
Id int
Code string `binding:"required"`
Name string `binding:"required"`
Type int `binding:"required,oneof=1 2"`
Weight int
Meta map[string]interface{}
}
type MenuResourceMeta struct {
RouteName string `valid:"Required"`
Component string `valid:"Required"`
RouteName string `binding:"required"`
Component string `binding:"required"`
Redirect string
Path string `valid:"Required"`
Path string `binding:"required"`
IsKeepAlive bool //
IsHide bool // 是否在菜单栏显示,默认显示
IsAffix bool // tag标签是否不可删除

View File

@@ -10,12 +10,13 @@ type RoleResourceForm struct {
type RoleForm struct {
Id int
Status int `json:"status"` // 1可用-1不可用
Name string `json:"name"`
Name string `binding:"required"`
Code string `binding:"required"`
Remark string `json:"remark"`
}
// 账号分配角色表单
type AccountRoleForm struct {
Id int
Id int `binding:"required"`
RoleIds string
}

View File

@@ -12,7 +12,7 @@ import (
)
type Resource struct {
ResourceApp application.IResource
ResourceApp application.Resource
}
func (r *Resource) GetAllResourceTree(rc *ctx.ReqCtx) {

View File

@@ -14,8 +14,8 @@ import (
)
type Role struct {
RoleApp application.IRole
ResourceApp application.IResource
RoleApp application.Role
ResourceApp application.Resource
}
func (r *Role) Roles(rc *ctx.ReqCtx) {

View File

@@ -7,8 +7,9 @@ import (
type AccountManageVO struct {
model.Model
Username *string `json:"username"`
Status int `json:"status"`
Username *string `json:"username"`
Status int `json:"status"`
LastLoginTime *time.Time `json:"lastLoginTime"`
}
type AccountRoleVO struct {

View File

@@ -1,29 +1,70 @@
package application
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/base/utils"
"mayfly-go/server/sys/domain/entity"
"mayfly-go/server/sys/domain/repository"
"mayfly-go/server/sys/infrastructure/persistence"
"gorm.io/gorm"
)
type IAccount interface {
type Account interface {
GetAccount(condition *entity.Account, cols ...string) error
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Create(account *entity.Account)
Update(account *entity.Account)
Delete(id uint64)
}
type accountApp struct {
type accountAppImpl struct {
accountRepo repository.Account
}
var Account IAccount = &accountApp{accountRepo: persistence.AccountDao}
var AccountApp Account = &accountAppImpl{
accountRepo: persistence.AccountDao,
}
// 根据条件获取账号信息
func (a *accountApp) GetAccount(condition *entity.Account, cols ...string) error {
func (a *accountAppImpl) GetAccount(condition *entity.Account, cols ...string) error {
return a.accountRepo.GetAccount(condition, cols...)
}
func (a *accountApp) GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (a *accountAppImpl) GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return a.accountRepo.GetPageList(condition, pageParam, toEntity)
}
func (a *accountAppImpl) Create(account *entity.Account) {
biz.IsTrue(a.GetAccount(&entity.Account{Username: account.Username}) != nil, "该账号用户名已存在")
// 默认密码为账号用户名
account.Password = utils.Md5(account.Username)
account.Status = entity.AccountEnableStatus
a.accountRepo.Insert(account)
}
func (a *accountAppImpl) Update(account *entity.Account) {
// 禁止更新用户名,防止误传被更新
account.Username = ""
a.accountRepo.Update(account)
}
func (a *accountAppImpl) Delete(id uint64) {
err := model.Tx(
func(db *gorm.DB) error {
// 删除account表信息
return db.Delete(new(entity.Account), "id = ?", id).Error
},
func(db *gorm.DB) error {
// 删除账号关联的角色信息
accountRole := &entity.AccountRole{AccountId: id}
return db.Where(accountRole).Delete(accountRole).Error
},
)
biz.ErrIsNilAppendErr(err, "删除失败:%s")
}

View File

@@ -9,7 +9,7 @@ import (
"strings"
)
type IResource interface {
type Resource interface {
GetResourceList(condition *entity.Resource, toEntity interface{}, orderBy ...string)
GetById(id uint64, cols ...string) *entity.Resource
@@ -23,28 +23,28 @@ type IResource interface {
GetAccountResources(accountId uint64, toEntity interface{})
}
type resourceApp struct {
type resourceAppImpl struct {
resourceRepo repository.Resource
}
// 实现类单例
var Resource IResource = &resourceApp{
var ResourceApp Resource = &resourceAppImpl{
resourceRepo: persistence.ResourceDao,
}
func (r *resourceApp) GetResourceList(condition *entity.Resource, toEntity interface{}, orderBy ...string) {
func (r *resourceAppImpl) GetResourceList(condition *entity.Resource, toEntity interface{}, orderBy ...string) {
r.resourceRepo.GetResourceList(condition, toEntity, orderBy...)
}
func (r *resourceApp) GetById(id uint64, cols ...string) *entity.Resource {
func (r *resourceAppImpl) GetById(id uint64, cols ...string) *entity.Resource {
return r.resourceRepo.GetById(id, cols...)
}
func (r *resourceApp) GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string) {
func (r *resourceAppImpl) GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string) {
r.resourceRepo.GetByIdIn(ids, toEntity, orderBy...)
}
func (r *resourceApp) Save(resource *entity.Resource) {
func (r *resourceAppImpl) Save(resource *entity.Resource) {
if resource.Id != 0 {
if resource.Code != "" {
oldRes := r.GetById(resource.Id, "Code")
@@ -67,12 +67,12 @@ func (r *resourceApp) Save(resource *entity.Resource) {
}
}
func (r *resourceApp) checkCode(code string) {
func (r *resourceAppImpl) checkCode(code string) {
biz.IsTrue(!strings.Contains(code, ","), "code不能包含','")
biz.IsEquals(model.CountBy(&entity.Resource{Code: code}), int64(0), "该code已存在")
}
func (r *resourceApp) Delete(id uint64) {
func (r *resourceAppImpl) Delete(id uint64) {
// 查找pid == id的资源
condition := &entity.Resource{Pid: int(id)}
var resources resourceList
@@ -84,7 +84,7 @@ func (r *resourceApp) Delete(id uint64) {
model.DeleteByCondition(&entity.RoleResource{ResourceId: id})
}
func (r *resourceApp) GetAccountResources(accountId uint64, toEntity interface{}) {
func (r *resourceAppImpl) GetAccountResources(accountId uint64, toEntity interface{}) {
r.resourceRepo.GetAccountResources(accountId, toEntity)
}

View File

@@ -5,10 +5,11 @@ import (
"mayfly-go/server/sys/domain/entity"
"mayfly-go/server/sys/domain/repository"
"mayfly-go/server/sys/infrastructure/persistence"
"strings"
)
type IRole interface {
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
type Role interface {
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
SaveRole(role *entity.Role)
@@ -18,12 +19,16 @@ type IRole interface {
GetRoleResources(roleId uint64, toEntity interface{})
// 保存角色资源关联记录
SaveRoleResource(rr *entity.RoleResource)
// 删除角色资源关联记录
DeleteRoleResource(roleId uint64, resourceId uint64)
// 获取账号角色id列表
GetAccountRoleIds(accountId uint64) []uint64
// 保存账号角色关联信息
SaveAccountRole(rr *entity.AccountRole)
DeleteAccountRole(accountId, roleId uint64)
@@ -31,61 +36,65 @@ type IRole interface {
GetAccountRoles(accountId uint64, toEntity interface{})
}
type roleApp struct {
type roleAppImpl struct {
roleRepo repository.Role
}
// 实现类单例
var Role IRole = &roleApp{
var RoleApp Role = &roleAppImpl{
roleRepo: persistence.RoleDao,
}
func (m *roleApp) GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (m *roleAppImpl) GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return m.roleRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
func (m *roleApp) SaveRole(role *entity.Role) {
func (m *roleAppImpl) SaveRole(role *entity.Role) {
role.Code = strings.ToUpper(role.Code)
if role.Id != 0 {
// code不可更改防止误传
role.Code = ""
model.UpdateById(role)
} else {
role.Status = 1
model.Insert(role)
}
}
func (m *roleApp) DeleteRole(id uint64) {
func (m *roleAppImpl) DeleteRole(id uint64) {
m.roleRepo.Delete(id)
// 删除角色与资源的关联关系
model.DeleteByCondition(&entity.RoleResource{RoleId: id})
}
func (m *roleApp) GetRoleResourceIds(roleId uint64) []uint64 {
func (m *roleAppImpl) GetRoleResourceIds(roleId uint64) []uint64 {
return m.roleRepo.GetRoleResourceIds(roleId)
}
func (m *roleApp) GetRoleResources(roleId uint64, toEntity interface{}) {
func (m *roleAppImpl) GetRoleResources(roleId uint64, toEntity interface{}) {
m.roleRepo.GetRoleResources(roleId, toEntity)
}
func (m *roleApp) SaveRoleResource(rr *entity.RoleResource) {
func (m *roleAppImpl) SaveRoleResource(rr *entity.RoleResource) {
m.roleRepo.SaveRoleResource(rr)
}
func (m *roleApp) DeleteRoleResource(roleId uint64, resourceId uint64) {
func (m *roleAppImpl) DeleteRoleResource(roleId uint64, resourceId uint64) {
m.roleRepo.DeleteRoleResource(roleId, resourceId)
}
func (m *roleApp) GetAccountRoleIds(accountId uint64) []uint64 {
func (m *roleAppImpl) GetAccountRoleIds(accountId uint64) []uint64 {
return m.roleRepo.GetAccountRoleIds(accountId)
}
func (m *roleApp) SaveAccountRole(rr *entity.AccountRole) {
func (m *roleAppImpl) SaveAccountRole(rr *entity.AccountRole) {
m.roleRepo.SaveAccountRole(rr)
}
func (m *roleApp) DeleteAccountRole(accountId, roleId uint64) {
func (m *roleAppImpl) DeleteAccountRole(accountId, roleId uint64) {
m.roleRepo.DeleteAccountRole(accountId, roleId)
}
func (m *roleApp) GetAccountRoles(accountId uint64, toEntity interface{}) {
func (m *roleAppImpl) GetAccountRoles(accountId uint64, toEntity interface{}) {
m.roleRepo.GetAccountRoles(accountId, toEntity)
}

View File

@@ -2,14 +2,20 @@ package entity
import (
"mayfly-go/base/model"
"time"
)
type Account struct {
model.Model
Username string `json:"username"`
Password string `json:"-"`
Status int8 `json:"status"`
Username string `json:"username"`
Password string `json:"-"`
Status int8 `json:"status"`
LastLoginTime *time.Time `json:"lastLoginTime"`
}
func (a *Account) TableName() string {
return "t_sys_account"
}
// 是否可用

View File

@@ -13,6 +13,10 @@ type Resource struct {
Meta string `json:"meta"`
}
func (a *Resource) TableName() string {
return "t_sys_resource"
}
const (
ResourceStatusEnable int8 = 1 // 启用状态
ResourceStatusDisable int8 = -1 // 禁用状态

View File

@@ -5,11 +5,22 @@ import (
"time"
)
const (
RoleTypeCommon int = 1 // 公共角色类型
RoleTypeSpecial int = 2 // 特殊角色类型
)
type Role struct {
model.Model
Status int `json:"status"` // 1可用-1不可用
Name string `json:"name"`
Remark string `json:"remark"`
Code string `json:"code"`
Type int `json:"type"`
}
func (a *Role) TableName() string {
return "t_sys_role"
}
// 角色资源
@@ -22,6 +33,10 @@ type RoleResource struct {
Creator string `json:"creator"`
}
func (a *RoleResource) TableName() string {
return "t_sys_role_resource"
}
// 账号角色
type AccountRole struct {
Id uint64 `json:"id"`
@@ -31,3 +46,7 @@ type AccountRole struct {
CreatorId uint64 `json:"creatorId"`
Creator string `json:"creator"`
}
func (a *AccountRole) TableName() string {
return "t_sys_account_role"
}

View File

@@ -9,5 +9,9 @@ type Account interface {
// 根据条件获取账号信息
GetAccount(condition *entity.Account, cols ...string) error
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Insert(account *entity.Account)
Update(account *entity.Account)
}

View File

@@ -10,7 +10,7 @@ type Resource interface {
GetById(id uint64, cols ...string) *entity.Resource
GetByIdIn(ids []uint64, toEntity interface{}, cols ...string)
GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string)
Delete(id uint64)

View File

@@ -6,7 +6,7 @@ import (
)
type Role interface {
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
Delete(id uint64)

View File

@@ -1,6 +1,7 @@
package persistence
import (
"mayfly-go/base/biz"
"mayfly-go/base/model"
"mayfly-go/server/sys/domain/entity"
"mayfly-go/server/sys/domain/repository"
@@ -14,6 +15,20 @@ func (a *accountRepo) GetAccount(condition *entity.Account, cols ...string) erro
return model.GetBy(condition, cols...)
}
func (m *accountRepo) GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
func (m *accountRepo) GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
sql := "SELECT * FROM t_sys_account "
username := condition.Username
if username != "" {
sql = sql + " WHERE username LIKE '%" + username + "%'"
}
return model.GetPageBySql(sql, pageParam, toEntity)
// return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
func (m *accountRepo) Insert(account *entity.Account) {
biz.ErrIsNil(model.Insert(account), "新增账号信息失败")
}
func (m *accountRepo) Update(account *entity.Account) {
biz.ErrIsNil(model.UpdateById(account), "更新账号信息失败")
}

View File

@@ -37,12 +37,38 @@ func (r *resourceRepo) GetByCondition(condition *entity.Resource, cols ...string
}
func (r *resourceRepo) GetAccountResources(accountId uint64, toEntity interface{}) {
sql := "SELECT m.id, m.pid, m.weight, m.name, m.code, m.meta, m.type, m.status " +
"FROM t_resource m WHERE m.status = 1 AND " +
"m.id IN " +
"(SELECT DISTINCT(rmb.resource_id) " +
"FROM t_account_role p JOIN t_role r ON p.role_Id = r.id AND p.account_id = ? AND r.status = 1 " +
"JOIN t_role_resource rmb ON rmb.role_id = r.id)" +
"ORDER BY m.pid ASC, m.weight ASC"
model.GetListBySql2Model(sql, toEntity, accountId)
sql := `SELECT
m.id,
m.pid,
m.weight,
m.name,
m.code,
m.meta,
m.type,
m.status
FROM
t_sys_resource m
WHERE
m.STATUS = 1
AND m.id IN (
SELECT DISTINCT
( rmb.resource_id )
FROM
t_sys_account_role p
JOIN t_sys_role r ON p.role_Id = r.id
AND p.account_id = ?
AND r.STATUS = 1
JOIN t_sys_role_resource rmb ON rmb.role_id = r.id UNION
SELECT
r.id
FROM
t_sys_resource r
JOIN t_sys_role_resource rr ON r.id = rr.resource_id
JOIN t_sys_role ro ON rr.role_id = ro.id
AND ro.status = 1 AND ro.code LIKE 'COMMON%'
)
ORDER BY
m.pid ASC,
m.weight ASC`
biz.ErrIsNilAppendErr(model.GetListBySql2Model(sql, toEntity, accountId), "查询账号资源失败: %s")
}

View File

@@ -11,7 +11,7 @@ type roleRepo struct{}
var RoleDao repository.Role = &roleRepo{}
func (m *roleRepo) GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) model.PageResult {
func (m *roleRepo) GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, toEntity, orderBy...)
}
@@ -36,7 +36,7 @@ func (m *roleRepo) GetRoleResourceIds(roleId uint64) []uint64 {
func (m *roleRepo) GetRoleResources(roleId uint64, toEntity interface{}) {
sql := "select rr.creator AS creator, rr.create_time AS CreateTime, rr.resource_id AS id, r.pid AS pid, " +
"r.name AS name, r.type AS type, r.status AS status " +
"FROM t_role_resource rr JOIN t_resource r ON rr.resource_id = r.id " +
"FROM t_sys_role_resource rr JOIN t_sys_resource r ON rr.resource_id = r.id " +
"WHERE rr.role_id = ? " +
"ORDER BY r.pid ASC, r.weight ASC"
model.GetListBySql2Model(sql, toEntity, roleId)
@@ -74,7 +74,7 @@ func (m *roleRepo) DeleteAccountRole(accountId, roleId uint64) {
// 获取账号角色信息列表
func (m *roleRepo) GetAccountRoles(accountId uint64, toEntity interface{}) {
sql := "SELECT r.status, r.name, ar.create_time AS CreateTime, ar.creator AS creator " +
"FROM t_role r JOIN t_account_role ar ON r.id = ar.role_id AND ar.account_id = ? " +
"FROM t_sys_role r JOIN t_sys_account_role ar ON r.id = ar.role_id AND ar.account_id = ? " +
"ORDER BY ar.create_time DESC"
model.GetListBySql2Model(sql, toEntity, accountId)
}

View File

@@ -11,9 +11,9 @@ import (
func InitAccountRouter(router *gin.RouterGroup) {
account := router.Group("sys/accounts")
a := &apis.Account{
AccountApp: application.Account,
ResourceApp: application.Resource,
RoleApp: application.Role,
AccountApp: application.AccountApp,
ResourceApp: application.ResourceApp,
RoleApp: application.RoleApp,
}
{
// 用户登录
@@ -27,14 +27,39 @@ func InitAccountRouter(router *gin.RouterGroup) {
ctx.NewReqCtxWithGin(c).Handle(a.Accounts)
})
createAccount := ctx.NewLogInfo("创建账号")
addAccountPermission := ctx.NewPermission("account:add")
account.POST("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).
WithRequiredPermission(addAccountPermission).
WithLog(createAccount).
Handle(a.CreateAccount)
})
changeStatus := ctx.NewLogInfo("修改账号状态")
account.PUT("change-status/:id/:status", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).
WithLog(changeStatus).
Handle(a.ChangeStatus)
})
delAccount := ctx.NewLogInfo("删除账号")
delAccountPermission := ctx.NewPermission("account:del")
account.DELETE(":id", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).
WithRequiredPermission(delAccountPermission).
WithLog(delAccount).
Handle(a.DeleteAccount)
})
// 获取所有用户角色id列表
account.GET(":id/roleIds", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).Handle(a.AccountRoleIds)
})
// 保存用户角色
saveAccountRole := ctx.NewLogInfo("保存用户角色")
sarPermission := ctx.NewPermission("account:saveRoles")
// 保存用户角色
account.POST("/roles", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(saveAccountRole).
WithRequiredPermission(sarPermission).

View File

@@ -0,0 +1,17 @@
package routers
import (
"mayfly-go/base/ctx"
"mayfly-go/server/sys/apis"
"github.com/gin-gonic/gin"
)
func InitCaptchaRouter(router *gin.RouterGroup) {
captcha := router.Group("sys/captcha")
{
captcha.GET("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithNeedToken(false).Handle(apis.GenerateCaptcha)
})
}
}

View File

@@ -9,7 +9,7 @@ import (
)
func InitResourceRouter(router *gin.RouterGroup) {
r := &apis.Resource{ResourceApp: application.Resource}
r := &apis.Resource{ResourceApp: application.ResourceApp}
db := router.Group("sys/resources")
{
// db.GET("/account", func(c *gin.Context) {

View File

@@ -10,8 +10,8 @@ import (
func InitRoleRouter(router *gin.RouterGroup) {
r := &apis.Role{
RoleApp: application.Role,
ResourceApp: application.Resource,
RoleApp: application.RoleApp,
ResourceApp: application.ResourceApp,
}
db := router.Group("sys/roles")
{
@@ -21,7 +21,7 @@ func InitRoleRouter(router *gin.RouterGroup) {
})
saveRole := ctx.NewLogInfo("保存角色")
sPermission := ctx.NewPermission("role:save")
sPermission := ctx.NewPermission("role:add")
db.POST("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).WithLog(saveRole).
WithRequiredPermission(sPermission).