You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2264 lines
62 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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("./images/guohui.png")
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))
// 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,
)
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()
})
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 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("./images/guohui.png")
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))
// //证卡管理
// 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_,
)
// 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://" + targetIP + ":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)
}