Commit 23def7bc authored by ibuler's avatar ibuler

[Update] 修改分页

parent 6d5e52db
package common
import "sync"
func NewPagination(data []interface{}, size int) *Pagination {
return &Pagination{
data: data,
pageSize: size,
currentPage: 1,
lock: new(sync.RWMutex),
}
}
type Pagination struct {
data []interface{}
currentPage int
pageSize int
totalPage int
lock *sync.RWMutex
}
func (p *Pagination) GetNextPageData() []interface{} {
if !p.HasNextPage() {
return []interface{}{}
}
p.lock.Lock()
p.currentPage++
p.lock.Unlock()
return p.GetPageData(p.currentPage)
}
func (p *Pagination) GetPrePageData() []interface{} {
if !p.HasPrePage() {
return []interface{}{}
}
p.lock.Lock()
p.currentPage--
p.lock.Unlock()
return p.GetPageData(p.currentPage)
}
func (p *Pagination) GetPageData(pageIndex int) []interface{} {
p.lock.RLock()
defer p.lock.RUnlock()
var (
endIndex int
startIndex int
)
endIndex = p.pageSize * pageIndex
startIndex = endIndex - p.pageSize
if endIndex > len(p.data) {
endIndex = len(p.data)
}
return p.data[startIndex:endIndex]
}
func (p *Pagination) CurrentPage() int {
p.lock.RLock()
defer p.lock.RUnlock()
return p.currentPage
}
func (p *Pagination) TotalCount() int {
p.lock.RLock()
defer p.lock.RUnlock()
return len(p.data)
}
func (p *Pagination) TotalPage() int {
p.lock.RLock()
defer p.lock.RUnlock()
return p.totalPage
}
func (p *Pagination) SetPageSize(size int) {
if size <= 0 {
panic("Pagination size should be larger than zero")
}
p.lock.Lock()
defer p.lock.Unlock()
if p.pageSize == size {
return
}
p.pageSize = size
if len(p.data)%size == 0 {
p.totalPage = len(p.data) / size
} else {
p.totalPage = len(p.data)/size + 1
}
p.currentPage = 1
}
func (p *Pagination) GetPageSize() int {
p.lock.RLock()
defer p.lock.RUnlock()
return p.pageSize
}
func (p *Pagination) HasNextPage() bool {
p.lock.RLock()
defer p.lock.RUnlock()
return p.currentPage < p.totalPage
}
func (p *Pagination) HasPrePage() bool {
p.lock.RLock()
defer p.lock.RUnlock()
return p.currentPage > 1
}
package common
import (
"fmt"
"strings"
"github.com/olekukonko/tablewriter"
)
const (
TruncSuffix = iota
TruncPrefix
TruncMiddle
)
type WrapperTable struct {
Fields []string
FieldsSize map[string][3]int // 列宽,列最小宽,列最大宽
Data []map[string]string
TotalSize int
TruncPolicy int
totalSize int
paddingSize int
bolderSize int
fieldsSize map[string]int // 计算后的最终宽度
cleanedData []map[string]string
Caption string
}
func (t *WrapperTable) Initial() {
// 如果设置的宽度小于title的size, 重写
t.paddingSize = 1
t.bolderSize = 1
for _, k := range t.Fields {
titleSize := len(k)
sizeDefine := t.FieldsSize[k]
if titleSize > sizeDefine[1] {
sizeDefine[1] = titleSize
t.FieldsSize[k] = sizeDefine
}
}
}
func (t *WrapperTable) CalculateColumnsSize() {
t.fieldsSize = make(map[string]int)
dataColMaxSize := make(map[string]int)
for _, row := range t.Data {
for _, colName := range t.Fields {
if colValue, ok := row[colName]; ok {
preSize, ok := dataColMaxSize[colName]
colSize := len(colValue)
if !ok || colSize > preSize {
dataColMaxSize[colName] = colSize
}
}
}
}
// 如果数据宽度大于设置最大值,则设置为准
// 如果数据最大值小彧最小值,已最小值为列宽
// 否则数据最大宽度为列宽
for k, v := range dataColMaxSize {
size, min, max := t.FieldsSize[k][0], t.FieldsSize[k][1], t.FieldsSize[k][2]
if size != 0 {
t.fieldsSize[k] = size
} else if max != 0 && v > max {
t.fieldsSize[k] = max
} else if min != 0 && v < min {
t.fieldsSize[k] = min
} else {
t.fieldsSize[k] = v
}
}
// 计算后列总长度
calSize := 0
for _, v := range t.fieldsSize {
calSize += v
}
if t.TotalSize == 0 {
t.totalSize = calSize
return
}
// 总宽度计算时应当减去 border和padding
t.totalSize = t.TotalSize - len(t.Fields)*2*t.paddingSize - (len(t.Fields)+1)*t.bolderSize
// 计算可以扩容和缩容的列
delta := t.totalSize - calSize
if delta == 0 {
return
}
var step = 1
if delta < 0 {
step = -1
}
delta = Abs(delta)
for delta > 0 {
canChangeCols := make([]string, 0)
for k, v := range t.FieldsSize {
size, min, max := v[0], v[1], v[2]
switch step {
// 扩容
case 1:
if size != 0 || (max != 0 && t.fieldsSize[k] >= max) {
continue
}
// 缩容
case -1:
if size != 0 || t.fieldsSize[k] <= min {
continue
}
}
canChangeCols = append(canChangeCols, k)
}
if len(canChangeCols) == 0 {
break
}
for _, k := range canChangeCols {
t.fieldsSize[k] += step
delta--
}
}
}
func (t *WrapperTable) convertDataToSlice() [][]string {
data := make([][]string, len(t.Data))
for i, j := range t.Data {
row := make([]string, len(t.Fields))
for m, n := range t.Fields {
row[m] = j[n]
}
data[i] = row
}
return data
}
func (t *WrapperTable) Display() string {
t.CalculateColumnsSize()
fmt.Println(t.fieldsSize)
tableString := &strings.Builder{}
table := tablewriter.NewWriter(tableString)
table.SetBorder(false)
table.SetHeader(t.Fields)
colors := make([]tablewriter.Colors, len(t.Fields))
for i := 0; i < len(t.Fields); i++ {
colors[i] = tablewriter.Colors{tablewriter.Bold, tablewriter.FgGreenColor}
}
table.SetHeaderColor(colors...)
data := t.convertDataToSlice()
table.AppendBulk(data)
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.SetAlignment(tablewriter.ALIGN_LEFT)
for i, j := range t.Fields {
n := t.fieldsSize[j]
table.SetColMinWidth(i, n)
}
table.SetColWidth(t.totalSize)
if t.Caption != "" {
table.SetCaption(true, t.Caption)
}
table.Render()
return tableString.String()
}
package common
import (
"fmt"
"testing"
)
func TestNewTable_CalculateColumnsSize(t *testing.T) {
table := WrapperTable{
Fields: []string{"ID", "主机名", "IP", "系统用户", "Comment"},
Data: []map[string]string{
{"ID": "1", "主机名": "asdfasdf", "IP": "192.168.1.1", "系统用户": "123", "Comment": "你好"},
{"ID": "2", "主机名": "bbb", "IP": "255.255.255.255", "系统用户": "o", "Comment": ""},
{"ID": "3", "主机名": "3", "IP": "1.1.1.1", "系统用户": "", "Comment": "aaaa"},
{"ID": "3", "主机名": "22323", "IP": "1.1.2.1", "系统用户": "", "Comment": ""},
{"ID": "2", "主机名": "22323", "IP": "192.168.1.1", "系统用户": "", "Comment": ""},
},
FieldsSize: map[string][3]int{
"ID": {0, 0, 5},
"主机名": {0, 8, 25},
"IP": {15, 0, 0},
"系统用户": {0, 12, 20},
"Comment": {0, 0, 0},
},
TotalSize: 140,
}
table.Initial()
data := table.Display()
fmt.Println(data)
fmt.Println(table.fieldsSize)
//if table.fieldsSize["comment"] != 6 {
// t.Error("comment需要为6")
//}
//
//table.TotalSize = 188
//table.CalculateColumnsSize()
//if table.fieldsSize["comment"] != 136 {
// t.Error("comment长度需要为136")
//}
//fmt.Println(table.fieldsSize)
}
...@@ -44,3 +44,18 @@ func GzipCompressFile(srcPath, dstPath string) error { ...@@ -44,3 +44,18 @@ func GzipCompressFile(srcPath, dstPath string) error {
} }
return nil return nil
} }
func Sum(i []int) int {
sum := 0
for _, v := range i {
sum += v
}
return sum
}
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}
...@@ -6,9 +6,7 @@ import ( ...@@ -6,9 +6,7 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"reflect"
"strings" "strings"
"sync"
) )
type Config struct { type Config struct {
...@@ -41,8 +39,6 @@ type Config struct { ...@@ -41,8 +39,6 @@ type Config struct {
Comment string `yaml:"COMMENT"` Comment string `yaml:"COMMENT"`
Language string `yaml:"LANG"` Language string `yaml:"LANG"`
LanguageCode string `yaml:"LANGUAGE_CODE"` // Abandon LanguageCode string `yaml:"LANGUAGE_CODE"` // Abandon
mu sync.RWMutex
} }
func (c *Config) EnsureConfigValid() { func (c *Config) EnsureConfigValid() {
...@@ -57,8 +53,6 @@ func (c *Config) EnsureConfigValid() { ...@@ -57,8 +53,6 @@ func (c *Config) EnsureConfigValid() {
} }
func (c *Config) LoadFromYAML(body []byte) error { func (c *Config) LoadFromYAML(body []byte) error {
c.mu.Lock()
defer c.mu.Unlock()
err := yaml.Unmarshal(body, c) err := yaml.Unmarshal(body, c)
if err != nil { if err != nil {
log.Printf("Load yaml error: %v", err) log.Printf("Load yaml error: %v", err)
...@@ -75,8 +69,6 @@ func (c *Config) LoadFromYAMLPath(filepath string) error { ...@@ -75,8 +69,6 @@ func (c *Config) LoadFromYAMLPath(filepath string) error {
} }
func (c *Config) LoadFromJSON(body []byte) error { func (c *Config) LoadFromJSON(body []byte) error {
c.mu.Lock()
defer c.mu.Unlock()
err := json.Unmarshal(body, c) err := json.Unmarshal(body, c)
if err != nil { if err != nil {
log.Printf("Config load yaml error") log.Printf("Config load yaml error")
...@@ -98,44 +90,6 @@ func (c *Config) LoadFromEnv() error { ...@@ -98,44 +90,6 @@ func (c *Config) LoadFromEnv() error {
return c.LoadFromYAML(envYAML) return c.LoadFromYAML(envYAML)
} }
func (c *Config) Get(key string) reflect.Value {
c.mu.Lock()
defer c.mu.Unlock()
//t := reflect.TypeOf(c)
v := reflect.ValueOf(c)
return v.FieldByName(key)
//for i := 0; i < v.NumField(); i++ {
// if v.Field(i).CanInterface() && t.Field(i).Name == key {
// return v.Field(i).Interface()
// }
//}
//return nil
}
func (c *Config) GetString(key string) string {
value := c.Get(key)
return value.String()
}
func (c *Config) GetBool(key string) bool {
value := c.Get(key)
return value.Bool()
}
func (c *Config) GetInt(key string) int {
value := c.Get(key)
return int(value.Int())
}
func (c *Config) GetMap(key string) map[string]string {
//value := c.Get(key)
//
//if val, ok := value.(map[string]string); ok {
// return val
//}
return map[string]string{}
}
func (c *Config) Load(filepath string) error { func (c *Config) Load(filepath string) error {
err := c.LoadFromYAMLPath(filepath) err := c.LoadFromYAMLPath(filepath)
if err != nil { if err != nil {
...@@ -147,7 +101,7 @@ func (c *Config) Load(filepath string) error { ...@@ -147,7 +101,7 @@ func (c *Config) Load(filepath string) error {
var name, _ = os.Hostname() var name, _ = os.Hostname()
var rootPath, _ = os.Getwd() var rootPath, _ = os.Getwd()
var Conf = &Config{ var Conf = Config{
Name: name, Name: name,
CoreHost: "http://localhost:8080", CoreHost: "http://localhost:8080",
BootstrapToken: "", BootstrapToken: "",
......
This diff is collapsed.
...@@ -233,7 +233,7 @@ func (h *interactiveHandler) displayAssets(assets model.AssetList) { ...@@ -233,7 +233,7 @@ func (h *interactiveHandler) displayAssets(assets model.AssetList) {
h.term.SetPrompt(": ") h.term.SetPrompt(": ")
pag := NewAssetPagination(h.term, assets) pag := NewAssetPagination(h.term, assets)
pag.Initial() pag.Initial()
selectOneAssets := pag.PaginationState() selectOneAssets := pag.Start()
if len(selectOneAssets) == 1 { if len(selectOneAssets) == 1 {
systemUser := h.chooseSystemUser(selectOneAssets[0].SystemUsers) systemUser := h.chooseSystemUser(selectOneAssets[0].SystemUsers)
h.assetSelect = &selectOneAssets[0] h.assetSelect = &selectOneAssets[0]
......
...@@ -80,6 +80,8 @@ func (s *SwitchSession) postBridge() { ...@@ -80,6 +80,8 @@ func (s *SwitchSession) postBridge() {
s.cmdRecorder.End() s.cmdRecorder.End()
s.replayRecorder.End() s.replayRecorder.End()
s.parser.Close() s.parser.Close()
_ = s.userTran.Close()
_ = s.srvTran.Close()
} }
func (s *SwitchSession) Bridge() (err error) { func (s *SwitchSession) Bridge() (err error) {
......
...@@ -76,10 +76,7 @@ func MustLoadServerConfigOnce() { ...@@ -76,10 +76,7 @@ func MustLoadServerConfigOnce() {
} }
func LoadConfigFromServer() (err error) { func LoadConfigFromServer() (err error) {
conf := config.Conf err = authClient.Get(TerminalConfigURL, &config.Conf)
conf.mu.Lock()
defer conf.mu.Unlock()
err = authClient.Get(TerminalConfigURL, conf)
return err return err
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment