mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
feat: 代码优化、机器计划任务完善
This commit is contained in:
@@ -251,7 +251,6 @@ onMounted(async () => {
|
|||||||
const handleCommand = (commond: any) => {
|
const handleCommand = (commond: any) => {
|
||||||
const data = commond.data;
|
const data = commond.data;
|
||||||
const type = commond.type;
|
const type = commond.type;
|
||||||
console.log(type);
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'detail': {
|
case 'detail': {
|
||||||
showInfo(data);
|
showInfo(data);
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ package api
|
|||||||
import (
|
import (
|
||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/cryptox"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Common struct {
|
type Common struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Common) RasPublicKey(rc *req.Ctx) {
|
func (i *Common) RasPublicKey(rc *req.Ctx) {
|
||||||
publicKeyStr, err := utils.GetRsaPublicKey()
|
publicKeyStr, err := cryptox.GetRsaPublicKey()
|
||||||
biz.ErrIsNilAppendErr(err, "rsa生成公私钥失败")
|
biz.ErrIsNilAppendErr(err, "rsa生成公私钥失败")
|
||||||
rc.ResData = publicKeyStr
|
rc.ResData = publicKeyStr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import (
|
|||||||
"mayfly-go/pkg/gormx"
|
"mayfly-go/pkg/gormx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/cryptox"
|
||||||
|
"mayfly-go/pkg/utils/stringx"
|
||||||
|
"mayfly-go/pkg/utils/structx"
|
||||||
"mayfly-go/pkg/ws"
|
"mayfly-go/pkg/ws"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -57,7 +59,7 @@ func (d *Db) Save(rc *req.Ctx) {
|
|||||||
db := ginx.BindJsonAndCopyTo[*entity.Db](rc.GinCtx, form, new(entity.Db))
|
db := ginx.BindJsonAndCopyTo[*entity.Db](rc.GinCtx, form, new(entity.Db))
|
||||||
|
|
||||||
// 密码解密,并使用解密后的赋值
|
// 密码解密,并使用解密后的赋值
|
||||||
originPwd, err := utils.DefaultRsaDecrypt(form.Password, true)
|
originPwd, err := cryptox.DefaultRsaDecrypt(form.Password, true)
|
||||||
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
||||||
db.Password = originPwd
|
db.Password = originPwd
|
||||||
|
|
||||||
@@ -83,10 +85,10 @@ func (d *Db) GetDatabaseNames(rc *req.Ctx) {
|
|||||||
ginx.BindJsonAndValid(rc.GinCtx, form)
|
ginx.BindJsonAndValid(rc.GinCtx, form)
|
||||||
|
|
||||||
db := new(entity.Db)
|
db := new(entity.Db)
|
||||||
utils.Copy(db, form)
|
structx.Copy(db, form)
|
||||||
|
|
||||||
// 密码解密,并使用解密后的赋值
|
// 密码解密,并使用解密后的赋值
|
||||||
originPwd, err := utils.DefaultRsaDecrypt(form.Password, true)
|
originPwd, err := cryptox.DefaultRsaDecrypt(form.Password, true)
|
||||||
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
||||||
db.Password = originPwd
|
db.Password = originPwd
|
||||||
|
|
||||||
@@ -143,7 +145,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
|
|||||||
biz.NotEmpty(form.Sql, "sql不能为空")
|
biz.NotEmpty(form.Sql, "sql不能为空")
|
||||||
|
|
||||||
// 去除前后空格及换行符
|
// 去除前后空格及换行符
|
||||||
sql := utils.StrTrimSpaceAndBr(form.Sql)
|
sql := stringx.TrimSpaceAndBr(form.Sql)
|
||||||
|
|
||||||
execReq := &application.DbSqlExecReq{
|
execReq := &application.DbSqlExecReq{
|
||||||
DbId: id,
|
DbId: id,
|
||||||
@@ -158,7 +160,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
|
|||||||
isMulti := len(sqls) > 1
|
isMulti := len(sqls) > 1
|
||||||
var execResAll *application.DbSqlExecRes
|
var execResAll *application.DbSqlExecRes
|
||||||
for _, s := range sqls {
|
for _, s := range sqls {
|
||||||
s = utils.StrTrimSpaceAndBr(s)
|
s = stringx.TrimSpaceAndBr(s)
|
||||||
// 多条执行,如果有查询语句,则跳过
|
// 多条执行,如果有查询语句,则跳过
|
||||||
if isMulti && strings.HasPrefix(strings.ToLower(s), "select") {
|
if isMulti && strings.HasPrefix(strings.ToLower(s), "select") {
|
||||||
continue
|
continue
|
||||||
@@ -308,7 +310,7 @@ func (d *Db) DumpSql(rc *req.Ctx) {
|
|||||||
if ok {
|
if ok {
|
||||||
values = append(values, fmt.Sprintf("%#v", strValue))
|
values = append(values, fmt.Sprintf("%#v", strValue))
|
||||||
} else {
|
} else {
|
||||||
values = append(values, utils.ToString(value))
|
values = append(values, stringx.AnyToStr(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.WriteString(fmt.Sprintf(insertSql, table, strings.Join(values, ", ")))
|
writer.WriteString(fmt.Sprintf(insertSql, table, strings.Join(values, ", ")))
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import (
|
|||||||
"mayfly-go/pkg/cache"
|
"mayfly-go/pkg/cache"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/collx"
|
||||||
|
"mayfly-go/pkg/utils/structx"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -120,7 +121,7 @@ func (d *dbAppImpl) Save(dbEntity *entity.Db) {
|
|||||||
newDbs = append(newDbs, v)
|
newDbs = append(newDbs, v)
|
||||||
}
|
}
|
||||||
// 比较新旧数据库列表,需要将移除的数据库相关联的信息删除
|
// 比较新旧数据库列表,需要将移除的数据库相关联的信息删除
|
||||||
_, delDb, _ := utils.ArrayCompare(newDbs, oldDbs, func(i1, i2 any) bool {
|
_, delDb, _ := collx.ArrayCompare(newDbs, oldDbs, func(i1, i2 any) bool {
|
||||||
return i1.(string) == i2.(string)
|
return i1.(string) == i2.(string)
|
||||||
})
|
})
|
||||||
for _, v := range delDb {
|
for _, v := range delDb {
|
||||||
@@ -193,7 +194,7 @@ func (da *dbAppImpl) GetDbInstance(id uint64, db string) *DbInstance {
|
|||||||
d.PwdDecrypt()
|
d.PwdDecrypt()
|
||||||
|
|
||||||
dbInfo := new(DbInfo)
|
dbInfo := new(DbInfo)
|
||||||
utils.Copy(dbInfo, d)
|
structx.Copy(dbInfo, d)
|
||||||
dbInfo.Database = db
|
dbInfo.Database = db
|
||||||
dbi := &DbInstance{Id: cacheKey, Info: dbInfo}
|
dbi := &DbInstance{Id: cacheKey, Info: dbInfo}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package application
|
|||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ func GetLocalSql(file, key string) string {
|
|||||||
sqls := strings.Split(allSql, "---------------------------------------")
|
sqls := strings.Split(allSql, "---------------------------------------")
|
||||||
var resSql string
|
var resSql string
|
||||||
for _, sql := range sqls {
|
for _, sql := range sqls {
|
||||||
sql = utils.StrTrimSpaceAndBr(sql)
|
sql = stringx.TrimSpaceAndBr(sql)
|
||||||
// 获取sql第一行的sql备注信息如:--MYSQL_TABLE_MA 表信息元数据
|
// 获取sql第一行的sql备注信息如:--MYSQL_TABLE_MA 表信息元数据
|
||||||
info := strings.SplitN(sql, "\n", 2)
|
info := strings.SplitN(sql, "\n", 2)
|
||||||
// 原始sql,即去除第一行的key与备注信息
|
// 原始sql,即去除第一行的key与备注信息
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"mayfly-go/internal/db/domain/entity"
|
"mayfly-go/internal/db/domain/entity"
|
||||||
machineapp "mayfly-go/internal/machine/application"
|
machineapp "mayfly-go/internal/machine/application"
|
||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/anyx"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
@@ -51,7 +51,7 @@ func (mm *MysqlMetadata) GetTables() []Table {
|
|||||||
for _, re := range res {
|
for _, re := range res {
|
||||||
tables = append(tables, Table{
|
tables = append(tables, Table{
|
||||||
TableName: re["tableName"].(string),
|
TableName: re["tableName"].(string),
|
||||||
TableComment: utils.Any2String(re["tableComment"]),
|
TableComment: anyx.ConvString(re["tableComment"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return tables
|
return tables
|
||||||
@@ -74,11 +74,11 @@ func (mm *MysqlMetadata) GetColumns(tableNames ...string) []Column {
|
|||||||
columns = append(columns, Column{
|
columns = append(columns, Column{
|
||||||
TableName: re["tableName"].(string),
|
TableName: re["tableName"].(string),
|
||||||
ColumnName: re["columnName"].(string),
|
ColumnName: re["columnName"].(string),
|
||||||
ColumnType: utils.Any2String(re["columnType"]),
|
ColumnType: anyx.ConvString(re["columnType"]),
|
||||||
ColumnComment: utils.Any2String(re["columnComment"]),
|
ColumnComment: anyx.ConvString(re["columnComment"]),
|
||||||
Nullable: utils.Any2String(re["nullable"]),
|
Nullable: anyx.ConvString(re["nullable"]),
|
||||||
ColumnKey: utils.Any2String(re["columnKey"]),
|
ColumnKey: anyx.ConvString(re["columnKey"]),
|
||||||
ColumnDefault: utils.Any2String(re["columnDefault"]),
|
ColumnDefault: anyx.ConvString(re["columnDefault"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return columns
|
return columns
|
||||||
@@ -106,11 +106,11 @@ func (mm *MysqlMetadata) GetTableInfos() []Table {
|
|||||||
for _, re := range res {
|
for _, re := range res {
|
||||||
tables = append(tables, Table{
|
tables = append(tables, Table{
|
||||||
TableName: re["tableName"].(string),
|
TableName: re["tableName"].(string),
|
||||||
TableComment: utils.Any2String(re["tableComment"]),
|
TableComment: anyx.ConvString(re["tableComment"]),
|
||||||
CreateTime: utils.Any2String(re["createTime"]),
|
CreateTime: anyx.ConvString(re["createTime"]),
|
||||||
TableRows: utils.Any2Int(re["tableRows"]),
|
TableRows: anyx.ConvInt(re["tableRows"]),
|
||||||
DataLength: utils.Any2Int64(re["dataLength"]),
|
DataLength: anyx.ConvInt64(re["dataLength"]),
|
||||||
IndexLength: utils.Any2Int64(re["indexLength"]),
|
IndexLength: anyx.ConvInt64(re["indexLength"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return tables
|
return tables
|
||||||
@@ -124,11 +124,11 @@ func (mm *MysqlMetadata) GetTableIndex(tableName string) []Index {
|
|||||||
for _, re := range res {
|
for _, re := range res {
|
||||||
indexs = append(indexs, Index{
|
indexs = append(indexs, Index{
|
||||||
IndexName: re["indexName"].(string),
|
IndexName: re["indexName"].(string),
|
||||||
ColumnName: utils.Any2String(re["columnName"]),
|
ColumnName: anyx.ConvString(re["columnName"]),
|
||||||
IndexType: utils.Any2String(re["indexType"]),
|
IndexType: anyx.ConvString(re["indexType"]),
|
||||||
IndexComment: utils.Any2String(re["indexComment"]),
|
IndexComment: anyx.ConvString(re["indexComment"]),
|
||||||
NonUnique: utils.Any2Int(re["nonUnique"]),
|
NonUnique: anyx.ConvInt(re["nonUnique"]),
|
||||||
SeqInIndex: utils.Any2Int(re["seqInIndex"]),
|
SeqInIndex: anyx.ConvInt(re["seqInIndex"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 把查询结果以索引名分组,索引字段以逗号连接
|
// 把查询结果以索引名分组,索引字段以逗号连接
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import (
|
|||||||
"mayfly-go/internal/db/domain/entity"
|
"mayfly-go/internal/db/domain/entity"
|
||||||
machineapp "mayfly-go/internal/machine/application"
|
machineapp "mayfly-go/internal/machine/application"
|
||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/anyx"
|
||||||
|
"mayfly-go/pkg/utils/collx"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -21,7 +22,7 @@ func getPgsqlDB(d *entity.Db, db string) (*sql.DB, error) {
|
|||||||
if d.SshTunnelMachineId > 0 {
|
if d.SshTunnelMachineId > 0 {
|
||||||
// 如果使用了隧道,则使用`postgres:ssh:隧道机器id`注册名
|
// 如果使用了隧道,则使用`postgres:ssh:隧道机器id`注册名
|
||||||
driverName = fmt.Sprintf("postgres:ssh:%d", d.SshTunnelMachineId)
|
driverName = fmt.Sprintf("postgres:ssh:%d", d.SshTunnelMachineId)
|
||||||
if !utils.ArrContains(sql.Drivers(), driverName) {
|
if !collx.ArrayContains(sql.Drivers(), driverName) {
|
||||||
sql.Register(driverName, &PqSqlDialer{sshTunnelMachineId: d.SshTunnelMachineId})
|
sql.Register(driverName, &PqSqlDialer{sshTunnelMachineId: d.SshTunnelMachineId})
|
||||||
}
|
}
|
||||||
sql.Drivers()
|
sql.Drivers()
|
||||||
@@ -78,7 +79,7 @@ func (pm *PgsqlMetadata) GetTables() []Table {
|
|||||||
for _, re := range res {
|
for _, re := range res {
|
||||||
tables = append(tables, Table{
|
tables = append(tables, Table{
|
||||||
TableName: re["tableName"].(string),
|
TableName: re["tableName"].(string),
|
||||||
TableComment: utils.Any2String(re["tableComment"]),
|
TableComment: anyx.ConvString(re["tableComment"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return tables
|
return tables
|
||||||
@@ -101,11 +102,11 @@ func (pm *PgsqlMetadata) GetColumns(tableNames ...string) []Column {
|
|||||||
columns = append(columns, Column{
|
columns = append(columns, Column{
|
||||||
TableName: re["tableName"].(string),
|
TableName: re["tableName"].(string),
|
||||||
ColumnName: re["columnName"].(string),
|
ColumnName: re["columnName"].(string),
|
||||||
ColumnType: utils.Any2String(re["columnType"]),
|
ColumnType: anyx.ConvString(re["columnType"]),
|
||||||
ColumnComment: utils.Any2String(re["columnComment"]),
|
ColumnComment: anyx.ConvString(re["columnComment"]),
|
||||||
Nullable: utils.Any2String(re["nullable"]),
|
Nullable: anyx.ConvString(re["nullable"]),
|
||||||
ColumnKey: utils.Any2String(re["columnKey"]),
|
ColumnKey: anyx.ConvString(re["columnKey"]),
|
||||||
ColumnDefault: utils.Any2String(re["columnDefault"]),
|
ColumnDefault: anyx.ConvString(re["columnDefault"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return columns
|
return columns
|
||||||
@@ -132,11 +133,11 @@ func (pm *PgsqlMetadata) GetTableInfos() []Table {
|
|||||||
for _, re := range res {
|
for _, re := range res {
|
||||||
tables = append(tables, Table{
|
tables = append(tables, Table{
|
||||||
TableName: re["tableName"].(string),
|
TableName: re["tableName"].(string),
|
||||||
TableComment: utils.Any2String(re["tableComment"]),
|
TableComment: anyx.ConvString(re["tableComment"]),
|
||||||
CreateTime: utils.Any2String(re["createTime"]),
|
CreateTime: anyx.ConvString(re["createTime"]),
|
||||||
TableRows: utils.Any2Int(re["tableRows"]),
|
TableRows: anyx.ConvInt(re["tableRows"]),
|
||||||
DataLength: utils.Any2Int64(re["dataLength"]),
|
DataLength: anyx.ConvInt64(re["dataLength"]),
|
||||||
IndexLength: utils.Any2Int64(re["indexLength"]),
|
IndexLength: anyx.ConvInt64(re["indexLength"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return tables
|
return tables
|
||||||
@@ -150,11 +151,11 @@ func (pm *PgsqlMetadata) GetTableIndex(tableName string) []Index {
|
|||||||
for _, re := range res {
|
for _, re := range res {
|
||||||
indexs = append(indexs, Index{
|
indexs = append(indexs, Index{
|
||||||
IndexName: re["indexName"].(string),
|
IndexName: re["indexName"].(string),
|
||||||
ColumnName: utils.Any2String(re["columnName"]),
|
ColumnName: anyx.ConvString(re["columnName"]),
|
||||||
IndexType: utils.Any2String(re["indexType"]),
|
IndexType: anyx.ConvString(re["indexType"]),
|
||||||
IndexComment: utils.Any2String(re["indexComment"]),
|
IndexComment: anyx.ConvString(re["indexComment"]),
|
||||||
NonUnique: utils.Any2Int(re["nonUnique"]),
|
NonUnique: anyx.ConvInt(re["nonUnique"]),
|
||||||
SeqInIndex: utils.Any2Int(re["seqInIndex"]),
|
SeqInIndex: anyx.ConvInt(re["seqInIndex"]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return indexs
|
return indexs
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ import (
|
|||||||
"mayfly-go/pkg/ginx"
|
"mayfly-go/pkg/ginx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/stringx"
|
||||||
|
"mayfly-go/pkg/utils/structx"
|
||||||
"mayfly-go/pkg/ws"
|
"mayfly-go/pkg/ws"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -82,7 +83,7 @@ func (m *Machine) TestConn(rc *req.Ctx) {
|
|||||||
ginx.BindJsonAndValid(g, machineForm)
|
ginx.BindJsonAndValid(g, machineForm)
|
||||||
|
|
||||||
me := new(entity.Machine)
|
me := new(entity.Machine)
|
||||||
utils.Copy(me, machineForm)
|
structx.Copy(me, machineForm)
|
||||||
|
|
||||||
m.MachineApp.TestConn(me)
|
m.MachineApp.TestConn(me)
|
||||||
}
|
}
|
||||||
@@ -192,7 +193,7 @@ func (m *Machine) WsSSH(g *gin.Context) {
|
|||||||
recorder = machine.NewRecorder(f)
|
recorder = machine.NewRecorder(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
mts, err := machine.NewTerminalSession(utils.RandString(16), wsConn, cli, rows, cols, recorder)
|
mts, err := machine.NewTerminalSession(stringx.Rand(16), wsConn, cli, rows, cols, recorder)
|
||||||
biz.ErrIsNilAppendErr(err, "\033[1;31m连接失败: %s\033[0m")
|
biz.ErrIsNilAppendErr(err, "\033[1;31m连接失败: %s\033[0m")
|
||||||
|
|
||||||
// 记录系统操作日志
|
// 记录系统操作日志
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import (
|
|||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/ginx"
|
"mayfly-go/pkg/ginx"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/jsonx"
|
||||||
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ func (m *MachineScript) RunMachineScript(rc *req.Ctx) {
|
|||||||
script := ms.Script
|
script := ms.Script
|
||||||
// 如果有脚本参数,则用脚本参数替换脚本中的模板占位符参数
|
// 如果有脚本参数,则用脚本参数替换脚本中的模板占位符参数
|
||||||
if params := g.Query("params"); params != "" {
|
if params := g.Query("params"); params != "" {
|
||||||
script = utils.TemplateParse(ms.Script, utils.Json2Map(params))
|
script = stringx.TemplateParse(ms.Script, jsonx.ToMap(params))
|
||||||
}
|
}
|
||||||
cli := m.MachineApp.GetCli(machineId)
|
cli := m.MachineApp.GetCli(machineId)
|
||||||
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.GetMachine().TagPath), "%s")
|
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.GetMachine().TagPath), "%s")
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import (
|
|||||||
"mayfly-go/internal/machine/domain/repository"
|
"mayfly-go/internal/machine/domain/repository"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
|
"mayfly-go/pkg/rediscli"
|
||||||
"mayfly-go/pkg/scheduler"
|
"mayfly-go/pkg/scheduler"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/collx"
|
||||||
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -107,7 +109,7 @@ func (m *machineCropJobAppImpl) GetRelateCronJobIds(machineId uint64) []uint64 {
|
|||||||
|
|
||||||
func (m *machineCropJobAppImpl) CronJobRelateMachines(cronJobId uint64, machineIds []uint64, la *model.LoginAccount) {
|
func (m *machineCropJobAppImpl) CronJobRelateMachines(cronJobId uint64, machineIds []uint64, la *model.LoginAccount) {
|
||||||
oldMachineIds := m.machineCropJobRelateRepo.GetMachineIds(cronJobId)
|
oldMachineIds := m.machineCropJobRelateRepo.GetMachineIds(cronJobId)
|
||||||
addIds, delIds, _ := utils.ArrayCompare[uint64](machineIds, oldMachineIds, func(u1, u2 uint64) bool { return u1 == u2 })
|
addIds, delIds, _ := collx.ArrayCompare[uint64](machineIds, oldMachineIds, func(u1, u2 uint64) bool { return u1 == u2 })
|
||||||
addVals := make([]*entity.MachineCronJobRelate, 0)
|
addVals := make([]*entity.MachineCronJobRelate, 0)
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@@ -129,7 +131,7 @@ func (m *machineCropJobAppImpl) CronJobRelateMachines(cronJobId uint64, machineI
|
|||||||
|
|
||||||
func (m *machineCropJobAppImpl) MachineRelateCronJobs(machineId uint64, cronJobs []uint64, la *model.LoginAccount) {
|
func (m *machineCropJobAppImpl) MachineRelateCronJobs(machineId uint64, cronJobs []uint64, la *model.LoginAccount) {
|
||||||
oldCronIds := m.machineCropJobRelateRepo.GetCronJobIds(machineId)
|
oldCronIds := m.machineCropJobRelateRepo.GetCronJobIds(machineId)
|
||||||
addIds, delIds, _ := utils.ArrayCompare[uint64](cronJobs, oldCronIds, func(u1, u2 uint64) bool { return u1 == u2 })
|
addIds, delIds, _ := collx.ArrayCompare[uint64](cronJobs, oldCronIds, func(u1, u2 uint64) bool { return u1 == u2 })
|
||||||
addVals := make([]*entity.MachineCronJobRelate, 0)
|
addVals := make([]*entity.MachineCronJobRelate, 0)
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@@ -186,7 +188,7 @@ func (m *machineCropJobAppImpl) addCronJob(mcj *entity.MachineCronJob) {
|
|||||||
var key string
|
var key string
|
||||||
isDisable := mcj.Status == entity.MachineCronJobStatusDisable
|
isDisable := mcj.Status == entity.MachineCronJobStatusDisable
|
||||||
if mcj.Id == 0 {
|
if mcj.Id == 0 {
|
||||||
key = utils.RandString(16)
|
key = stringx.Rand(16)
|
||||||
mcj.Key = key
|
mcj.Key = key
|
||||||
if isDisable {
|
if isDisable {
|
||||||
return
|
return
|
||||||
@@ -201,11 +203,19 @@ func (m *machineCropJobAppImpl) addCronJob(mcj *entity.MachineCronJob) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scheduler.AddFunByKey(key, mcj.Cron, func() {
|
scheduler.AddFunByKey(key, mcj.Cron, func() {
|
||||||
m.runCronJob(key)
|
go m.runCronJob(key)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *machineCropJobAppImpl) runCronJob(key string) {
|
func (m *machineCropJobAppImpl) runCronJob(key string) {
|
||||||
|
// 简单使用redis分布式锁防止多实例同一时刻重复执行
|
||||||
|
if lock := rediscli.NewLock(key, 30*time.Second); lock != nil {
|
||||||
|
if !lock.Lock() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer lock.UnLock()
|
||||||
|
}
|
||||||
|
|
||||||
cronJob := new(entity.MachineCronJob)
|
cronJob := new(entity.MachineCronJob)
|
||||||
cronJob.Key = key
|
cronJob.Key = key
|
||||||
err := m.machineCropJobRepo.GetBy(cronJob)
|
err := m.machineCropJobRepo.GetBy(cronJob)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package machine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -69,7 +69,7 @@ func TestTemplateRev(t *testing.T) {
|
|||||||
//key := temp[index+1 : ei-1]
|
//key := temp[index+1 : ei-1]
|
||||||
//value := SubString(str, index, UnicodeIndex(str, next))
|
//value := SubString(str, index, UnicodeIndex(str, next))
|
||||||
res := make(map[string]any)
|
res := make(map[string]any)
|
||||||
utils.ReverStrTemplate(temp, str, res)
|
stringx.ReverStrTemplate(temp, str, res)
|
||||||
fmt.Println(res)
|
fmt.Println(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/scheduler"
|
"mayfly-go/pkg/scheduler"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/netx"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -75,7 +75,7 @@ func (stm *SshTunnelMachine) OpenSshTunnel(id uint64, ip string, port int) (expo
|
|||||||
stm.mutex.Lock()
|
stm.mutex.Lock()
|
||||||
defer stm.mutex.Unlock()
|
defer stm.mutex.Unlock()
|
||||||
|
|
||||||
localPort, err := utils.GetAvailablePort()
|
localPort, err := netx.GetAvailablePort()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/gormx"
|
"mayfly-go/pkg/gormx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/collx"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -29,7 +29,7 @@ func (m *machineRepoImpl) GetMachineList(condition *entity.MachineQuery, pagePar
|
|||||||
|
|
||||||
if condition.Ids != "" {
|
if condition.Ids != "" {
|
||||||
// ,分割id转为id数组
|
// ,分割id转为id数组
|
||||||
qd.In("id", utils.ArrayMap[string, uint64](strings.Split(condition.Ids, ","), func(val string) uint64 {
|
qd.In("id", collx.ArrayMap[string, uint64](strings.Split(condition.Ids, ","), func(val string) uint64 {
|
||||||
id, _ := strconv.Atoi(val)
|
id, _ := strconv.Atoi(val)
|
||||||
return uint64(id)
|
return uint64(id)
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import (
|
|||||||
"mayfly-go/pkg/cache"
|
"mayfly-go/pkg/cache"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/netx"
|
||||||
|
"mayfly-go/pkg/utils/structx"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
@@ -201,7 +202,7 @@ func connect(me *entity.Mongo) (*MongoInstance, error) {
|
|||||||
|
|
||||||
func toMongiInfo(me *entity.Mongo) *MongoInfo {
|
func toMongiInfo(me *entity.Mongo) *MongoInfo {
|
||||||
mi := new(MongoInfo)
|
mi := new(MongoInfo)
|
||||||
utils.Copy(mi, me)
|
structx.Copy(mi, me)
|
||||||
return mi
|
return mi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +213,7 @@ type MongoSshDialer struct {
|
|||||||
func (sd *MongoSshDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
func (sd *MongoSshDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
if sshConn, err := machineapp.GetMachineApp().GetSshTunnelMachine(sd.machineId).GetDialConn(network, address); err == nil {
|
if sshConn, err := machineapp.GetMachineApp().GetSshTunnelMachine(sd.machineId).GetDialConn(network, address); err == nil {
|
||||||
// 将ssh conn包装,否则内部部设置超时会报错,ssh conn不支持设置超时会返回错误: ssh: tcpChan: deadline not supported
|
// 将ssh conn包装,否则内部部设置超时会报错,ssh conn不支持设置超时会返回错误: ssh: tcpChan: deadline not supported
|
||||||
return &utils.WrapSshConn{Conn: sshConn}, nil
|
return &netx.WrapSshConn{Conn: sshConn}, nil
|
||||||
} else {
|
} else {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import (
|
|||||||
"mayfly-go/pkg/ginx"
|
"mayfly-go/pkg/ginx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/cryptox"
|
||||||
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ func (r *Redis) Save(rc *req.Ctx) {
|
|||||||
redis := ginx.BindJsonAndCopyTo[*entity.Redis](rc.GinCtx, form, new(entity.Redis))
|
redis := ginx.BindJsonAndCopyTo[*entity.Redis](rc.GinCtx, form, new(entity.Redis))
|
||||||
|
|
||||||
// 密码解密,并使用解密后的赋值
|
// 密码解密,并使用解密后的赋值
|
||||||
originPwd, err := utils.DefaultRsaDecrypt(redis.Password, true)
|
originPwd, err := cryptox.DefaultRsaDecrypt(redis.Password, true)
|
||||||
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
||||||
redis.Password = originPwd
|
redis.Password = originPwd
|
||||||
|
|
||||||
@@ -133,7 +134,7 @@ func (r *Redis) RedisInfo(rc *req.Ctx) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if strings.Contains(datas[i], "#") {
|
if strings.Contains(datas[i], "#") {
|
||||||
key := utils.SubString(datas[i], strings.Index(datas[i], "#")+1, utils.StrLen(datas[i]))
|
key := stringx.SubString(datas[i], strings.Index(datas[i], "#")+1, stringx.Len(datas[i]))
|
||||||
i++
|
i++
|
||||||
key = strings.Trim(key, " ")
|
key = strings.Trim(key, " ")
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/ginx"
|
"mayfly-go/pkg/ginx"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ func (r *Redis) SetStringValue(rc *req.Ctx) {
|
|||||||
|
|
||||||
ri := r.getRedisIns(rc)
|
ri := r.getRedisIns(rc)
|
||||||
cmd := ri.GetCmdable()
|
cmd := ri.GetCmdable()
|
||||||
rc.ReqParam = fmt.Sprintf("%s -> %s", ri.Info.GetLogDesc(), utils.ToString(keyValue))
|
rc.ReqParam = fmt.Sprintf("%s -> %s", ri.Info.GetLogDesc(), stringx.AnyToStr(keyValue))
|
||||||
|
|
||||||
str, err := cmd.Set(context.TODO(), keyValue.Key, keyValue.Value, time.Second*time.Duration(keyValue.Timed)).Result()
|
str, err := cmd.Set(context.TODO(), keyValue.Key, keyValue.Value, time.Second*time.Duration(keyValue.Timed)).Result()
|
||||||
biz.ErrIsNilAppendErr(err, "保存字符串值失败: %s")
|
biz.ErrIsNilAppendErr(err, "保存字符串值失败: %s")
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import (
|
|||||||
"mayfly-go/pkg/cache"
|
"mayfly-go/pkg/cache"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/netx"
|
||||||
|
"mayfly-go/pkg/utils/structx"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -176,7 +177,7 @@ func getRedisCacheKey(id uint64, db int) string {
|
|||||||
|
|
||||||
func toRedisInfo(re *entity.Redis, db int) *RedisInfo {
|
func toRedisInfo(re *entity.Redis, db int) *RedisInfo {
|
||||||
redisInfo := new(RedisInfo)
|
redisInfo := new(RedisInfo)
|
||||||
utils.Copy(redisInfo, re)
|
structx.Copy(redisInfo, re)
|
||||||
redisInfo.Db = db
|
redisInfo.Db = db
|
||||||
return redisInfo
|
return redisInfo
|
||||||
}
|
}
|
||||||
@@ -243,7 +244,7 @@ func getRedisDialer(machineId int) func(ctx context.Context, network, addr strin
|
|||||||
return func(_ context.Context, network, addr string) (net.Conn, error) {
|
return func(_ context.Context, network, addr string) (net.Conn, error) {
|
||||||
if sshConn, err := sshTunnel.GetDialConn(network, addr); err == nil {
|
if sshConn, err := sshTunnel.GetDialConn(network, addr); err == nil {
|
||||||
// 将ssh conn包装,否则redis内部设置超时会报错,ssh conn不支持设置超时会返回错误: ssh: tcpChan: deadline not supported
|
// 将ssh conn包装,否则redis内部设置超时会报错,ssh conn不支持设置超时会返回错误: ssh: tcpChan: deadline not supported
|
||||||
return &utils.WrapSshConn{Conn: sshConn}, nil
|
return &netx.WrapSshConn{Conn: sshConn}, nil
|
||||||
} else {
|
} else {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ import (
|
|||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/otp"
|
"mayfly-go/pkg/otp"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/collx"
|
||||||
|
"mayfly-go/pkg/utils/cryptox"
|
||||||
|
"mayfly-go/pkg/utils/jsonx"
|
||||||
|
"mayfly-go/pkg/utils/netx"
|
||||||
|
"mayfly-go/pkg/utils/stringx"
|
||||||
|
"mayfly-go/pkg/utils/timex"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -55,7 +60,7 @@ func (a *Account) Login(rc *req.Ctx) {
|
|||||||
clientIp := getIpAndRegion(rc)
|
clientIp := getIpAndRegion(rc)
|
||||||
rc.ReqParam = fmt.Sprintf("username: %s | ip: %s", username, clientIp)
|
rc.ReqParam = fmt.Sprintf("username: %s | ip: %s", username, clientIp)
|
||||||
|
|
||||||
originPwd, err := utils.DefaultRsaDecrypt(loginForm.Password, true)
|
originPwd, err := cryptox.DefaultRsaDecrypt(loginForm.Password, true)
|
||||||
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
||||||
|
|
||||||
account := &entity.Account{Username: username}
|
account := &entity.Account{Username: username}
|
||||||
@@ -67,7 +72,7 @@ func (a *Account) Login(rc *req.Ctx) {
|
|||||||
loginFailMin := accountLoginSecurity.LoginFailMin
|
loginFailMin := accountLoginSecurity.LoginFailMin
|
||||||
biz.IsTrue(nowFailCount < loginFailCount, "登录失败超过%d次, 请%d分钟后再试", loginFailCount, loginFailMin)
|
biz.IsTrue(nowFailCount < loginFailCount, "登录失败超过%d次, 请%d分钟后再试", loginFailCount, loginFailMin)
|
||||||
|
|
||||||
if err != nil || !utils.CheckPwdHash(originPwd, account.Password) {
|
if err != nil || !cryptox.CheckPwdHash(originPwd, account.Password) {
|
||||||
nowFailCount++
|
nowFailCount++
|
||||||
cache.SetStr(failCountKey, strconv.Itoa(nowFailCount), time.Minute*time.Duration(loginFailMin))
|
cache.SetStr(failCountKey, strconv.Itoa(nowFailCount), time.Minute*time.Duration(loginFailMin))
|
||||||
panic(biz.NewBizErr(fmt.Sprintf("用户名或密码错误【当前登录失败%d次】", nowFailCount)))
|
panic(biz.NewBizErr(fmt.Sprintf("用户名或密码错误【当前登录失败%d次】", nowFailCount)))
|
||||||
@@ -96,7 +101,7 @@ func (a *Account) Login(rc *req.Ctx) {
|
|||||||
// 修改状态为已注册
|
// 修改状态为已注册
|
||||||
otpStatus = OtpStatusReg
|
otpStatus = OtpStatusReg
|
||||||
// 该token用于otp双因素校验
|
// 该token用于otp双因素校验
|
||||||
token = utils.RandString(32)
|
token = stringx.Rand(32)
|
||||||
// 未注册otp secret或重置了秘钥
|
// 未注册otp secret或重置了秘钥
|
||||||
if otpSecret == "" || otpSecret == "-" {
|
if otpSecret == "" || otpSecret == "-" {
|
||||||
otpStatus = OtpStatusNoReg
|
otpStatus = OtpStatusNoReg
|
||||||
@@ -116,7 +121,7 @@ func (a *Account) Login(rc *req.Ctx) {
|
|||||||
OtpSecret: otpSecret,
|
OtpSecret: otpSecret,
|
||||||
AccessToken: accessToken,
|
AccessToken: accessToken,
|
||||||
}
|
}
|
||||||
cache.SetStr(fmt.Sprintf("otp:token:%s", token), utils.ToJsonStr(otpInfo), time.Minute*time.Duration(3))
|
cache.SetStr(fmt.Sprintf("otp:token:%s", token), jsonx.ToStr(otpInfo), time.Minute*time.Duration(3))
|
||||||
} else {
|
} else {
|
||||||
// 不进行otp二次校验则直接返回accessToken
|
// 不进行otp二次校验则直接返回accessToken
|
||||||
token = accessToken
|
token = accessToken
|
||||||
@@ -133,7 +138,7 @@ func (a *Account) Login(rc *req.Ctx) {
|
|||||||
// 获取ip与归属地信息
|
// 获取ip与归属地信息
|
||||||
func getIpAndRegion(rc *req.Ctx) string {
|
func getIpAndRegion(rc *req.Ctx) string {
|
||||||
clientIp := rc.GinCtx.ClientIP()
|
clientIp := rc.GinCtx.ClientIP()
|
||||||
return fmt.Sprintf("%s %s", clientIp, utils.Ip2Region(clientIp))
|
return fmt.Sprintf("%s %s", clientIp, netx.Ip2Region(clientIp))
|
||||||
}
|
}
|
||||||
|
|
||||||
type OtpVerifyInfo struct {
|
type OtpVerifyInfo struct {
|
||||||
@@ -214,22 +219,22 @@ func (a *Account) ChangePassword(rc *req.Ctx) {
|
|||||||
form := new(form.AccountChangePasswordForm)
|
form := new(form.AccountChangePasswordForm)
|
||||||
ginx.BindJsonAndValid(rc.GinCtx, form)
|
ginx.BindJsonAndValid(rc.GinCtx, form)
|
||||||
|
|
||||||
originOldPwd, err := utils.DefaultRsaDecrypt(form.OldPassword, true)
|
originOldPwd, err := cryptox.DefaultRsaDecrypt(form.OldPassword, true)
|
||||||
biz.ErrIsNilAppendErr(err, "解密旧密码错误: %s")
|
biz.ErrIsNilAppendErr(err, "解密旧密码错误: %s")
|
||||||
|
|
||||||
account := &entity.Account{Username: form.Username}
|
account := &entity.Account{Username: form.Username}
|
||||||
err = a.AccountApp.GetAccount(account, "Id", "Username", "Password", "Status")
|
err = a.AccountApp.GetAccount(account, "Id", "Username", "Password", "Status")
|
||||||
biz.ErrIsNil(err, "旧密码错误")
|
biz.ErrIsNil(err, "旧密码错误")
|
||||||
biz.IsTrue(utils.CheckPwdHash(originOldPwd, account.Password), "旧密码错误")
|
biz.IsTrue(cryptox.CheckPwdHash(originOldPwd, account.Password), "旧密码错误")
|
||||||
biz.IsTrue(account.IsEnable(), "该账号不可用")
|
biz.IsTrue(account.IsEnable(), "该账号不可用")
|
||||||
|
|
||||||
originNewPwd, err := utils.DefaultRsaDecrypt(form.NewPassword, true)
|
originNewPwd, err := cryptox.DefaultRsaDecrypt(form.NewPassword, true)
|
||||||
biz.ErrIsNilAppendErr(err, "解密新密码错误: %s")
|
biz.ErrIsNilAppendErr(err, "解密新密码错误: %s")
|
||||||
biz.IsTrue(CheckPasswordLever(originNewPwd), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
|
biz.IsTrue(CheckPasswordLever(originNewPwd), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
|
||||||
|
|
||||||
updateAccount := new(entity.Account)
|
updateAccount := new(entity.Account)
|
||||||
updateAccount.Id = account.Id
|
updateAccount.Id = account.Id
|
||||||
updateAccount.Password = utils.PwdHash(originNewPwd)
|
updateAccount.Password = cryptox.PwdHash(originNewPwd)
|
||||||
a.AccountApp.Update(updateAccount)
|
a.AccountApp.Update(updateAccount)
|
||||||
|
|
||||||
// 赋值loginAccount 主要用于记录操作日志,因为操作日志保存请求上下文没有该信息不保存日志
|
// 赋值loginAccount 主要用于记录操作日志,因为操作日志保存请求上下文没有该信息不保存日志
|
||||||
@@ -267,7 +272,7 @@ func (a *Account) saveLogin(account *entity.Account, ip string) {
|
|||||||
// 创建登录消息
|
// 创建登录消息
|
||||||
loginMsg := &msgentity.Msg{
|
loginMsg := &msgentity.Msg{
|
||||||
RecipientId: int64(account.Id),
|
RecipientId: int64(account.Id),
|
||||||
Msg: fmt.Sprintf("于[%s]-[%s]登录", ip, utils.DefaultTimeFormat(now)),
|
Msg: fmt.Sprintf("于[%s]-[%s]登录", ip, timex.DefaultFormat(now)),
|
||||||
Type: 1,
|
Type: 1,
|
||||||
}
|
}
|
||||||
loginMsg.CreateTime = &now
|
loginMsg.CreateTime = &now
|
||||||
@@ -295,7 +300,7 @@ func (a *Account) UpdateAccount(rc *req.Ctx) {
|
|||||||
|
|
||||||
if updateAccount.Password != "" {
|
if updateAccount.Password != "" {
|
||||||
biz.IsTrue(CheckPasswordLever(updateAccount.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
|
biz.IsTrue(CheckPasswordLever(updateAccount.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
|
||||||
updateAccount.Password = utils.PwdHash(updateAccount.Password)
|
updateAccount.Password = cryptox.PwdHash(updateAccount.Password)
|
||||||
}
|
}
|
||||||
a.AccountApp.Update(updateAccount)
|
a.AccountApp.Update(updateAccount)
|
||||||
}
|
}
|
||||||
@@ -323,7 +328,7 @@ func (a *Account) SaveAccount(rc *req.Ctx) {
|
|||||||
} else {
|
} else {
|
||||||
if account.Password != "" {
|
if account.Password != "" {
|
||||||
biz.IsTrue(CheckPasswordLever(account.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
|
biz.IsTrue(CheckPasswordLever(account.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
|
||||||
account.Password = utils.PwdHash(account.Password)
|
account.Password = cryptox.PwdHash(account.Password)
|
||||||
}
|
}
|
||||||
a.AccountApp.Update(account)
|
a.AccountApp.Update(account)
|
||||||
}
|
}
|
||||||
@@ -380,14 +385,14 @@ func (a *Account) SaveRoles(rc *req.Ctx) {
|
|||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
// 将,拼接的字符串进行切割并转换
|
// 将,拼接的字符串进行切割并转换
|
||||||
newIds := utils.ArrayMap[string, uint64](strings.Split(form.RoleIds, ","), func(val string) uint64 {
|
newIds := collx.ArrayMap[string, uint64](strings.Split(form.RoleIds, ","), func(val string) uint64 {
|
||||||
id, _ := strconv.Atoi(val)
|
id, _ := strconv.Atoi(val)
|
||||||
return uint64(id)
|
return uint64(id)
|
||||||
})
|
})
|
||||||
|
|
||||||
oIds := a.RoleApp.GetAccountRoleIds(uint64(form.Id))
|
oIds := a.RoleApp.GetAccountRoleIds(uint64(form.Id))
|
||||||
|
|
||||||
addIds, delIds, _ := utils.ArrayCompare(newIds, oIds, func(i1, i2 uint64) bool {
|
addIds, delIds, _ := collx.ArrayCompare(newIds, oIds, func(i1, i2 uint64) bool {
|
||||||
return i1 == i2
|
return i1 == i2
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"mayfly-go/pkg/ginx"
|
"mayfly-go/pkg/ginx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/collx"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -72,14 +72,14 @@ func (r *Role) SaveResource(rc *req.Ctx) {
|
|||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
// 将,拼接的字符串进行切割并转换
|
// 将,拼接的字符串进行切割并转换
|
||||||
newIds := utils.ArrayMap[string, uint64](strings.Split(form.ResourceIds, ","), func(val string) uint64 {
|
newIds := collx.ArrayMap[string, uint64](strings.Split(form.ResourceIds, ","), func(val string) uint64 {
|
||||||
id, _ := strconv.Atoi(val)
|
id, _ := strconv.Atoi(val)
|
||||||
return uint64(id)
|
return uint64(id)
|
||||||
})
|
})
|
||||||
|
|
||||||
oIds := r.RoleApp.GetRoleResourceIds(uint64(form.Id))
|
oIds := r.RoleApp.GetRoleResourceIds(uint64(form.Id))
|
||||||
|
|
||||||
addIds, delIds, _ := utils.ArrayCompare(newIds, oIds, func(i1, i2 uint64) bool {
|
addIds, delIds, _ := collx.ArrayCompare(newIds, oIds, func(i1, i2 uint64) bool {
|
||||||
return i1 == i2
|
return i1 == i2
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/gormx"
|
"mayfly-go/pkg/gormx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/cryptox"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
@@ -45,7 +45,7 @@ func (a *accountAppImpl) GetPageList(condition *entity.Account, pageParam *model
|
|||||||
func (a *accountAppImpl) Create(account *entity.Account) {
|
func (a *accountAppImpl) Create(account *entity.Account) {
|
||||||
biz.IsTrue(a.GetAccount(&entity.Account{Username: account.Username}) != nil, "该账号用户名已存在")
|
biz.IsTrue(a.GetAccount(&entity.Account{Username: account.Username}) != nil, "该账号用户名已存在")
|
||||||
// 默认密码为账号用户名
|
// 默认密码为账号用户名
|
||||||
account.Password = utils.PwdHash(account.Username)
|
account.Password = cryptox.PwdHash(account.Username)
|
||||||
account.Status = entity.AccountEnableStatus
|
account.Status = entity.AccountEnableStatus
|
||||||
a.accountRepo.Insert(account)
|
a.accountRepo.Insert(account)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"mayfly-go/pkg/cache"
|
"mayfly-go/pkg/cache"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/jsonx"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SysConfigKeyPrefix = "sys:config:"
|
const SysConfigKeyPrefix = "sys:config:"
|
||||||
@@ -56,7 +56,7 @@ func (a *configAppImpl) GetConfig(key string) *entity.Config {
|
|||||||
if err := a.configRepo.GetConfig(config, "Id", "Key", "Value"); err != nil {
|
if err := a.configRepo.GetConfig(config, "Id", "Key", "Value"); err != nil {
|
||||||
global.Log.Warnf("不存在key = [%s] 的系统配置", key)
|
global.Log.Warnf("不存在key = [%s] 的系统配置", key)
|
||||||
} else {
|
} else {
|
||||||
cache.SetStr(SysConfigKeyPrefix+key, utils.ToJsonStr(config), -1)
|
cache.SetStr(SysConfigKeyPrefix+key, jsonx.ToStr(config), -1)
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"mayfly-go/internal/sys/domain/repository"
|
"mayfly-go/internal/sys/domain/repository"
|
||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/gormx"
|
"mayfly-go/pkg/gormx"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -59,7 +59,7 @@ func (r *resourceAppImpl) Save(resource *entity.Resource) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 生成随机八位唯一标识符
|
// 生成随机八位唯一标识符
|
||||||
ui := utils.RandString(8)
|
ui := stringx.Rand(8)
|
||||||
if pid := resource.Pid; pid != 0 {
|
if pid := resource.Pid; pid != 0 {
|
||||||
pResource := r.GetById(uint64(pid))
|
pResource := r.GetById(uint64(pid))
|
||||||
biz.IsTrue(pResource != nil, "该父资源不存在")
|
biz.IsTrue(pResource != nil, "该父资源不存在")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/anyx"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reqParam := req.ReqParam
|
reqParam := req.ReqParam
|
||||||
if !utils.IsBlank(reqParam) {
|
if !anyx.IsBlank(reqParam) {
|
||||||
// 如果是字符串类型,则不使用json序列化
|
// 如果是字符串类型,则不使用json序列化
|
||||||
if reqStr, ok := reqParam.(string); ok {
|
if reqStr, ok := reqParam.(string); ok {
|
||||||
syslog.ReqParam = reqStr
|
syslog.ReqParam = reqStr
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/ginx"
|
"mayfly-go/pkg/ginx"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/collx"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -125,7 +125,7 @@ func (p *Team) SaveTags(rc *req.Ctx) {
|
|||||||
oIds := p.TeamApp.ListTagIds(teamId)
|
oIds := p.TeamApp.ListTagIds(teamId)
|
||||||
|
|
||||||
// 比较新旧两合集
|
// 比较新旧两合集
|
||||||
addIds, delIds, _ := utils.ArrayCompare(form.TagIds, oIds, func(i1, i2 uint64) bool {
|
addIds, delIds, _ := collx.ArrayCompare(form.TagIds, oIds, func(i1, i2 uint64) bool {
|
||||||
return i1 == i2
|
return i1 == i2
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ CREATE TABLE `t_machine_cron_job` (
|
|||||||
`modifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
`modifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||||
`create_time` datetime DEFAULT NULL,
|
`create_time` datetime DEFAULT NULL,
|
||||||
`update_time` datetime DEFAULT NULL,
|
`update_time` datetime DEFAULT NULL,
|
||||||
`is_deleted` tinyint NOT NULL DEFAULT '-1',
|
`is_deleted` tinyint NOT NULL DEFAULT 0,
|
||||||
`delete_time` datetime DEFAULT NULL,
|
`delete_time` datetime DEFAULT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='机器计划任务';
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='机器计划任务';
|
||||||
@@ -266,7 +266,7 @@ CREATE TABLE `t_machine_cron_job_exec` (
|
|||||||
`status` tinyint DEFAULT NULL COMMENT '状态',
|
`status` tinyint DEFAULT NULL COMMENT '状态',
|
||||||
`res` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '执行结果',
|
`res` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '执行结果',
|
||||||
`exec_time` datetime DEFAULT NULL COMMENT '执行时间',
|
`exec_time` datetime DEFAULT NULL COMMENT '执行时间',
|
||||||
`is_deleted` tinyint NOT NULL DEFAULT '-1',
|
`is_deleted` tinyint NOT NULL DEFAULT 0,
|
||||||
`delete_time` datetime DEFAULT NULL,
|
`delete_time` datetime DEFAULT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='机器计划任务执行记录';
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='机器计划任务执行记录';
|
||||||
@@ -279,7 +279,7 @@ CREATE TABLE `t_machine_cron_job_relate` (
|
|||||||
`creator_id` bigint DEFAULT NULL,
|
`creator_id` bigint DEFAULT NULL,
|
||||||
`creator` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
`creator` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||||
`create_time` datetime DEFAULT NULL,
|
`create_time` datetime DEFAULT NULL,
|
||||||
`is_deleted` tinyint NOT NULL DEFAULT '-1',
|
`is_deleted` tinyint NOT NULL DEFAULT 0,
|
||||||
`delete_time` datetime DEFAULT NULL,
|
`delete_time` datetime DEFAULT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='机器计划任务关联表';
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='机器计划任务关联表';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package biz
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/anyx"
|
||||||
|
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
@@ -56,7 +56,7 @@ func NotNil(data any, msg string, params ...any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NotBlank(data any, msg string, params ...any) {
|
func NotBlank(data any, msg string, params ...any) {
|
||||||
if utils.IsBlank(data) {
|
if anyx.IsBlank(data) {
|
||||||
panic(NewBizErr(fmt.Sprintf(msg, params...)))
|
panic(NewBizErr(fmt.Sprintf(msg, params...)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"mayfly-go/pkg/utils"
|
|
||||||
"mayfly-go/pkg/utils/assert"
|
"mayfly-go/pkg/utils/assert"
|
||||||
|
"mayfly-go/pkg/utils/cryptox"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Aes struct {
|
type Aes struct {
|
||||||
@@ -12,12 +12,12 @@ type Aes struct {
|
|||||||
|
|
||||||
// 编码并base64
|
// 编码并base64
|
||||||
func (a *Aes) EncryptBase64(data []byte) (string, error) {
|
func (a *Aes) EncryptBase64(data []byte) (string, error) {
|
||||||
return utils.AesEncryptBase64(data, []byte(a.Key))
|
return cryptox.AesEncryptBase64(data, []byte(a.Key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// base64解码后再aes解码
|
// base64解码后再aes解码
|
||||||
func (a *Aes) DecryptBase64(data string) ([]byte, error) {
|
func (a *Aes) DecryptBase64(data string) ([]byte, error) {
|
||||||
return utils.AesDecryptBase64(data, []byte(a.Key))
|
return cryptox.AesDecryptBase64(data, []byte(a.Key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Aes) Valid() {
|
func (j *Aes) Valid() {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package config
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"mayfly-go/pkg/utils"
|
|
||||||
"mayfly-go/pkg/utils/assert"
|
"mayfly-go/pkg/utils/assert"
|
||||||
|
"mayfly-go/pkg/utils/ymlx"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
@@ -20,7 +20,7 @@ func Init() {
|
|||||||
startConfigParam := &CmdConfigParam{ConfigFilePath: path}
|
startConfigParam := &CmdConfigParam{ConfigFilePath: path}
|
||||||
// 读取配置文件信息
|
// 读取配置文件信息
|
||||||
yc := &Config{}
|
yc := &Config{}
|
||||||
if err := utils.LoadYml(startConfigParam.ConfigFilePath, yc); err != nil {
|
if err := ymlx.LoadYml(startConfigParam.ConfigFilePath, yc); err != nil {
|
||||||
panic(fmt.Sprintf("读取配置文件[%s]失败: %s", startConfigParam.ConfigFilePath, err.Error()))
|
panic(fmt.Sprintf("读取配置文件[%s]失败: %s", startConfigParam.ConfigFilePath, err.Error()))
|
||||||
}
|
}
|
||||||
// 校验配置文件内容信息
|
// 校验配置文件内容信息
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/structx"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -25,7 +25,7 @@ func BindJsonAndValid[T any](g *gin.Context, data T) T {
|
|||||||
// 绑定请求体中的json至form结构体,并拷贝至另一结构体
|
// 绑定请求体中的json至form结构体,并拷贝至另一结构体
|
||||||
func BindJsonAndCopyTo[T any](g *gin.Context, form any, toStruct T) T {
|
func BindJsonAndCopyTo[T any](g *gin.Context, form any, toStruct T) T {
|
||||||
BindJsonAndValid(g, form)
|
BindJsonAndValid(g, form)
|
||||||
utils.Copy(toStruct, form)
|
structx.Copy(toStruct, form)
|
||||||
return toStruct
|
return toStruct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"mayfly-go/pkg/consts"
|
"mayfly-go/pkg/consts"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/anyx"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -159,7 +159,7 @@ func (q *QueryCond) Le(column string, val any) *QueryCond {
|
|||||||
|
|
||||||
func (q *QueryCond) Cond(cond, column string, val any, skipBlank bool) *QueryCond {
|
func (q *QueryCond) Cond(cond, column string, val any, skipBlank bool) *QueryCond {
|
||||||
// 零值跳过
|
// 零值跳过
|
||||||
if skipBlank && utils.IsBlank(val) {
|
if skipBlank && anyx.IsBlank(val) {
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
q.columns = append(q.columns, fmt.Sprintf("%s %s ?", column, cond))
|
q.columns = append(q.columns, fmt.Sprintf("%s %s ?", column, cond))
|
||||||
|
|||||||
96
server/pkg/rediscli/lock.go
Normal file
96
server/pkg/rediscli/lock.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package rediscli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"mayfly-go/pkg/global"
|
||||||
|
"mayfly-go/pkg/utils/stringx"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
)
|
||||||
|
|
||||||
|
const LockKeyPrefix = "mayfly:lock:"
|
||||||
|
|
||||||
|
// RedisLock redis实现的分布式锁
|
||||||
|
type RedisLock struct {
|
||||||
|
key string
|
||||||
|
value string // 唯一标识,一般使用uuid
|
||||||
|
expiration time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLock(key string, expiration time.Duration) *RedisLock {
|
||||||
|
if key == "" || cli == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &RedisLock{
|
||||||
|
key: key,
|
||||||
|
value: stringx.Rand(32),
|
||||||
|
expiration: expiration,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock 添加分布式锁,expiration过期时间,小于等于0,不过期,需要通过 UnLock方法释放锁
|
||||||
|
func (rl *RedisLock) Lock() bool {
|
||||||
|
result, err := cli.SetNX(context.Background(), LockKeyPrefix+rl.key, rl.value, rl.expiration).Result()
|
||||||
|
if err != nil {
|
||||||
|
global.Log.Errorf("redis lock setNx fail: %s", err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// TryLock 加锁重试五次
|
||||||
|
func (rl *RedisLock) TryLock() bool {
|
||||||
|
var locked bool
|
||||||
|
for index := 0; index < 5; index++ {
|
||||||
|
locked = rl.Lock()
|
||||||
|
if locked {
|
||||||
|
return locked
|
||||||
|
}
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
return locked
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rl *RedisLock) UnLock() bool {
|
||||||
|
script := redis.NewScript(`
|
||||||
|
if redis.call("get", KEYS[1]) == ARGV[1] then
|
||||||
|
return redis.call("del", KEYS[1])
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
`)
|
||||||
|
|
||||||
|
result, err := script.Run(context.Background(), cli, []string{LockKeyPrefix + rl.key}, rl.value).Int64()
|
||||||
|
if err != nil {
|
||||||
|
global.Log.Errorf("redis unlock runScript fail: %s", err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return result > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// RefreshLock 存在则更新过期时间,不存在则创建key
|
||||||
|
func (rl *RedisLock) RefreshLock() bool {
|
||||||
|
script := redis.NewScript(`
|
||||||
|
local val = redis.call("GET", KEYS[1])
|
||||||
|
if not val then
|
||||||
|
redis.call("setex", KEYS[1], ARGV[2], ARGV[1])
|
||||||
|
return 2
|
||||||
|
elseif val == ARGV[1] then
|
||||||
|
return redis.call("expire", KEYS[1], ARGV[2])
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
`)
|
||||||
|
|
||||||
|
result, err := script.Run(context.Background(), cli, []string{LockKeyPrefix + rl.key}, rl.value, rl.expiration/time.Second).Int64()
|
||||||
|
if err != nil {
|
||||||
|
global.Log.Errorf("redis refreshLock runScript fail: %s", err.Error())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return result > 0
|
||||||
|
}
|
||||||
@@ -4,7 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"mayfly-go/pkg/biz"
|
"mayfly-go/pkg/biz"
|
||||||
"mayfly-go/pkg/logger"
|
"mayfly-go/pkg/logger"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/anyx"
|
||||||
|
"mayfly-go/pkg/utils/stringx"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@@ -72,21 +73,21 @@ func LogHandler(rc *Ctx) error {
|
|||||||
func getLogMsg(rc *Ctx) string {
|
func getLogMsg(rc *Ctx) string {
|
||||||
logInfo := rc.Conf.logInfo
|
logInfo := rc.Conf.logInfo
|
||||||
msg := logInfo.Description + fmt.Sprintf(" ->%dms", rc.timed)
|
msg := logInfo.Description + fmt.Sprintf(" ->%dms", rc.timed)
|
||||||
if !utils.IsBlank(rc.ReqParam) {
|
if !anyx.IsBlank(rc.ReqParam) {
|
||||||
msg = msg + fmt.Sprintf("\n--> %s", utils.ToString(rc.ReqParam))
|
msg = msg + fmt.Sprintf("\n--> %s", stringx.AnyToStr(rc.ReqParam))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回结果不为空,则记录返回结果
|
// 返回结果不为空,则记录返回结果
|
||||||
if logInfo.LogResp && !utils.IsBlank(rc.ResData) {
|
if logInfo.LogResp && !anyx.IsBlank(rc.ResData) {
|
||||||
msg = msg + fmt.Sprintf("\n<-- %s", utils.ToString(rc.ResData))
|
msg = msg + fmt.Sprintf("\n<-- %s", stringx.AnyToStr(rc.ResData))
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func getErrMsg(rc *Ctx, err any) string {
|
func getErrMsg(rc *Ctx, err any) string {
|
||||||
msg := rc.Conf.logInfo.Description
|
msg := rc.Conf.logInfo.Description
|
||||||
if !utils.IsBlank(rc.ReqParam) {
|
if !anyx.IsBlank(rc.ReqParam) {
|
||||||
msg = msg + fmt.Sprintf("\n--> %s", utils.ToString(rc.ReqParam))
|
msg = msg + fmt.Sprintf("\n--> %s", stringx.AnyToStr(rc.ReqParam))
|
||||||
}
|
}
|
||||||
|
|
||||||
var errMsg string
|
var errMsg string
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"mayfly-go/pkg/cache"
|
"mayfly-go/pkg/cache"
|
||||||
"mayfly-go/pkg/config"
|
"mayfly-go/pkg/config"
|
||||||
"mayfly-go/pkg/rediscli"
|
"mayfly-go/pkg/rediscli"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ type RedisPermissionCodeRegistry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RedisPermissionCodeRegistry) SaveCodes(userId uint64, codes []string) {
|
func (r *RedisPermissionCodeRegistry) SaveCodes(userId uint64, codes []string) {
|
||||||
rediscli.Set(fmt.Sprintf("mayfly:%v:codes", userId), utils.ToString(codes), time.Minute*time.Duration(config.Conf.Jwt.ExpireTime))
|
rediscli.Set(fmt.Sprintf("mayfly:%v:codes", userId), stringx.AnyToStr(codes), time.Minute*time.Duration(config.Conf.Jwt.ExpireTime))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RedisPermissionCodeRegistry) HasCode(userId uint64, code string) bool {
|
func (r *RedisPermissionCodeRegistry) HasCode(userId uint64, code string) bool {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"mayfly-go/pkg/config"
|
"mayfly-go/pkg/config"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils"
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
@@ -35,7 +35,7 @@ func CreateToken(userId uint64, username string) string {
|
|||||||
|
|
||||||
// 如果配置文件中的jwt key为空,则随机生成字符串
|
// 如果配置文件中的jwt key为空,则随机生成字符串
|
||||||
if JwtKey == "" {
|
if JwtKey == "" {
|
||||||
JwtKey = utils.RandString(32)
|
JwtKey = stringx.Rand(32)
|
||||||
global.Log.Infof("config.yml未配置jwt.key, 随机生成key为: %s", JwtKey)
|
global.Log.Infof("config.yml未配置jwt.key, 随机生成key为: %s", JwtKey)
|
||||||
}
|
}
|
||||||
// 使用自定义字符串加密 and get the complete encoded token as a string
|
// 使用自定义字符串加密 and get the complete encoded token as a string
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package starter
|
package starter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"mayfly-go/initialize"
|
||||||
"mayfly-go/pkg/config"
|
"mayfly-go/pkg/config"
|
||||||
"mayfly-go/pkg/logger"
|
"mayfly-go/pkg/logger"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
@@ -9,17 +10,25 @@ import (
|
|||||||
func RunWebServer() {
|
func RunWebServer() {
|
||||||
// 初始化config.yml配置文件映射信息
|
// 初始化config.yml配置文件映射信息
|
||||||
config.Init()
|
config.Init()
|
||||||
|
|
||||||
// 初始化日志配置信息
|
// 初始化日志配置信息
|
||||||
logger.Init()
|
logger.Init()
|
||||||
|
|
||||||
// 初始化jwt key与expire time等
|
// 初始化jwt key与expire time等
|
||||||
req.InitTokenConfig()
|
req.InitTokenConfig()
|
||||||
|
|
||||||
// 打印banner
|
// 打印banner
|
||||||
printBanner()
|
printBanner()
|
||||||
|
|
||||||
// 初始化并赋值数据库全局变量
|
// 初始化并赋值数据库全局变量
|
||||||
initDb()
|
initDb()
|
||||||
|
|
||||||
// 有配置redis信息,则初始化redis。多台机器部署需要使用redis存储验证码、权限、公私钥等
|
// 有配置redis信息,则初始化redis。多台机器部署需要使用redis存储验证码、权限、公私钥等
|
||||||
initRedis()
|
initRedis()
|
||||||
|
|
||||||
|
// 初始化其他需要启动时运行的方法
|
||||||
|
initialize.InitOther()
|
||||||
|
|
||||||
// 运行web服务
|
// 运行web服务
|
||||||
runWebServer()
|
runWebServer()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ func runWebServer() {
|
|||||||
// 注册路由
|
// 注册路由
|
||||||
web := initialize.InitRouter()
|
web := initialize.InitRouter()
|
||||||
|
|
||||||
// 初始化其他需要启动时运行的方法
|
|
||||||
initialize.InitOther()
|
|
||||||
|
|
||||||
server := config.Conf.Server
|
server := config.Conf.Server
|
||||||
port := server.GetPort()
|
port := server.GetPort()
|
||||||
global.Log.Infof("Listening and serving HTTP on %s", port)
|
global.Log.Infof("Listening and serving HTTP on %s", port)
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// any类型转换为string, 如果any为nil则返回空字符串
|
|
||||||
func Any2String(val any) string {
|
|
||||||
if value, ok := val.(string); !ok {
|
|
||||||
return ""
|
|
||||||
} else {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// any类型转换为int(可将字符串或int64转换), 如果any为nil则返回0
|
|
||||||
func Any2Int(val any) int {
|
|
||||||
switch value := val.(type) {
|
|
||||||
case int:
|
|
||||||
return value
|
|
||||||
case string:
|
|
||||||
if intV, err := strconv.Atoi(value); err == nil {
|
|
||||||
return intV
|
|
||||||
}
|
|
||||||
case int64:
|
|
||||||
return int(value)
|
|
||||||
case uint64:
|
|
||||||
return int(value)
|
|
||||||
case int32:
|
|
||||||
return int(value)
|
|
||||||
case uint32:
|
|
||||||
return int(value)
|
|
||||||
case int16:
|
|
||||||
return int(value)
|
|
||||||
case uint16:
|
|
||||||
return int(value)
|
|
||||||
case int8:
|
|
||||||
return int(value)
|
|
||||||
case uint8:
|
|
||||||
return int(value)
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// any类型转换为int64, 如果any为nil则返回0
|
|
||||||
func Any2Int64(val any) int64 {
|
|
||||||
if value, ok := val.(int64); !ok {
|
|
||||||
return int64(Any2Int(val))
|
|
||||||
} else {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
77
server/pkg/utils/anyx/anyx.go
Normal file
77
server/pkg/utils/anyx/anyx.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package anyx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// any类型转换为string, 如果any为nil则返回空字符串
|
||||||
|
func ConvString(val any) string {
|
||||||
|
if value, ok := val.(string); !ok {
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// any类型转换为int(可将字符串或int64转换), 如果any为nil则返回0
|
||||||
|
func ConvInt(val any) int {
|
||||||
|
switch value := val.(type) {
|
||||||
|
case int:
|
||||||
|
return value
|
||||||
|
case string:
|
||||||
|
if intV, err := strconv.Atoi(value); err == nil {
|
||||||
|
return intV
|
||||||
|
}
|
||||||
|
case int64:
|
||||||
|
return int(value)
|
||||||
|
case uint64:
|
||||||
|
return int(value)
|
||||||
|
case int32:
|
||||||
|
return int(value)
|
||||||
|
case uint32:
|
||||||
|
return int(value)
|
||||||
|
case int16:
|
||||||
|
return int(value)
|
||||||
|
case uint16:
|
||||||
|
return int(value)
|
||||||
|
case int8:
|
||||||
|
return int(value)
|
||||||
|
case uint8:
|
||||||
|
return int(value)
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// any类型转换为int64, 如果any为nil则返回0
|
||||||
|
func ConvInt64(val any) int64 {
|
||||||
|
if value, ok := val.(int64); !ok {
|
||||||
|
return int64(ConvInt(val))
|
||||||
|
} else {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsBlank(value any) bool {
|
||||||
|
if value == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
rValue := reflect.ValueOf(value)
|
||||||
|
switch rValue.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return rValue.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !rValue.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return rValue.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return rValue.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return rValue.Float() == 0
|
||||||
|
case reflect.Interface, reflect.Ptr:
|
||||||
|
return rValue.IsNil()
|
||||||
|
}
|
||||||
|
return reflect.DeepEqual(rValue.Interface(), reflect.Zero(rValue.Type()).Interface())
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package utils
|
package collx
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 数组比较
|
// 数组比较
|
||||||
// 依次返回,新增值,删除值,以及不变值
|
// 依次返回,新增值,删除值,以及不变值
|
||||||
@@ -53,7 +51,7 @@ func NumberArr2StrArr[T NumT](numberArr []T) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 判断数组中是否含有指定元素
|
// 判断数组中是否含有指定元素
|
||||||
func ArrContains[T comparable](arr []T, el T) bool {
|
func ArrayContains[T comparable](arr []T, el T) bool {
|
||||||
for _, v := range arr {
|
for _, v := range arr {
|
||||||
if v == el {
|
if v == el {
|
||||||
return true
|
return true
|
||||||
@@ -64,7 +62,7 @@ func ArrContains[T comparable](arr []T, el T) bool {
|
|||||||
|
|
||||||
// 数组转为map
|
// 数组转为map
|
||||||
// @param keyFunc key的主键
|
// @param keyFunc key的主键
|
||||||
func Array2Map[T any, K comparable](arr []T, keyFunc func(val T) K) map[K]T {
|
func ArrayToMap[T any, K comparable](arr []T, keyFunc func(val T) K) map[K]T {
|
||||||
res := make(map[K]T, len(arr))
|
res := make(map[K]T, len(arr))
|
||||||
for _, val := range arr {
|
for _, val := range arr {
|
||||||
key := keyFunc(val)
|
key := keyFunc(val)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package collx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package collx
|
||||||
|
|
||||||
import "encoding/binary"
|
import "encoding/binary"
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package collx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package collx
|
||||||
|
|
||||||
// ConvertToINodeArray 其他的结构体想要生成菜单树,直接实现这个接口
|
// ConvertToINodeArray 其他的结构体想要生成菜单树,直接实现这个接口
|
||||||
type INode interface {
|
type INode interface {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package cryptox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
package utils
|
package jsonx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Json2Map(jsonStr string) map[string]any {
|
// json字符串转map
|
||||||
|
func ToMap(jsonStr string) map[string]any {
|
||||||
var res map[string]any
|
var res map[string]any
|
||||||
if jsonStr == "" {
|
if jsonStr == "" {
|
||||||
return res
|
return res
|
||||||
@@ -14,7 +15,8 @@ func Json2Map(jsonStr string) map[string]any {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToJsonStr(val any) string {
|
// 转换为json字符串
|
||||||
|
func ToStr(val any) string {
|
||||||
if strBytes, err := json.Marshal(val); err != nil {
|
if strBytes, err := json.Marshal(val); err != nil {
|
||||||
global.Log.Error("toJsonStr error: ", err)
|
global.Log.Error("toJsonStr error: ", err)
|
||||||
return ""
|
return ""
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package netx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package netx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
import "runtime"
|
|
||||||
|
|
||||||
// 获取调用堆栈信息
|
|
||||||
func GetStackTrace() string {
|
|
||||||
var buf [2 << 10]byte
|
|
||||||
return string(buf[:runtime.Stack(buf[:], false)])
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package stringx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
const randChar = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
const randChar = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
|
||||||
// 生成随机字符串
|
// 生成随机字符串
|
||||||
func RandString(l int) string {
|
func Rand(l int) string {
|
||||||
strList := []byte(randChar)
|
strList := []byte(randChar)
|
||||||
|
|
||||||
result := []byte{}
|
result := []byte{}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package stringx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -9,17 +9,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 可判断中文
|
// 可判断中文
|
||||||
func StrLen(str string) int {
|
func Len(str string) int {
|
||||||
return len([]rune(str))
|
return len([]rune(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去除字符串左右空字符
|
// 去除字符串左右空字符
|
||||||
func StrTrim(str string) string {
|
func Trim(str string) string {
|
||||||
return strings.Trim(str, " ")
|
return strings.Trim(str, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去除字符串左右空字符与\n\r换行回车符
|
// 去除字符串左右空字符与\n\r换行回车符
|
||||||
func StrTrimSpaceAndBr(str string) string {
|
func TrimSpaceAndBr(str string) string {
|
||||||
return strings.TrimFunc(str, func(r rune) bool {
|
return strings.TrimFunc(str, func(r rune) bool {
|
||||||
s := string(r)
|
s := string(r)
|
||||||
return s == " " || s == "\n" || s == "\r"
|
return s == " " || s == "\n" || s == "\r"
|
||||||
@@ -96,7 +96,7 @@ func TemplateResolve(temp string, data any) string {
|
|||||||
func ReverStrTemplate(temp, str string, res map[string]any) {
|
func ReverStrTemplate(temp, str string, res map[string]any) {
|
||||||
index := UnicodeIndex(temp, "{")
|
index := UnicodeIndex(temp, "{")
|
||||||
ei := UnicodeIndex(temp, "}") + 1
|
ei := UnicodeIndex(temp, "}") + 1
|
||||||
next := StrTrim(temp[ei:])
|
next := Trim(temp[ei:])
|
||||||
nextContain := UnicodeIndex(next, "{")
|
nextContain := UnicodeIndex(next, "{")
|
||||||
nextIndexValue := next
|
nextIndexValue := next
|
||||||
if nextContain != -1 {
|
if nextContain != -1 {
|
||||||
@@ -106,19 +106,19 @@ func ReverStrTemplate(temp, str string, res map[string]any) {
|
|||||||
// 如果后面没有内容了,则取字符串的长度即可
|
// 如果后面没有内容了,则取字符串的长度即可
|
||||||
var valueLastIndex int
|
var valueLastIndex int
|
||||||
if nextIndexValue == "" {
|
if nextIndexValue == "" {
|
||||||
valueLastIndex = StrLen(str)
|
valueLastIndex = Len(str)
|
||||||
} else {
|
} else {
|
||||||
valueLastIndex = UnicodeIndex(str, nextIndexValue)
|
valueLastIndex = UnicodeIndex(str, nextIndexValue)
|
||||||
}
|
}
|
||||||
value := StrTrim(SubString(str, index, valueLastIndex))
|
value := Trim(SubString(str, index, valueLastIndex))
|
||||||
res[key] = value
|
res[key] = value
|
||||||
// 如果后面的还有需要解析的,则递归调用解析
|
// 如果后面的还有需要解析的,则递归调用解析
|
||||||
if nextContain != -1 {
|
if nextContain != -1 {
|
||||||
ReverStrTemplate(next, StrTrim(SubString(str, UnicodeIndex(str, value)+StrLen(value), StrLen(str))), res)
|
ReverStrTemplate(next, Trim(SubString(str, UnicodeIndex(str, value)+Len(value), Len(str))), res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToString(value any) string {
|
func AnyToStr(value any) string {
|
||||||
// interface 转 string
|
// interface 转 string
|
||||||
var key string
|
var key string
|
||||||
if value == nil {
|
if value == nil {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package stringx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package structx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package utils
|
package structx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -188,7 +189,7 @@ func TestTemplateResolve(t *testing.T) {
|
|||||||
d := make(map[string]string)
|
d := make(map[string]string)
|
||||||
d["Name"] = "黄先生"
|
d["Name"] = "黄先生"
|
||||||
d["Age"] = "23jlfdsjf"
|
d["Age"] = "23jlfdsjf"
|
||||||
resolve := TemplateResolve("{{.Name}} is name, and {{.Age}} is age", d)
|
resolve := stringx.TemplateResolve("{{.Name}} is name, and {{.Age}} is age", d)
|
||||||
fmt.Println(resolve)
|
fmt.Println(resolve)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func DefaultTimeFormat(time time.Time) string {
|
|
||||||
return time.Format("2006-01-02 15:04:05")
|
|
||||||
}
|
|
||||||
7
server/pkg/utils/timex/timex.go
Normal file
7
server/pkg/utils/timex/timex.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package timex
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
func DefaultFormat(time time.Time) string {
|
||||||
|
return time.Format("2006-01-02 15:04:05")
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package utils
|
package ymlx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
Reference in New Issue
Block a user