package main import ( "bufio" "encoding/json" "flx/Common" "flx/DAL" FLXDevice "flx/Device" "flx/Device/FLXCheckInController" "flx/Device/FLXNetworkController" "flx/Model" "flx/localcache" "flx/routers" "flx/websocketservers" "fmt" "image/color" "io" "sync" "math" "net/http" "net/url" "os" "path" "strconv" "strings" "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "github.com/flopp/go-findfont" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/jlaffaye/ftp" log "github.com/sirupsen/logrus" ) // 默认加载 func init() { defer func() { if r := recover(); r != nil { log.Error("init:", r) } }() IsGetDate = true fontPaths := findfont.List() for _, path := range fontPaths { //fmt.Println(path) //楷体:simkai.ttf //黑体:simhei.ttf //windows: simkai.ttf //麒麟: CESI_KT_GB2312.TTF if strings.Contains(path, "CESI_KT_GB2312.TTF") || strings.Contains(path, "simkai.ttf") { os.Setenv("FYNE_FONT", path) break } } fmt.Println("=============") os.Setenv("FYNE_SCALE", "0.5") } // 主窗体 var MainWindow fyne.Window // 发卡界面 var CardWindow fyne.Window // 大屏 var ScreenWindow fyne.Window // APP var NAPP fyne.App // 当前选择会议ID var CurrentSelectAgendaID string // 当前选择会议级别 var CurrentSelectLevel string // 会议状态 0 未召开 1已召开 2 已报到 var CrrentCongressStatus int // var magnify float32 = 1 var AgendaName string // 是否获取数据 var IsGetDate bool = true //------------------------------------------------------------------------------------------ // var CurrentScreenSessionStatus Common.SessionStatus // // id对应字典表 // var MDDictionary map[string]*Model.TDictionary // var Currentreportper *Model.T_AgendaPerson = nil // // 基础人员map // var MStIDStaffInfo map[string]*Model.T_StaffInfo // // 民族字典表 // var MNations map[string]*Model.TDicNation // var MGroups map[string]*Model.TStaffgroup // var MIDStaffCategory map[string]*Model.TStaffcategory // var SysSets []*Model.TSysset // var AllSysSet map[string]*Model.TSysset // var AllScren []Model.TScreen // var MIDScren = make(map[string]Model.TScreen) // // 所有窗体 // var AllScrenForm []Model.TScreenform // // 所有窗体事件 // var AllScreenFormEvent []Model.TScreenformevent // //问题:上面的都是新加的从cpcs获取----------------------------------------------------------------------------------- // // 可修改应到人数 // var CanChangePersonDueCount int // // 可修改实到人数 // var CanChangePersonInCount int // // 当前会议议题 // var CurrentTopic *Model.TTopic // var CurrentTopicChildTopic []*Model.TTopic // // 大屏多项议题当前议题编号 // var IndexChildTopic int // // 大屏多项议题当前页 // var IndexPageTopic int // // 全部按键人数 // var FinishPerson int // // 部分按键人数 // var PartFinishPerson int // // 未按键人数 // var NoPressPerson int // // 定时表决剩余时间 // var VoteCursorTimer int // // 申请发言人员 // var ApplySpeakPersons []*Model.SpeakingPerson // // 发言人员 // var SpeakingPersons []*Model.SpeakingPerson // // 发言过人员列表 // var SpeakedPersons []*Model.T_AgendaPerson // // var MScreenData map[string]map[string]interface{} // var MScreenData = make(map[string]map[string]interface{}) //----------------------------------------------------------------------------------------------------------------------------------- func main() { // a := app.New() // w := a.NewWindow("窗口尺寸监控") // sizeLabel := widget.NewLabel("初始化中...") // updateSize := func() { // size := w.Canvas().Size() // sizeLabel.SetText(fmt.Sprintf("窗口尺寸: %.0f×%.0f", size.Width, size.Height)) // fmt.Println("窗口尺寸: %.0f×%.0f", size.Width, size.Height) // } // content := container.NewVBox( // sizeLabel, // widget.NewButton("刷新尺寸", updateSize), // ) // 自动刷新 // go func() { // for range time.Tick(300 * time.Millisecond) { // updateSize() // } // }() // w.SetContent(content) // w.Resize(fyne.NewSize(400, 300)) // w.ShowAndRun() defer func() { if r := recover(); r != nil { log.Error("main:", r) } }() Common.InitLog("./log/", "", "gb18030") log.WithFields(log.Fields{"animal": "walrus"}).Info("A walrus appears") // go initsocket() go func() { go websocketservers.Manager.Start() engine := gin.Default() server := &http.Server{ Addr: ":9999", Handler: routers.InitRouter(engine), } if err := server.ListenAndServe(); err != nil { log.Fatal("HTTP服务错误", err) } }() MainWindowControl() // DownFile2("https://img-blog.csdnimg.cn/20200701203719488.png") select {} } func initsocket() { websocketservers.Manager.Start() gin.ForceConsoleColor() gin.SetMode("debug") engine := gin.Default() server := &http.Server{ Addr: ":9999", Handler: routers.InitRouter(engine), ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } log.Println(" Connect used httpport " + "9999" + " ..") if err := server.ListenAndServe(); err != nil { log.Fatal("gin错误", err) } } // 主窗体加载 func MainWindowControl() { defer func() { if r := recover(); r != nil { log.Error("MainWindowControl:", r) } }() CFLXCfig = Common.LoadConfig() BigPara = CFLXCfig.CheckInDoor.BigPara NAPP = app.NewWithID("FlxCongress") fyne.CurrentApp().Settings().SetTheme(theme.LightTheme()) iconResource, _ := fyne.LoadResourceFromPath("icon.ico") MainWindow = NAPP.NewWindow("飞利信报道门系统") MainWindow.SetIcon(iconResource) mainview = container.NewMax() if CFLXCfig.Other.ISServer { mainview.Add(ServerViewLayout()) } else { mainview.Add(DefaultLayout()) } mainview.Refresh() // mainview.Add(ReportLayout()) MainWindow.SetContent(mainview) // MainWindow.Maxwindow() // MainWindow.Resize(fyne.NewSize(1920, 1080), 0, 100) // width, height := robotgo.GetScreenSize() // fmt.Printf("当前屏幕尺寸: 宽度 = %d, 高度 = %d\n", width, height) MainWindow.Resize(fyne.NewSize(1920*BigPara, 1080*BigPara)) // MainWindow.Canvas().Size().Max(fyne.NewSize(1920, 1080)) MainWindow.Show() // MainWindow.SetFullScreen(true) //设置全屏 // 获取设备像素比例 // dpr := MainWindow.Canvas().Scale() // 直接获取统一 DPR:ml-citation{ref="3,12" data="citationList"} // fmt.Println("dpr", dpr) // scale := canvas.Scale() // // 计算物理像素分辨率 // physicalWidth := int(float32(logicWidth) * scale) // physicalHeight := int(float32(logicHeight) * scale) // fmt.Printf("物理像素分辨率: %dx%d\n", physicalWidth, physicalHeight) MainWindow.CenterOnScreen() MainWindow.SetMaster() // MergePersonImage() // go InitSocketServer() //网络监听 FLXNetworkController.FLXNetConnect.InitFlxNetControl() FLXNetworkController.FLXNetConnect.InvokeDeviceEventHandler = OnDeviceEventHandler //自定义二屏 go SMainWindowControl() MainWindow.SetCloseIntercept(func() { fmt.Println("正在执行自定义操作...") // 此处添加业务逻辑 closeChromeWindow(ChromeCmd) MainWindow.Close() }) MainWindow.ShowAndRun() // dpr := MainWindow.Canvas().Scale() // 正确时机 // fmt.Println("dpr", dpr) } func InitSocketServer() { defer func() { if r := recover(); r != nil { log.Error("InitSocketServer:", r) } }() serverAddr := "ws://" + Common.LoadConfig().SeverData.ServerIP + ":9800/vhwcapi/v1/websocket/ccuwebsocket?userid=rdoor" // 建立 WebSocket 连接 conn, _, err := websocket.DefaultDialer.Dial(serverAddr, nil) if err != nil { log.Fatal("Dial failed:", err) } defer conn.Close() // 循环读取消息 for { // ReadMessage 返回消息类型和消息内容 msgType, msg, err := conn.ReadMessage() if err != nil { log.Println("Error reading message:", err) break } var result map[string]interface{} err = json.Unmarshal(msg, &result) if err != nil { log.Fatal(err) } var agendaPersons []Model.T_AgendaPerson = make([]Model.T_AgendaPerson, 0) // 打印收到的消息 switch msgType { case websocket.TextMessage: if result["contenttype"].(string) == "AgendaForCheckDoor" { // AgendaName = result["datarecord"].(map[string]interface{})["agendaname"].(string) // lblAgendaName.Text = AgendaName // lblAgendaName.Refresh() // CurrentAgenda = result["datarecord"].(map[string]interface{})["currentAgenda"].(Model.T_Agenda) dataRecord, ok := result["datarecord"].(map[string]interface{}) if !ok { log.Fatal("datarecord 类型断言失败") } // 将 map 转换为 JSON 字节流 currentAgendaBytes, err := json.Marshal(dataRecord["currentAgenda"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(currentAgendaBytes, &localcache.CurrentAgenda); err != nil { log.Fatal("JSON反序列化失败:", err) } currentCongressBytes, err := json.Marshal(dataRecord["currentCongress"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(currentCongressBytes, &localcache.CurrentCongress); err != nil { log.Fatal("JSON反序列化失败:", err) } // CurrentCongress = result["datarecord"].(map[string]interface{})["currentCongress"].(Model.T_Congress) fmt.Println(result) // 第一步:断言为[]interface{} rawSlice, ok := result["datarecord"].(map[string]interface{})["agendaperson"].([]interface{}) fmt.Println("rawSlice", rawSlice) if !ok { fmt.Errorf("agendaperson字段类型断言失败") } // 第二步:遍历转换元素 // 3. 遍历转换每个元素 for _, item := range rawSlice { personMap := item.(map[string]interface{}) // 4. 逐个字段映射 var person Model.T_AgendaPerson person.AP_ID = personMap["Id"].(string) person.AP_StaffID = personMap["Ap_staffid"].(string) person.AP_StaffInfo.St_Name = personMap["Ap_name"].(string) person.AP_StaffInfo.St_Image = personMap["St_Image"].(string) person.AP_CodeNum = personMap["Ap_codenum"].(string) person.AP_StaffInfo.St_ViceCardNum = personMap["St_ViceCardNum"].(string) person.AP_StaffInfo.St_ViceCardNumA = personMap["St_ViceCardNuma"].(string) person.AP_StaffInfo.St_ViceCardNumB = personMap["St_ViceCardNumb"].(string) // 5. 处理时间字段 checkinTime, _ := time.Parse(time.RFC3339, personMap["Ap_checkintime"].(string)) person.AP_CheckInTime = checkinTime checkoutTime, _ := time.Parse(time.RFC3339, personMap["Ap_checkouttime"].(string)) person.AP_CheckOutTime = checkoutTime // 6. 数值类型转换 person.AP_CheckState = int(personMap["Ap_checkstate"].(float64)) person.AP_AgendaID = personMap["Ap_agendaid"].(string) person.AP_CardType = int(personMap["AP_CardType"].(float64)) person.AP_ReportPower = int(personMap["AP_ReportPower"].(float64)) person.AP_VotePower = int(personMap["AP_VotePower"].(float64)) person.AP_SpeakPower = int(personMap["AP_SpeakPower"].(float64)) person.AP_FirstSpeakPower = int(personMap["AP_FirstSpeakPower"].(float64)) person.AP_CallPower = int(personMap["AP_CallPower"].(float64)) person.AP_SearchPower = int(personMap["AP_SearchPower"].(float64)) person.AP_Status = personMap["AP_Status"].(string) person.AP_Remark = personMap["AP_Remark"].(string) person.AP_Moderator = int(personMap["AP_Moderator"].(float64)) agendaPersons = append(agendaPersons, person) } // AgendaPerson = agendaPersons var allPersonPtrs []*Model.T_AgendaPerson for _, p := range agendaPersons { personCopy := p // 创建一个副本 allPersonPtrs = append(allPersonPtrs, &personCopy) } localcache.ALLAPinfo = agendaPersons localcache.AllPerson = allPersonPtrs if APersonlist != nil { fyne.DoAndWait(func() { APersonlist.Refresh() }) } } if result["contenttype"].(string) == "Report" { fmt.Println("收到Report数据", result) rawSlice, ok := result["datarecord"].(map[string]interface{})["ArrPerson"].([]interface{}) if !ok { fmt.Errorf("agendaperson字段类型断言失败") } for _, itemperson := range rawSlice { for j, item := range agendaPersons { if item.AP_ID == itemperson.(map[string]interface{})["Ap_Id"].(string) { if itemperson.(map[string]interface{})["Ap_status"].(string) == "已报到" { agendaPersons[j].AP_CheckState = 1 } checkinTime, _ := time.Parse(time.RFC3339, itemperson.(map[string]interface{})["AP_CheckInTime"].(string)) agendaPersons[j].AP_CheckInTime = checkinTime // checkoutTime, _ := time.Parse(time.RFC3339, itemperson.(map[string]interface{})["Ap_checkouttime"].(string)) // item.Ap_checkouttime = checkoutTime } } } // AgendaPerson = agendaPersons } case websocket.BinaryMessage: log.Printf("Received binary message: %v\n", msg) default: log.Println("Received unknown message type") } } } // 会议名称 var lblCongressName *canvas.Text // 议程名称 var lblAgendaName *canvas.Text // 主窗体主体 var mainview *fyne.Container // 默认屏幕 func DefaultLayout() fyne.CanvasObject { defer func() { if r := recover(); r != nil { log.Error("DefaultLayout:", r) } }() // GPersonlist := widget.NewTable( // func() (int, int) { return 2, 2 }, // func() fyne.CanvasObject { // return widget.NewLabel("") // }, // func(id widget.TableCellID, cell fyne.CanvasObject) { // label := cell.(*widget.Label) // switch id.Col { // case 0: // Ceshi = Ceshi + 1 // label.SetText(strconv.Itoa(Ceshi)) // case 1: // label.SetText("MM") // } // }) // GPersonlist.OnSelected = func(id widget.TableCellID) { // CurrentSCID = id // } // GPersonlist.SetColumnWidth(0, 70) // GPersonlist.Resize(fyne.NewSize(150, 150)) // GPersonlist.Move(fyne.NewPos(50, 50)) //国徽 图标 var imagepath string iconType := Common.LoadConfig().CheckInDoor.IconType if iconType == "1" { imagepath = "./images/guohui.png" } if iconType == "2" { imagepath = "./images/huibiao.png" } imgIcon := canvas.NewImageFromFile(imagepath) // imgIcon.Resize(fyne.NewSize(500, 500)) // // 设置图像位置为屏幕宽度的 50% 和高度的 20% // imgIcon.Move(fyne.NewPos(1920*0.5, 1080*0.2)) imgIcon.Resize(fyne.NewSize(300*BigPara, 300*BigPara)) imgIcon.Move(fyne.NewPos(810*BigPara, 100*BigPara)) // 系统名称 或 会议名称 lblCongressName = canvas.NewText("飞利信报道门系统", color.Black) lblCongressName.TextSize = 150 lblCongressName.Alignment = fyne.TextAlignCenter lblCongressName.Resize(fyne.NewSize(1920*BigPara, 200*BigPara)) lblCongressName.Move(fyne.NewPos(10*BigPara, 500*BigPara)) // 系统名称 或 会议名称 lblAgendaName = canvas.NewText(AgendaName, color.Black) lblAgendaName.TextSize = 150 lblAgendaName.Alignment = fyne.TextAlignCenter lblAgendaName.Resize(fyne.NewSize(1920*BigPara, 200*BigPara)) lblAgendaName.Move(fyne.NewPos(0, 700*BigPara)) //在线图标 imgOnline := canvas.NewImageFromFile(imagepath) imgOnline.Resize(fyne.NewSize(50*BigPara, 50*BigPara)) imgOnline.Move(fyne.NewPos(50*BigPara, 1000*BigPara)) //时间 lblTime = canvas.NewText("2021年11月22日 16:56", color.Black) lblTime.TextSize = 20 lblTime.Alignment = fyne.TextAlignCenter lblTime.Resize(fyne.NewSize(300*BigPara, 50*BigPara)) lblTime.Move(fyne.NewPos(150*BigPara, 1000*BigPara)) LblLine = canvas.NewText(localcache.LineStatus, color.Black) LblLine.TextSize = 20 LblLine.Alignment = fyne.TextAlignCenter LblLine.Resize(fyne.NewSize(300*BigPara, 50*BigPara)) LblLine.Move(fyne.NewPos(400*BigPara, 1000*BigPara)) // datebind := binding.NewString() // checkLabel := widget.NewLabelWithData(datebind) // lbltext := widget.NewLabel(time.Now().Format("2006年01月02日 15:04:05")) // lblTime := widget.NewLabel(time.Now().Format("2006年01月02日 15:04:05")) // lblTime.Alignment = fyne.TextAlignCenter // lblTime.Resize(fyne.NewSize(300, 50)) // lblTime.Move(fyne.NewPos(150, 1000)) // ShowTime1(lblt) //同步照片 btnMergeImage := widget.NewButton("同步照片", func() { //同步照片 MergePersonImage() w := fyne.CurrentApp().NewWindow("提示") w.SetContent(fyne.NewContainerWithLayout(layout.NewCenterLayout(), widget.NewLabel("同步照片完成!"))) // w.Resize(fyne.NewSize(200, 100), 0, 1) w.Resize(fyne.NewSize(200*BigPara, 100*BigPara)) w.CenterOnScreen() w.Show() go func() { time.Sleep(time.Second * 2) w.Close() }() }) btnMergeImage.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) btnMergeImage.Move(fyne.NewPos(1000*BigPara, 1000*BigPara)) //证卡管理 btnCardManage := widget.NewButton("证卡管理", func() { //证卡管理 // go SetCardWindowControl() fyne.DoAndWait(func() { SetCardWindowControl() }) }) btnCardManage.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) btnCardManage.Move(fyne.NewPos(1200*BigPara, 1000*BigPara)) btnPersonManage := widget.NewButton("人员管理", func() { //人员管理 // go AgendaPersonWindowControl() //使用DoAndWait确保在主线程执行 否则会报错,可能会导致软件崩溃 fyne.DoAndWait(func() { AgendaPersonWindowControl() }) }) btnPersonManage.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) btnPersonManage.Move(fyne.NewPos(1400*BigPara, 1000*BigPara)) //退出 btnClose := widget.NewButton("退出", func() { closeChromeWindow(ChromeCmd) MainWindow.Close() // GPersonlist.Refresh() }) btnClose.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) btnClose.Move(fyne.NewPos(1600*BigPara, 1000*BigPara)) content := container.NewWithoutLayout( btnMergeImage, imgIcon, lblTime, lblCongressName, lblAgendaName, imgOnline, btnClose, btnCardManage, btnPersonManage, LblLine, ) go ShowTime(lblTime) return content } // 服务器默认界面 func ServerViewLayout() fyne.CanvasObject { defer func() { if r := recover(); r != nil { log.Error("ServerViewLayout:", r) } }() lblTime = canvas.NewText("2021年11月22日 16:56", color.Black) lblTime.TextSize = 20 lblTime.Alignment = fyne.TextAlignCenter lblTime.Resize(fyne.NewSize(300, 50)) lblTime.Move(fyne.NewPos(150, 1000)) //会议列表 TrCongree := makeCongressTree() TrCongree.Resize(fyne.NewSize(1600, 700)) TrCongree.Move(fyne.NewPos(100, 100)) //证卡管理 btnCardManage := widget.NewButton("证卡管理", func() { //证卡管理 go SetCardWindowControl() }) btnCardManage.Resize(fyne.NewSize(200, 50)) btnCardManage.Move(fyne.NewPos(1100, 1000)) //会控端同步图片 btnMergeImage_MeetControl := widget.NewButton("同步照片——", func() { MergePersonImage() w := fyne.CurrentApp().NewWindow("提示") w.SetContent(fyne.NewContainerWithLayout(layout.NewCenterLayout(), widget.NewLabel("同步照片完成!!"))) // w.Resize(fyne.NewSize(200, 100), 0, 1) w.Resize(fyne.NewSize(200, 100)) w.CenterOnScreen() w.Show() go func() { time.Sleep(time.Second * 2) w.Close() }() }) btnMergeImage_MeetControl.Resize(fyne.NewSize(200, 50)) btnMergeImage_MeetControl.Move(fyne.NewPos(900, 1000)) btnStartAgenda := widget.NewButton("开始会议", func() { //按钮点击事件 if CurrentSelectLevel == "1" || CurrentSelectLevel == "" { // fyne.CurrentApp().SendNotification(&fyne.Notification{ // Title: "提示", // Content: "请选择一个日程!", // }) w := fyne.CurrentApp().NewWindow("警告") w.SetContent(fyne.NewContainerWithLayout(layout.NewCenterLayout(), widget.NewLabel("请选择一个日程!"))) // w.Resize(fyne.NewSize(200, 100), 0, 1) w.Resize(fyne.NewSize(200, 100)) w.CenterOnScreen() w.Show() go func() { time.Sleep(time.Second * 2) w.Close() }() } else if CurrentSelectLevel == "2" { GetAgenda(CurrentSelectAgendaID) InitImagePath() SetCongressStatus(2) go FLXNetworkController.FLXNetConnect.StartTCPListen() go FLXNetworkController.FLXNetConnect.SendCongressIDByUDP(CurrentSelectAgendaID) } }) btnStartAgenda.Resize(fyne.NewSize(200, 50)) btnStartAgenda.Move(fyne.NewPos(1400, 1000)) btnSClose := widget.NewButton("退出", func() { MainWindow.Close() // GPersonlist.Refresh() }) btnSClose.Resize(fyne.NewSize(200, 50)) btnSClose.Move(fyne.NewPos(1700, 1000)) content := container.NewWithoutLayout( btnMergeImage_MeetControl, btnStartAgenda, btnCardManage, TrCongree, lblTime, btnSClose, ) // go ShowTime(lblTime) fyne.DoAndWait(func() { go ShowTime(lblTime) }) return content } // 加载会议议程树 func makeCongressTree() fyne.CanvasObject { defer func() { if r := recover(); r != nil { log.Error("makeCongressTree:", r) } }() //定义dict为map类型 data := make(map[string][]string) ALLCongresses := DAL.GetAllCongress() allCongress := make([]string, 0) for i := 0; i < len(ALLCongresses); i++ { allCongress = append(allCongress, ALLCongresses[i].ID+"|"+ALLCongresses[i].Co_Name+"|1") CAllAgenda := DAL.GeAlltAgendaByCingressID(ALLCongresses[i].ID) allt := make([]string, 0) for j := 0; j < len(CAllAgenda); j++ { allt = append(allt, CAllAgenda[j].ID+"|"+CAllAgenda[j].Ag_Name+"|2") } if len(CAllAgenda) > 0 { data[ALLCongresses[i].ID+"|"+ALLCongresses[i].Co_Name+"|1"] = allt } } data[""] = allCongress tree := Common.NewTreeWithDatas(data) tree.OnSelected = func(id string) { fmt.Println("Tree node selected:", id) CurrentSelectAgendaID = strings.Split(id, "|")[0] CurrentSelectLevel = strings.Split(id, "|")[2] } tree.OnUnselected = func(id string) { fmt.Println("Tree node unselected:", id) } tree.OpenAllBranches() return tree } // update text content func UpdateTextConten(cvtxt *canvas.Text, cont string) { defer func() { if r := recover(); r != nil { log.Error("UpdateTextConten:", r) } }() cvtxt.Text = cont cvtxt.Refresh() } // update time show func ShowTime(lblt *canvas.Text) { defer func() { if r := recover(); r != nil { log.Error("ShowTime:", r) } }() for { lblt.Text = time.Now().Format("2006年01月02日 15:04:05") fyne.DoAndWait(func() { lblt.Refresh() }) LblLine.Text = localcache.LineStatus fyne.DoAndWait(func() { LblLine.Refresh() }) time.Sleep(1 * time.Second) } } // 设置显示界面 func SetCongressStatus(Index int) { defer func() { if r := recover(); r != nil { log.Error("SetCongressStatus:", r) } }() //调用frmScreen里面的方法,初始化 lblSCongressName 等控件 SetSCongressStatus(Index) if Index == 0 { mainview.Remove(mainview.Objects[0]) mainview.Add(DefaultLayout()) lblCongressName.Text = "报到门系统" fyne.DoAndWait(func() { lblCongressName.Refresh() }) } else if Index == 1 { mainview.Remove(mainview.Objects[0]) mainview.Add(DefaultLayout()) lblCongressName.Text = localcache.CurrentCongress.Co_Name lblAgendaName.Text = localcache.CurrentAgenda.Ag_Name fyne.DoAndWait(func() { lblCongressName.Refresh() lblAgendaName.Refresh() }) } else if Index == 2 { mainview.Remove(mainview.Objects[0]) mainview.Add(ReportLayout()) fyne.DoAndWait(func() { mainview.Refresh() }) // mainview.Refresh() UpdateStatisticsNumShow() } else if Index == 3 { mainview.Remove(mainview.Objects[0]) mainview.Add(ServerViewLayout()) } } // 会议名称 var lblRCongressName *canvas.Text // 日程名称 var lblRAgendaName *canvas.Text // 报到界面应到人数 var lblRShoudNum *canvas.Text // 报到界面实到人数 var lblRArriveNum *canvas.Text // 报到界面未到人数 var lblRNoNum *canvas.Text // 报到界面本机报到人书 var lblRCArriveNum *canvas.Text // 时间 var lblTime *canvas.Text // 在线状态 var LblLine *canvas.Text // 当前报到人图片 var imgCurrentPerson *canvas.Image // 当前报到人图片路径 var imgCurrentPersonPath string // 6人图片 var imgPerson1 *canvas.Image var imgPerson2 *canvas.Image var imgPerson3 *canvas.Image var imgPerson4 *canvas.Image var imgPerson5 *canvas.Image var imgPerson6 *canvas.Image // 6人路径 var imgPerson1Path string var imgPerson2Path string var imgPerson3Path string var imgPerson4Path string var imgPerson5Path string var imgPerson6Path string // 是否为发卡模式 var IsStartCard bool // // 当前报到委员 // var CurrentPerson *Model.T_AgendaPerson // // 所有人员信息 // var AllPerson []*Model.T_AgendaPerson // // 当前会议信息 // var CurrentAgenda Model.T_Agenda // var CurrentCongress Model.T_Congress // // 应到人员 // var ShouldNum int // // 实到人员 // var ArriveNum int // // 本机报到人员 // var CArriveNum int = 0 // // 本机报到人员ID // var CArrivePersonsID []string // // 未到人员 // var NoArriveNum int // 报道门 var FLXCheckInDoorDevice FLXCheckInController.FlxCheckInDeviceController // 配置文件 var CFLXCfig Common.FLXConfig var BigPara float32 // 报到界面加载 func ReportLayout() fyne.CanvasObject { defer func() { if r := recover(); r != nil { log.Error("ReportLayout:", r) } }() //国徽 图标 //./PersonImage/61d53f3db642a44ab4000003.jpg // imgIcon := canvas.NewImageFromFile("./images/huibiao.png") // // imgIcon := canvas.NewImageFromFile(CFLXCfig.SeverData.HttpFileUrl + "static/upload/61d6a54576d09c3e14000029.jpg") var imagepath string iconType := Common.LoadConfig().CheckInDoor.IconType if iconType == "1" { imagepath = "./images/guohui.png" } if iconType == "2" { imagepath = "./images/huibiao.png" } imgIcon := canvas.NewImageFromFile(imagepath) imgIcon.Resize(fyne.NewSize(180*BigPara, 200*BigPara)) imgIcon.Move(fyne.NewPos(50*BigPara, 50*BigPara)) // 系统名称 或 会议名称 lblRCongressName = canvas.NewText(localcache.CurrentCongress.Co_Name, color.Black) lblRCongressName.TextSize = 65 * BigPara lblRCongressName.Alignment = fyne.TextAlignCenter lblRCongressName.Resize(fyne.NewSize(1610*BigPara, 80*BigPara)) lblRCongressName.Move(fyne.NewPos(250*BigPara, 60*BigPara)) // 系统名称 或 会议名称 lblRAgendaName = canvas.NewText(localcache.CurrentAgenda.Ag_Name, color.Black) lblRAgendaName.TextSize = 65 * BigPara lblRAgendaName.Alignment = fyne.TextAlignCenter lblRAgendaName.Resize(fyne.NewSize(1610*BigPara, 80*BigPara)) lblRAgendaName.Move(fyne.NewPos(250*BigPara, 160*BigPara)) // 应到 lblRShoudNumName := canvas.NewText("应 到", color.Black) lblRShoudNumName.TextSize = 65 * BigPara lblRShoudNumName.Alignment = fyne.TextAlignCenter lblRShoudNumName.Resize(fyne.NewSize(170*BigPara, 60*BigPara)) lblRShoudNumName.Move(fyne.NewPos(95*BigPara, 520*BigPara)) lblRShoudNum = canvas.NewText("", color.Black) lblRShoudNum.TextSize = 65 * BigPara lblRShoudNum.Alignment = fyne.TextAlignCenter lblRShoudNum.Resize(fyne.NewSize(135*BigPara, 60*BigPara)) lblRShoudNum.Move(fyne.NewPos(285*BigPara, 520*BigPara)) // 实到 lblRArriveNumName := canvas.NewText("实 到", color.Black) lblRArriveNumName.TextSize = 65 * BigPara lblRArriveNumName.Alignment = fyne.TextAlignCenter lblRArriveNumName.Resize(fyne.NewSize(170*BigPara, 60*BigPara)) lblRArriveNumName.Move(fyne.NewPos(95*BigPara, 630*BigPara)) lblRArriveNum = canvas.NewText("", color.Black) lblRArriveNum.TextSize = 65 * BigPara lblRArriveNum.Alignment = fyne.TextAlignCenter lblRArriveNum.Resize(fyne.NewSize(135*BigPara, 60*BigPara)) lblRArriveNum.Move(fyne.NewPos(285*BigPara, 630*BigPara)) // 未到 lblRNoNumName := canvas.NewText("未 到", color.Black) lblRNoNumName.TextSize = 65 * BigPara lblRNoNumName.Alignment = fyne.TextAlignCenter lblRNoNumName.Resize(fyne.NewSize(170*BigPara, 60*BigPara)) lblRNoNumName.Move(fyne.NewPos(95*BigPara, 740*BigPara)) lblRNoNum = canvas.NewText("", color.Black) lblRNoNum.TextSize = 65 * BigPara lblRNoNum.Alignment = fyne.TextAlignCenter lblRNoNum.Resize(fyne.NewSize(135*BigPara, 60*BigPara)) lblRNoNum.Move(fyne.NewPos(285*BigPara, 740*BigPara)) // 本机报到 lblRCArriveNumName := canvas.NewText("本机报到", color.Black) lblRCArriveNumName.TextSize = 65 * BigPara lblRCArriveNumName.Alignment = fyne.TextAlignCenter lblRCArriveNumName.Resize(fyne.NewSize(170*BigPara, 60*BigPara)) lblRCArriveNumName.Move(fyne.NewPos(45*BigPara, 850*BigPara)) lblRCArriveNum = canvas.NewText("", color.Black) lblRCArriveNum.TextSize = 65 * BigPara lblRCArriveNum.Alignment = fyne.TextAlignCenter lblRCArriveNum.Resize(fyne.NewSize(135*BigPara, 60*BigPara)) lblRCArriveNum.Move(fyne.NewPos(285*BigPara, 850*BigPara)) //当前报到人 imgCurrentPerson = canvas.NewImageFromFile("") imgCurrentPerson.Resize(fyne.NewSize(510*BigPara, 680*BigPara)) imgCurrentPerson.Move(fyne.NewPos(705*BigPara, 300*BigPara)) //历史报到人1 imgPerson1 = canvas.NewImageFromFile("") imgPerson1.Resize(fyne.NewSize(150*BigPara, 200*BigPara)) imgPerson1.Move(fyne.NewPos(1400*BigPara, 300*BigPara)) //历史报到人2 imgPerson2 = canvas.NewImageFromFile("") imgPerson2.Resize(fyne.NewSize(150*BigPara, 200*BigPara)) imgPerson2.Move(fyne.NewPos(1625*BigPara, 300*BigPara)) //历史报到人3 imgPerson3 = canvas.NewImageFromFile("") imgPerson3.Resize(fyne.NewSize(150*BigPara, 200*BigPara)) imgPerson3.Move(fyne.NewPos(1400*BigPara, 550*BigPara)) //历史报到人4 imgPerson4 = canvas.NewImageFromFile("") imgPerson4.Resize(fyne.NewSize(150*BigPara, 200*BigPara)) imgPerson4.Move(fyne.NewPos(1625*BigPara, 550*BigPara)) //当历史报到人5 imgPerson5 = canvas.NewImageFromFile("") imgPerson5.Resize(fyne.NewSize(150*BigPara, 200*BigPara)) imgPerson5.Move(fyne.NewPos(1400*BigPara, 800*BigPara)) //历史报到人6 imgPerson6 = canvas.NewImageFromFile("") imgPerson6.Resize(fyne.NewSize(150*BigPara, 200*BigPara)) imgPerson6.Move(fyne.NewPos(1625*BigPara, 800*BigPara)) //在线图标 imgOnline := canvas.NewImageFromFile(imagepath) imgOnline.Resize(fyne.NewSize(50*BigPara, 50*BigPara)) imgOnline.Move(fyne.NewPos(50*BigPara, 1000*BigPara)) //时间 lblReTime := canvas.NewText("2021年11月22日 16:56", color.Black) lblReTime.TextSize = 20 * BigPara lblReTime.Alignment = fyne.TextAlignCenter lblReTime.Resize(fyne.NewSize(300*BigPara, 50*BigPara)) lblReTime.Move(fyne.NewPos(150*BigPara, 1000*BigPara)) LblLine = canvas.NewText(localcache.LineStatus, color.Black) LblLine.TextSize = 20 LblLine.Alignment = fyne.TextAlignCenter LblLine.Resize(fyne.NewSize(300*BigPara, 50*BigPara)) LblLine.Move(fyne.NewPos(400*BigPara, 1000*BigPara)) // //证卡管理 // btnCardManage := widget.NewButton("证卡管理", func() { // //证卡管理 // // if btnCardManage.Text == "证卡管理" { // // } else { //补报销报 // // } // }) // btnCardManage.Resize(fyne.NewSize(200, 50)) // btnCardManage.Move(fyne.NewPos(1400, 1000)) btnMergeImage_ := widget.NewButton("同步图片_", func() { MergePersonImage() w := fyne.CurrentApp().NewWindow("提示") w.SetContent(fyne.NewContainerWithLayout(layout.NewCenterLayout(), widget.NewLabel("同步照片完成"))) // w.Resize(fyne.NewSize(200, 100), 0, 1) w.Resize(fyne.NewSize(200*BigPara, 100*BigPara)) w.CenterOnScreen() w.Show() go func() { time.Sleep(time.Second * 2) w.Close() }() }) btnMergeImage_.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) btnMergeImage_.Move(fyne.NewPos(1100*BigPara, 1000*BigPara)) btnPersonManage := widget.NewButton("人员管理", func() { //人员管理 // AgendaPersonWindowControl() go AgendaPersonWindowControl() }) btnPersonManage.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) btnPersonManage.Move(fyne.NewPos(1300*BigPara, 1000*BigPara)) //证卡管理 btnCardManage := widget.NewButton("test!!", func() { //证卡管理 // if btnCardManage.Text == "证卡管理" { // } else { //补报销报 go TestCard() // } }) btnCardManage.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) btnCardManage.Move(fyne.NewPos(1500*BigPara, 1000*BigPara)) //关闭 btnRClose := widget.NewButton("退出会议", func() { if CFLXCfig.Other.ISServer { //通知终端结束会议 FLXNetworkController.FLXNetConnect.StopAgenda() SetCongressStatus(3) } else { MainWindow.Close() closeChromeWindow(ChromeCmd) } }) btnRClose.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) btnRClose.Move(fyne.NewPos(1700*BigPara, 1000*BigPara)) content := container.NewWithoutLayout( imgIcon, lblRCongressName, lblRAgendaName, lblRShoudNumName, lblRShoudNum, lblRArriveNumName, lblRArriveNum, lblRNoNumName, lblRNoNum, lblRCArriveNumName, lblRCArriveNum, imgCurrentPerson, imgPerson1, imgPerson2, imgPerson3, imgPerson4, imgPerson5, imgPerson6, imgOnline, lblReTime, btnRClose, btnCardManage, btnPersonManage, btnMergeImage_, LblLine, ) // go ShowTime(lblReTime) fyne.DoAndWait(func() { go ShowTime(lblReTime) }) return content } func InitImagePath() { defer func() { if r := recover(); r != nil { log.Error("InitImagePath:", r) } }() imgPerson6Path = "" imgPerson5Path = "" imgPerson4Path = "" imgPerson3Path = "" imgPerson2Path = "" imgPerson1Path = "" imgCurrentPersonPath = "" } // 更新图片 // 返回卡号:{0} // 206893ae678007e07e func UpdateCurrentImg(CPath string) { defer func() { if r := recover(); r != nil { log.Error("UpdateCurrentImg:", r) } }() fmt.Println(CPath) imgPerson6Path = imgPerson5Path imgPerson5Path = imgPerson4Path imgPerson4Path = imgPerson3Path imgPerson3Path = imgPerson2Path imgPerson2Path = imgPerson1Path imgPerson1Path = imgCurrentPersonPath if strings.Contains(CPath, "/") { // // imgCurrentPersonPath = CFLXCfig.SeverData.HttpFileUrl + "PersonImage" + CPath[strings.LastIndex(CPath, "/"):] imgCurrentPersonPath = "./PersonImage" + CPath[strings.LastIndex(CPath, "/"):] } else { imgCurrentPersonPath = "" } imgPerson6.File = imgPerson6Path imgPerson6.Refresh() imgPerson5.File = imgPerson5Path imgPerson5.Refresh() imgPerson4.File = imgPerson4Path imgPerson4.Refresh() imgPerson3.File = imgPerson3Path imgPerson3.Refresh() imgPerson2.File = imgPerson2Path imgPerson2.Refresh() imgPerson1.File = imgPerson1Path imgPerson1.Refresh() imgCurrentPerson.File = imgCurrentPersonPath imgCurrentPerson.Refresh() //二屏做成动态的 先去掉 SUpdateCurrentImg() } // 启动报到门设备 func OpenDevice() { defer func() { if r := recover(); r != nil { log.Error("OpenDevice:", r) } }() fmt.Println("entering 启动报到门设备") FLXCheckInDoorDevice.FlxCheckInDeviceController() FLXCheckInDoorDevice.InvokeDeviceEventHandler = OnDeviceEventHandler FLXCheckInDoorDevice.OpenDevice() } // 关闭设备 func CloseDevice() { defer func() { if r := recover(); r != nil { log.Error("CloseDevice:", r) } }() FLXCheckInDoorDevice.CloseDevice() } // 开始会议 func CongressStart(IsStart bool, AgID string, ServerIP string) { defer func() { if r := recover(); r != nil { log.Error("CongressStart:", r) } }() if IsStart { if CrrentCongressStatus == 0 { CrrentCongressStatus = 1 AgIDAndBackUpIP := strings.Split(AgID, "|") if len(AgIDAndBackUpIP) > 1 { GetAgenda(AgIDAndBackUpIP[0]) } // GetAgenda(AgID) 22222222 SetCongressStatus(1) // SetSCongressStatus(1) if len(AgIDAndBackUpIP) > 1 { FLXNetworkController.FLXNetConnect.StartTCP(2) } else { if ServerIP == CFLXCfig.SeverData.ServerIP { // FLXNetConnect.StartTCP(0) } else if ServerIP == CFLXCfig.SeverData.BackUpServerIP { FLXNetworkController.FLXNetConnect.StartTCP(1) } } FLXNetworkController.FLXNetConnect.SendToServerGetCongressStatus() } } else { if CrrentCongressStatus > 0 { SetCongressStatus(0) //清除缓存数据 DisposeContent() // SetSCongressStatus(0) CrrentCongressStatus = 0 } } } // 退会清除会议信息 func DisposeContent() { defer func() { if r := recover(); r != nil { // tempresultmap[common.DBRESULT] = "发生错误,无法获取数据" log.Error("DisposeContent:", r) } }() localcache.MDDictionary = nil localcache.Currentreportper = nil localcache.MStIDStaffInfo = nil localcache.MNations = nil localcache.MGroups = nil localcache.MIDStaffCategory = nil localcache.SysSets = nil localcache.AllSysSet = nil localcache.AllScren = nil localcache.MIDScren = make(map[string]Model.TScreen) localcache.AllScrenForm = nil localcache.AllScreenFormEvent = nil localcache.CurrentAgenda.Ag_Name = "" localcache.ALLAPinfo = nil localcache.AllPerson = nil localcache.Allperpiccontent = make([]map[string]interface{}, 0) localcache.LastCardTime = make(map[string]time.Time, 0) FLXNetworkController.UnSendToServerData = make([]FLXNetworkController.Message, 0) } // 开始报到 func CheckInStart() { defer func() { if r := recover(); r != nil { log.Error("CheckInStart:", r) } }() if CrrentCongressStatus == 1 { CrrentCongressStatus = 2 SetCongressStatus(2) // SetSCongressStatus(2) } fyne.DoAndWait(func() { mainview.Refresh() }) // mainview.Refresh() // SCArriveNum = 0 // lblRCArriveNum.Text = "0" // lblRCArriveNum.Refresh() } // 暂停报到 func CheckInPause() { defer func() { if r := recover(); r != nil { log.Error("CheckInPause:", r) } }() fyne.DoAndWait(func() { mainview.Refresh() }) localcache.CArrivePersonsID = []string{} } // 继续报到 func CheckInResume() { } // 停止报到 func CheckInStop() { } // 网络同步人员报到信息 func NetCheckInOne(IsCkeckIn bool, APID string) { defer func() { if r := recover(); r != nil { log.Error("NetCheckInOne:", r) } }() person := GetAgendaPersonByID(APID) NetRefrushData(person, IsCkeckIn) } // 服务器网络同步人员报到信息 func NetCheckInOneServer(IsCkeckIn bool, APID string) { defer func() { if r := recover(); r != nil { log.Error("NetCheckInOneServer:", r) } }() person := GetAgendaPersonByID(APID) RefrushData(person, IsCkeckIn) DAL.UpdateAgendaPerson(person) } var IndexCo int func TestCard() { defer func() { if r := recover(); r != nil { log.Error("TestCard:", r) } }() resultmap := map[string]interface{}{} resultmap["seatid"] = "123" resultmap["seatstatus"] = "456" resultmap["deviceusedid"] = "" //测试 // websocketservers.ServerSendHTMLSeatsData(resultmap) var seatInfos []FLXDevice.SeatChangeEventArg if IndexCo >= len(localcache.AllPerson)-1 { IndexCo = 0 } var seatInf FLXDevice.SeatChangeEventArg cardNumbers := []string{"123", "234", "345", "456", "567", "678", "789"} seatInf.Value_ExtraStr = cardNumbers[IndexCo%len(cardNumbers)] seatInf.Value_ExtraInt = FLXCheckInController.CheckInDirection_In seatInfos = append(seatInfos, seatInf) IndexCo++ OnDeviceEventHandler(FLXDevice.EventArgSource_SivtChecker, FLXDevice.EventArgType_RegisterEvent, seatInfos) } // var LastCardTime = make(map[string]time.Time) var mu sync.Mutex // 通讯信息处理 包括意外重启后,能够自动跳转到当前会序 func OnDeviceEventHandler(eventSource FLXDevice.EventArgSource, eventType FLXDevice.EventArgType, seatInfos []FLXDevice.SeatChangeEventArg) { defer func() { if r := recover(); r != nil { log.Error("OnDeviceEventHandler:", r) } }() mu.Lock() defer mu.Unlock() if eventSource == FLXDevice.EventArgSource_SivtChecker { for i := 0; i < len(seatInfos); i++ { //报到键 if eventType == FLXDevice.EventArgType_RegisterEvent { card := seatInfos[i].Value_ExtraStr if card == "" { continue } if IsStartCard { UpdatePersonCardNum(card) } else { // if localcache.CurrentScreenSessionStatus == Common.SessionStatus_StartReport || localcache.CurrentScreenSessionStatus == Common.SessionStatus_Reporting { //五秒钟内不处理刷过的卡号 if lastTime, exists := localcache.LastCardTime[card]; exists { if time.Since(lastTime) < 5*time.Second { return } } localcache.LastCardTime[card] = time.Now() fmt.Println(card) // FLXNetConnect.SendToServerPersonCheckIn("753321ea400245ab8ff68dca2951f7bf") //测试发送 22222222 person := GetAgendaPersonByCardNum(card) if person != nil { switch seatInfos[i].Value_ExtraInt { case FLXCheckInController.CheckInDirection_In: if person.AP_CheckState != 1 { person.AP_CheckState = 1 person.AP_CheckInTime = time.Now() for j := 0; j < len(localcache.ALLAPinfo); j++ { if localcache.ALLAPinfo[j].AP_ID == person.AP_ID { localcache.ALLAPinfo[j].AP_CheckState = 1 } } } localcache.Currentreportper = person if !Common.IsContain(localcache.CArrivePersonsID, person.AP_ID) && person.AP_VotePower == 1 { localcache.CArrivePersonsID = append(localcache.CArrivePersonsID, person.AP_ID) } RefrushData(person, true) FLXNetworkController.FLXNetConnect.SendToServerPersonCheckIn(person.AP_StaffID) case FLXCheckInController.CheckInDirection_Out: person.AP_CheckState = 0 if Common.IsContain(localcache.CArrivePersonsID, person.AP_ID) { localcache.CArrivePersonsID = Common.Remove(localcache.CArrivePersonsID, person.AP_ID) } RefrushData(person, false) FLXNetworkController.FLXNetConnect.SendToServerPersonCheckOut(person.AP_ID) case FLXCheckInController.CheckInDirection_Unkown: // RefrushData(person, true) default: break } } // } } } } } else if eventSource == FLXDevice.EventArgSource_SeverDevice { for i := 0; i < len(seatInfos); i++ { if eventType == FLXDevice.EventArgType_ServerToClient { switch seatInfos[i].CMD { case FLXNetworkController.FlxNetworkComPara_Meeting: //开始会议 if byte(seatInfos[i].Value_ExtraInt) == FLXNetworkController.FlxNetworkComPara_Meeting_Start { CongressStart(byte(seatInfos[i].Value_ExtraInt) == FLXNetworkController.FlxNetworkComPara_Meeting_Start, string(seatInfos[i].Data), seatInfos[i].IPAddress) if localcache.CurrentAgenda.Ag_Name == "" { localcache.CurrentScreenSessionStatus = Common.SessionStatus_StartSession GetAgenda(CurrentSelectAgendaID) //重新进软件更新应到实到人数 UpdateStatisticsNumShow() localcache.OnChangeProcess() CheckInStart() if localcache.CurrentScreenSessionStatus == Common.SessionStatus_StartReport || localcache.CurrentScreenSessionStatus == Common.SessionStatus_Reporting { OpenDevice() } } //测试 开始会议后直接开始报到 看看 TAO能不能接收到 // if localcache.CurrentAgenda.Ag_Name == "" { // GetAgenda(CurrentSelectAgendaID) // } // localcache.CurrentScreenSessionStatus = Common.SessionStatus_StartReport // CrrentCongressStatus = 1 // OpenDevice() // CheckInStart() // localcache.OnChangeProcess() } //结束会议 if byte(seatInfos[i].Value_ExtraInt) == FLXNetworkController.FlxNetworkComPara_Meeting_Close { localcache.CurrentScreenSessionStatus = Common.SessionStatus_StopSession localcache.OnChangeProcess() CloseDevice() CongressStart(byte(seatInfos[i].Value_ExtraInt) == FLXNetworkController.FlxNetworkComPara_Meeting_Start, string(seatInfos[i].Data), seatInfos[i].IPAddress) } case FLXNetworkController.FlxNetworkComPara_Main_Start_Register: //开始报到 if localcache.CurrentAgenda.Ag_Name == "" { GetAgenda(CurrentSelectAgendaID) } localcache.CurrentScreenSessionStatus = Common.SessionStatus_StartReport CrrentCongressStatus = 1 OpenDevice() CheckInStart() //开始报到时 清空实到未到人数 InitUpdateStatisticsNumShow() localcache.OnChangeProcess() case FLXNetworkController.FlxNetworkComPara_Main_Pause_Register: //暂停报到 CheckInPause() CloseDevice() InitImagePath() IsGetDate = true localcache.CurrentAgenda.Ag_Name = "" localcache.CurrentScreenSessionStatus = Common.SessionStatus_StopReport localcache.OnChangeProcess() DisposeContent() case FLXNetworkController.FlxNetworkComPara_Main_Resume_Register: //继续报到 CheckInResume() case FLXNetworkController.FlxNetworkComPara_Main_Stop_Register: //停止报到 CheckInStop() CloseDevice() localcache.CurrentScreenSessionStatus = Common.SessionStatus_StopReport //上位机下发实到,未到人数: case FLXNetworkController.FlxNetworkComPara_Reply_Register_Succeed: StrData := string(seatInfos[i].Data) PersonNum := strings.Split(StrData, "|") fmt.Println("报到信息", PersonNum) numarrive, _ := strconv.Atoi(PersonNum[1]) numnoarrive, _ := strconv.Atoi(PersonNum[2]) localcache.ArriveNum = numarrive lblRArriveNum.Text = strconv.Itoa(localcache.ArriveNum) fyne.DoAndWait(func() { lblRArriveNum.Refresh() }) localcache.NoArriveNum = numnoarrive lblRNoNum.Text = strconv.Itoa(localcache.NoArriveNum) fyne.DoAndWait(func() { lblRNoNum.Refresh() }) case FLXNetworkController.FlxNetworkComPara_Un_Register: StrData := string(seatInfos[i].Data) PersonIDs := strings.Split(StrData, "|") var id string for j := 0; j < len(PersonIDs); j++ { id = PersonIDs[j] if id != "" { switch byte(seatInfos[i].Value_ExtraInt) { case FLXNetworkController.FlxNetworkComPara_CheckIn_Sub_Signed: //补报 NetCheckInOne(true, id) case FLXNetworkController.FlxNetworkComPara_CheckIn_Sub_Cancel: //销报 NetCheckInOne(false, id) } } } // OnCheckInOne(person) // case FlxNetworkComPara.Data_Down_Control: // switch (arg.Value_ExtraInt){ // case FlxNetworkComPara.Data_Down_ControlShutDown://关机 // WindowsContols.PowerOff(); // break; // case FlxNetworkComPara.Data_Down_ControlRestart://重启 // WindowsContols.Reboot(); // break; // case FlxNetworkComPara.CMD_Control_RestartProgram://软件重启 // PaperNetCtrler.StopClient(); // Process p = new Process(); // p.StartInfo.FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Philisense.Congress.CheckInDoor.exe"; // p.StartInfo.UseShellExecute = false; // p.Start(); // break; // case FlxNetworkComPara.Data_Down_BarSub_Hide://隐藏 // WindowsContols.HideTaskBar(); // break; // case FlxNetworkComPara.Data_Down_BarSub_Show://显示 // WindowsContols.ShowTaskBar(); // break; // case FlxNetworkComPara.CMD_Control_ExitProgram://软件关闭 // Process Current = Process.GetCurrentProcess(); // Process processesByID = Process.GetProcessById(Current.Id); // processesByID.Kill(); // break; // } } } } } else if eventSource == FLXDevice.EventArgSource_ClientDevice { for i := 0; i < len(seatInfos); i++ { if eventType == FLXDevice.EventArgType_ClientToServer { switch seatInfos[i].CMD { case FLXNetworkController.FlxNetworkComPara_Client_Request_Register: StrData := string(seatInfos[i].Data) if StrData != "" { switch byte(seatInfos[i].Value_ExtraInt) { case FLXNetworkController.FlxNetworkComPara_DoorCheckIn_Sub: //补报 NetCheckInOneServer(true, StrData) FLXNetworkController.FLXNetConnect.SendToWithOutClientPersonCheckIn(StrData, seatInfos[i].IPAddress) case FLXNetworkController.FlxNetworkComPara_DoorCheckOut_Sub: //销报 NetCheckInOneServer(false, StrData) FLXNetworkController.FLXNetConnect.SendToWithOutClientPersonCheckOut(StrData, seatInfos[i].IPAddress) } } case FLXNetworkController.FlxNetworkComPara_Server_Congress_Status: FLXNetworkController.FLXNetConnect.ServerSendToApointClientCheckInStart(seatInfos[i].IPAddress) var AP_IDS string for i := 0; i < len(localcache.AllPerson); i++ { if localcache.AllPerson[i].AP_Status == "1" { AP_IDS = AP_IDS + "|" + localcache.AllPerson[i].AP_ID } } FLXNetworkController.FLXNetConnect.SendToClientPersonCheckIn(AP_IDS, seatInfos[i].IPAddress) } } } } } // 更新人员报到信息 func RefrushData(cperson *Model.T_AgendaPerson, IsCheckIn bool) { defer func() { if r := recover(); r != nil { log.Error("RefrushData:", r) } }() localcache.CurrentPerson = cperson if IsCheckIn { localcache.CurrentPerson.AP_CheckState = 1 //不在这更新AP_CheckInTime 否则当前报到人状态一直是您已报到 // localcache.CurrentPerson.AP_CheckInTime = time.Now() } else { localcache.CurrentPerson.AP_CheckState = 0 localcache.CurrentPerson.AP_CheckOutTime = time.Now() } UpdateStatisticsNumShow() UpdateCurrentImg(localcache.CurrentPerson.AP_StaffInfo.St_Image) localcache.OnChangeProcess() // SUpdateStatisticsNumShow() // SUpdateCurrentImg(CurrentPerson.AP_StaffInfo.St_Image) } // 更新人员报到信息 func NetRefrushData(cperson *Model.T_AgendaPerson, IsCheckIn bool) { defer func() { if r := recover(); r != nil { log.Error("NetRefrushData:", r) } }() localcache.CurrentPerson = cperson if IsCheckIn { localcache.CurrentPerson.AP_Status = "1" fmt.Println("报到人ID:" + cperson.AP_ID) } else { localcache.CurrentPerson.AP_Status = "2" } UpdateStatisticsNumShow() } // 更新实到和未到人员信息 func UpdateStatisticsNumShow() { defer func() { if r := recover(); r != nil { log.Error("UpdateStatisticsNumShow:", r) } }() AN := 0 SH := 0 for id := range localcache.AllPerson { if localcache.AllPerson[id].AP_VotePower == 1 { SH = SH + 1 if localcache.AllPerson[id].AP_CheckState == 1 { AN = AN + 1 } } } localcache.ShouldNum = SH localcache.ArriveNum = AN localcache.NoArriveNum = localcache.ShouldNum - localcache.ArriveNum lblRShoudNum.Text = strconv.Itoa(localcache.ShouldNum) lblRArriveNum.Text = strconv.Itoa(localcache.ArriveNum) lblRNoNum.Text = strconv.Itoa(localcache.NoArriveNum) localcache.CArriveNum = len(localcache.CArrivePersonsID) lblRCArriveNum.Text = strconv.Itoa(localcache.CArriveNum) lblRShoudNum.Refresh() lblRArriveNum.Refresh() lblRNoNum.Refresh() lblRCArriveNum.Refresh() SUpdateStatisticsNumShow() } // 重新初始化实到未到信息,用于二次报道时初始化 func InitUpdateStatisticsNumShow() { defer func() { if r := recover(); r != nil { log.Error("UpdateStatisticsNumShow:", r) } }() AN := 0 SH := 0 for id := range localcache.AllPerson { localcache.AllPerson[id].AP_CheckState = 0 if localcache.AllPerson[id].AP_VotePower == 1 { SH = SH + 1 // if localcache.AllPerson[id].AP_CheckState == 1 { // AN = AN + 1 // } } } localcache.ShouldNum = SH localcache.ArriveNum = AN localcache.NoArriveNum = localcache.ShouldNum - localcache.ArriveNum lblRShoudNum.Text = strconv.Itoa(localcache.ShouldNum) lblRArriveNum.Text = strconv.Itoa(localcache.ArriveNum) lblRNoNum.Text = strconv.Itoa(localcache.NoArriveNum) localcache.CArriveNum = 0 lblRCArriveNum.Text = strconv.Itoa(localcache.CArriveNum) localcache.CArrivePersonsID = []string{} lblRShoudNum.Refresh() lblRArriveNum.Refresh() lblRNoNum.Refresh() lblRCArriveNum.Refresh() } // 获取会议信息 func GetAgenda(AgID string) { defer func() { if r := recover(); r != nil { log.Error("GetAgenda:", r) } }() // CurrentAgenda = DAL.GetAgenda(AgID) // CurrentCongress = DAL.GetCongress(CurrentAgenda.Ag_CongressID) // AllPerson = DAL.GetAllAgendaPersonWithAll(AgID) //通过接口获取会议,人员信息 var agendaPersons []Model.T_AgendaPerson = make([]Model.T_AgendaPerson, 0) targetIP := Common.GetAvailableEndpoint() if targetIP == "" { log.Error("所有IP均不可达") log.Println("所有IP均不可达") return } url := "http://" + Common.LoadConfig().SeverData.ServerIP + ":9800/vhwcapi/v1/web/api/service/congresscontrol/getpersonforcheckdoor" jsonData := `{}` body, statusCode, err := Common.SendPostRequest(url, jsonData, "application/json") if err != nil { log.Fatalf("请求错误: %v", err) } fmt.Printf("响应状态码: %d\n响应体: %s\n", statusCode, body) var responses map[string]interface{} err = json.Unmarshal([]byte(body), &responses) if err != nil { log.Fatalf("JSON 解析失败: %v", err) } dataRecord, ok := responses["datarecord"].(map[string]interface{}) if !ok { log.Fatal("datarecord 类型断言失败") } // 将 map 转换为 JSON 字节流 currentAgendaBytes, err := json.Marshal(dataRecord["currentAgenda"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(currentAgendaBytes, &localcache.CurrentAgenda); err != nil { log.Fatal("JSON反序列化失败:", err) } currentCongressBytes, err := json.Marshal(dataRecord["currentCongress"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(currentCongressBytes, &localcache.CurrentCongress); err != nil { log.Fatal("JSON反序列化失败:", err) } rawSlice, ok := responses["datarecord"].(map[string]interface{})["agendaperson"].([]interface{}) fmt.Println("rawSlice", rawSlice) if !ok { fmt.Errorf("agendaperson字段类型断言失败") } for _, item := range rawSlice { personMap := item.(map[string]interface{}) var person Model.T_AgendaPerson person.AP_ID = personMap["Id"].(string) person.AP_StaffID = personMap["Ap_staffid"].(string) person.AP_StaffInfo.St_Name = personMap["Ap_name"].(string) person.AP_StaffInfo.St_Image = personMap["St_Image"].(string) person.AP_StaffInfo.St_ViceCardNum = personMap["St_ViceCardNum"].(string) person.AP_StaffInfo.St_ViceCardNumA = personMap["St_ViceCardNuma"].(string) person.AP_StaffInfo.St_ViceCardNumB = personMap["St_ViceCardNumb"].(string) person.AP_CodeNum = personMap["Ap_codenum"].(string) checkinTime, _ := time.Parse(time.RFC3339, personMap["Ap_checkintime"].(string)) person.AP_CheckInTime = checkinTime checkoutTime, _ := time.Parse(time.RFC3339, personMap["Ap_checkouttime"].(string)) person.AP_CheckOutTime = checkoutTime person.AP_CheckState = int(personMap["Ap_checkstate"].(float64)) person.AP_AgendaID = personMap["Ap_agendaid"].(string) person.AP_CardType = int(personMap["AP_CardType"].(float64)) person.AP_ReportPower = int(personMap["AP_ReportPower"].(float64)) person.AP_VotePower = int(personMap["AP_VotePower"].(float64)) person.AP_SpeakPower = int(personMap["AP_SpeakPower"].(float64)) person.AP_FirstSpeakPower = int(personMap["AP_FirstSpeakPower"].(float64)) person.AP_CallPower = int(personMap["AP_CallPower"].(float64)) person.AP_SearchPower = int(personMap["AP_SearchPower"].(float64)) person.AP_Status = personMap["AP_Status"].(string) person.AP_Remark = personMap["AP_Remark"].(string) person.AP_Moderator = int(personMap["AP_Moderator"].(float64)) agendaPersons = append(agendaPersons, person) } currentstatusBytes, err := json.Marshal(dataRecord["currentstatus"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(currentstatusBytes, &localcache.CurrentScreenSessionStatus); err != nil { log.Fatal("JSON反序列化失败:", err) } fmt.Println(localcache.CurrentScreenSessionStatus) MDDictionaryBytes, err := json.Marshal(dataRecord["MDDictionary"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(MDDictionaryBytes, &localcache.MDDictionary); err != nil { log.Fatal("JSON反序列化失败:", err) } MStIDStaffInfoBytes, err := json.Marshal(dataRecord["MStIDStaffInfo"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(MStIDStaffInfoBytes, &localcache.MStIDStaffInfo); err != nil { log.Fatal("JSON反序列化失败:", err) } MNationsBytes, err := json.Marshal(dataRecord["MNations"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(MNationsBytes, &localcache.MNations); err != nil { log.Fatal("JSON反序列化失败:", err) } MGroupsBytes, err := json.Marshal(dataRecord["MGroups"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(MGroupsBytes, &localcache.MGroups); err != nil { log.Fatal("JSON反序列化失败:", err) } MIDStaffCategoryBytes, err := json.Marshal(dataRecord["MIDStaffCategory"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(MIDStaffCategoryBytes, &localcache.MIDStaffCategory); err != nil { log.Fatal("JSON反序列化失败:", err) } SysSetsBytes, err := json.Marshal(dataRecord["SysSets"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(SysSetsBytes, &localcache.SysSets); err != nil { log.Fatal("JSON反序列化失败:", err) } AllSysSetBytes, err := json.Marshal(dataRecord["AllSysSet"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(AllSysSetBytes, &localcache.AllSysSet); err != nil { log.Fatal("JSON反序列化失败:", err) } AllScrenBytes, err := json.Marshal(dataRecord["AllScren"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(AllScrenBytes, &localcache.AllScren); err != nil { log.Fatal("JSON反序列化失败:", err) } for index := range localcache.AllScren { localcache.MIDScren[localcache.AllScren[index].Id] = localcache.AllScren[index] } AllScrenFormBytes, err := json.Marshal(dataRecord["AllScrenForm"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(AllScrenFormBytes, &localcache.AllScrenForm); err != nil { log.Fatal("JSON反序列化失败:", err) } AllScreenFormEventBytes, err := json.Marshal(dataRecord["AllScreenFormEvent"]) if err != nil { log.Fatal("JSON序列化失败:", err) } if err := json.Unmarshal(AllScreenFormEventBytes, &localcache.AllScreenFormEvent); err != nil { log.Fatal("JSON反序列化失败:", err) } var allPersonPtrs []*Model.T_AgendaPerson for _, p := range agendaPersons { personCopy := p allPersonPtrs = append(allPersonPtrs, &personCopy) } localcache.ALLAPinfo = agendaPersons localcache.AllPerson = allPersonPtrs if APersonlist != nil { fyne.DoAndWait(func() { APersonlist.Refresh() }) } IsGetDate = false } // 通过卡号获取委员 func GetAgendaPersonByCardNum(cardNum string) *Model.T_AgendaPerson { defer func() { if r := recover(); r != nil { log.Error("GetAgendaPersonByCardNum:", r) } }() for id := range localcache.AllPerson { if cardNum == localcache.AllPerson[id].AP_StaffInfo.St_ViceCardNum { return localcache.AllPerson[id] } } return nil } // 通过卡号获取委员 func GetAgendaPersonByID(APID string) *Model.T_AgendaPerson { defer func() { if r := recover(); r != nil { log.Error("GetAgendaPersonByID:", r) } }() for id := range localcache.AllPerson { if APID == localcache.AllPerson[id].AP_ID { return localcache.AllPerson[id] } } return nil } // 定时器 func timerRefrush() { defer func() { if r := recover(); r != nil { log.Error("timerRefrush:", r) } }() timer1 := time.NewTicker(10 * time.Second) select { case <-timer1.C: UpdateImage() } } func UpdateImage() { fmt.Println("测试定时器") } // 下载图片文件 func DownFile(durl string) { defer func() { if r := recover(); r != nil { log.Error("DownFile:", r) } }() uri, err := url.ParseRequestURI(durl) if err != nil { panic("网址错误") } filename := path.Base(uri.Path) log.Println("[*] Filename " + filename) client := http.DefaultClient client.Timeout = time.Second * 60 //设置超时时间 resp, err := client.Get(durl) if err != nil { panic(err) } if resp.ContentLength <= 0 { log.Println("[*] Destination server does not support breakpoint download.") } raw := resp.Body defer raw.Close() reader := bufio.NewReaderSize(raw, 1024*32) file, err := os.Create("./PersonImage/" + filename) if err != nil { panic(err) } writer := bufio.NewWriter(file) buff := make([]byte, 32*1024) written := 0 go func() { for { nr, er := reader.Read(buff) if nr > 0 { nw, ew := writer.Write(buff[0:nr]) if nw > 0 { written += nw } if ew != nil { err = ew break } if nr != nw { err = io.ErrShortWrite break } } if er != nil { if er != io.EOF { err = er } break } } if err != nil { panic(err) } }() spaceTime := time.Second * 1 ticker := time.NewTicker(spaceTime) lastWtn := 0 stop := false for { select { case <-ticker.C: speed := written - lastWtn log.Printf("[*] Speed %s / %s \n", bytesToSize(speed), spaceTime.String()) if written-lastWtn == 0 { ticker.Stop() stop = true break } lastWtn = written } if stop { break } } } func bytesToSize(length int) string { defer func() { if r := recover(); r != nil { log.Error("bytesToSize:", r) } }() var k = 1024 // or 1024 var sizes = []string{"Bytes", "KB", "MB", "GB", "TB"} if length == 0 { return "0 Bytes" } i := math.Floor(math.Log(float64(length)) / math.Log(float64(k))) r := float64(length) / math.Pow(float64(k), i) return strconv.FormatFloat(r, 'f', 3, 64) + " " + sizes[int(i)] } // 同步照片 func MergePersonImage() { defer func() { if r := recover(); r != nil { log.Error("MergePersonImage:", r) } }() // ALLStaffinfos := DAL.GetAllStaffInfoAll() // for id := range ALLStaffinfos { // if ALLStaffinfos[id].St_Image != "" { // DownFile2(CFLXCfig.SeverData.HttpFileUrl + ALLStaffinfos[id].St_Image) // } // } // FTP 服务器信息 ftpServer := Common.LoadConfig().CheckInDoor.FtpServerIP // "127.0.0.1" FTP 服务器地址 ftpPort := Common.LoadConfig().CheckInDoor.FtpServerPort //"21" FTP默认 FTP 端口 ftpUsername := Common.LoadConfig().CheckInDoor.FtpUsername //"admin" FTP 用户名 ftpPassword := Common.LoadConfig().CheckInDoor.FTPtpPassword //"admin" FTP 密码 // 要下载的远程目录 remoteDir := Common.LoadConfig().CheckInDoor.FtpPath // "/" 远程文件夹的路径 // 本地保存目录 localDir := Common.LoadConfig().CheckInDoor.FtplocalDir //"./PersonImage/" 本地保存文件夹的路径 // 连接到 FTP 服务器 c, err := ftp.Dial(ftpServer + ":" + ftpPort) if err != nil { log.Fatalf("连接到 FTP 服务器失败: %v", err) } defer c.Quit() // 登录到 FTP 服务器 err = c.Login(ftpUsername, ftpPassword) if err != nil { log.Fatalf("登录失败: %v", err) } // 打印当前工作目录 currentDir, err := c.CurrentDir() if err != nil { log.Fatalf("获取当前目录失败: %v", err) } log.Printf("当前工作目录: %v", currentDir) // 下载整个文件夹 err = Common.DownloadDir(c, remoteDir, localDir) if err != nil { log.Fatalf("下载文件夹失败: %v", err) } fmt.Printf("文件夹下载完成,保存路径: %s\n", localDir) } // 下载照片 func DownFile2(durl string) { defer func() { if r := recover(); r != nil { log.Error("DownFile2:", r) } }() defer func() { if err := recover(); err != nil { fmt.Println("下载图片错误: ", err) } }() imgPath := "./PersonImage/" imgUrl := durl fileName := path.Base(imgUrl) res, err := http.Get(imgUrl) if err != nil { fmt.Println("A error occurred!") return } defer res.Body.Close() // 获得get请求响应的reader对象 reader := bufio.NewReaderSize(res.Body, 32*1024) file, err := os.Create(imgPath + fileName) if err != nil { fmt.Println(err) } // 获得文件的writer对象 writer := bufio.NewWriter(file) written, _ := io.Copy(writer, reader) fmt.Printf("Total length: %d", written) }