mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 15:30:25 +08:00
refactor: 数组比较方法优化等
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
"splitpanes": "^3.1.5",
|
||||
"sql-formatter": "^14.0.0",
|
||||
"uuid": "^9.0.1",
|
||||
"vue": "^3.4.10",
|
||||
"vue": "^3.4.12",
|
||||
"vue-router": "^4.2.5",
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-addon-fit": "^0.8.0",
|
||||
@@ -48,7 +48,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
||||
"@typescript-eslint/parser": "^6.7.4",
|
||||
"@vitejs/plugin-vue": "^5.0.3",
|
||||
"@vue/compiler-sfc": "^3.4.8",
|
||||
"@vue/compiler-sfc": "^3.4.12",
|
||||
"dotenv": "^16.3.1",
|
||||
"eslint": "^8.35.0",
|
||||
"eslint-plugin-vue": "^9.19.2",
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ref, nextTick, reactive, onMounted, onBeforeUnmount, watch } from 'vue'
|
||||
import TerminalSearch from './TerminalSearch.vue';
|
||||
import { debounce } from 'lodash';
|
||||
import { TerminalStatus } from './common';
|
||||
import { useEventListener } from '@vueuse/core';
|
||||
|
||||
const props = defineProps({
|
||||
/**
|
||||
@@ -145,7 +146,7 @@ const onConnected = () => {
|
||||
state.status = TerminalStatus.Connected;
|
||||
|
||||
// 注册窗口大小监听器
|
||||
window.addEventListener('resize', debounce(fitTerminal, 400));
|
||||
useEventListener('resize', debounce(fitTerminal, 400));
|
||||
|
||||
focus();
|
||||
|
||||
@@ -178,7 +179,7 @@ const clear = () => {
|
||||
|
||||
function initSocket() {
|
||||
if (props.socketUrl) {
|
||||
let socketUrl = `${props.socketUrl}&rows=${term.rows}&cols=${term.cols}`;
|
||||
let socketUrl = `${props.socketUrl}&rows=${term?.rows}&cols=${term?.cols}`;
|
||||
socket = new WebSocket(socketUrl);
|
||||
}
|
||||
|
||||
@@ -196,8 +197,6 @@ function initSocket() {
|
||||
|
||||
socket.onclose = (e: CloseEvent) => {
|
||||
console.log('terminal socket close...', e.reason);
|
||||
// 关闭窗口大小监听器
|
||||
window.removeEventListener('resize', debounce(fitTerminal, 100));
|
||||
// 清除 ping
|
||||
pingInterval && clearInterval(pingInterval);
|
||||
state.status = TerminalStatus.Disconnected;
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="terminal-wrapper" :style="{ height: `calc(100vh - ${openTerminal.fullscreen ? '47px' : '200px'})` }">
|
||||
<div class="terminal-wrapper" :style="{ height: `calc(100vh - ${openTerminal.fullscreen ? '49px' : '200px'})` }">
|
||||
<TerminalBody
|
||||
@status-change="terminalStatusChange(openTerminal.terminalId, $event)"
|
||||
:ref="(el) => setTerminalRef(el, openTerminal.terminalId)"
|
||||
|
||||
@@ -101,9 +101,7 @@ func (d *dbAppImpl) SaveDb(ctx context.Context, dbEntity *entity.Db, tagIds ...u
|
||||
oldDbs := strings.Split(old.Database, " ")
|
||||
newDbs := strings.Split(dbEntity.Database, " ")
|
||||
// 比较新旧数据库列表,需要将移除的数据库相关联的信息删除
|
||||
_, delDb, _ := collx.ArrayCompare(newDbs, oldDbs, func(i1, i2 string) bool {
|
||||
return i1 == i2
|
||||
})
|
||||
_, delDb, _ := collx.ArrayCompare(newDbs, oldDbs)
|
||||
|
||||
for _, v := range delDb {
|
||||
// 关闭数据库连接
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package dbi
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
machineapp "mayfly-go/internal/machine/application"
|
||||
"mayfly-go/internal/machine/mcm"
|
||||
"mayfly-go/pkg/errorx"
|
||||
"mayfly-go/pkg/logx"
|
||||
)
|
||||
|
||||
// 获取sql.DB函数
|
||||
type GetSqlDbFunc func(*DbInfo) (*sql.DB, error)
|
||||
|
||||
type DbInfo struct {
|
||||
InstanceId uint64 // 实例id
|
||||
Id uint64 // dbId
|
||||
@@ -76,7 +73,7 @@ func (dbInfo *DbInfo) Conn(meta Meta) (*DbConn, error) {
|
||||
func (di *DbInfo) IfUseSshTunnelChangeIpPort() error {
|
||||
// 开启ssh隧道
|
||||
if di.SshTunnelMachineId > 0 {
|
||||
sshTunnelMachine, err := machineapp.GetMachineApp().GetSshTunnelMachine(di.SshTunnelMachineId)
|
||||
sshTunnelMachine, err := GetSshTunnel(di.SshTunnelMachineId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -90,6 +87,11 @@ func (di *DbInfo) IfUseSshTunnelChangeIpPort() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 根据ssh tunnel机器id返回ssh tunnel
|
||||
func GetSshTunnel(sshTunnelMachineId int) (*mcm.SshTunnelMachine, error) {
|
||||
return machineapp.GetMachineApp().GetSshTunnelMachine(sshTunnelMachineId)
|
||||
}
|
||||
|
||||
// 获取连接id
|
||||
func GetDbConnId(dbId uint64, db string) string {
|
||||
if dbId == 0 {
|
||||
|
||||
@@ -4,7 +4,7 @@ import "database/sql"
|
||||
|
||||
// 数据库元信息获取,如获取sql.DB、Dialect等
|
||||
type Meta interface {
|
||||
// 获取数据库服务实例信息
|
||||
// 根据数据库信息获取sql.DB
|
||||
GetSqlDb(*DbInfo) (*sql.DB, error)
|
||||
|
||||
// 获取数据库方言,用于获取表结构等信息
|
||||
|
||||
@@ -52,7 +52,7 @@ func getDbMetaByType(dt dbi.DbType) dbi.Meta {
|
||||
|
||||
// 从缓存中获取数据库连接信息,若缓存中不存在则会使用回调函数获取dbInfo进行连接并缓存
|
||||
func GetDbConn(dbId uint64, database string, getDbInfo func() (*dbi.DbInfo, error)) (*dbi.DbConn, error) {
|
||||
connId := GetDbConnId(dbId, database)
|
||||
connId := dbi.GetDbConnId(dbId, database)
|
||||
|
||||
// connId不为空,则为需要缓存
|
||||
needCache := connId != ""
|
||||
@@ -102,14 +102,5 @@ func GetDbConnByInstanceId(instanceId uint64) *dbi.DbConn {
|
||||
|
||||
// 删除db缓存并关闭该数据库所有连接
|
||||
func CloseDb(dbId uint64, db string) {
|
||||
connCache.Delete(GetDbConnId(dbId, db))
|
||||
}
|
||||
|
||||
// 获取连接id
|
||||
func GetDbConnId(dbId uint64, db string) string {
|
||||
if dbId == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%d:%s", dbId, db)
|
||||
connCache.Delete(dbi.GetDbConnId(dbId, db))
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"mayfly-go/internal/db/dbm/dbi"
|
||||
machineapp "mayfly-go/internal/machine/application"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
@@ -30,7 +29,7 @@ type MysqlMeta struct {
|
||||
func (md *MysqlMeta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
||||
// SSH Conect
|
||||
if d.SshTunnelMachineId > 0 {
|
||||
sshTunnelMachine, err := machineapp.GetMachineApp().GetSshTunnelMachine(d.SshTunnelMachineId)
|
||||
sshTunnelMachine, err := dbi.GetSshTunnel(d.SshTunnelMachineId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"mayfly-go/internal/db/dbm/dbi"
|
||||
machineapp "mayfly-go/internal/machine/application"
|
||||
"mayfly-go/pkg/utils/collx"
|
||||
"mayfly-go/pkg/utils/netx"
|
||||
"net"
|
||||
@@ -94,7 +93,7 @@ func (d *PqSqlDialer) Open(name string) (driver.Conn, error) {
|
||||
}
|
||||
|
||||
func (pd *PqSqlDialer) Dial(network, address string) (net.Conn, error) {
|
||||
sshTunnel, err := machineapp.GetMachineApp().GetSshTunnelMachine(pd.sshTunnelMachineId)
|
||||
sshTunnel, err := dbi.GetSshTunnel(pd.sshTunnelMachineId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ func (m *machineCropJobAppImpl) GetRelateCronJobIds(machineId uint64) []uint64 {
|
||||
|
||||
func (m *machineCropJobAppImpl) CronJobRelateMachines(ctx context.Context, cronJobId uint64, machineIds []uint64) {
|
||||
oldMachineIds := m.machineCropJobRelateRepo.GetMachineIds(cronJobId)
|
||||
addIds, delIds, _ := collx.ArrayCompare[uint64](machineIds, oldMachineIds, func(u1, u2 uint64) bool { return u1 == u2 })
|
||||
addIds, delIds, _ := collx.ArrayCompare[uint64](machineIds, oldMachineIds)
|
||||
addVals := make([]*entity.MachineCronJobRelate, 0)
|
||||
|
||||
for _, addId := range addIds {
|
||||
@@ -143,7 +143,7 @@ func (m *machineCropJobAppImpl) MachineRelateCronJobs(ctx context.Context, machi
|
||||
}
|
||||
|
||||
oldCronIds := m.machineCropJobRelateRepo.GetCronJobIds(machineId)
|
||||
addIds, delIds, _ := collx.ArrayCompare[uint64](cronJobs, oldCronIds, func(u1, u2 uint64) bool { return u1 == u2 })
|
||||
addIds, delIds, _ := collx.ArrayCompare[uint64](cronJobs, oldCronIds)
|
||||
addVals := make([]*entity.MachineCronJobRelate, 0)
|
||||
|
||||
for _, addId := range addIds {
|
||||
|
||||
@@ -98,9 +98,7 @@ func (m *roleAppImpl) GetRoleResources(roleId uint64, toEntity any) {
|
||||
func (m *roleAppImpl) SaveRoleResource(ctx context.Context, roleId uint64, resourceIds []uint64) {
|
||||
oIds := m.GetRoleResourceIds(roleId)
|
||||
|
||||
addIds, delIds, _ := collx.ArrayCompare(resourceIds, oIds, func(i1, i2 uint64) bool {
|
||||
return i1 == i2
|
||||
})
|
||||
addIds, delIds, _ := collx.ArrayCompare(resourceIds, oIds)
|
||||
|
||||
la := contextx.GetLoginAccount(ctx)
|
||||
createTime := time.Now()
|
||||
|
||||
@@ -126,9 +126,7 @@ func (p *Team) SaveTags(rc *req.Ctx) {
|
||||
oIds := p.TeamApp.ListTagIds(teamId)
|
||||
|
||||
// 比较新旧两合集
|
||||
addIds, delIds, _ := collx.ArrayCompare(form.TagIds, oIds, func(i1, i2 uint64) bool {
|
||||
return i1 == i2
|
||||
})
|
||||
addIds, delIds, _ := collx.ArrayCompare(form.TagIds, oIds)
|
||||
|
||||
for _, v := range addIds {
|
||||
tagId := v
|
||||
|
||||
@@ -168,7 +168,7 @@ func (p *tagTreeAppImpl) RelateResource(ctx context.Context, resourceCode string
|
||||
oldTagIds := collx.ArrayMap[*entity.TagResource, uint64](oldTagResources, func(tr *entity.TagResource) uint64 {
|
||||
return tr.TagId
|
||||
})
|
||||
addTagIds, delTagIds, _ = collx.ArrayCompare[uint64](tagIds, oldTagIds, func(u1, u2 uint64) bool { return u1 == u2 })
|
||||
addTagIds, delTagIds, _ = collx.ArrayCompare[uint64](tagIds, oldTagIds)
|
||||
}
|
||||
|
||||
if len(addTagIds) > 0 {
|
||||
|
||||
@@ -2,38 +2,41 @@ package collx
|
||||
|
||||
// 数组比较
|
||||
// 依次返回,新增值,删除值,以及不变值
|
||||
func ArrayCompare[T any](newArr []T, oldArr []T, compareFun func(T, T) bool) ([]T, []T, []T) {
|
||||
var unmodifierValue []T
|
||||
ni, oi := 0, 0
|
||||
for {
|
||||
if ni >= len(newArr) {
|
||||
break
|
||||
}
|
||||
nv := newArr[ni]
|
||||
for {
|
||||
if oi >= len(oldArr) {
|
||||
oi = 0
|
||||
break
|
||||
}
|
||||
ov := oldArr[oi]
|
||||
if compareFun(nv, ov) {
|
||||
unmodifierValue = append(unmodifierValue, nv)
|
||||
// 新数组移除该位置值
|
||||
if len(newArr) > ni {
|
||||
newArr = append(newArr[:ni], newArr[ni+1:]...)
|
||||
ni = ni - 1
|
||||
}
|
||||
if len(oldArr) > oi {
|
||||
oldArr = append(oldArr[:oi], oldArr[oi+1:]...)
|
||||
oi = oi - 1
|
||||
}
|
||||
}
|
||||
oi = oi + 1
|
||||
}
|
||||
ni = ni + 1
|
||||
func ArrayCompare[T comparable](newArr []T, oldArr []T) ([]T, []T, []T) {
|
||||
newSet := make(map[T]bool)
|
||||
oldSet := make(map[T]bool)
|
||||
|
||||
// 将新数组和旧数组的元素分别添加到对应的哈希集合中
|
||||
for _, elem := range newArr {
|
||||
newSet[elem] = true
|
||||
}
|
||||
for _, elem := range oldArr {
|
||||
oldSet[elem] = true
|
||||
}
|
||||
|
||||
return newArr, oldArr, unmodifierValue
|
||||
var (
|
||||
added []T
|
||||
deleted []T
|
||||
unmodified []T
|
||||
)
|
||||
|
||||
// 遍历新数组,根据元素是否存在于旧数组进行分类
|
||||
for _, elem := range newArr {
|
||||
if oldSet[elem] {
|
||||
unmodified = append(unmodified, elem)
|
||||
} else {
|
||||
added = append(added, elem)
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历旧数组,找出被删除的元素
|
||||
for _, elem := range oldArr {
|
||||
if !newSet[elem] {
|
||||
deleted = append(deleted, elem)
|
||||
}
|
||||
}
|
||||
|
||||
return added, deleted, unmodified
|
||||
}
|
||||
|
||||
// 判断数组中是否含有指定元素
|
||||
|
||||
@@ -8,14 +8,26 @@ import (
|
||||
func TestArrayCompare(t *testing.T) {
|
||||
newArr := []any{1, 2, 3, 5}
|
||||
oldArr := []any{3, 6}
|
||||
add, del, unmodifier := ArrayCompare(newArr, oldArr, func(i1, i2 any) bool {
|
||||
return i1.(int) == i2.(int)
|
||||
})
|
||||
add, del, unmodifier := ArrayCompare(newArr, oldArr)
|
||||
fmt.Println(add...)
|
||||
fmt.Println(del...)
|
||||
fmt.Println(unmodifier...)
|
||||
}
|
||||
|
||||
type Student struct {
|
||||
Id uint64
|
||||
Name string
|
||||
}
|
||||
|
||||
func TestArrayCompareStruct(t *testing.T) {
|
||||
newArr := []Student{{Id: 1, Name: "1"}, {Id: 2, Name: "2"}, {Id: 3, Name: "3"}, {Id: 5, Name: "5"}}
|
||||
oldArr := []Student{{Id: 3, Name: "3"}, {Id: 6, Name: "6"}}
|
||||
add, del, unmodifier := ArrayCompare(newArr, oldArr)
|
||||
fmt.Println(add)
|
||||
fmt.Println(del)
|
||||
fmt.Println(unmodifier)
|
||||
}
|
||||
|
||||
func TestArrayChunk(t *testing.T) {
|
||||
arr := []int{1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
res := ArrayChunk[int](arr, 3)
|
||||
|
||||
Reference in New Issue
Block a user