更新工具
This commit is contained in:
parent
ebafb109b4
commit
1516520a4b
BIN
cmd/v2/.DS_Store
vendored
Normal file
BIN
cmd/v2/.DS_Store
vendored
Normal file
Binary file not shown.
@ -126,6 +126,9 @@ func (a *assistant) asyncCall() {
|
||||
}()
|
||||
|
||||
req := a.caller.BuildReq()
|
||||
if req.ID == 0 {
|
||||
return
|
||||
}
|
||||
//调用状态 0未调用 1调用结束 2调用超时
|
||||
var callStatus uint32
|
||||
|
||||
@ -180,7 +183,7 @@ func (a *assistant) prepareStop(ctxErr error) {
|
||||
}
|
||||
|
||||
// 发送请求即调用接口
|
||||
func (a *assistant) handleReq(tick <-chan time.Time) {
|
||||
func (a *assistant) handleReq(throttle <-chan time.Time) {
|
||||
for {
|
||||
select {
|
||||
case <-a.ctx.Done():
|
||||
@ -191,7 +194,7 @@ func (a *assistant) handleReq(tick <-chan time.Time) {
|
||||
a.asyncCall()
|
||||
if a.lps > 0 {
|
||||
select {
|
||||
case <-tick:
|
||||
case <-throttle:
|
||||
case <-a.ctx.Done():
|
||||
a.prepareStop(a.ctx.Err())
|
||||
return
|
||||
@ -226,12 +229,12 @@ func (a *assistant) Start() bool {
|
||||
logrus.Debug("AI助手启动")
|
||||
|
||||
// 节流 周期性向目标发送
|
||||
var ticker <-chan time.Time
|
||||
var throttle <-chan time.Time
|
||||
if a.lps > 0 {
|
||||
//间隔时间
|
||||
interval := time.Duration(1e9 / a.lps)
|
||||
logrus.Debugf("启动节流控制 间隔: %v", interval)
|
||||
ticker = time.Tick(interval)
|
||||
throttle = time.Tick(interval)
|
||||
}
|
||||
|
||||
// 初始化上下文和设置取消函数
|
||||
@ -245,7 +248,7 @@ func (a *assistant) Start() bool {
|
||||
|
||||
go func() {
|
||||
logrus.Debug("请求处理中...")
|
||||
a.handleReq(ticker)
|
||||
a.handleReq(throttle)
|
||||
logrus.Infof("停止 调用次数:%d", a.callCount)
|
||||
}()
|
||||
|
||||
|
@ -101,6 +101,7 @@ const (
|
||||
TOOLBAR_PERF_CONF = "配置"
|
||||
TOOLBAR_PERF_LOGIN = "登陆"
|
||||
TOOLBAR_PERF_CREATE = "创角"
|
||||
TOOLBAR_PERF_CHOOSE = "选项"
|
||||
TOOLBAR_PERF_PB = "协议"
|
||||
TOOLBAR_PERF_RES = "结果"
|
||||
|
||||
|
@ -1,16 +1,21 @@
|
||||
package lib
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 处理器接口
|
||||
type Handler interface {
|
||||
SetReq(req []byte)
|
||||
SetReq(req []byte, flag bool)
|
||||
// 处理请求
|
||||
BuildReq() RawReq
|
||||
//调用
|
||||
Call(req []byte) ([]byte, error)
|
||||
// 检查响应
|
||||
Check(req RawReq, rsp RawResp) *CallResult
|
||||
|
||||
GetConnMap() sync.Map
|
||||
}
|
||||
|
||||
// 调用结果
|
||||
|
56
cmd/v2/lib/quen.go
Normal file
56
cmd/v2/lib/quen.go
Normal file
@ -0,0 +1,56 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Queue[T any] struct {
|
||||
data []T
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewQueue[T any]() *Queue[T] {
|
||||
return &Queue[T]{data: make([]T, 0)}
|
||||
}
|
||||
|
||||
func (this *Queue[T]) Add(obj T) {
|
||||
this.lock.Lock()
|
||||
defer this.lock.Unlock()
|
||||
this.data = append(this.data, obj)
|
||||
}
|
||||
|
||||
func (this *Queue[T]) List() []T {
|
||||
this.lock.RLock()
|
||||
defer this.lock.RUnlock()
|
||||
list := make([]T, 0, len(this.data))
|
||||
for _, v := range this.data {
|
||||
list = append(list, v)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func (this *Queue[T]) Get(index int) (T, bool) {
|
||||
this.lock.RLock()
|
||||
defer this.lock.RUnlock()
|
||||
|
||||
var ret T
|
||||
if index < 0 || index >= len(this.data) {
|
||||
return ret, false
|
||||
}
|
||||
|
||||
return this.data[index], true
|
||||
}
|
||||
|
||||
func (this *Queue[T]) Pop() (T, error) {
|
||||
this.lock.Lock()
|
||||
defer this.lock.Unlock()
|
||||
var ret T
|
||||
if len(this.data) == 0 {
|
||||
return ret, fmt.Errorf("not found")
|
||||
}
|
||||
|
||||
pop := this.data[0]
|
||||
this.data = this.data[1:]
|
||||
return pop, nil
|
||||
}
|
@ -164,7 +164,7 @@ func setupLogger() (err error) {
|
||||
// FullTimestamp: true,
|
||||
})
|
||||
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetOutput(os.Stdout)
|
||||
|
||||
//设置output,默认为stderr,可以为任何io.Writer,比如文件*os.File
|
||||
|
@ -21,6 +21,6 @@ services:
|
||||
name: 李伟
|
||||
url: ws://10.0.0.85:7891/gateway
|
||||
- service:
|
||||
sid: "0"
|
||||
name: 广告位
|
||||
url:
|
||||
sid: "df01"
|
||||
name: 压测服
|
||||
url: ws://106.54.189.74:7891/gateway
|
||||
|
@ -42,7 +42,7 @@ func TestStart(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
h.SetReq(b)
|
||||
h.SetReq(b, false)
|
||||
param := lib.ParamMgr{
|
||||
Caller: h,
|
||||
Timeout: 50 * time.Millisecond,
|
||||
|
@ -1,33 +1,48 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"go_dreamfactory/cmd/v2/lib"
|
||||
"go_dreamfactory/cmd/v2/lib/common"
|
||||
"go_dreamfactory/comm"
|
||||
"go_dreamfactory/lego/sys/log"
|
||||
"go_dreamfactory/pb"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type WsCli struct {
|
||||
addr string
|
||||
conn *websocket.Conn
|
||||
reqData []byte //请求数据
|
||||
// reqData []byte //请求数据
|
||||
uid string
|
||||
reqDatas *lib.Queue[[]byte]
|
||||
conns sync.Map
|
||||
flag bool
|
||||
reqData []byte
|
||||
}
|
||||
|
||||
func NewWsCli(addr string, timeout time.Duration) (lib.Handler, error) {
|
||||
cli := &WsCli{addr: addr}
|
||||
if err := cli.connect(timeout); err != nil {
|
||||
return nil, err
|
||||
cli := &WsCli{
|
||||
addr: addr,
|
||||
reqDatas: lib.NewQueue[[]byte](),
|
||||
}
|
||||
// if err := cli.connect(timeout); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
return cli, nil
|
||||
}
|
||||
|
||||
func (cli *WsCli) GetConnMap() sync.Map {
|
||||
return cli.conns
|
||||
}
|
||||
|
||||
func (cli *WsCli) connect(timeout time.Duration) error {
|
||||
if cli.conn == nil {
|
||||
dialer := &websocket.Dialer{
|
||||
@ -55,7 +70,7 @@ func (cli *WsCli) connect(timeout time.Duration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查登录相应
|
||||
// 检查相应
|
||||
func (cli *WsCli) checkResp(data []byte) bool {
|
||||
msg := &pb.UserMessage{}
|
||||
if err := proto.Unmarshal(data, msg); err != nil {
|
||||
@ -97,7 +112,12 @@ func (cli *WsCli) checkPush(data []byte) bool {
|
||||
|
||||
if strings.HasSuffix(methodName, "Push") {
|
||||
if methodName == "NotifyErrorNotifyPush" {
|
||||
logrus.WithField("methodName", methodName).Debug("收到错误码")
|
||||
push := &pb.NotifyErrorNotifyPush{}
|
||||
if !comm.ProtoUnmarshal(msg, push) {
|
||||
logrus.Error("unmarsh err")
|
||||
return false
|
||||
}
|
||||
logrus.WithField("methodName", methodName).WithField("code", push.Code).Debug("收到错误码")
|
||||
} else {
|
||||
logrus.WithField("methodName", methodName).Debug("收到推送")
|
||||
}
|
||||
@ -106,35 +126,88 @@ func (cli *WsCli) checkPush(data []byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (cli *WsCli) SetReq(data []byte) {
|
||||
func (cli *WsCli) SetReq(data []byte, flag bool) {
|
||||
cli.flag = flag
|
||||
if flag {
|
||||
cli.reqData = data
|
||||
}
|
||||
cli.reqDatas.Add(data)
|
||||
}
|
||||
|
||||
func (cli *WsCli) BuildReq() lib.RawReq {
|
||||
id := time.Now().UnixNano()
|
||||
rawReq := lib.RawReq{ID: id, Req: cli.reqData}
|
||||
var (
|
||||
data []byte
|
||||
err error
|
||||
)
|
||||
|
||||
data, err = cli.reqDatas.Pop()
|
||||
if err != nil {
|
||||
if cli.flag {
|
||||
data = cli.reqData
|
||||
} else {
|
||||
return lib.RawReq{}
|
||||
}
|
||||
}
|
||||
|
||||
rawReq := lib.RawReq{ID: id, Req: data}
|
||||
return rawReq
|
||||
}
|
||||
|
||||
func (cli *WsCli) Call(req []byte) ([]byte, error) {
|
||||
msg := &pb.UserMessage{}
|
||||
if err := proto.Unmarshal(req, msg); err != nil {
|
||||
logrus.Error("结果解析失败")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base64Str := msg.Sec
|
||||
dec, err := base64.StdEncoding.DecodeString(base64Str[35:])
|
||||
if err != nil {
|
||||
log.Errorf("base64 decode err %v", err)
|
||||
return nil, err
|
||||
}
|
||||
jsonRet := gjson.Parse(string(dec))
|
||||
|
||||
account := jsonRet.Get("account").String()
|
||||
|
||||
dialer := &websocket.Dialer{
|
||||
HandshakeTimeout: 2 * time.Second,
|
||||
}
|
||||
var conn *websocket.Conn
|
||||
if c, ok := cli.conns.Load(account); ok {
|
||||
conn = c.(*websocket.Conn)
|
||||
} else {
|
||||
conn, _, err = dialer.Dial(cli.addr, nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("websocket conn err:%v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if msg.MainType == "user" && msg.SubType == "login" {
|
||||
cli.conns.Store(account, conn)
|
||||
}
|
||||
|
||||
// 向连接写数据
|
||||
cli.conn.WriteMessage(websocket.BinaryMessage, req)
|
||||
conn.WriteMessage(websocket.BinaryMessage, req)
|
||||
|
||||
// 读数据
|
||||
var res []byte
|
||||
for {
|
||||
_, data, err := cli.conn.ReadMessage()
|
||||
_, data, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
logrus.Errorf("readMessage err:%v", err)
|
||||
break
|
||||
}
|
||||
|
||||
if cli.checkResp(data) {
|
||||
// if cli.checkResp(data) {
|
||||
// return data, nil
|
||||
// } else {
|
||||
if !cli.checkPush(data) {
|
||||
return data, nil
|
||||
} else {
|
||||
cli.checkPush(data)
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
@ -39,6 +39,7 @@ var (
|
||||
&perfConf{},
|
||||
&perfPb{},
|
||||
&perfResult{},
|
||||
&perfChoose{},
|
||||
}
|
||||
)
|
||||
|
||||
|
226
cmd/v2/ui/perf_choose.go
Normal file
226
cmd/v2/ui/perf_choose.go
Normal file
@ -0,0 +1,226 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
cfg "go_dreamfactory/cmd/v2/configure/structs"
|
||||
"go_dreamfactory/cmd/v2/lib"
|
||||
"go_dreamfactory/cmd/v2/lib/common"
|
||||
"go_dreamfactory/cmd/v2/lib/storage"
|
||||
"go_dreamfactory/cmd/v2/service"
|
||||
"go_dreamfactory/cmd/v2/service/observer"
|
||||
"go_dreamfactory/comm"
|
||||
"go_dreamfactory/pb"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/layout"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"github.com/Pallinder/go-randomdata"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type perfChoose struct {
|
||||
appAdapter
|
||||
|
||||
obs observer.Observer
|
||||
conf *storage.Config
|
||||
binduids []string //账号
|
||||
handler lib.Handler
|
||||
}
|
||||
|
||||
func (app *perfChoose) LazyInit(ptService service.PttService, obs observer.Observer) error {
|
||||
app.obs = obs
|
||||
app.conf = perfWin.UIImpl.config
|
||||
|
||||
app.tabItem = container.NewTabItemWithIcon(common.TOOLBAR_PERF_CHOOSE, theme.ContentCopyIcon(), nil)
|
||||
content := container.NewMax()
|
||||
content.Objects = []fyne.CanvasObject{}
|
||||
|
||||
loginTestBtn := widget.NewButton("登陆(注册)", nil)
|
||||
loginTestBtn.OnTapped = func() {
|
||||
closeApp3(perfWin.tabs, common.TOOLBAR_PERF_CHOOSE)
|
||||
openApp3(perfWin.tabs, common.TOOLBAR_PERF_RES)
|
||||
var err error
|
||||
|
||||
app.handler, err = service.NewWsCli(app.conf.WsAddr, 2*time.Second)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
userCount := app.conf.UserCount
|
||||
for i := int32(0); i < userCount; i++ {
|
||||
account := randomdata.SillyName()
|
||||
app.binduids = append(app.binduids, account)
|
||||
// 登录
|
||||
rqLogin := ReqParams{
|
||||
Sid: app.conf.SId,
|
||||
Account: account,
|
||||
PbReq: &pb.UserLoginReq{Sid: app.conf.SId, Account: account},
|
||||
MainType: "user",
|
||||
SubType: "login",
|
||||
}
|
||||
b, err := app.buildReq(rqLogin)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
app.handler.SetReq(b, false)
|
||||
|
||||
}
|
||||
|
||||
param := lib.ParamMgr{
|
||||
Caller: app.handler,
|
||||
Timeout: time.Duration(app.conf.Pressure.TimeoutMs) * time.Millisecond,
|
||||
Lps: uint32(app.conf.Pressure.Concurrency),
|
||||
Duration: time.Duration(app.conf.Pressure.DurationS) * time.Second,
|
||||
ResultCh: make(chan *lib.CallResult, 50),
|
||||
}
|
||||
a, err := lib.NewAssistant(obs, param)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
a.Start()
|
||||
|
||||
a.ShowResult()
|
||||
}
|
||||
|
||||
createTestBtn := widget.NewButton("创角", func() {
|
||||
closeApp3(perfWin.tabs, common.TOOLBAR_PERF_CHOOSE)
|
||||
openApp3(perfWin.tabs, common.TOOLBAR_PERF_RES)
|
||||
|
||||
for _, account := range app.binduids {
|
||||
rq := ReqParams{
|
||||
Sid: app.conf.SId,
|
||||
Account: account,
|
||||
PbReq: &pb.UserCreateReq{NickName: account},
|
||||
MainType: "user",
|
||||
SubType: "create",
|
||||
}
|
||||
b, err := app.buildReq(rq)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
app.handler.SetReq(b, false)
|
||||
}
|
||||
|
||||
param := lib.ParamMgr{
|
||||
Caller: app.handler,
|
||||
Timeout: time.Duration(app.conf.Pressure.TimeoutMs) * time.Millisecond,
|
||||
Lps: uint32(app.conf.Pressure.Concurrency),
|
||||
Duration: time.Duration(app.conf.Pressure.DurationS) * time.Second,
|
||||
ResultCh: make(chan *lib.CallResult, 50),
|
||||
}
|
||||
a, err := lib.NewAssistant(obs, param)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
a.Start()
|
||||
|
||||
a.ShowResult()
|
||||
})
|
||||
|
||||
//场景
|
||||
scenBtn := widget.NewButton("其它场景", nil)
|
||||
scenBtn.OnTapped = func() {
|
||||
// defer openApp3(perfWin.tabs, common.TOOLBAR_PERF_PB)
|
||||
// closeApp3(perfWin.tabs, common.TOOLBAR_PERF_CHOOSE)
|
||||
closeApp3(perfWin.tabs, common.TOOLBAR_PERF_CHOOSE)
|
||||
openApp3(perfWin.tabs, common.TOOLBAR_PERF_RES)
|
||||
|
||||
if tables, err := cfg.NewTables(common.Loader); err != nil {
|
||||
println(err.Error())
|
||||
} else {
|
||||
for _, v := range tables.TestFlow.GetDataList() {
|
||||
p, ok := pbMap[v.Route]
|
||||
if !ok {
|
||||
logrus.WithField("route", v.Route).Debug("未注册")
|
||||
continue
|
||||
}
|
||||
routeStr := strings.SplitN(v.Route, ".", 2)
|
||||
for _, account := range app.binduids {
|
||||
rq := ReqParams{
|
||||
Sid: app.conf.SId,
|
||||
Account: account,
|
||||
PbReq: p,
|
||||
MainType: routeStr[0],
|
||||
SubType: routeStr[1],
|
||||
}
|
||||
b, err := app.buildReq(rq)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
app.handler.SetReq(b, true)
|
||||
}
|
||||
|
||||
param := lib.ParamMgr{
|
||||
Caller: app.handler,
|
||||
Timeout: time.Duration(app.conf.Pressure.TimeoutMs) * time.Millisecond,
|
||||
Lps: uint32(app.conf.Pressure.Concurrency),
|
||||
Duration: time.Duration(app.conf.Pressure.DurationS) * time.Second,
|
||||
ResultCh: make(chan *lib.CallResult, 50),
|
||||
}
|
||||
a, err := lib.NewAssistant(obs, param)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
a.Start()
|
||||
|
||||
a.ShowResult()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//上一步
|
||||
preBtn := widget.NewButtonWithIcon("上一步", theme.NavigateBackIcon(), nil)
|
||||
preBtn.OnTapped = func() {
|
||||
defer openApp3(perfWin.tabs, common.TOOLBAR_PERF_CONF)
|
||||
closeApp3(perfWin.tabs, common.TOOLBAR_PERF_CHOOSE)
|
||||
}
|
||||
btns := container.NewVBox(loginTestBtn, createTestBtn, scenBtn)
|
||||
c := container.NewBorder(nil, container.NewHBox(layout.NewSpacer(), preBtn), nil, nil, btns)
|
||||
content.Objects = append(content.Objects, c)
|
||||
app.tabItem.Content = content
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *perfChoose) GetAppName() string {
|
||||
return common.TOOLBAR_PERF_CHOOSE
|
||||
}
|
||||
|
||||
func (a *perfChoose) OnClose() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *perfChoose) OnDestroy() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type ReqParams struct {
|
||||
Sid string
|
||||
Account string
|
||||
PbReq proto.Message
|
||||
MainType string
|
||||
SubType string
|
||||
}
|
||||
|
||||
func (a *perfChoose) buildReq(rp ReqParams) ([]byte, error) {
|
||||
head := &pb.UserMessage{MainType: rp.MainType, SubType: rp.SubType}
|
||||
head.Sec = common.BuildSecStr(rp.Sid, rp.Account)
|
||||
if comm.ProtoMarshal(rp.PbReq, head) {
|
||||
data, err := proto.Marshal(head)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
@ -115,7 +115,7 @@ func (app *perfConf) LazyInit(ptService service.PttService, obs observer.Observe
|
||||
|
||||
//next
|
||||
defer closeApp3(perfWin.tabs, common.TOOLBAR_PERF_CONF)
|
||||
openApp3(perfWin.tabs, common.TOOLBAR_PERF_PB)
|
||||
openApp3(perfWin.tabs, common.TOOLBAR_PERF_CHOOSE)
|
||||
}
|
||||
|
||||
resetBtn := widget.NewButtonWithIcon("重置", theme.ContentRedoIcon(), nil)
|
||||
|
@ -84,7 +84,7 @@ func (app *perfPb) LazyInit(ptService service.PttService, obs observer.Observer)
|
||||
}
|
||||
var login *UserLogin
|
||||
login, err = app.loginReq(perfWin.config.SId)
|
||||
handler.SetReq(login.req)
|
||||
handler.SetReq(login.req, false)
|
||||
assist := app.createAssistantWithoutConf(handler)
|
||||
assist.Start()
|
||||
assist.ShowResult()
|
||||
@ -127,7 +127,7 @@ func (app *perfPb) LazyInit(ptService service.PttService, obs observer.Observer)
|
||||
}
|
||||
// }
|
||||
|
||||
handler.SetReq(reqData)
|
||||
handler.SetReq(reqData, false)
|
||||
assist := app.createAssistant(handler)
|
||||
assist.Start()
|
||||
assist.ShowResult()
|
||||
|
@ -48,13 +48,21 @@ func (app *perfResult) LazyInit(ptService service.PttService, obs observer.Obser
|
||||
closeApp3(perfWin.tabs, common.TOOLBAR_PERF_RES)
|
||||
}
|
||||
|
||||
// 返回
|
||||
returnBtn := widget.NewButtonWithIcon("返回", theme.NavigateBackIcon(), nil)
|
||||
returnBtn.OnTapped = func() {
|
||||
defer openApp3(perfWin.tabs, common.TOOLBAR_PERF_CHOOSE)
|
||||
app.itemList.Reset()
|
||||
closeApp3(perfWin.tabs, common.TOOLBAR_PERF_RES)
|
||||
}
|
||||
|
||||
//统计Panel
|
||||
app.report = widget.NewCard("测试报告", "登录/创角", container.NewVBox(
|
||||
// widget.NewLabel("结果:"),
|
||||
))
|
||||
app.report.Hide()
|
||||
//layout
|
||||
c := container.NewBorder(app.report, container.NewHBox(layout.NewSpacer(), app.resetBtn), nil, nil, app.itemList.ItemList)
|
||||
c := container.NewBorder(app.report, container.NewHBox(layout.NewSpacer(), app.resetBtn, returnBtn), nil, nil, app.itemList.ItemList)
|
||||
content.Objects = append(content.Objects, c)
|
||||
app.tabItem.Content = content
|
||||
app.listen()
|
||||
|
Loading…
Reference in New Issue
Block a user