package controllers import ( "ColdVerify_server/Nats" "ColdVerify_server/conf" "ColdVerify_server/lib" "ColdVerify_server/logs" "ColdVerify_server/models/Account" "ColdVerify_server/models/Device" "ColdVerify_server/models/System" "ColdVerify_server/models/Task" "errors" "fmt" beego "github.com/beego/beego/v2/server/web" "github.com/signintech/gopdf" "github.com/vmihailenco/msgpack/v5" "github.com/xuri/excelize/v2" "log" "math" "os" "sort" "strconv" "strings" "time" ) type TaskDataController struct { beego.Controller } // 获取- func (c *TaskDataController) Extract_TaskData() { // 验证登录 User_is, User_r user_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Time_start := c.GetString("Time_start") Time_end := c.GetString("Time_end") T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } DeviceClass_List := Device.Read_DeviceClassList_List_id(Task_r.T_class) if len(DeviceClass_List) == 0 { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_Class_id 分类设备列表 为空!"} c.ServeJSON() return } logs.Println("----导入 :", DeviceClass_List) // 清空表 Task.Truncate_TaskData(Task_r.T_task_id) // 插入 数据 for _, v := range DeviceClass_List { logs.Println("---- :", v.T_sn, Task_r.T_task_id, Time_start, Time_end) Task.Import_TaskData(v.T_sn, v.T_id, Task_r.T_task_id, Time_start, Time_end) } // 提取数据后 将 当前任务 数据采集 标志 为 1 Task_r.T_collection_state = 1 if !Task.Update_Task(Task_r, "T_collection_state") { c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"} c.ServeJSON() return } System.Add_UserLogs_T(user_r.T_uuid, "任务", "修改", Task_r) System.Add_UserLogs(user_r.T_uuid, "提取数据", "提取数据"+Task_r.T_name, Task_r.T_task_id+"|"+Time_start+"|"+Time_end) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"} c.ServeJSON() return } // 后台导出数据 func (c *TaskDataController) Extract_TaskData_Back() { // 验证登录 User_is, User_r user_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Time_start := c.GetString("Time_start") Time_end := c.GetString("Time_end") T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } // 采集中 if Task_r.T_collection_state == 2 { c.Data["json"] = lib.JSONS{Code: 202, Msg: "数据正采集中,请勿重复提交!"} c.ServeJSON() return } DeviceClass_List := Device.Read_DeviceClassList_List_id(Task_r.T_class) if len(DeviceClass_List) == 0 { c.Data["json"] = lib.JSONS{Code: 202, Msg: "设备列表为空,请先添加设备!"} c.ServeJSON() return } // 更新状态为采集中 Task_r.T_collection_state = 2 if !Task.Update_Task(Task_r, "T_collection_state") { c.Data["json"] = lib.JSONS{Code: 202, Msg: "导出数据失败!"} c.ServeJSON() return } data := Nats.Extract_TaskData_Back{ T_uuid: user_r.T_uuid, Time_start: Time_start, Time_end: Time_end, DeviceClassList: DeviceClass_List, Task: Task_r, } // 后台执行打包数据 b, _ := msgpack.Marshal(&data) _ = lib.Nats.Publish("ColdVerify_Server_Extract_TaskData_Back", b) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"} c.ServeJSON() return } // 列表 - func (c *TaskDataController) TaskData_List() { // 验证登录 User_is, User_r _, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } var r_jsons lib.R_JSONS page, _ := c.GetInt("page") if page < 1 { page = 1 } page_z, _ := c.GetInt("page_z") if page_z < 1 { page_z = conf.Page_size } Time_start := c.GetString("Time_start") Time_end := c.GetString("Time_end") T_sn := c.GetString("T_sn") T_id := c.GetString("T_id") T_layout_no := c.GetString("T_layout_no") // 替换之前的T_id if len(T_layout_no) > 0 { T_id = T_layout_no } T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } if Task_r.T_delivery_state == 2 { c.Data["json"] = lib.JSONS{Code: 202, Msg: "数据采集中,请稍后!"} c.ServeJSON() return } // 查询设备列表 dcList, _ := Device.Read_DeviceClassList_OrderList(Task_r.T_class, T_sn, "", "", page, 9999) // 保存布局编号和校准证书对应关系 var deviceCertificateMap = make(map[string]string) // t_id, T_Certificate_sn for _, v := range dcList { deviceCertificateMap[v.T_id] = v.T_Certificate_sn } var cnt int64 List, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, T_sn, T_id, Time_start, Time_end, page, page_z) for i := 0; i < len(List); i++ { List[i].T_Certificate_sn = deviceCertificateMap[List[i].T_id] } page_size := math.Ceil(float64(cnt) / float64(page_z)) r_jsons.List = List r_jsons.Page = page r_jsons.Page_size = int(page_size) r_jsons.Pages = lib.Func_page(int64(page), int64(page_size)) r_jsons.Num = int(cnt) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons} c.ServeJSON() return } // 列表 - func (c *TaskDataController) UserTaskData_List() { // 验证登录 User_is, User_r User_r, User_is := Account.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } var r_jsons lib.R_JSONS page, _ := c.GetInt("page") if page < 1 { page = 1 } page_z, _ := c.GetInt("page_z") if page_z < 1 { page_z = conf.Page_size } Time_start := c.GetString("Time_start") Time_end := c.GetString("Time_end") T_sn := c.GetString("T_sn") T_id := c.GetString("T_id") T_layout_no := c.GetString("T_layout_no") // 替换之前的T_id if len(T_layout_no) > 0 { T_id = T_layout_no } T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } if Task_r.T_delivery_state == 2 { c.Data["json"] = lib.JSONS{Code: 202, Msg: "数据采集中,请稍后!"} c.ServeJSON() return } if Task_r.T_uuid != User_r.T_uuid { c.Data["json"] = lib.JSONS{Code: 200, Msg: "无权访问!"} c.ServeJSON() return } if len(Time_start) == 0 { Time_start = Task_r.T_VerifyDeviceDataStartTime } if len(Time_end) == 0 { Time_end = Task_r.T_VerifyDeviceDataEndTime } // 查询设备列表 dcList, _ := Device.Read_DeviceClassList_OrderList(Task_r.T_class, T_sn, "", "", page, 9999) // 保存布局编号和校准证书对应关系 var deviceCertificateMap = make(map[string]string) // t_id, T_Certificate_sn for _, v := range dcList { deviceCertificateMap[v.T_id] = v.T_Certificate_sn } var cnt int64 List, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, T_sn, T_id, Time_start, Time_end, page, page_z) for i := 0; i < len(List); i++ { List[i].T_Certificate_sn = deviceCertificateMap[List[i].T_id] } page_size := math.Ceil(float64(cnt) / float64(page_z)) r_jsons.List = List r_jsons.Page = page r_jsons.Page_size = int(page_size) r_jsons.Pages = lib.Func_page(int64(page), int64(page_size)) r_jsons.Num = int(cnt) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons} c.ServeJSON() return } // 列表 - func (c *TaskDataController) TaskDataClass_List() { // 验证登录 User_is, User_r _, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } if Task_r.T_delivery_state == 2 { c.Data["json"] = lib.JSONS{Code: 202, Msg: "数据采集中,请稍后!"} c.ServeJSON() return } List := Task.Read_TaskData_ById_ClassList(Task_r.T_task_id) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: List} c.ServeJSON() return } // 添加- func (c *TaskDataController) TaskData_AddS() { // 验证登录 User_is, User_r user_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } //T_sn|T_id|T_t|T_rh|T_time? T_Data := c.GetString("T_Data") if len(T_Data) < 5 { c.Data["json"] = lib.JSONS{Code: 202, Msg: "err T_Data!"} c.ServeJSON() return } T_Data_list := strings.Split(T_Data, "?") println(len(T_Data_list), "len(T_Data_list)") var T_Data_list_x = 0 for _, v := range T_Data_list { // 2022-08-09 14:25:00|27.7|55.2 if len(v) < 5 { println(v, "len(v) < 5") continue } v_list := strings.Split(v, "|") is = Task.Add_TaskData(Task_r.T_task_id, v_list[0], v_list[1], v_list[2], v_list[3], v_list[4]) if is { T_Data_list_x += 1 } } System.Add_UserLogs(user_r.T_uuid, "任务数据", "添加数据"+Task_r.T_name, Task_r.T_task_id+"结果:"+string(len(T_Data_list))+"/"+string(T_Data_list_x)+"|=> "+T_Data) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: strconv.Itoa(T_Data_list_x)} c.ServeJSON() return } // 添加- func (c *TaskDataController) TaskData_Add() { // 验证登录 User_is, User_r user_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } T_sn := c.GetString("T_sn") T_id, _ := c.GetInt("T_id") T_t, _ := c.GetFloat("T_t") T_rh, _ := c.GetFloat("T_rh") T_time := c.GetString("T_time") T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } is = Task.Add_TaskData(Task_r.T_task_id, T_sn, strconv.Itoa(T_id), fmt.Sprintf("%.2f", T_t), fmt.Sprintf("%.2f", T_rh), T_time) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加失败!"} c.ServeJSON() return } System.Add_UserLogs(user_r.T_uuid, "任务数据", "添加数据"+Task_r.T_name, Task_r.T_task_id+"|"+T_sn+"|"+strconv.Itoa(T_id)+"|"+fmt.Sprintf("%.2f", T_t)+"|"+fmt.Sprintf("%.2f", T_rh)+T_time) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"} c.ServeJSON() return } // 修改- func (c *TaskDataController) TaskData_Up() { // 验证登录 User_is, User_r user_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Id, err := c.GetInt("Id") if err != nil { c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"} c.ServeJSON() return } T_t, err := c.GetFloat("T_t") if err != nil { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_t 错误!"} c.ServeJSON() return } T_rh, err := c.GetFloat("T_rh") if err != nil { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_rh 错误!"} c.ServeJSON() return } T_time := c.GetString("T_time") T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } is = Task.Up_TaskData(Task_r.T_task_id, strconv.Itoa(Id), fmt.Sprintf("%.2f", T_t), fmt.Sprintf("%.2f", T_rh), T_time) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改失败!"} c.ServeJSON() return } System.Add_UserLogs(user_r.T_uuid, "任务数据", "修改数据"+Task_r.T_name, Task_r.T_task_id+"|"+strconv.Itoa(Id)+"|"+fmt.Sprintf("%.2f", T_t)+"|"+fmt.Sprintf("%.2f", T_rh)+T_time) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"} c.ServeJSON() return } // 删除- func (c *TaskDataController) TaskData_Del() { // 验证登录 User_is, User_r user_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Id, err := c.GetInt("Id") if err != nil { c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"} c.ServeJSON() return } T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } is = Task.Del_TaskData(Task_r.T_task_id, strconv.Itoa(Id)) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"} c.ServeJSON() return } System.Add_UserLogs(user_r.T_uuid, "任务数据", "删除"+Task_r.T_name, Task_r.T_task_id+"|"+strconv.Itoa(Id)) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"} c.ServeJSON() return } // 删除- func (c *TaskDataController) TaskData_Del_t_id() { // 验证登录 User_is, User_r user_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Id, err := c.GetInt("Id") if err != nil { c.Data["json"] = lib.JSONS{Code: 202, Msg: "Id 错误!"} c.ServeJSON() return } T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } is = Task.Del_TaskData_t_id(Task_r.T_task_id, strconv.Itoa(Id)) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"} c.ServeJSON() return } System.Add_UserLogs(user_r.T_uuid, "任务数据", "删除"+Task_r.T_name, Task_r.T_task_id+"|"+strconv.Itoa(Id)) c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"} c.ServeJSON() return } // 列表 - 接口 func (c *TaskDataController) Export_Data_Excel() { // 验证登录 User_is, User_r _, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Time_start := c.GetString("Time_start") Time_end := c.GetString("Time_end") T_sn_str := c.GetString("T_sn_list") //865901058809339,865901058815849,865901058818991,865901058810568 //T_id, err := c.GetInt("T_id") //if err != nil { // T_id = -1 // //} T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } T_sn_list := strings.Split(T_sn_str, ",") DeviceSensor_data_list := []Task.TaskData_{} for _, v := range T_sn_list { DeviceSensor_data, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, v, "", Time_start, Time_end, 1, 9999) DeviceSensor_data_list = append(DeviceSensor_data_list, DeviceSensor_data...) } f := excelize.NewFile() // 设置单元格的值 // 这里设置表头 f.SetCellValue("Sheet1", "A1", "编号") f.SetCellValue("Sheet1", "B1", "SN") f.SetCellValue("Sheet1", "C1", "温度℃") f.SetCellValue("Sheet1", "D1", "湿度%") f.SetCellValue("Sheet1", "E1", "记录时间") // 设置列宽 f.SetColWidth("Sheet1", "A", "A", 7) f.SetColWidth("Sheet1", "B", "B", 20) f.SetColWidth("Sheet1", "C", "C", 10) f.SetColWidth("Sheet1", "D", "D", 10) f.SetColWidth("Sheet1", "E", "E", 22) line := 1 // 循环写入数据 for _, v := range DeviceSensor_data_list { line++ f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), v.T_id) f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), v.T_sn) f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), strconv.FormatFloat(float64(v.T_t), 'f', 1, 64)) f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), strconv.FormatFloat(float64(v.T_rh), 'f', 1, 64)) f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.T_time) } logs.Println("DeviceSensor_data:", len(DeviceSensor_data_list)) lib.Create_Dir("./ofile") timeStr := time.Now().Format("20060102150405") // 保存文件 if err := f.SaveAs("ofile/" + timeStr + ".xlsx"); err != nil { logs.Error(lib.FuncName(), err) } if !lib.Pload_qiniu("ofile/"+timeStr+".xlsx", "ofile/"+timeStr+".xlsx") { c.Data["json"] = lib.JSONS{Code: 203, Msg: "oss!"} c.ServeJSON() return } //删除目录 //err = os.Remove("ofile/" + timeStr + ".xlsx") //if err != nil { // logs.Error(lib.FuncName(),err) //} c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: "https://bzdcoldverifyoss.baozhida.cn/" + "ofile/" + timeStr + ".xlsx"} c.ServeJSON() return } // 列表 - 接口 func (c *TaskDataController) Export_Data_PDF() { // 验证登录 User_is, User_r _, User_is := Account.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Time_start := c.GetString("Time_start") Time_end := c.GetString("Time_end") T_sn_str := c.GetString("T_sn_list") //865901058809339,865901058815849,865901058818991,865901058810568 //T_id, err := c.GetInt("T_id") //if err != nil { // T_id = -1 // //} T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } dcList, _ := Device.Read_DeviceClassList_OrderList(Task_r.T_class, "", "", "", 0, 9999) // 查询设备列表 // 保存布局编号和校准证书对应关系 var deviceCertificateMap = make(map[string]string) // t_id, T_Certificate_sn for _, v := range dcList { deviceCertificateMap[v.T_id] = v.T_Certificate_sn } T_sn_list := strings.Split(T_sn_str, ",") DeviceSensor_data_list := []Task.TaskData_{} for _, v := range T_sn_list { DeviceSensor_data, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, v, "", Time_start, Time_end, 1, 9999) DeviceSensor_data_list = append(DeviceSensor_data_list, DeviceSensor_data...) for i := 0; i < len(DeviceSensor_data_list); i++ { DeviceSensor_data_list[i].T_Certificate_sn = deviceCertificateMap[DeviceSensor_data_list[i].T_id] } } //------ var err error pdf := &gopdf.GoPdf{} pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4 //err = GetFont(pdf, "LiberationSerif-Regular.ttf") //if err != nil { // log.Fatalln(err) //} //err = pdf.SetFont("Ubuntu-L", "", 14) //if err != nil { // log.Fatalln(err) //} err = pdf.AddTTFFont("simsun", "static/fonts/三极行楷简体-粗.ttf") if err != nil { c.Data["json"] = lib.JSONS{Code: 204, Msg: "ok!", Data: err} c.ServeJSON() return } err = pdf.SetFont("simsun", "", 24) if err != nil { c.Data["json"] = lib.JSONS{Code: 205, Msg: "ok!", Data: err} c.ServeJSON() return } pdf.SetGrayFill(0.5) pdf.SetMargins(0, 20, 0, 20) pdf.AddPage() //use path //pdf.Image("logo.png", 100, 50, &gopdf.Rect{W: 50, H: 50}) textw, _ := pdf.MeasureTextWidth(Task_r.T_name) pdf.SetX((595 / 2) - (textw / 2)) pdf.SetY(40) pdf.Text(Task_r.T_name) // 线 pdf.SetLineWidth(2) pdf.SetLineType("dashed") pdf.Line(10, 60, 585, 60) err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf") if err != nil { c.Data["json"] = lib.JSONS{Code: 206, Msg: "ok!", Data: err} c.ServeJSON() return } err = pdf.SetFont("wts", "", 12) if err != nil { c.Data["json"] = lib.JSONS{Code: 207, Msg: "ok!", Data: err} c.ServeJSON() return } t_ := Time_start + " / " + Time_end if len(Time_start) == 0 { t_ = "所有数据" } //fmt.Sprintf(" %.1f ", v.T_t) lib.RectFillColor(pdf, "提取数据时间段["+t_+"]", 14, 22, 80, 550, 40, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, "布局编号", 12, 22, 120, 80, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, "证书编号", 12, 92, 120, 150, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, "温度℃", 12, 242, 120, 100, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, "湿度%", 12, 342, 120, 100, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) //lib.RectFillColor(pdf, "温度范围", 12, 272, 120, 100, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) //lib.RectFillColor(pdf, "湿度范围", 12, 362, 120, 100, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, "记录时间", 12, 442, 120, 130, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) var y float64 = 140 err = pdf.SetFont("wts", "", 10) if err != nil { c.Data["json"] = lib.JSONS{Code: 207, Msg: "ok!", Data: err} c.ServeJSON() return } for _, v := range DeviceSensor_data_list { //text := fmt.Sprintf(" %d ", i+1) var textH float64 = 25 // if text height is 25px. pdf.SetNewY(y, textH) y = pdf.GetY() //pdf.SetX(x) // must after pdf.SetNewY() called. //err = pdf.Text(text) //if err != nil { // log.Fatalln(err) //} T_t := fmt.Sprintf(" %.1f ", v.T_t) T_rh := fmt.Sprintf(" %.1f ", v.T_rh) T_time := fmt.Sprintf("%s", v.T_time) lib.RectFillColor(pdf, v.T_id, 10, 22, y, 80, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, v.T_Certificate_sn, 10, 92, y, 150, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, T_t, 10, 242, y, 100, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, T_rh, 10, 342, y, 100, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) lib.RectFillColor(pdf, T_time, 10, 442, y, 130, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) y += 20 } timeStr := "ofile/" + time.Now().Format("20060102150405") + ".pdf" err = pdf.WritePdf(timeStr) if err != nil { c.Data["json"] = lib.JSONS{Code: 207, Msg: "ok!", Data: err} c.ServeJSON() return } if !lib.Pload_qiniu(timeStr, timeStr) { c.Data["json"] = lib.JSONS{Code: 203, Msg: "oss!"} c.ServeJSON() return } //删除目录 err = os.Remove(timeStr) if err != nil { logs.Error(lib.FuncName(), err) } c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: "https://bzdcoldverifyoss.baozhida.cn/" + timeStr} c.ServeJSON() return } // 列表 - 接口 func (c *TaskDataController) Check() { // 验证登录 User_is, User_r _, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } T_task_id := c.GetString("T_task_id") Task_r, is := Task.Read_Task(T_task_id) if !is { c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_task_id 错误!"} c.ServeJSON() return } type R_JSONS struct { T_sn string // SN T_id string // 编号 T_unm int // 数据量 T_time_interval int64 // 时间间隔 Time_start string // 开始 Time_end string // 结束 Result int // 200 OK, 201 可以补 , 202 不能补 Result_str string // 提示内容 Result_Time_start string // 2022-8-05 21:01 Result_Time_defect int64 // 缺失时间间隔 } var r_jsons []R_JSONS List := Task.Read_TaskData_ById_ClassList(Task_r.T_task_id) for _, v := range List { var r_json R_JSONS r_json.T_sn = v.T_sn r_json.Result = 200 DeviceSensor_data := Task.Read_TaskData_ById_List_(Task_r.T_task_id, v.T_sn) r_json.T_unm = len(DeviceSensor_data) if r_json.T_unm > 2 { r_json.T_id = DeviceSensor_data[0].T_id r_json.Time_end = DeviceSensor_data[len(DeviceSensor_data)-1].T_time r_json.Time_start = DeviceSensor_data[0].T_time formatTime_a, _ := time.Parse("2006-1-2 15:04", DeviceSensor_data[0].T_time) formatTime_b, _ := time.Parse("2006-1-2 15:04", DeviceSensor_data[1].T_time) formatTime_x := formatTime_b.Unix() - formatTime_a.Unix() r_json.T_time_interval = formatTime_x println("formatTime_x:", v.T_id, v.T_sn, formatTime_x) if formatTime_x > 60*30 || formatTime_x < 60 { r_json.Result = 202 r_json.Result_str = "数据异常(数据的第一个时间与第二个时间相差 " + strconv.FormatInt(formatTime_x, 10) + "秒),必须大于60秒,小于30分钟" r_jsons = append(r_jsons, r_json) continue } for data_i := 2; data_i < len(DeviceSensor_data); data_i++ { formatTime_a = formatTime_b formatTime_b, _ = time.Parse("2006-1-2 15:04", DeviceSensor_data[data_i].T_time) formatTime_ := formatTime_b.Unix() - formatTime_a.Unix() println("formatTime_x-:", formatTime_) if formatTime_ < formatTime_x { r_json.Result = 202 r_json.Result_str = "开始时间:" + DeviceSensor_data[data_i-1].T_time + " 离下一条时间间隔:" + strconv.FormatInt(formatTime_, 10) + "秒,间隔小于时间间隔,不能自动补充" break } if formatTime_x != formatTime_ { if formatTime_ > 60*30 { r_json.Result = 202 r_json.Result_str = "开始时间:" + DeviceSensor_data[data_i-1].T_time + " 离下一条时间间隔:" + strconv.FormatInt(formatTime_, 10) + "秒,相差时间大于30分钟,不能自动补充" break } r_json.Result = 201 r_json.Result_str = "开始时间:" + DeviceSensor_data[data_i-1].T_time + " 离下一条时间间隔:" + strconv.FormatInt(formatTime_, 10) + "秒" r_json.Result_Time_start = DeviceSensor_data[data_i-1].T_time r_json.Result_Time_defect = formatTime_ println(r_json.Result_str) break } } } else { r_json.Result = 202 r_json.Result_str = "数据量太少 必须大于 2条以上!" } r_jsons = append(r_jsons, r_json) } c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons} c.ServeJSON() return } func (c *TaskDataController) TaskData_Temperature_Pdf() { // 验证登录管理员 User_is, User_r _, User_Admin_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) // 验证登录用户 User_is, User_r _, User_is := Account.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_Admin_is && !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Time_start := c.GetString("Time_start") Time_end := c.GetString("Time_end") T_sn := c.GetString("T_sn") T_id := c.GetString("T_id") T_task_id := c.GetString("T_task_id") err := c.TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn, T_id, Task.Temperature) if err != nil { c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()} c.ServeJSON() return } } func (c *TaskDataController) TaskData_Humidity_Pdf() { // 验证登录管理员 User_is, User_r _, User_Admin_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) // 验证登录用户 User_is, User_r _, User_is := Account.Verification(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey")) if !User_Admin_is && !User_is { c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"} c.ServeJSON() return } Time_start := c.GetString("Time_start") Time_end := c.GetString("Time_end") T_sn := c.GetString("T_sn") T_id := c.GetString("T_id") T_task_id := c.GetString("T_task_id") err := c.TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn, T_id, Task.Humidity) if err != nil { c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()} c.ServeJSON() return } } func (c *TaskDataController) TaskData_Pdf(Time_start, Time_end, T_task_id, T_sn, T_id, T_type string) (err error) { Task_r, is := Task.Read_Task(T_task_id) if !is { return errors.New("T_task_id 错误!") } user, is := Account.Read_User(Task_r.T_uuid) if !is { return errors.New("Task uuid 错误!") } if Task_r.T_delivery_state == 2 { return errors.New("数据采集中,请稍后!") } pdf := &gopdf.GoPdf{} pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4 err = pdf.AddTTFFont("wts", "static/fonts/MiSans-Medium.ttf") if err != nil { return } err = pdf.SetFont("wts", "", 15) if err != nil { return } pdf.SetGrayFill(0.5) pdf.SetMargins(0, 20, 0, 20) pdf.AddPage() imgH, _ := gopdf.ImageHolderByPath("./static/logo.jpg") err = pdf.ImageByHolder(imgH, 10, 10, &gopdf.Rect{W: 93, H: 32}) name := user.T_name var y float64 = 40 textw, _ := pdf.MeasureTextWidth(name) pdf.SetX((595 / 2) - (textw / 2)) pdf.SetY(y) pdf.Text(name) y += 20 T_type_name := "" if T_type == Task.Temperature { T_type_name = "温度" } if T_type == Task.Humidity { T_type_name = "湿度" } title := Task_r.T_name + T_type_name + "验证数据" textw, _ = pdf.MeasureTextWidth(title) pdf.SetX((595 / 2) - (textw / 2)) pdf.SetY(y) pdf.Text(title) // 查询设备列表 //dcList, _ := Device.Read_DeviceClassList_OrderList(Task_r.T_class, T_sn, T_id, "", 0, 9999) dcList := []Device.DeviceClassList{} dataList, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, T_sn, T_id, Time_start, Time_end, 0, 9999) dataListMap := make(map[string][]Task.TaskData_) dcListMap := make(map[string]string) dataMap := make(map[string]string) timeMap := make(map[string]bool) for _, data := range dataList { dataListMap[data.T_id] = append(dataListMap[data.T_id], data) if _, ok := dcListMap[data.T_id]; !ok { dcListMap[data.T_id] = data.T_sn } k := fmt.Sprintf("%s,%s", data.T_time, data.T_id) if T_type == Task.Temperature { dataMap[k] = fmt.Sprintf("%.1f", data.T_t) } if T_type == Task.Humidity { dataMap[k] = fmt.Sprintf("%.1f", data.T_rh) } if _, ok := timeMap[data.T_time]; !ok { timeMap[data.T_time] = true } } for id, sn := range dcListMap { dcList = append(dcList, Device.DeviceClassList{T_id: id, T_sn: sn}) } for id, list := range dataListMap { sort.Slice(list, func(i, j int) bool { return list[i].T_time < list[j].T_time }) dataListMap[id] = list } var timeList []string for k, _ := range timeMap { timeList = append(timeList, k) } sort.Slice(timeList, func(i, j int) bool { return timeList[i] < timeList[j] }) err = pdf.SetFont("wts", "", 12) if err != nil { return } if len(timeList) > 0 { y += 20 timeStr := fmt.Sprintf("%s - %s", timeList[0], timeList[len(timeList)-1]) textw, _ = pdf.MeasureTextWidth(timeStr) pdf.SetX((595 / 2) - (textw / 2)) pdf.SetY(y) pdf.Text(timeStr) } //y += 20 var x float64 = 10 var w float64 = 120 err = pdf.SetFont("wts", "", 10) if err != nil { return } idWidthMap := make(map[string]float64) dcList1 := make([]Device.DeviceClassList, 0) for _, list := range dcList { idw, _ := pdf.MeasureTextWidth(list.T_id) if !lib.IsNumeric(list.T_id) { dcList1 = append(dcList1, list) } if idw > 20 { idWidthMap[list.T_id] = idw + 12 } else { idWidthMap[list.T_id] = 30.3 } } sort.Slice(dcList1, func(i, j int) bool { return dcList1[i].T_id < dcList1[j].T_id }) dcList2 := listSubtract(dcList, dcList1) // 获取探头时间 var timeList2 []string timeMap2 := make(map[string]struct{}) for _, list := range dcList2 { dataList2, ok := dataListMap[list.T_id] if ok { for _, data := range dataList2 { if _, ok = timeMap2[data.T_time]; !ok { timeMap2[data.T_time] = struct{}{} } } } } for k, _ := range timeMap2 { timeList2 = append(timeList2, k) } sort.Slice(timeList2, func(i, j int) bool { return timeList2[i] < timeList2[j] }) var temp int for index, dc := range dcList1 { dataList2, _ := dataListMap[dc.T_id] err = pdf.SetFont("wts", "", 15) if err != nil { return } y += 30 var textH float64 = 20 // if text height is 25px. if y >= 790 { addStampImage(pdf, 455, y-150) // AddWatermark(Task_r, pdf) pdf.AddPage() y = 30 } else { if index > 0 { y += 10 } } textw, _ = pdf.MeasureTextWidth(dc.T_id) pdf.SetX((595 / 2) - (textw / 2)) pdf.SetY(y) pdf.Text(dc.T_id) y += 10 err = pdf.SetFont("wts", "", 10) if err != nil { return } if y < 790 { x = 10 for i := 0; i < 4; i++ { w = 113.8 lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30 lib.RectFillColor(pdf, T_type_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w } y += 20 } else { addStampImage(pdf, 455, y-150) // AddWatermark(Task_r, pdf) pdf.AddPage() y = 20 x = 10 for i := 0; i < 4; i++ { w = 113.8 lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30 lib.RectFillColor(pdf, T_type_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w } y += 20 } for i := 0; i < len(dataList2); i++ { if y > 790 { addStampImage(pdf, 455, y-130) // AddWatermark(Task_r, pdf) pdf.AddPage() y = pdf.GetY() x = 10 for k := 0; k < 4; k++ { w = 113.8 lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30 lib.RectFillColor(pdf, T_type_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w } y += 20 } temp = i % 4 // 每页添加表头 if y == 20 && temp == 0 { x = 10 for k := 0; k < 4; k++ { w = 113.8 lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30 lib.RectFillColor(pdf, T_type_name, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w } y += 20 } x = 10 + 143.8*float64(temp) w = 113.8 lib.RectFillColor(pdf, dataList2[i].T_time, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30 if T_type == Task.Temperature { lib.RectFillColor(pdf, fmt.Sprintf("%.1f", dataList2[i].T_t), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) } if T_type == Task.Humidity { lib.RectFillColor(pdf, fmt.Sprintf("%.1f", dataList2[i].T_rh), 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) } //if y > 760 { // fmt.Println("=====y:", y) //} //if y > 790 { // addStampImage(pdf, 455, y-130) //} if temp == 3 { y += 20 pdf.SetNewY(y, textH) y = pdf.GetY() } } } if len(dcList2) > 0 { if temp != 3 { y += 20 } y += 40 } sort.Slice(dcList2, func(i, j int) bool { return dcList2[i].T_id < dcList2[j].T_id }) chunks := splitData(dcList2, 454.5, idWidthMap) for i, list := range chunks { if i > 0 { y += 40 } if y < 790 { x = 10 w = 120.7 lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30.3 for _, v2 := range list { w = idWidthMap[v2.T_id] lib.RectFillColor(pdf, v2.T_id, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w } y += 20 } else { addStampImage(pdf, 455, y-150) // AddWatermark(Task_r, pdf) pdf.AddPage() y = 20 } StampImageX := x for j, t := range timeList2 { if j > 0 { y += 20 } if y >= 790 { addStampImage(pdf, StampImageX-130, y-130) // AddWatermark(Task_r, pdf) pdf.AddPage() y = pdf.GetY() x = 10 w = 120.7 lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30.3 for _, v2 := range list { w = idWidthMap[v2.T_id] lib.RectFillColor(pdf, v2.T_id, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w } y += 20 x = 10 } x = 10 if y == 20 { w = 120.7 lib.RectFillColor(pdf, "时间", 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30.3 for _, v2 := range list { w = idWidthMap[v2.T_id] lib.RectFillColor(pdf, v2.T_id, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w } y += 20 x = 10 } w = 120.7 lib.RectFillColor(pdf, t, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w w = 30.3 for _, v := range list { t_t := dataMap[fmt.Sprintf("%s,%s", t, v.T_id)] w = idWidthMap[v.T_id] lib.RectFillColor(pdf, t_t, 12, x, y, w, 20, 255, 255, 255, lib.AlignCenter, lib.ValignMiddle) x += w } StampImageX = x } } if y <= 790 { if y < 150 { y = 20 } else { y = y - 145 } x = x - 135 if len(dcList2) == 0 { x = 455 } addStampImage(pdf, x, y) // AddWatermark(Task_r, pdf) } else if y > 790 && len(dcList2) == 0 { if y < 150 { y = 20 } else { y = y - 145 } addStampImage(pdf, 455, y) } filename := time.Now().Format("20060102150405") + ".pdf" timeStr := "ofile/" + T_type_name + filename err = pdf.WritePdf(timeStr) if err != nil { c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()} c.ServeJSON() return } // 上传 OSS //url, is := NatsServer.Qiniu_UploadFile(lib.GetCurrentDirectory()+"/ofile/"+timeStr, timeStr) //url, is := NatsServer.Qiniu_UploadFile("/Users/zoie/work/bzd_project/ColdVerify_server/"+timeStr, timeStr) //if !is { // err = errors.New("oss!") // return //} defer func() { //删除目录 os.Remove(timeStr) }() c.Ctx.Output.Download(timeStr) //c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: url} //c.ServeJSON() //return return nil } // 添加公章图片 func addStampImage(pdf *gopdf.GoPdf, x, y float64) { imagePath := "./static/commonSeal.jpg" if x < 10 { x = 10 } if y < 20 { y = 20 } err := pdf.Image(imagePath, x, y, &gopdf.Rect{W: 123, H: 128.6}) if err != nil { log.Print(err.Error()) } } func listSubtract(sliceA, sliceB []Device.DeviceClassList) []Device.DeviceClassList { // 创建一个集合用于存储 sliceB 的元素 elementsToRemove := make(map[string]Device.DeviceClassList) for _, item := range sliceB { elementsToRemove[item.T_id] = item } // 构建新切片,包含 sliceA 中不在 elementsToRemove 中的元素 var result []Device.DeviceClassList for _, item := range sliceA { if _, found := elementsToRemove[item.T_id]; !found { result = append(result, item) } } return result } func chunkBy1[T any](list []T, size int) [][]T { var chunks [][]T for size < len(list) { list, chunks = list[size:], append(chunks, list[0:size:size]) } return append(chunks, list) } func splitData(data []Device.DeviceClassList, threshold float64, idWidthMap map[string]float64) [][]Device.DeviceClassList { var result [][]Device.DeviceClassList var currentBatch []Device.DeviceClassList var currentSum float64 for _, item := range data { wd := idWidthMap[item.T_id] if currentSum+wd > threshold+0.1 { // 当前批次超过阈值,切分 result = append(result, currentBatch) // 重置当前批次和当前总和 currentBatch = []Device.DeviceClassList{} currentSum = 0 } currentBatch = append(currentBatch, item) currentSum += wd } // 添加最后一批 if len(currentBatch) > 0 { result = append(result, currentBatch) } return result } func AddWatermark(task Task.Task, pdf *gopdf.GoPdf) { // 设置透明度 (通过绘制透明背景实现) // 使用浅色字体来模拟透明度 //originalX := pdf.GetX() //originalY := pdf.GetY() //grayColor := color.RGBA{R: 200, G: 200, B: 200, A: 255} // 浅灰色,接近透明效果 //pdf.SetTextColor(grayColor.R, grayColor.G, grayColor.B) // 设置字体颜色 //pdf.SetFontSize(50) // //// 设置水印的重复布局 //text := "水印" //xOffset := 180.0 // X 坐标的偏移量 //yOffset := 180.0 // Y 坐标的偏移量 //angle := 45.0 // 旋转角度(度) // //// 循环绘制水印 //for y := 0.0; y < 780; y += yOffset { // 842 是 A4 页面高度的像素数 (72 DPI) // for x := -100.0; x < 595; x += xOffset { // 595 是 A4 页面宽度的像素数 (72 DPI) // // 保存当前的绘制状态 // pdf.SetX(x) // pdf.SetY(y) // pdf.Rotate(angle, x+100, y+50) // 旋转水印 // pdf.Cell(nil, text) // pdf.RotateReset() // 恢复旋转状态 // } //} // //grayColor2 := color.RGBA{R: 0, G: 0, B: 0, A: 0} // 浅灰色,接近透明效果 //pdf.SetTextColor(grayColor2.R, grayColor2.G, grayColor2.B) // 设置字体颜色 //pdf.SetFontSize(10) //pdf.SetX(originalX) //pdf.SetY(originalY) }