Roc 2 months ago
parent
commit
9490d07453

+ 5 - 1
controllers/english_report/report.go

@@ -147,7 +147,7 @@ func (this *EnglishReportController) Add() {
 		refItem := excel.ReferencedExcelConfig{
 			UniqueCode:   r.UniqueCode,
 			ReferencedId: int(newReportId),
-			FromScene:    3,
+			FromScene:    utils.TableReferencedByEnReport,
 			Uuid:         r.Uuid,
 			WidthList:    r.WidthList,
 			HeightList:   r.HeightList,
@@ -225,6 +225,7 @@ func (this *EnglishReportController) Edit() {
 	}
 	var contentSub string
 	if req.Content != "" {
+		req.Content = services.HandleReportContentTable(int(req.ReportId), req.Content)
 		e := utils.ContentXssCheck(req.Content)
 		if e != nil {
 			br.Msg = "存在非法标签"
@@ -347,6 +348,8 @@ func (this *EnglishReportController) Detail() {
 
 	item.Content = html.UnescapeString(item.Content)
 	item.ContentSub = html.UnescapeString(item.ContentSub)
+	// 处理关联excel的表格id
+	item.Content = services.HandleReportContentTable(item.Id, item.Content)
 
 	classifyNameMap := make(map[int]*models.EnglishClassifyFullName)
 	if item.ClassifyIdSecond > 0 {
@@ -1095,6 +1098,7 @@ func (this *EnglishReportController) ClassifyIdDetail() {
 			}
 		}
 	}
+	item.Content = services.HandleReportContentTable(0, item.Content)
 
 	br.Ret = 200
 	br.Success = true

+ 1 - 1
controllers/ppt_english.go

@@ -180,7 +180,7 @@ func (this *PptEnglishController) AddPpt() {
 			refItem := excel.ReferencedExcelConfig{
 				UniqueCode:   r.UniqueCode,
 				ReferencedId: int(newId),
-				FromScene:    5,
+				FromScene:    utils.TableReferencedByEnPPT,
 				Uuid:         r.Uuid,
 				WidthList:    r.WidthList,
 				HeightList:   r.HeightList,

+ 1 - 1
controllers/ppt_v2.go

@@ -181,7 +181,7 @@ func (this *PptV2Controller) AddPpt() {
 			refItem := excel.ReferencedExcelConfig{
 				UniqueCode:   r.UniqueCode,
 				ReferencedId: int(newId),
-				FromScene:    4,
+				FromScene:    utils.TableReferencedByPPT,
 				Uuid:         r.Uuid,
 				WidthList:    r.WidthList,
 				HeightList:   r.HeightList,

+ 7 - 0
controllers/report_chapter.go

@@ -389,6 +389,8 @@ func (this *ReportController) EditDayWeekChapter() {
 	// 更新章节及指标
 	contentSub := ""
 	if req.Content != "" {
+		// 处理关联excel的表格id
+		req.Content = services.HandleReportContentTable(reportInfo.Id, req.Content)
 		e := utils.ContentXssCheck(req.Content)
 		if e != nil {
 			br.Msg = "存在非法标签"
@@ -429,6 +431,9 @@ func (this *ReportController) EditDayWeekChapter() {
 	reportChapterInfo.LastModifyAdminId = sysUser.AdminId
 	reportChapterInfo.LastModifyAdminName = sysUser.RealName
 	reportChapterInfo.ContentModifyTime = time.Now()
+	if req.ContentStruct != `` {
+		req.ContentStruct = services.HandleReportContentStructTable(reportChapterInfo.ReportId, req.ContentStruct)
+	}
 	reportChapterInfo.ContentStruct = html.EscapeString(req.ContentStruct)
 
 	updateCols = append(updateCols, "Author", "Content", "ContentSub", "IsEdit", "ModifyTime")
@@ -826,6 +831,8 @@ func (this *ReportController) GetDayWeekChapter() {
 	chapterItem.Content = html.UnescapeString(chapterItem.Content)
 	chapterItem.ContentSub = html.UnescapeString(chapterItem.ContentSub)
 	chapterItem.ContentStruct = html.UnescapeString(chapterItem.ContentStruct)
+	chapterItem.Content = services.HandleReportContentTable(chapterItem.ReportId, chapterItem.Content)
+	chapterItem.ContentStruct = services.HandleReportContentStructTable(chapterItem.ReportId, chapterItem.ContentStruct)
 
 	// 授权用户列表map
 	chapterGrantIdList := make([]int, 0)

+ 10 - 0
controllers/report_v2.go

@@ -573,6 +573,9 @@ func (this *ReportController) Edit() {
 		return
 	}
 
+	req.Content = services.HandleReportContentTable(int(req.ReportId), req.Content)
+	req.ContentStruct = services.HandleReportContentStructTable(int(req.ReportId), req.ContentStruct)
+
 	// 编辑报告信息
 	err, errMsg := services.EditReport(reportInfo, req, sysUser)
 	if err != nil {
@@ -684,6 +687,13 @@ func (this *ReportController) Detail() {
 		item.EndStyle = endResource.Style
 	}
 
+	item.Content = services.HandleReportContentTable(item.Id, item.Content)
+	item.ContentStruct = services.HandleReportContentStructTable(item.Id, item.ContentStruct)
+	for _, v := range chapterList {
+		v.Content = services.HandleReportContentTable(item.Id, v.Content)
+		v.ContentStruct = services.HandleReportContentStructTable(item.Id, v.ContentStruct)
+	}
+
 	resp := &models.ReportDetailView{
 		ReportDetail: item,
 		ChapterList:  chapterList,

+ 60 - 0
models/data_manage/excel/referenced_excel_config.go

@@ -1,6 +1,7 @@
 package excel
 
 import (
+	"eta/eta_api/utils"
 	"github.com/beego/beego/v2/client/orm"
 	"time"
 )
@@ -58,3 +59,62 @@ func DeleteReferencedExcelConfig(uniqueCode string) (err error) {
 	_, err = o.Raw(sql, uniqueCode).Exec()
 	return
 }
+
+// GetReferencedExcelConfigList
+// @Description: 根据来源类型和来源id获取所有配置列表
+// @author: Roc
+// @datetime 2025-01-09 14:31:20
+// @param referencedId int
+// @param fromScene int
+// @return items []ReferencedExcelConfig
+// @return err error
+func GetReferencedExcelConfigList(referencedId, fromScene int) (items []ReferencedExcelConfig, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM referenced_excel_config WHERE referenced_id = ? AND from_scene = ? `
+	_, err = o.Raw(sql, referencedId, fromScene).QueryRows(&items)
+
+	return
+}
+
+// CopyReferencedExcelConfigByReferencedIdAndFromScene
+// @Description: 根据原引用Id和引用类型创建新的表格关系
+// @author: Roc
+// @datetime 2025-01-09 15:02:43
+// @param oldReferencedId int
+// @param oldFromScene int
+// @param newReferencedId int
+// @param newFromScene int
+// @param sysUserId int
+// @param sysUserName string
+// @return err error
+func CopyReferencedExcelConfigByReferencedIdAndFromScene(oldReferencedId, oldFromScene, newReferencedId, newFromScene, sysUserId int, sysUserName string) (addList []*ReferencedExcelConfig, err error) {
+	o := orm.NewOrmUsingDB("data")
+	var items []ReferencedExcelConfig
+	sql := ` SELECT * FROM referenced_excel_config WHERE referenced_id = ? AND from_scene = ? `
+	_, err = o.Raw(sql, oldReferencedId, oldFromScene).QueryRows(&items)
+	if err != nil {
+		return
+	}
+
+	addList = make([]*ReferencedExcelConfig, 0)
+	for _, v := range items {
+		addList = append(addList, &ReferencedExcelConfig{
+			ReferencedExcelConfigId: 0,
+			UniqueCode:              v.UniqueCode,
+			ReferencedId:            newReferencedId,
+			FromScene:               newFromScene,
+			Uuid:                    v.Uuid,
+			WidthList:               v.WidthList,
+			HeightList:              v.HeightList,
+			OpUserId:                sysUserId,
+			OpUserName:              sysUserName,
+			CreateTime:              time.Now(),
+			Content:                 v.Content,
+			ModifyTime:              time.Now(),
+		})
+	}
+	// 批量复制表格关系
+	_, err = o.InsertMulti(utils.MultiAddNum, addList)
+
+	return
+}

+ 199 - 0
services/report_v2.go

@@ -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
+}

+ 7 - 0
utils/constants.go

@@ -513,6 +513,13 @@ const (
 	SourceNameTradeAnalysis = "持仓分析"
 )
 
+const (
+	TableReferencedByReport   = 2 // 研报列表 与表格的关系
+	TableReferencedByEnReport = 3 // 英文研报 与表格的关系
+	TableReferencedByPPT      = 4 // PPT 与表格的关系
+	TableReferencedByEnPPT    = 5 // 英文PPT 与表格的关系
+)
+
 // 基础数据初始化日期
 var (
 	BASE_START_DATE         = `1900-01-01`                                          //基础数据开始日期