feat: v1.7.1新增支持sqlite&oracle分页限制等问题修复

This commit is contained in:
meilin.huang
2024-01-19 21:33:37 +08:00
parent 9a59749763
commit f4a64b96a9
18 changed files with 103 additions and 43 deletions

View File

@@ -22,7 +22,7 @@
### 介绍 ### 介绍
web 版 **linux(终端[终端回放] 文件 脚本 进程 计划任务)、数据库mysql postgres oracle 达梦 高斯、redis(单机 哨兵 集群)、mongo 统一管理操作平台** web 版 **linux(终端[终端回放] 文件 脚本 进程 计划任务)、数据库mysql postgres oracle 达梦 高斯 sqlite、redis(单机 哨兵 集群)、mongo 统一管理操作平台**
### 开发语言与主要框架 ### 开发语言与主要框架

View File

@@ -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",

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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,

View File

@@ -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 (

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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))
} }

View File

@@ -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"`
} }
// 账号个人信息 // 账号个人信息

View File

@@ -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)
} }

View File

@@ -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
View 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 ""
}