|
@@ -2,9 +2,11 @@ package services
|
|
|
|
|
|
import (
|
|
|
"archive/zip"
|
|
|
+ "encoding/json"
|
|
|
"errors"
|
|
|
"eta/eta_api/models"
|
|
|
"eta/eta_api/models/company"
|
|
|
+ "eta/eta_api/models/data_manage/excel"
|
|
|
"eta/eta_api/models/report"
|
|
|
"eta/eta_api/models/report_approve"
|
|
|
"eta/eta_api/models/system"
|
|
@@ -14,10 +16,13 @@ import (
|
|
|
"fmt"
|
|
|
"github.com/rdlucklib/rdluck_tools/file"
|
|
|
"github.com/rdlucklib/rdluck_tools/http"
|
|
|
+ html2 "golang.org/x/net/html"
|
|
|
"html"
|
|
|
+ "net/url"
|
|
|
"os"
|
|
|
"path"
|
|
|
"strconv"
|
|
|
+ "strings"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
@@ -113,6 +118,11 @@ func AddReportAndChapter(reportInfo *models.Report, inheritReportId int, grantAd
|
|
|
go models.ModifyReportCode(reportId, reportCode)
|
|
|
}
|
|
|
|
|
|
+ // 如果是继承报告,那么同时需要继承被引用的表格设置
|
|
|
+ if reportInfo.InheritReportId > 0 {
|
|
|
+ handlerReportTableReferenced(reportInfo)
|
|
|
+ }
|
|
|
+
|
|
|
// 报告权限处理
|
|
|
go handleReportPermission(reportId, minClassifyId)
|
|
|
|
|
@@ -1367,6 +1377,51 @@ func handleReportPermission(reportId int64, minClassifyId int) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+// handlerReportTableReferenced
|
|
|
+// @Description: 继承报告后,需要同时继承原来报告中表格的拖动数据逻辑
|
|
|
+// @author: Roc
|
|
|
+// @datetime 2025-01-09 15:35:55
|
|
|
+// @param reportInfo *models.Report
|
|
|
+func handlerReportTableReferenced(reportInfo *models.Report) {
|
|
|
+ var err error
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ utils.FileLog.Error("报告表关联处理失败,旧报告ID:%d,新报告ID:%d,Err:%s", reportInfo.InheritReportId, reportInfo.Id, err.Error())
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ addList, err := excel.CopyReferencedExcelConfigByReferencedIdAndFromScene(reportInfo.InheritReportId, utils.TableReferencedByReport, reportInfo.Id, utils.TableReferencedByReport, reportInfo.AdminId, reportInfo.AdminRealName)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(addList) > 0 {
|
|
|
+ // 修改内容
|
|
|
+ reportInfo.Content = HandleReportContentTable(reportInfo.Id, reportInfo.Content)
|
|
|
+ reportInfo.ContentStruct = HandleReportContentStructTable(reportInfo.Id, reportInfo.ContentStruct)
|
|
|
+ err = reportInfo.Update([]string{"Content", "ContentStruct"})
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if reportInfo.HasChapter == 1 {
|
|
|
+ chapterList, tmpErr := models.GetChapterListByReportId(reportInfo.Id)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for _, v := range chapterList {
|
|
|
+ v.Content = HandleReportContentTable(reportInfo.Id, v.Content)
|
|
|
+ v.ContentStruct = HandleReportContentStructTable(reportInfo.Id, v.ContentStruct)
|
|
|
+ err = v.Update([]string{"Content", "ContentStruct"})
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
// HandleReportPermission
|
|
|
// @Description: 报告权限处理
|
|
|
// @author: Roc
|
|
@@ -1532,3 +1587,147 @@ func ResetMiniProgramReportDetailCover(reportId int) (err error) {
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+// HandleReportContentTable
|
|
|
+// @Description: 处理报告内容(动态表格添加报告来源id)(跟另一个需求代码冲突了,不好处理,只能额外写个方法出来使用了)
|
|
|
+// @author: Roc
|
|
|
+// @datetime 2025-01-09 13:25:41
|
|
|
+// @param reportId int
|
|
|
+// @param body string
|
|
|
+// @return newBody string
|
|
|
+func HandleReportContentTable(reportId int, body string) (newBody string) {
|
|
|
+ if body == `` {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ newBody = body
|
|
|
+
|
|
|
+ // 解析HTML
|
|
|
+ doc, err := html2.Parse(strings.NewReader(body))
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error parsing HTML:", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ replaceIframeSrcTable(doc, reportId)
|
|
|
+
|
|
|
+ // 输出修改后的HTML
|
|
|
+ var modifiedHtml strings.Builder
|
|
|
+ err = html2.Render(&modifiedHtml, doc)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error rendering HTML:", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ newBody = modifiedHtml.String()
|
|
|
+ fmt.Println(newBody)
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// replaceIframeSrc 遍历HTML节点,替换iframe的src属性
|
|
|
+func replaceIframeSrcTable(n *html2.Node, reportId int) {
|
|
|
+ if n.Type == html2.ElementNode && n.Data == "iframe" {
|
|
|
+ for i, attr := range n.Attr {
|
|
|
+ if attr.Key == "src" {
|
|
|
+ newLink := handleTableLinkReportId(attr.Val, reportId)
|
|
|
+ // 替换原来的链接
|
|
|
+ n.Attr[i].Val = newLink
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 递归处理子节点
|
|
|
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
|
+ replaceIframeSrcTable(c, reportId)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// handleTableLinkReportId 链接添加token
|
|
|
+func handleTableLinkReportId(link string, reportId int) string {
|
|
|
+ var err error
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ utils.FileLog.Info("处理链接失败,ERR:" + err.Error())
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ parsedURL, err := url.Parse(link)
|
|
|
+ if err != nil {
|
|
|
+ return link
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取查询参数
|
|
|
+ queryParams := parsedURL.Query()
|
|
|
+
|
|
|
+ // 先移除sourceId参数,避免莫名其妙的这个值入库了
|
|
|
+ queryParams.Del("sourceId")
|
|
|
+
|
|
|
+ queryParams.Add("sourceId", fmt.Sprint(reportId))
|
|
|
+
|
|
|
+ // 在链接后面添加一个来源值
|
|
|
+ return parsedURL.String()
|
|
|
+}
|
|
|
+
|
|
|
+// HandleReportContentStructTable
|
|
|
+// @Description: 处理内容组件的表格链接(跟另一个需求代码冲突了,不好处理,只能额外写个方法出来使用了)
|
|
|
+// @author: Roc
|
|
|
+// @datetime 2025-01-09 13:40:35
|
|
|
+// @param reportId int
|
|
|
+// @param body string
|
|
|
+// @return newBody string
|
|
|
+func HandleReportContentStructTable(reportId int, body string) (newBody string) {
|
|
|
+ if body == `` {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ newBody = body
|
|
|
+
|
|
|
+ // 解析JSON数据到map[string]interface{}
|
|
|
+ var jsonData []map[string]interface{}
|
|
|
+ if err := json.Unmarshal([]byte(body), &jsonData); err != nil {
|
|
|
+ fmt.Println("Error parsing JSON:", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理每个组件
|
|
|
+ for i := range jsonData {
|
|
|
+ if err := processMapTable(jsonData[i], reportId); err != nil {
|
|
|
+ fmt.Println("Error processing component:", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将处理后的数据转换回JSON字符串
|
|
|
+ modifiedJSON, err := json.MarshalIndent(jsonData, "", " ")
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error marshaling JSON:", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ newBody = string(modifiedJSON)
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// processMapTable 递归处理map中的content字段
|
|
|
+func processMapTable(data map[string]interface{}, reportId int) error {
|
|
|
+ for key, value := range data {
|
|
|
+ switch v := value.(type) {
|
|
|
+ case string:
|
|
|
+ if key == "content" {
|
|
|
+ newContent := handleTableLinkReportId(v, reportId)
|
|
|
+ data[key] = newContent
|
|
|
+ }
|
|
|
+ case map[string]interface{}:
|
|
|
+ if err := processMapTable(v, reportId); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ case []interface{}:
|
|
|
+ for i := range v {
|
|
|
+ if m, ok := v[i].(map[string]interface{}); ok {
|
|
|
+ if err := processMapTable(m, reportId); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|