diff --git a/deescloud.exe b/deescloud.exe index ef032c3..208672f 100644 Binary files a/deescloud.exe and b/deescloud.exe differ diff --git a/main.go b/main.go index 29b1100..c6db775 100644 --- a/main.go +++ b/main.go @@ -1501,6 +1501,7 @@ func main() { http.HandleFunc("/deescloud/get_tool_warning_en", get_tool_warning_en) http.HandleFunc("/deescloud/get_tool_warning_pdf", get_tool_warning_pdf) http.HandleFunc("/deescloud/get_tool_mess_pdf", get_tool_mess_pdf) + http.HandleFunc("/deescloud/get_tool_mess_pdf_en", get_tool_mess_pdf_en) http.HandleFunc("/deescloud/get_tool_warning_pdf_en", get_tool_warning_pdf_en) http.HandleFunc("/deescloud/get_dev_manage", get_dev_manage) @@ -1545,6 +1546,7 @@ func main() { http.HandleFunc("/deescloud/get_tool_WarningCsv", get_tool_WarningCsv) http.HandleFunc("/deescloud/getInstrumentMess", getInstrumentMess) + http.HandleFunc("/deescloud/getInstrumentMess_en", getInstrumentMess_en) http.HandleFunc("/deescloud/addQualityData", addQualityData) http.HandleFunc("/deescloud/getQualityData", getQualityData) http.HandleFunc("/deescloud/upload", upload) @@ -3521,6 +3523,59 @@ func get_tool_mess_pdf(response http.ResponseWriter, request *http.Request) { } +func get_tool_mess_pdf_en(response http.ResponseWriter, request *http.Request) { + beginTime := time.Now().UnixNano() + logs.Info("导出仪器报告 begin", time.Now().Format("2006-01-02 15:04:05")) + reqdata, _ := ioutil.ReadAll(request.Body) + var resp get_cmr_pdf_resp + var reqMess InstrumentMess + json.Unmarshal(reqdata, &reqMess) + warnData := get_tool_warning_info(reqMess.Opuser, reqMess.WellName) + + // 创建用于存储所有响应数据的切片 + var allRespData []interface{} + + // 循环处理每个警告项 + for _, warn := range warnData { + + // 更新请求参数 + reqMess.Series = warn.Series + reqMess.Instrument = warn.Instrument + reqMess.Content = warn.Context + + // 调用工具方法 + respData, err := getInstrumentMessUtil(reqMess) + + // 打印响应结果 + if err != nil { + fmt.Printf("!!! 调用出错: %v\n", err) + } else { + _, marshalErr := json.MarshalIndent(respData, "", " ") + if marshalErr != nil { + // 将原始响应内容添加到切片 + allRespData = append(allRespData, respData) + fmt.Println("原始响应内容:", respData) + } else { + // 成功序列化也添加到切片 + allRespData = append(allRespData, respData) + } + } + } + + fullData, _ := json.MarshalIndent(allRespData, "", " ") + fmt.Println(string(fullData)) + + filename := GenerateInstrumentPDF_EN(fullData, warnData) + fmt.Println("文件名------------------------:", filename) + resp.FileId = filename + + jdata, _ := json.Marshal(resp) + fmt.Fprintf(response, string(jdata)) + + endTime := time.Now().UnixNano() + logs.Info(fmt.Sprintf("get_tool_warning_pdf recv req end, use time: %v ms", (endTime-beginTime)/1e6)) +} + func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename string) { respJSON, err := json.Marshal(resp) if err != nil { @@ -3546,7 +3601,7 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin } // 基础样式参数 - margin := 40.0 // 页边距 + margin := 28.0 // 页边距 lineHeight := 22.0 // 行高 sectionGap := 20.0 // 段落间距 colGap := 15.0 // 列间距 @@ -3555,6 +3610,24 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin minBottomMargin := 10.0 // 最小底部间距 y := margin + // 添加页码的函数 + addPageNumber := func(pageNum int) { + // 保存当前状态 + currentY := pdf.GetY() + currentX := pdf.GetX() + + // 设置页码样式 + pdf.SetFont("simfang", "", 10) + pdf.SetTextColor(0, 0, 0) + pdf.SetX(gopdf.PageSizeA4.W - margin - 30) + pdf.SetY(gopdf.PageSizeA4.H - margin/2) + pdf.Cell(nil, fmt.Sprintf("第 %d 页", pageNum)) + + // 恢复位置 + pdf.SetY(currentY) + pdf.SetX(currentX) + } + // 样式函数 titleStyle := func() { pdf.SetFont("simfang", "", 18) @@ -3563,7 +3636,7 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin sectionStyle := func() { pdf.SetFont("simfang", "", 14) - pdf.SetTextColor(30, 30, 150) + pdf.SetTextColor(0, 0, 0) } tableHeaderStyle := func() { @@ -3587,10 +3660,14 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if checkPageBreak(lineHeight * 2) { pdf.AddPage() y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) } // 生成PDF报告 pdf.AddPage() + // 添加第一页的页码 + addPageNumber(pdf.GetNumberOfPages()) // 获取井名 var wellName string @@ -3611,7 +3688,7 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin // 风险提示部分 if len(resp) > 0 { pdf.SetFont("simfang", "B", 12) - pdf.SetTextColor(0, 0, 0) + pdf.SetTextColor(0, 0, 255) pdf.SetX(margin) pdf.SetY(y) pdf.Cell(nil, "本口井风险提示") @@ -3638,6 +3715,8 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if checkPageBreak(lineHeight * 1.2) { pdf.AddPage() y = margin + 15 + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) } var contextText string @@ -3649,7 +3728,7 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin pdf.SetTextColor(200, 0, 0) } - warningText := fmt.Sprintf("%s %s %s", warning.Series, warning.Instrument, contextText) + warningText := fmt.Sprintf("%s %s %s", warning.Series+" - ", warning.Instrument, contextText) pdf.SetFont("simfang", "", 13) pdf.SetX(margin) pdf.SetY(y) @@ -3670,7 +3749,8 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin sectionStyle() pdf.SetX(margin) pdf.SetY(y) - pdf.Cell(nil, "▍ 基本信息 ("+inst.Series+" "+inst.Instrument+")") + pdf.SetTextColor(0, 0, 255) + pdf.Cell(nil, "▍ 基本信息 ("+inst.Series+" - "+inst.Instrument+")") y += lineHeight formattedTime := inst.Time @@ -3702,19 +3782,21 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if checkPageBreak(lineHeight * 2) { pdf.AddPage() y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) } // 第一列 pdf.SetX(margin) pdf.SetY(y) pdf.SetFont("simfang", "", 12) - pdf.SetTextColor(80, 80, 80) + pdf.SetTextColor(0, 0, 0) pdf.Cell(&gopdf.Rect{W: labelWidth, H: lineHeight}, basicInfo[i].Label) pdf.SetX(margin + labelWidth) pdf.SetTextColor(0, 0, 0) if basicInfo[i].Value == "" { - pdf.SetTextColor(150, 150, 150) + pdf.SetTextColor(0, 0, 0) pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, "无数据") } else { pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, basicInfo[i].Value) @@ -3724,13 +3806,13 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if i+1 < len(basicInfo) { pdf.SetX(margin + colWidth + colGap) pdf.SetY(y) - pdf.SetTextColor(80, 80, 80) + pdf.SetTextColor(0, 0, 0) pdf.Cell(&gopdf.Rect{W: labelWidth, H: lineHeight}, basicInfo[i+1].Label) pdf.SetX(margin + colWidth + colGap + labelWidth) pdf.SetTextColor(0, 0, 0) if basicInfo[i+1].Value == "" { - pdf.SetTextColor(150, 150, 150) + pdf.SetTextColor(0, 0, 0) pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, "无数据") } else { pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, basicInfo[i+1].Value) @@ -3745,6 +3827,7 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin sectionStyle() pdf.SetX(margin) pdf.SetY(y) + pdf.SetTextColor(0, 0, 255) pdf.Cell(nil, "▍ 产品质检记录") y += lineHeight @@ -3752,9 +3835,11 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if checkPageBreak(lineHeight) { pdf.AddPage() y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) } pdf.SetFont("simfang", "", 12) - pdf.SetTextColor(150, 150, 150) + pdf.SetTextColor(0, 0, 0) pdf.SetX(margin) pdf.SetY(y) pdf.Cell(nil, "暂无质检记录") @@ -3770,27 +3855,29 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin } for _, item := range qcItems { - // 计算文本高度 + // 计算文本行数 lines, _ := pdf.SplitText(item.Value, gopdf.PageSizeA4.W-margin*2-labelWidth) - itemHeight := lineHeight * float64(max(1, len(lines))) - if checkPageBreak(itemHeight) { + // 检查是否需要分页 + if checkPageBreak(lineHeight) { pdf.AddPage() y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) } // 标签 pdf.SetX(margin) pdf.SetY(y) pdf.SetFont("simfang", "", 12) - pdf.SetTextColor(80, 80, 80) + pdf.SetTextColor(0, 0, 0) pdf.Cell(&gopdf.Rect{W: labelWidth, H: lineHeight}, item.Label) // 值 pdf.SetX(margin + labelWidth) pdf.SetTextColor(0, 0, 0) if item.Value == "" { - pdf.SetTextColor(150, 150, 150) + pdf.SetTextColor(0, 0, 0) pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, "无数据") y += lineHeight } else { @@ -3798,67 +3885,90 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if j > 0 { y += lineHeight pdf.SetX(margin + labelWidth) + pdf.SetY(y) + } else { + pdf.SetY(y) } - pdf.SetY(y + float64(j)*lineHeight) pdf.Cell(&gopdf.Rect{W: gopdf.PageSizeA4.W - margin*2 - labelWidth, H: lineHeight}, line) } - y += lineHeight * float64(len(lines)) + y += lineHeight } } } y += sectionGap - // 3. 上井记录表格 + // 3. 仪器施工汇总 sectionStyle() pdf.SetX(margin) pdf.SetY(y) + pdf.SetTextColor(0, 0, 255) pdf.Cell(nil, "▍ 仪器施工汇总") y += lineHeight // 表格参数 colWidths := []float64{80, 60, 60, 60, 60, 60, 50, 100} - headers := []string{"井名", "入井状态", "工作井深", "最高温度", "最高压力", "仪器状况", "上井人", "报告"} + headers := []string{"井名", "入井状态", "工作井深", "最高温度", "最高压强", "仪器状况", "上井人", "链接"} if len(inst.WorkMessList) == 0 { // 没有上井记录时显示提示信息 if y > pageHeight-lineHeight*2 { pdf.AddPage() y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) } pdf.SetFont("simfang", "", 12) - pdf.SetTextColor(150, 150, 150) // 灰色表示无数据 + pdf.SetTextColor(0, 0, 0) // 灰色表示无数据 pdf.SetX(margin) pdf.SetY(y) pdf.Cell(nil, "暂无上井记录") y += lineHeight } else { + // 计算总宽度 + totalWidth := 0.0 + for _, width := range colWidths { + totalWidth += width + } + // 表头高度 headerHeight := lineHeight + cellPadding*2 - // 只在第一页绘制表头 + // 绘制表头背景(整个表头作为一个矩形) + pdf.SetFillColor(57, 99, 156) + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, headerHeight, "F") + + // 设置表头样式 tableHeaderStyle() + pdf.SetTextColor(255, 255, 255) + startX := margin currX := startX for i, width := range colWidths { - // 绘制单元格(填充+边框) - pdf.SetFillColor(57, 99, 156) - pdf.RectFromUpperLeftWithStyle(currX, y, width, headerHeight, "F") - pdf.SetLineWidth(0.1) - pdf.SetStrokeColor(255, 255, 255) - pdf.RectFromUpperLeftWithStyle(currX, y, width, headerHeight, "D") - // 表头居中 text := headers[i] textWidth, _ := pdf.MeasureTextWidth(text) textX := currX + (width-textWidth)/2 pdf.SetX(textX) pdf.SetY(y + cellPadding) - pdf.Cell(&gopdf.Rect{W: width, H: lineHeight}, text) + pdf.Cell(nil, text) // 修改:使用nil而不是指定宽度 + + // 绘制黑色列分隔线(只在列之间绘制) + if i < len(colWidths)-1 { + pdf.SetLineWidth(0.2) + pdf.SetStrokeColor(0, 0, 0) // 黑色分隔线 + pdf.Line(currX+width, y, currX+width, y+headerHeight) + } currX += width } + + // 绘制表头外边框(黑色,确保与内容表格对齐) + pdf.SetLineWidth(0.5) + pdf.SetStrokeColor(0, 0, 0) // 黑色边框 + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, headerHeight, "D") + y += headerHeight // 绘制表格内容 @@ -3901,6 +4011,8 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if y+rowHeight > pageHeight-5 { // 保留5mm底部间距 pdf.AddPage() y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) // 注意:换页后不再绘制表头 } @@ -3913,14 +4025,28 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin pdf.RectFromUpperLeftWithStyle(currX, y, width, rowHeight, "D") // 绘制多行文本 - textY := y + cellPadding - for _, line := range cellLines[i] { - pdf.SetX(currX + cellPadding) - pdf.SetY(textY) - pdf.Cell(&gopdf.Rect{W: width - cellPadding*2, H: lineHeight}, line) - textY += lineHeight - } + lines := cellLines[i] + // 计算垂直居中位置 + totalTextHeight := lineHeight * float64(len(lines)) + startTextY := y + (rowHeight-totalTextHeight)/2 + for j, line := range lines { + // 计算水平居中位置 + textWidth, _ := pdf.MeasureTextWidth(line) + textX := currX + (width-textWidth)/2 + + // 边界检查,防止文本溢出 + if textX < currX+cellPadding { + textX = currX + cellPadding + } else if textX+textWidth > currX+width-cellPadding { + textX = currX + width - textWidth - cellPadding + } + + pdf.SetX(textX) + pdf.SetY(startTextY + float64(j)*lineHeight) + pdf.SetTextColor(0, 0, 0) + pdf.Cell(nil, line) // 关键修改:使用nil而不是指定宽度 + } currX += width } y += rowHeight @@ -3932,6 +4058,7 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin sectionStyle() pdf.SetX(margin) pdf.SetY(y) + pdf.SetTextColor(0, 0, 255) pdf.Cell(nil, "▍ 维保记录") y += lineHeight @@ -3940,9 +4067,11 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if y > pageHeight-lineHeight { pdf.AddPage() y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) } pdf.SetFont("simfang", "", 12) - pdf.SetTextColor(150, 150, 150) + pdf.SetTextColor(0, 0, 0) pdf.SetX(margin) pdf.SetY(y) pdf.Cell(nil, "暂无维保记录") @@ -3950,28 +4079,50 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin } else { // 表格参数 colWidths := []float64{120, 80, 80, 140, 120} - headers := []string{"维保时间", "维保等级", "维保人员", "维保内容", "报告"} + headers := []string{"维保时间", "维保等级", "维保人员", "维保内容", "链接"} headerHeight := lineHeight + cellPadding*2 - startX := margin - // 只在第一页绘制表头 + // 计算总宽度 + totalWidth := 0.0 + for _, width := range colWidths { + totalWidth += width + } + + // 绘制表头背景(整个表头作为一个矩形) + pdf.SetFillColor(57, 99, 156) + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, headerHeight, "F") + + // 设置表头样式 tableHeaderStyle() - currX := startX - for i, width := range colWidths { - pdf.SetFillColor(57, 99, 156) - pdf.RectFromUpperLeftWithStyle(currX, y, width, headerHeight, "F") - pdf.SetLineWidth(0.1) - pdf.SetStrokeColor(255, 255, 255) - pdf.RectFromUpperLeftWithStyle(currX, y, width, headerHeight, "D") + pdf.SetTextColor(255, 255, 255) + startX := margin + currX := startX + + for i, width := range colWidths { + // 表头居中 text := headers[i] textWidth, _ := pdf.MeasureTextWidth(text) textX := currX + (width-textWidth)/2 pdf.SetX(textX) pdf.SetY(y + cellPadding) pdf.Cell(&gopdf.Rect{W: width, H: lineHeight}, text) + + // 绘制黑色列分隔线(只在列之间绘制) + if i < len(colWidths)-1 { + pdf.SetLineWidth(0.2) + pdf.SetStrokeColor(0, 0, 0) // 黑色分隔线 + pdf.Line(currX+width, y, currX+width, y+headerHeight) + } + currX += width } + + // 绘制表头外边框(黑色,确保与内容表格对齐) + pdf.SetLineWidth(0.5) + pdf.SetStrokeColor(0, 0, 0) // 黑色边框 + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, headerHeight, "D") + y += headerHeight // 绘制表格内容 @@ -4009,6 +4160,8 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin if y+rowHeight > pageHeight-5 { // 保留5mm底部间距 pdf.AddPage() y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) // 注意:换页后不再绘制表头 } @@ -4019,12 +4172,19 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin pdf.SetStrokeColor(0, 0, 0) pdf.RectFromUpperLeftWithStyle(currX, y, width, rowHeight, "D") - textY := y + cellPadding - for _, line := range cellLines[i] { - pdf.SetX(currX + cellPadding) - pdf.SetY(textY) - pdf.Cell(&gopdf.Rect{W: width - cellPadding*2, H: lineHeight}, line) - textY += lineHeight + lines := cellLines[i] + // 计算垂直居中位置 + totalTextHeight := lineHeight * float64(len(lines)) + startTextY := y + (rowHeight-totalTextHeight)/2 + + for j, line := range lines { + // 计算水平居中位置 + textWidth, _ := pdf.MeasureTextWidth(line) + textX := currX + (width-textWidth)/2 // 水平居中 + pdf.SetX(textX) + pdf.SetY(startTextY + float64(j)*lineHeight) // 垂直居中 + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: width, H: lineHeight}, line) } currX += width } @@ -4033,16 +4193,721 @@ func GenerateInstrumentPDF(fullData []byte, resp []Tool_warning) (filename strin } y += sectionGap - // ... 后面的代码保持不变 ... - } - // 页码 - pdf.SetFont("simfang", "", 10) - pdf.SetTextColor(100, 100, 100) - pdf.SetX(gopdf.PageSizeA4.W - margin - 30) - pdf.SetY(gopdf.PageSizeA4.H - margin/2) - pdf.Cell(nil, fmt.Sprintf("第 %d 页", pdf.GetNumberOfPages())) + // 保存PDF + beginTime := time.Now().UnixNano() + filename = fmt.Sprintf("./authfile/%d.pdf", beginTime) + if err := pdf.WritePdf(filename); err != nil { + logs.Error("PDF保存失败:", err) + return "" + } + + return strconv.FormatInt(beginTime, 10) + ".pdf" +} + +func GenerateInstrumentPDF_EN(fullData []byte, resp []Tool_warning) (filename string) { + respJSON, err := json.Marshal(resp) + if err != nil { + logs.Error("Tool_warning数据JSON序列化错误:", err) + } + fmt.Println("Tool_warning JSON:", string(respJSON)) + + // 解析JSON数据 + var instruments []InstrumentMessRespdata + if err := json.Unmarshal(fullData, &instruments); err != nil { + logs.Error("JSON解析错误:", err) + return "" + } + + // 初始化PDF + pdf := gopdf.GoPdf{} + pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4}) + + // 加载中文字体 + if err := pdf.AddTTFFont("simfang", "./simsun.ttf"); err != nil { + logs.Error("加载字体错误:", err) + return "" + } + + // 基础样式参数 + margin := 28.0 // 页边距 + lineHeight := 22.0 // 行高 + sectionGap := 20.0 // 段落间距 + colGap := 15.0 // 列间距 + cellPadding := 5.0 // 表格单元格内边距 + pageHeight := gopdf.PageSizeA4.H - margin*2 + minBottomMargin := 10.0 // 最小底部间距 + y := margin + + // 添加页码的函数 + addPageNumber := func(pageNum int) { + // 保存当前状态 + currentY := pdf.GetY() + currentX := pdf.GetX() + + // 设置页码样式 + pdf.SetFont("simfang", "", 10) + pdf.SetTextColor(0, 0, 0) + pdf.SetX(gopdf.PageSizeA4.W - margin - 30) + pdf.SetY(gopdf.PageSizeA4.H - margin/2) + pdf.Cell(nil, fmt.Sprintf("Page %d", pageNum)) + + // 恢复位置 + pdf.SetY(currentY) + pdf.SetX(currentX) + } + + // 样式函数 + titleStyle := func() { + pdf.SetFont("simfang", "", 18) + pdf.SetTextColor(0, 0, 0) + } + + sectionStyle := func() { + pdf.SetFont("simfang", "", 14) + pdf.SetTextColor(30, 30, 150) + } + + tableHeaderStyle := func() { + pdf.SetFont("simfang", "", 12) + pdf.SetTextColor(255, 255, 255) + pdf.SetFillColor(57, 99, 156) + } + + tableCellStyle := func() { + pdf.SetFont("simfang", "", 11) + pdf.SetTextColor(0, 0, 0) + pdf.SetFillColor(255, 255, 255) + } + + // 辅助函数:检查是否需要换页 + checkPageBreak := func(requiredHeight float64) bool { + return y+requiredHeight > pageHeight-minBottomMargin + } + + // 使用示例 + if checkPageBreak(lineHeight * 2) { + pdf.AddPage() + y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) + } + + // 生成PDF报告 + pdf.AddPage() + // 添加第一页的页码 + addPageNumber(pdf.GetNumberOfPages()) + + // 获取井名 + var wellName string + if len(instruments) > 0 { + wellName = instruments[0].WellName + } + + // 主标题 + titleStyle() + pdf.SetX(margin) + pdf.SetY(y) + titleWidth := gopdf.PageSizeA4.W - margin*2 + var titleOption gopdf.CellOption + titleOption.Align = gopdf.Center + pdf.CellWithOption(&gopdf.Rect{W: titleWidth, H: lineHeight}, wellName, titleOption) + y += lineHeight * 1.8 + + // 风险提示部分 + if len(resp) > 0 { + pdf.SetFont("simfang", "B", 12) + pdf.SetTextColor(0, 0, 0) + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "Risk warning for this well") + y += lineHeight * 1.5 + + reportTime := time.Now().Format("2006-01-02 15:04:05") + pdf.SetFont("simfang", "", 12) + pdf.SetTextColor(0, 0, 0) + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, fmt.Sprintf("Well num:%s\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tReport time:%s", wellName, reportTime)) + y += lineHeight * 1.2 + pdf.Line(margin, y, gopdf.PageSizeA4.W-margin, y) + y += 10 + + pdf.SetFont("simfang", "B", 16) + pdf.SetTextColor(220, 20, 60) + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "Risk Warning:") + y += lineHeight * 1.2 + + for _, warning := range resp { + if checkPageBreak(lineHeight * 1.2) { + pdf.AddPage() + y = margin + 15 + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) + } + + var contextText string + if warning.Flag == 0 { + contextText = "Normal" + pdf.SetTextColor(0, 0, 0) + } else { + contextText = warning.Context + pdf.SetTextColor(200, 0, 0) + } + + warningText := fmt.Sprintf("%s %s %s", warning.Series+" - ", warning.Instrument, contextText) + pdf.SetFont("simfang", "", 13) + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(&gopdf.Rect{W: gopdf.PageSizeA4.W - margin*2, H: lineHeight}, warningText) + y += lineHeight * 1.2 + } + y += 15 + } + + // 遍历所有仪器 + for _, inst := range instruments { + pdf.SetLineWidth(1) + pdf.SetStrokeColor(0, 0, 0) + pdf.Line(margin, y, gopdf.PageSizeA4.W-margin, y) + y += 15 + + // 1. 基本信息区块 + sectionStyle() + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "▍ Basic information ("+inst.Series+" - "+inst.Instrument+")") + y += lineHeight + + formattedTime := inst.Time + if inst.Time != "" { + if t, err := time.Parse(time.RFC3339, inst.Time); err == nil { + formattedTime = t.Format("2006-01-02") + } else if t, err := time.Parse("2006-01-02T15:04:05Z", inst.Time); err == nil { + formattedTime = t.Format("2006-01-02") + } + } + + basicInfo := []struct { + Label string + Value string + }{ + {"Date of manufacture:", formattedTime}, + {"Date of warehouse:", ""}, + {"This work hour:", inst.WorkTime + "hour"}, + {"Work hour:", inst.WorkTimes + "hour"}, + {"Department:", inst.Dept}, + {"Firmware version:", inst.Version}, + } + + colWidth := (gopdf.PageSizeA4.W - margin*2 - colGap) / 2 + labelWidth := 190.0 + valueWidth := colWidth - labelWidth + + for i := 0; i < len(basicInfo); i += 2 { + if checkPageBreak(lineHeight * 2) { + pdf.AddPage() + y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) + } + + // 第一列 + pdf.SetX(margin) + pdf.SetY(y) + pdf.SetFont("simfang", "", 12) + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: labelWidth, H: lineHeight}, basicInfo[i].Label) + + pdf.SetX(margin + labelWidth) + pdf.SetTextColor(0, 0, 0) + if basicInfo[i].Value == "" { + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, "No data") + } else { + pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, basicInfo[i].Value) + } + + // 第二列 + if i+1 < len(basicInfo) { + pdf.SetX(margin + colWidth + colGap) + pdf.SetY(y) + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: labelWidth, H: lineHeight}, basicInfo[i+1].Label) + + pdf.SetX(margin + colWidth + colGap + labelWidth) + pdf.SetTextColor(0, 0, 0) + if basicInfo[i+1].Value == "" { + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, "No data") + } else { + pdf.Cell(&gopdf.Rect{W: valueWidth, H: lineHeight}, basicInfo[i+1].Value) + } + } + + y += lineHeight + } + y += sectionGap + + // 2. 质检记录 + sectionStyle() + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "▍ Product Quality inspection record") + y += lineHeight + + if inst.QualityData.ProcessRecord == "" && inst.QualityData.ProcessInspection == "" && inst.QualityData.FinalInspection == "" { + if checkPageBreak(lineHeight) { + pdf.AddPage() + y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) + } + pdf.SetFont("simfang", "", 12) + pdf.SetTextColor(0, 0, 0) + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "No data") + y += lineHeight + } else { + qcItems := []struct { + Label string + Value string + }{ + {"Production process record:", inst.QualityData.ProcessRecord}, + {"Production process inspection:", inst.QualityData.ProcessInspection}, + {"Final inspection display:", inst.QualityData.FinalInspection}, + } + + for _, item := range qcItems { + availableWidth := gopdf.PageSizeA4.W - margin*2 - labelWidth + + // 先设置字体再计算分割 + pdf.SetFont("simfang", "", 12) + lines, _ := pdf.SplitText(item.Value, availableWidth) + + fmt.Printf("DEBUG: %s - %d lines, text: '%s'\n", item.Label, len(lines), item.Value) + + itemHeight := lineHeight * float64(len(lines)) + if len(lines) == 0 { + itemHeight = lineHeight + } + + if checkPageBreak(itemHeight) { + pdf.AddPage() + y = margin + addPageNumber(pdf.GetNumberOfPages()) + } + + // 绘制标签 + pdf.SetXY(margin, y) + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: labelWidth, H: lineHeight}, item.Label) + + // 绘制值 + if item.Value == "" { + pdf.SetXY(margin+labelWidth, y) + pdf.SetTextColor(150, 150, 150) + pdf.Cell(&gopdf.Rect{W: availableWidth, H: lineHeight}, "No data") + y += lineHeight + } else { + for i, line := range lines { + pdf.SetXY(margin+labelWidth, y+float64(i)*lineHeight) + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: availableWidth, H: lineHeight}, line) + } + y += lineHeight * float64(len(lines)) + } + + y += lineHeight * 0.3 // 项目间距 + } + } + y += sectionGap + + // 3. 上井记录 + sectionStyle() + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "▍ Summary of Instrument Construction") + y += lineHeight + + // 表格参数 + colWidths := []float64{80, 60, 60, 60, 60, 60, 50, 100} + // 使用缩写避免换行问题 + headers := []string{ + "Well Name", + "Status", + "Depth", + "Max Temp", + "Max Press", + "Situation", + "Person", + "URL", + } + + if len(inst.WorkMessList) == 0 { + // 没有上井记录时显示提示信息 + if y > pageHeight-lineHeight*2 { + pdf.AddPage() + y = margin + addPageNumber(pdf.GetNumberOfPages()) + } + + pdf.SetFont("simfang", "", 10) + pdf.SetTextColor(0, 0, 0) + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "No Data") + y += lineHeight + } else { + // 计算表头每列的最大行数 + maxHeaderLines := 1 + headerLines := make([][]string, len(colWidths)) + for i, width := range colWidths { + availableWidth := width - cellPadding*2 + 20 + lines, _ := pdf.SplitText(headers[i], availableWidth) + headerLines[i] = lines + if len(lines) > maxHeaderLines { + maxHeaderLines = len(lines) + } + } + + // 表头高度 + headerHeight := lineHeight*float64(maxHeaderLines) + cellPadding*2 + + // 检查表头是否需要换页 + if y+headerHeight > pageHeight-5 { + pdf.AddPage() + y = margin + addPageNumber(pdf.GetNumberOfPages()) + } + + // 计算总宽度(确保与内容表格一致) + totalWidth := 0.0 + for _, width := range colWidths { + totalWidth += width + } + + // 绘制表头背景(整个表头作为一个矩形) + pdf.SetFillColor(57, 99, 156) + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, headerHeight, "F") + + // 设置表头样式 + pdf.SetFont("simfang", "", 10) + pdf.SetTextColor(255, 255, 255) + + startX := margin + currX := startX + + for i, width := range colWidths { + // 绘制多行表头文本(居中) + lines := headerLines[i] + // 计算垂直居中位置 + totalTextHeight := lineHeight * float64(len(lines)) + startTextY := y + (headerHeight-totalTextHeight)/2 + + for j, line := range lines { + textWidth, _ := pdf.MeasureTextWidth(line) + textX := currX + (width-textWidth)/2 + pdf.SetX(textX) + pdf.SetY(startTextY + float64(j)*lineHeight) + pdf.Cell(&gopdf.Rect{W: width, H: lineHeight}, line) + } + + // 绘制黑色列分隔线(只在列之间绘制) + if i < len(colWidths)-1 { + pdf.SetLineWidth(0.2) + pdf.SetStrokeColor(0, 0, 0) // 改为黑色分隔线 + pdf.Line(currX+width, y, currX+width, y+headerHeight) + } + + currX += width + } + + // 绘制表头外边框(黑色,确保与内容表格对齐) + pdf.SetLineWidth(0.5) + pdf.SetStrokeColor(0, 0, 0) // 改为黑色边框 + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, headerHeight, "D") + + y += headerHeight + + // 绘制表格内容 + tableCellStyle() + pdf.SetFont("simfang", "", 12) + + for _, work := range inst.WorkMessList { + // 准备行数据 + rowData := []string{ + work.WellName, + work.SampleField, + work.ValueInterval + "m", + work.GlobalMax1 + "℃", + work.GlobalMax2 + "MPa", + work.Content, + work.PersonnelList, + work.Link, + } + + // 处理空数据 + for i := range rowData { + if rowData[i] == "" || rowData[i] == "℃" || rowData[i] == "MPa" || rowData[i] == "m" { + rowData[i] = "No data" + } + } + + // 计算最大行数 + maxLines := 1 + cellLines := make([][]string, len(colWidths)) + for i, width := range colWidths { + // 增加可用宽度 + availableWidth := width - cellPadding*2 + 5 + lines, _ := pdf.SplitText(rowData[i], availableWidth) + cellLines[i] = lines + if len(lines) > maxLines { + maxLines = len(lines) + } + } + + // 计算行高 + rowHeight := lineHeight*float64(maxLines) + cellPadding*2 + + // 检查是否需要换页 + if y+rowHeight > pageHeight-5 { + pdf.AddPage() + y = margin + addPageNumber(pdf.GetNumberOfPages()) + } + + // 绘制行背景(可选,使隔行变色更易读) + if len(inst.WorkMessList)%2 == 0 { + pdf.SetFillColor(245, 245, 245) + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, rowHeight, "F") + } + + currX = startX + for i, width := range colWidths { + // 绘制多行文本 + lines := cellLines[i] + // 计算垂直居中位置 + totalTextHeight := lineHeight * float64(len(lines)) + startTextY := y + (rowHeight-totalTextHeight)/2 + + for j, line := range lines { + // 计算水平居中位置 + textWidth, _ := pdf.MeasureTextWidth(line) + textX := currX + (width-textWidth)/2 // 水平居中 + pdf.SetX(textX) + pdf.SetY(startTextY + float64(j)*lineHeight) // 垂直居中 + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: width, H: lineHeight}, line) + } + + // 绘制列分隔线 + if i < len(colWidths)-1 { + pdf.SetLineWidth(0.1) + pdf.SetStrokeColor(0, 0, 0) + pdf.Line(currX+width, y, currX+width, y+rowHeight) + } + + currX += width + } + + // 绘制行边框(确保与表头对齐) + pdf.SetLineWidth(0.2) + pdf.SetStrokeColor(0, 0, 0) + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, rowHeight, "D") + + y += rowHeight + } + } + y += sectionGap + + // 4. 维保记录表格 + sectionStyle() + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "▍ Maintenance record") + y += lineHeight + + if len(inst.GetLcmRespData) == 0 { + // 无数据提示(保持不变) + if y > pageHeight-lineHeight { + pdf.AddPage() + y = margin + // 添加新页的页码 + addPageNumber(pdf.GetNumberOfPages()) + } + pdf.SetFont("simfang", "", 12) + pdf.SetTextColor(0, 0, 0) + pdf.SetX(margin) + pdf.SetY(y) + pdf.Cell(nil, "No data") + y += lineHeight + } else { + // 表格参数 + colWidths := []float64{120, 80, 80, 140, 120} + headers := []string{"Time", "Level", "Maintenance person", "Maintenance content", "url"} + + // 计算表头每列的最大行数 + maxHeaderLines := 1 + headerLines := make([][]string, len(colWidths)) + for i, width := range colWidths { + availableWidth := width - cellPadding*2 + 20 + lines, _ := pdf.SplitText(headers[i], availableWidth) + headerLines[i] = lines + if len(lines) > maxHeaderLines { + maxHeaderLines = len(lines) + } + } + + // 表头高度 + headerHeight := lineHeight*float64(maxHeaderLines) + cellPadding*2 + + // 检查表头是否需要换页 + if y+headerHeight > pageHeight-5 { + pdf.AddPage() + y = margin + addPageNumber(pdf.GetNumberOfPages()) + } + + // 计算总宽度 + totalWidth := 0.0 + for _, width := range colWidths { + totalWidth += width + } + + // 绘制表头背景(整个表头作为一个矩形) + pdf.SetFillColor(57, 99, 156) + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, headerHeight, "F") + + // 设置表头样式 + tableHeaderStyle() + pdf.SetTextColor(255, 255, 255) + + startX := margin + currX := startX + + for i, width := range colWidths { + // 绘制多行表头文本(居中) + lines := headerLines[i] + // 计算垂直居中位置 + totalTextHeight := lineHeight * float64(len(lines)) + startTextY := y + (headerHeight-totalTextHeight)/2 + + for j, line := range lines { + textWidth, _ := pdf.MeasureTextWidth(line) + textX := currX + (width-textWidth)/2 + pdf.SetX(textX) + pdf.SetY(startTextY + float64(j)*lineHeight) + pdf.Cell(&gopdf.Rect{W: width, H: lineHeight}, line) + } + + // 绘制黑色列分隔线(只在列之间绘制) + if i < len(colWidths)-1 { + pdf.SetLineWidth(0.2) + pdf.SetStrokeColor(0, 0, 0) // 黑色分隔线 + pdf.Line(currX+width, y, currX+width, y+headerHeight) + } + + currX += width + } + + // 绘制表头外边框(黑色,确保与内容表格对齐) + pdf.SetLineWidth(0.5) + pdf.SetStrokeColor(0, 0, 0) // 黑色边框 + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, headerHeight, "D") + + y += headerHeight + + // 绘制表格内容 + tableCellStyle() + pdf.SetFont("simfang", "", 12) + + for _, repair := range inst.GetLcmRespData { + // 准备行数据 + rowData := []string{ + repair.Time, + repair.Repair_level, + repair.Applicanter, + repair.Note, + repair.Link, + } + + // 处理空数据 + for i := range rowData { + if rowData[i] == "" { + rowData[i] = "No data" + } + } + + // 计算最大行数 + maxLines := 1 + cellLines := make([][]string, len(colWidths)) + for i, width := range colWidths { + // 增加可用宽度 + availableWidth := width - cellPadding*2 + 5 + lines, _ := pdf.SplitText(rowData[i], availableWidth) + cellLines[i] = lines + if len(lines) > maxLines { + maxLines = len(lines) + } + } + + // 计算行高 + rowHeight := lineHeight*float64(maxLines) + cellPadding*2 + + // 检查是否需要换页 + if y+rowHeight > pageHeight-5 { + pdf.AddPage() + y = margin + addPageNumber(pdf.GetNumberOfPages()) + // 注意:换页后不再绘制表头 + } + + // 移除行背景色(删除隔行变色代码) + // 绘制行内容 + currX = startX + for i, width := range colWidths { + // 绘制多行文本 + lines := cellLines[i] + // 计算垂直居中位置 + totalTextHeight := lineHeight * float64(len(lines)) + startTextY := y + (rowHeight-totalTextHeight)/2 + + for j, line := range lines { + // 计算水平居中位置 + textWidth, _ := pdf.MeasureTextWidth(line) + textX := currX + (width-textWidth)/2 // 水平居中 + pdf.SetX(textX) + pdf.SetY(startTextY + float64(j)*lineHeight) // 垂直居中 + pdf.SetTextColor(0, 0, 0) + pdf.Cell(&gopdf.Rect{W: width, H: lineHeight}, line) + } + + // 绘制列分隔线(改为黑色) + if i < len(colWidths)-1 { + pdf.SetLineWidth(0.1) + pdf.SetStrokeColor(0, 0, 0) // 改为黑色竖线 + pdf.Line(currX+width, y, currX+width, y+rowHeight) + } + + currX += width + } + + // 绘制行边框(确保与表头对齐) + pdf.SetLineWidth(0.2) + pdf.SetStrokeColor(0, 0, 0) + pdf.RectFromUpperLeftWithStyle(margin, y, totalWidth, rowHeight, "D") + + y += rowHeight + } + } + y += sectionGap + + } // 保存PDF beginTime := time.Now().UnixNano() @@ -5152,7 +6017,7 @@ func export_tool_warning_pdf(opuser string, baseinfo get_srr_base_resp, data []T if len(data) > 0 { pdf.Text(fmt.Sprintf(`风险预警:`)) } else { - pdf.Text(fmt.Sprintf(`本口井仪器工作正常。`)) + pdf.Text(fmt.Sprintf(`本口井未上传仪器。`)) } for i := 0; i < len(data); i++ { @@ -5567,62 +6432,296 @@ func get_tool_warning_info(user string, wellname string) (resp []Tool_warning) { return } +// func get_tool_warning_info_en(user string, wellname string) (resp []Tool_warning) { + +// ps_info := get_ps_info(user) + +// var data []Tool_warning +// sel_sql := fmt.Sprintf(`select [time],[err_level],[context_en] FROM [analysis_tool_warning] where [wellname]='%s' order by [time] desc`, wellname) +// rows, err := sqlConn.Query(sel_sql) +// if err == nil { +// for rows.Next() { +// var v Tool_warning +// if err = rows.Scan(&v.Time, &v.Err_level, &v.Context); err != nil { +// logs.Error(fmt.Sprintf(`get_tool_warning_info_en scan upload err:%s`, err.Error())) +// } else { +// if len(v.Time) >= 19 { +// v.Time = v.Time[:10] + " " + v.Time[11:19] +// v.Time = do_time_by_ps(v.Time, ps_info) +// } + +// if ps_info.R1 == "2" { +// if strings.Contains(v.Context, "MPa") { +// bid := strings.Index(v.Context, "=") +// eid := strings.Index(v.Context, "(") + +// f, _ := strconv.ParseFloat(v.Context[bid+1:eid], 64) +// f, _ = decimal.NewFromFloat(float64(145.038 * f)).Round(2).Float64() + +// v.Context = v.Context[:bid+1] + fmt.Sprintf("%.02f", f) + v.Context[eid:] + +// v.Context = strings.ReplaceAll(v.Context, "MPa", "psi") +// } +// } + +// if ps_info.R2 == "2" { +// if strings.Contains(v.Context, "℃") { + +// bid := strings.Index(v.Context, "=") +// eid := strings.Index(v.Context, "(") + +// f, _ := strconv.ParseFloat(v.Context[bid+1:eid], 64) +// f, _ = decimal.NewFromFloat(float64(1.8*f + 32)).Round(2).Float64() + +// v.Context = v.Context[:bid+1] + fmt.Sprintf("%.02f", f) + v.Context[eid:] + +// v.Context = strings.ReplaceAll(v.Context, "℃", "℉") +// } +// } + +// data = append(data, v) +// } +// } +// rows.Close() +// } + +// if len(data) > 0 { +// resp = data +// } else { +// resp = []Tool_warning{} +// } + +// return +// } + func get_tool_warning_info_en(user string, wellname string) (resp []Tool_warning) { - ps_info := get_ps_info(user) - - var data []Tool_warning - sel_sql := fmt.Sprintf(`select [time],[err_level],[context_en] FROM [analysis_tool_warning] where [wellname]='%s' order by [time] desc`, wellname) - rows, err := sqlConn.Query(sel_sql) - if err == nil { - for rows.Next() { - var v Tool_warning - if err = rows.Scan(&v.Time, &v.Err_level, &v.Context); err != nil { - logs.Error(fmt.Sprintf(`get_tool_warning_info_en scan upload err:%s`, err.Error())) - } else { - if len(v.Time) >= 19 { - v.Time = v.Time[:10] + " " + v.Time[11:19] - v.Time = do_time_by_ps(v.Time, ps_info) - } - - if ps_info.R1 == "2" { - if strings.Contains(v.Context, "MPa") { - bid := strings.Index(v.Context, "=") - eid := strings.Index(v.Context, "(") - - f, _ := strconv.ParseFloat(v.Context[bid+1:eid], 64) - f, _ = decimal.NewFromFloat(float64(145.038 * f)).Round(2).Float64() - - v.Context = v.Context[:bid+1] + fmt.Sprintf("%.02f", f) + v.Context[eid:] - - v.Context = strings.ReplaceAll(v.Context, "MPa", "psi") - } - } - - if ps_info.R2 == "2" { - if strings.Contains(v.Context, "℃") { - - bid := strings.Index(v.Context, "=") - eid := strings.Index(v.Context, "(") - - f, _ := strconv.ParseFloat(v.Context[bid+1:eid], 64) - f, _ = decimal.NewFromFloat(float64(1.8*f + 32)).Round(2).Float64() - - v.Context = v.Context[:bid+1] + fmt.Sprintf("%.02f", f) + v.Context[eid:] - - v.Context = strings.ReplaceAll(v.Context, "℃", "℉") - } - } - - data = append(data, v) - } + var db string + wellSql := fmt.Sprintf(`SELECT WELLName from WellInformation where WELLNameSource = '%s'`, wellname) + wellRow := sqlConn.QueryRow(wellSql) + wellRow.Scan(&db) + fmt.Println("db----------", db) + // 第一个查询:获取仪器组合 + if strings.HasPrefix(db, "LH2020-") || + strings.HasPrefix(db, "LH2021-") || + strings.HasPrefix(db, "LH2022-") || + strings.HasPrefix(db, "LH2023-") || + strings.HasPrefix(db, "LH2024-") { + conn, err := getOdbcConn("master") + if err != nil { + logs.Info("链接master库失败", err.Error()) + fmt.Println("链接master库失败", err.Error()) } - rows.Close() + defer conn.Close() + cmdSql := fmt.Sprintf("ALTER DATABASE [%s] SET ONLINE", db) + _, err = conn.Exec(cmdSql) + } + conn, err := getOdbcConn(db) + + if err != nil { + logs.Info("Connecting Error", err.Error()) + } + defer conn.Close() + sel_sql := fmt.Sprintf(`select DISTINCT [2327], [2328] from REPAIRANDMENT where [2327] IS NOT NULL`) + logs.Info("第一个查询:获取仪器组合--------", sel_sql) + fmt.Println("第一个查询:获取仪器组合--------", sel_sql) + rows, err := conn.Query(sel_sql) + if err != nil { + fmt.Println("仪器组合查询错误:", err.Error()) + logs.Info("仪器组合查询错误:", err.Error()) + return + } + defer rows.Close() + + // 获取仪器组合列表 + type ToolPair struct { + Series string + Instrument string + } + var toolPairs []ToolPair + + for rows.Next() { + var ( + seriesPtr sql.NullString + instrumentPtr sql.NullString + ) + + err = rows.Scan(&seriesPtr, &instrumentPtr) + if err != nil { + fmt.Println("仪器组合行扫描错误:", err.Error()) + logs.Info("仪器组合行扫描错误:", err.Error()) + continue + } + + toolPairs = append(toolPairs, ToolPair{ + Series: seriesPtr.String, + Instrument: instrumentPtr.String, + }) } + if err = rows.Err(); err != nil { + fmt.Println("仪器组合遍历错误:", err.Error()) + logs.Info("仪器组合遍历错误:", err.Error()) + } + + // 第二个查询:获取警告信息 + warningSql := fmt.Sprintf(`SELECT [time], [err_level], [context] + FROM [analysis_tool_warning] + WHERE [wellname] = '%s' + ORDER BY [time] DESC`, wellname) + fmt.Println("第二个查询:获取警告信息warningSql:-----------------", warningSql) + logs.Info("第二个查询:获取警告信息warningSql:-----------------", warningSql) + warningRows, err := sqlConn.Query(warningSql) + if err != nil { + fmt.Println("警告信息查询错误:", err.Error()) + logs.Info("警告信息查询错误:", err.Error()) + return + } + defer warningRows.Close() + + fmt.Println("警告信息:-----------------", warningRows) + logs.Info("警告信息:-----------------", warningRows) + // 存储所有警告记录 + var warnings []Tool_warning + for warningRows.Next() { + var w Tool_warning + var ( + timePtr sql.NullString + errLevelPtr sql.NullString + contextPtr sql.NullString + ) + + err = warningRows.Scan(&timePtr, &errLevelPtr, &contextPtr) + if err != nil { + fmt.Println("警告信息行扫描错误:", err.Error()) + logs.Info("警告信息行扫描错误:", err.Error()) + continue + } + + w.Time = timePtr.String + w.Err_level = errLevelPtr.String + w.Context = contextPtr.String + warnings = append(warnings, w) + } + fmt.Println("warnings----------------------:", warnings) + + if err = warningRows.Err(); err != nil { + fmt.Println("警告信息遍历错误:", err.Error()) + logs.Info("警告信息遍历错误:", err.Error()) + } + + // 处理结果:检查每个仪器组合是否出现在警告记录中 + var data []Tool_warning + for _, pair := range toolPairs { + v := Tool_warning{ + Series: pair.Series, + Instrument: pair.Instrument, + Flag: 0, // 默认flag=0 + Context: "正常", + } + + // 构建要查找的字符串格式:系列号 + 空格 + 仪器号 + searchStr := pair.Series + " " + pair.Instrument + fmt.Println("searchStr----------------------:", searchStr) + + // 在警告记录中查找匹配的context + for _, warn := range warnings { + fmt.Println("warn.Context----------------------:", warn.Context) + if strings.Contains(warn.Context, searchStr) { + // 找到匹配项,使用警告记录的信息 + v.Time = warn.Time + v.Err_level = warn.Err_level + v.Context = warn.Context + v.Flag = 1 // 设置flag=1 + fmt.Println("warn.Context----------------------:", warn.Context) + // 处理时间格式 + if len(v.Time) >= 19 { + originalTime := v.Time + v.Time = v.Time[:10] + " " + v.Time[11:19] + fmt.Printf("格式化时间: %s -> %s\n", originalTime, v.Time) + + convertedTime := do_time_by_ps(v.Time, ps_info) + fmt.Printf("转换时间: %s -> %s\n", v.Time, convertedTime) + v.Time = convertedTime + } else { + fmt.Printf("时间格式异常,长度不足19: %s\n", v.Time) + } + fmt.Println("ps_info.R1----------", ps_info.R1) + // 压力单位转换 + if ps_info.R1 == "2" { + if strings.Contains(v.Context, "MPa") { + fmt.Printf("压力单位转换(MPa->psi): %s\n", v.Context) + + bid := strings.Index(v.Context, "=") + eid := strings.Index(v.Context, "(") + + if bid != -1 && eid != -1 && bid < eid { + valueStr := v.Context[bid+1 : eid] + f, err := strconv.ParseFloat(valueStr, 64) + if err == nil { + originalValue := f + f = 145.038 * f + f, _ = decimal.NewFromFloat(f).Round(2).Float64() + + newContext := v.Context[:bid+1] + fmt.Sprintf("%.02f", f) + v.Context[eid:] + fmt.Printf("压力值转换: %.2f MPa -> %.2f psi\n", originalValue, f) + + v.Context = strings.ReplaceAll(newContext, "MPa", "psi") + } else { + fmt.Printf("解析压力值失败: %s\n", valueStr) + } + } else { + fmt.Println("在内容中未找到有效的压力值位置") + } + } + } + + // 温度单位转换 + if ps_info.R2 == "2" { + if strings.Contains(v.Context, "℃") { + logs.Info(fmt.Sprintf("温度单位转换(℃->℉): %s", v.Context)) + + bid := strings.Index(v.Context, "=") + eid := strings.Index(v.Context, "(") + + if bid != -1 && eid != -1 && bid < eid { + valueStr := v.Context[bid+1 : eid] + f, err := strconv.ParseFloat(valueStr, 64) + if err == nil { + originalValue := f + f = 1.8*f + 32 + f, _ = decimal.NewFromFloat(f).Round(2).Float64() + + newContext := v.Context[:bid+1] + fmt.Sprintf("%.02f", f) + v.Context[eid:] + fmt.Printf("温度值转换: %.2f ℃ -> %.2f ℉\n", originalValue, f) + + v.Context = strings.ReplaceAll(newContext, "℃", "℉") + } else { + fmt.Printf("解析温度值失败: %s\n", valueStr) + } + } else { + fmt.Println("在内容中未找到有效的温度值位置") + } + } + } + + // 找到匹配后跳出循环 + break + } + } + + data = append(data, v) + fmt.Printf("处理后的数据: %+v\n", v) + } + + fmt.Printf("总共处理 %d 条仪器组合\n", len(data)) + logs.Info("总共处理 %d 条仪器组合\n", len(data)) if len(data) > 0 { resp = data + fmt.Printf("成功返回 %d 条警告信息\n", len(data)) + logs.Info("成功返回 %d 条警告信息\n", len(data)) } else { + logs.Info("未查询到任何仪器组合") resp = []Tool_warning{} } @@ -18164,6 +19263,7 @@ func postLcm(response http.ResponseWriter, request *http.Request) { repair_level, _ = strconv.Atoi(req.Repair_level) req.Time = time.Now().Format("2006-01-02 15:04:05") + fmt.Println(" req.OperType--------------", req.OperType) if req.OperType == 1 { //add //opContent = fmt.Sprintf("新增授权信息:仪器系列号:%s, 编码:%s, 授权到期时间:%s", req.Series, req.InstrumentID, req.Expire_date) sqlstr = fmt.Sprintf(`INSERT INTO [life_cycle_manager] ([sid],[iid],[repair_cnt],[repair_level],[repair_context],[time],[user]) VALUES('%s','%s',%d,%d,'%s','%s','%s')`, @@ -18184,7 +19284,7 @@ func postLcm(response http.ResponseWriter, request *http.Request) { goto exit } - fmt.Println(sqlstr) + fmt.Println("维保记录sql-------------------", sqlstr) _, err = sqlConn.Exec(sqlstr) if err != nil { logs.Info("postLcm Exec Error:", err.Error()) @@ -23943,25 +25043,23 @@ func getFaultRate(response http.ResponseWriter, request *http.Request) { //prevTotalDep += curDep rds[index].tfootage += curDep - /* - if prevTotalDep > float64(0) { - rds[index].TotalFootage = fmt.Sprintf("%.4f", prevTotalDep/float64(10000)) //strconv.FormatFloat(prevTotalDep/float64(10000), 'f', -1, 64) - if rds[index].RepairCnt != 0 { - rate := prevTotalDep / float64(rds[index].RepairCnt*10000) + /*if prevTotalDep > float64(0) { + rds[index].TotalFootage = fmt.Sprintf("%.4f", prevTotalDep/float64(10000)) //strconv.FormatFloat(prevTotalDep/float64(10000), 'f', -1, 64) + if rds[index].RepairCnt != 0 { + rate := prevTotalDep / float64(rds[index].RepairCnt*10000) - //rds[index].Rate = fmt.Sprintf("%.4f", rate) + //rds[index].Rate = fmt.Sprintf("%.4f", rate) - rate, _ = decimal.NewFromFloat(rate).Round(4).Float64() - if rate < float64(0.0001) { - rds[index].Rate = "0" - } else { - rds[index].Rate = fmt.Sprintf("%v", rate) - } + rate, _ = decimal.NewFromFloat(rate).Round(4).Float64() + if rate < float64(0.0001) { + rds[index].Rate = "0" + } else { + rds[index].Rate = fmt.Sprintf("%v", rate) } - } else { - rds[index].Rate = "0" } - */ + } else { + rds[index].Rate = "0" + }*/ } else { v.Series = series_new_name prevTotalDep, _ := strconv.ParseFloat(v.TotalFootage, 64) @@ -29869,6 +30967,10 @@ func getInstrumentMess(response http.ResponseWriter, request *http.Request) { } } +func getInstrumentMess_en(response http.ResponseWriter, request *http.Request) { + +} + func getInstrumentMessUtil(req InstrumentMess) (*InstrumentMessRespdata, error) { // 查询仪器所在的所有井 sqlWellData := fmt.Sprintf(`SELECT DISTINCT wi.WELLNameSource , wi.WELLName @@ -29900,9 +31002,9 @@ func getInstrumentMessUtil(req InstrumentMess) (*InstrumentMessRespdata, error) FORMAT([2329], 'yyyy-MM-ddTHH:mm:ssZ') AS Time, COALESCE([2340], '') AS [2340], CASE - WHEN COALESCE([2326], 0) < COALESCE([2340], 0) THEN COALESCE([2340], '') - ELSE COALESCE([2326], '') - END AS [2326] + WHEN COALESCE([2331], 0) < COALESCE([2340], 0) THEN COALESCE([2340], '') + ELSE COALESCE([2331], '') + END AS [2331] FROM REPAIRANDMENT WHERE [2321] = '%s' AND [2327] = '%s' @@ -29971,7 +31073,7 @@ func getInstrumentMessUtil(req InstrumentMess) (*InstrumentMessRespdata, error) ) resp.QualityData = respData //仪器施工汇总 - resp.WorkMessList = workMess(wellInfos, req.Flag, req.Content) + resp.WorkMessList = workMess(wellInfos, req.Flag, req.Content, req.Series, req.Instrument) //维保情况 resp.GetLcmRespData = getMaintenanceMess(req.Series, req.Instrument, req.Opuser) //仪器所在部门 @@ -30000,9 +31102,11 @@ func getInstrumentMessUtil(req InstrumentMess) (*InstrumentMessRespdata, error) return resp, nil } -func workMess(wellInfos []get_vibration_resp, flag string, content string) []WellMessRespdata { +func workMess(wellInfos []get_vibration_resp, flag string, content string, series string, instrument string) []WellMessRespdata { fmt.Println("仪器施工汇总开始------------------------------------", wellInfos) + fmt.Println("series------------------------------------", series) + fmt.Println("instrument------------------------------------", instrument) var results []WellMessRespdata if len(wellInfos) == 0 { fmt.Println("wellInfos 是空的,没有数据可打印") @@ -30081,7 +31185,7 @@ func workMess(wellInfos []get_vibration_resp, flag string, content string) []Wel //查询上传文件数据 queryUploadSql := fmt.Sprintf(`SELECT id, file_name, create_user, create_time, well_file_id, type,real_file_name FROM t_file - WHERE type='tool_detail_instrument' AND well_file_id='%s' AND file_name IS NOT NULL`, id) + WHERE type='tool_detail_instrument' AND well_file_id='%s' AND series = '%s' AND instrument = '%s' AND file_name IS NOT NULL`, id, series, instrument) uploadRows, err := sqlConn.Query(queryUploadSql) if err != nil { @@ -30090,8 +31194,11 @@ func workMess(wellInfos []get_vibration_resp, flag string, content string) []Wel continue } //查询上传链接 - row, err := sqlConn.Query(fmt.Sprintf(`SELECT DISTINCT link FROM t_file - WHERE type='tool_detail_instrument' AND well_file_id='%s'`, id)) + linkId := fmt.Sprintf(`SELECT DISTINCT link FROM t_file + WHERE type='tool_detail_instrument' AND well_file_id='%s' AND series = '%s' AND instrument = '%s'`, id, series, instrument) + fmt.Println("linkId--------", linkId) + logs.Info("查询上传链接", linkId) + row, err := sqlConn.Query(linkId) if err != nil { fmt.Printf("查询链接失败: %v\n", err) logs.Info("查询链接失败: %v\n", err) @@ -30340,7 +31447,7 @@ func get_DeptMess(series string, instrument string) string { // 处理结果并返回 switch len(results) { case 0: - return "未找到相关信息" + return "" case 1: return results[0] // 只有一条结果时直接返回 default: @@ -30381,17 +31488,14 @@ func saveLinkData(response http.ResponseWriter, request *http.Request) { } querySQL := fmt.Sprintf(`SELECT id FROM t_file - WHERE well_name = '%s' AND series = '%s' AND instrument = '%s'`, - req.WellName, req.Series, req.Instrument) - row := sqlConn.QueryRow(querySQL, - sql.Named("wellName", req.WellName), - sql.Named("series", req.Series), - sql.Named("instrument", req.Instrument)) + WHERE well_name = '%s' AND series = '%s' AND instrument = '%s' AND well_file_id = '%s'`, + req.WellName, req.Series, req.Instrument, req.ID) + row := sqlConn.QueryRow(querySQL) var id string err = row.Scan(&id) - // 根据查询结果执行插入或更新操作 + // 根据查询结果执行插入或更新 if err != nil { if err == sql.ErrNoRows { fmt.Println("记录不存在,执行插入") @@ -30768,6 +31872,8 @@ func insertFileRecord(id string, filename string, realFileName string, opuser st } func updateFileRecord(id, filename, realFileName, opuser, types, series, instrument, wellName, link string) error { + + fmt.Println("updateFileRecordid-----------", id) // 构建基础SQL updateSQL := "UPDATE [t_file] SET " @@ -30795,6 +31901,10 @@ func updateFileRecord(id, filename, realFileName, opuser, types, series, instrum // 构建WHERE条件(使用type, series, instrument, well_name) whereConditions := []string{} + if id != "" { + whereConditions = append(whereConditions, "[id] = @p"+strconv.Itoa(len(args)+1)) + args = append(args, id) + } if types != "" { whereConditions = append(whereConditions, "[type] = @p"+strconv.Itoa(len(args)+1)) args = append(args, types)