mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 07:50:25 +08:00
feat: v1.7.1新增支持sqlite&oracle分页限制等问题修复
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
### 介绍
|
### 介绍
|
||||||
|
|
||||||
web 版 **linux(终端[终端回放] 文件 脚本 进程 计划任务)、数据库(mysql postgres oracle 达梦 高斯)、redis(单机 哨兵 集群)、mongo 统一管理操作平台**
|
web 版 **linux(终端[终端回放] 文件 脚本 进程 计划任务)、数据库(mysql postgres oracle 达梦 高斯 sqlite)、redis(单机 哨兵 集群)、mongo 统一管理操作平台**
|
||||||
|
|
||||||
### 开发语言与主要框架
|
### 开发语言与主要框架
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"countup.js": "^2.7.0",
|
"countup.js": "^2.7.0",
|
||||||
"cropperjs": "^1.5.11",
|
"cropperjs": "^1.5.11",
|
||||||
"echarts": "^5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"element-plus": "^2.5.1",
|
"element-plus": "^2.5.2",
|
||||||
"js-base64": "^3.7.5",
|
"js-base64": "^3.7.5",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"splitpanes": "^3.1.5",
|
"splitpanes": "^3.1.5",
|
||||||
"sql-formatter": "^15.0.2",
|
"sql-formatter": "^15.0.2",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"vue": "^3.4.14",
|
"vue": "^3.4.15",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
"xterm": "^5.3.0",
|
"xterm": "^5.3.0",
|
||||||
"xterm-addon-fit": "^0.8.0",
|
"xterm-addon-fit": "^0.8.0",
|
||||||
|
|||||||
@@ -307,7 +307,8 @@ const NodeTypeTableMenu = new NodeType(SqlExecNodeType.TableMenu)
|
|||||||
state.reloadStatus = false;
|
state.reloadStatus = false;
|
||||||
let dbTableSize = 0;
|
let dbTableSize = 0;
|
||||||
const tablesNode = tables.map((x: any) => {
|
const tablesNode = tables.map((x: any) => {
|
||||||
dbTableSize += x.dataLength + x.indexLength;
|
const tableSize = x.dataLength + x.indexLength;
|
||||||
|
dbTableSize += tableSize;
|
||||||
return new TagTreeNode(`${id}.${db}.${x.tableName}`, x.tableName, NodeTypeTable)
|
return new TagTreeNode(`${id}.${db}.${x.tableName}`, x.tableName, NodeTypeTable)
|
||||||
.withIsLeaf(true)
|
.withIsLeaf(true)
|
||||||
.withParams({
|
.withParams({
|
||||||
@@ -315,13 +316,13 @@ const NodeTypeTableMenu = new NodeType(SqlExecNodeType.TableMenu)
|
|||||||
db,
|
db,
|
||||||
tableName: x.tableName,
|
tableName: x.tableName,
|
||||||
tableComment: x.tableComment,
|
tableComment: x.tableComment,
|
||||||
size: formatByteSize(x.dataLength + x.indexLength, 1),
|
size: tableSize == 0 ? '' : formatByteSize(tableSize, 1),
|
||||||
})
|
})
|
||||||
.withIcon(TableIcon)
|
.withIcon(TableIcon)
|
||||||
.withLabelRemark(`${x.tableName} ${x.tableComment ? '| ' + x.tableComment : ''}`);
|
.withLabelRemark(`${x.tableName} ${x.tableComment ? '| ' + x.tableComment : ''}`);
|
||||||
});
|
});
|
||||||
// 设置父节点参数的表大小
|
// 设置父节点参数的表大小
|
||||||
parentNode.params.dbTableSize = formatByteSize(dbTableSize);
|
parentNode.params.dbTableSize = dbTableSize == 0 ? '' : formatByteSize(dbTableSize);
|
||||||
return tablesNode;
|
return tablesNode;
|
||||||
})
|
})
|
||||||
.withNodeClickFunc(nodeClickChangeDb);
|
.withNodeClickFunc(nodeClickChangeDb);
|
||||||
|
|||||||
@@ -868,7 +868,7 @@ defineExpose({
|
|||||||
color: var(--el-color-info-light-3);
|
color: var(--el-color-info-light-3);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -7px;
|
top: -5px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ const search = async () => {
|
|||||||
|
|
||||||
const changeStatus = async (row: any) => {
|
const changeStatus = async (row: any) => {
|
||||||
let id = row.id;
|
let id = row.id;
|
||||||
let status = row.status == -1 ? 1 : -1;
|
let status = row.status == AccountStatusEnum.Disable.value ? AccountStatusEnum.Enable.value : AccountStatusEnum.Disable.value;
|
||||||
await accountApi.changeStatus.request({
|
await accountApi.changeStatus.request({
|
||||||
id,
|
id,
|
||||||
status,
|
status,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ require (
|
|||||||
github.com/pquerna/otp v1.4.0
|
github.com/pquerna/otp v1.4.0
|
||||||
github.com/redis/go-redis/v9 v9.4.0
|
github.com/redis/go-redis/v9 v9.4.0
|
||||||
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
||||||
github.com/sijms/go-ora/v2 v2.8.5
|
github.com/sijms/go-ora/v2 v2.8.6
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
go.mongodb.org/mongo-driver v1.13.1 // mongo
|
go.mongodb.org/mongo-driver v1.13.1 // mongo
|
||||||
golang.org/x/crypto v0.18.0 // ssh
|
golang.org/x/crypto v0.18.0 // ssh
|
||||||
@@ -35,6 +35,7 @@ require (
|
|||||||
// gorm
|
// gorm
|
||||||
gorm.io/driver/mysql v1.5.2
|
gorm.io/driver/mysql v1.5.2
|
||||||
gorm.io/gorm v1.25.5
|
gorm.io/gorm v1.25.5
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ package oracle
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
go_ora "github.com/sijms/go-ora/v2"
|
|
||||||
"mayfly-go/internal/db/dbm/dbi"
|
"mayfly-go/internal/db/dbm/dbi"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
go_ora "github.com/sijms/go-ora/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -58,10 +59,6 @@ func (md *OraMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 默认设置为UTF8
|
|
||||||
//if urlOptions["client charset"] == "" {
|
|
||||||
// urlOptions["client charset"] = "UTF8"
|
|
||||||
//}
|
|
||||||
urlOptions["TIMEOUT"] = "10"
|
urlOptions["TIMEOUT"] = "10"
|
||||||
connStr := go_ora.BuildUrl(d.Host, d.Port, d.Sid, d.Username, d.Password, urlOptions)
|
connStr := go_ora.BuildUrl(d.Host, d.Port, d.Sid, d.Username, d.Password, urlOptions)
|
||||||
conn, err := sql.Open(driverName, connStr)
|
conn, err := sql.Open(driverName, connStr)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package sqlite
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
|
||||||
"mayfly-go/internal/db/dbm/dbi"
|
"mayfly-go/internal/db/dbm/dbi"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -30,7 +29,7 @@ func (md *SqliteMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
|||||||
if _, err := os.Stat(d.Host); err != nil {
|
if _, err := os.Stat(d.Host); err != nil {
|
||||||
return nil, errors.New("数据库文件不存在")
|
return nil, errors.New("数据库文件不存在")
|
||||||
}
|
}
|
||||||
return sql.Open("sqlite3", d.Host)
|
return sql.Open("sqlite", d.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (md *SqliteMeta) GetDialect(conn *dbi.DbConn) dbi.Dialect {
|
func (md *SqliteMeta) GetDialect(conn *dbi.DbConn) dbi.Dialect {
|
||||||
|
|||||||
@@ -154,7 +154,11 @@ func (a *Account) ChangeStatus(rc *req.Ctx) {
|
|||||||
|
|
||||||
account := &entity.Account{}
|
account := &entity.Account{}
|
||||||
account.Id = uint64(ginx.PathParamInt(g, "id"))
|
account.Id = uint64(ginx.PathParamInt(g, "id"))
|
||||||
account.Status = int8(ginx.PathParamInt(g, "status"))
|
|
||||||
|
status := entity.AccountStatus(int8(ginx.PathParamInt(g, "status")))
|
||||||
|
biz.ErrIsNil(entity.AccountStatusEnum.Valid(status))
|
||||||
|
account.Status = status
|
||||||
|
|
||||||
rc.ReqParam = collx.Kvs("accountId", account.Id, "status", account.Status)
|
rc.ReqParam = collx.Kvs("accountId", account.Id, "status", account.Status)
|
||||||
biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account))
|
biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,32 @@
|
|||||||
package vo
|
package vo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"mayfly-go/internal/sys/domain/entity"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AccountManageVO struct {
|
type AccountManageVO struct {
|
||||||
model.Model
|
model.Model
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Status int `json:"status"`
|
Status entity.AccountStatus `json:"status"`
|
||||||
LastLoginTime *time.Time `json:"lastLoginTime"`
|
LastLoginTime *time.Time `json:"lastLoginTime"`
|
||||||
OtpSecret string `json:"otpSecret"`
|
OtpSecret string `json:"otpSecret"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 账号角色信息
|
// 账号角色信息
|
||||||
type AccountRoleVO struct {
|
type AccountRoleVO struct {
|
||||||
RoleId uint64 `json:"roleId"`
|
RoleId uint64 `json:"roleId"`
|
||||||
RoleName string `json:"roleName"`
|
RoleName string `json:"roleName"`
|
||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
AccountId uint64 `json:"accountId" gorm:"column:accountId"`
|
AccountId uint64 `json:"accountId" gorm:"column:accountId"`
|
||||||
AccountName string `json:"accountName" gorm:"column:accountName"`
|
AccountName string `json:"accountName" gorm:"column:accountName"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
AccountStatus int `json:"accountStatus" gorm:"column:accountStatus"`
|
AccountStatus entity.AccountStatus `json:"accountStatus" gorm:"column:accountStatus"`
|
||||||
CreateTime *time.Time `json:"createTime"`
|
CreateTime *time.Time `json:"createTime"`
|
||||||
Creator string `json:"creator"`
|
Creator string `json:"creator"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 账号个人信息
|
// 账号个人信息
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func (a *accountAppImpl) Create(ctx context.Context, account *entity.Account) er
|
|||||||
}
|
}
|
||||||
// 默认密码为账号用户名
|
// 默认密码为账号用户名
|
||||||
account.Password = cryptox.PwdHash(account.Username)
|
account.Password = cryptox.PwdHash(account.Username)
|
||||||
account.Status = entity.AccountEnableStatus
|
account.Status = entity.AccountEnable
|
||||||
return a.Insert(ctx, account)
|
return a.Insert(ctx, account)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package entity
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"mayfly-go/internal/common/utils"
|
"mayfly-go/internal/common/utils"
|
||||||
|
"mayfly-go/pkg/enumx"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -10,13 +11,13 @@ import (
|
|||||||
type Account struct {
|
type Account struct {
|
||||||
model.Model
|
model.Model
|
||||||
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Password string `json:"-"`
|
Password string `json:"-"`
|
||||||
Status int8 `json:"status"`
|
Status AccountStatus `json:"status"`
|
||||||
LastLoginTime *time.Time `json:"lastLoginTime"`
|
LastLoginTime *time.Time `json:"lastLoginTime"`
|
||||||
LastLoginIp string `json:"lastLoginIp"`
|
LastLoginIp string `json:"lastLoginIp"`
|
||||||
OtpSecret string `json:"-"`
|
OtpSecret string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Account) TableName() string {
|
func (a *Account) TableName() string {
|
||||||
@@ -25,7 +26,7 @@ func (a *Account) TableName() string {
|
|||||||
|
|
||||||
// 是否可用
|
// 是否可用
|
||||||
func (a *Account) IsEnable() bool {
|
func (a *Account) IsEnable() bool {
|
||||||
return a.Status == AccountEnableStatus
|
return a.Status == AccountEnable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Account) OtpSecretEncrypt() error {
|
func (a *Account) OtpSecretEncrypt() error {
|
||||||
@@ -49,7 +50,13 @@ func (a *Account) OtpSecretDecrypt() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AccountStatus int8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AccountEnableStatus int8 = 1 // 启用状态
|
AccountEnable AccountStatus = 1 // 启用状态
|
||||||
AccountDisableStatus int8 = -1 // 禁用状态
|
AccountDisable AccountStatus = -1 // 禁用状态
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var AccountStatusEnum = enumx.NewEnum[AccountStatus]("账号状态").
|
||||||
|
Add(AccountEnable, "启用").
|
||||||
|
Add(AccountDisable, "禁用")
|
||||||
|
|||||||
50
server/pkg/enumx/enumx.go
Normal file
50
server/pkg/enumx/enumx.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package enumx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"mayfly-go/pkg/errorx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Enum[T comparable] struct {
|
||||||
|
name string // 枚举值名称
|
||||||
|
|
||||||
|
values map[T]string // 所有枚举值。枚举值 -> desc(描述)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新建枚举
|
||||||
|
func NewEnum[T comparable](name string) *Enum[T] {
|
||||||
|
return &Enum[T]{
|
||||||
|
name: name,
|
||||||
|
values: make(map[T]string),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加枚举值
|
||||||
|
func (e *Enum[T]) Add(value T, desc string) *Enum[T] {
|
||||||
|
e.values[value] = desc
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验枚举值是否合法
|
||||||
|
func (e *Enum[T]) Valid(value T) error {
|
||||||
|
_, ok := e.values[value]
|
||||||
|
if ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
errMsg := fmt.Sprintf("%s可选值为: ", e.name)
|
||||||
|
for val, desc := range e.values {
|
||||||
|
errMsg = fmt.Sprintf("%s [%v->%s]", errMsg, val, desc)
|
||||||
|
}
|
||||||
|
return errorx.NewBiz(errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据枚举值获取描述
|
||||||
|
func (e *Enum[T]) GetDesc(value T) string {
|
||||||
|
desc, ok := e.values[value]
|
||||||
|
if ok {
|
||||||
|
return desc
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user