Răsfoiți Sursa

Merge branch 'debug' of http://8.136.199.33:3000/eta_server/eta_api into debug

kobe6258 2 luni în urmă
părinte
comite
8f8272b029

+ 9 - 4
controllers/data_manage/chart_common.go

@@ -11,6 +11,7 @@ import (
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services"
 	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/excel"
@@ -355,7 +356,8 @@ func getBalanceChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoVie
 // GeneralChartToken
 // @Title 根据图表唯一code生成token
 // @Description 根据编码获取图表详情接口
-// @Param   UniqueCode   query   int  true       "图表唯一编码,如果是管理后台访问,传固定字符串:7c69b590249049942070ae9dcd5bf6dc"
+// @Param   UniqueCode   query   string  true       "图表/表格唯一编码"
+// @Param   Source   query   string  true       "来源,枚举值:chart、table"
 // @Success 200 {object} data_manage.ChartInfoDetailFromUniqueCodeResp
 // @router /chart_info/common/general_token [get]
 func (this *ChartInfoController) GeneralChartToken() {
@@ -378,6 +380,7 @@ func (this *ChartInfoController) GeneralChartToken() {
 		br.ErrMsg = "参数错误,uniqueCode is empty"
 		return
 	}
+	source := this.GetString("Source", "chart")
 
 	businessConf, err := models.GetBusinessConfByKey(models.BusinessConfIsOpenChartExpired)
 	if err != nil {
@@ -389,9 +392,11 @@ func (this *ChartInfoController) GeneralChartToken() {
 	var token string
 	if businessConf.ConfVal == `true` {
 		// 缓存key
-		token = utils.MD5(fmt.Sprint(`chart:`, uniqueCode, time.Now().UnixNano()/1e6))
-		key := fmt.Sprint(utils.CACHE_CHART_AUTH, token)
-		err = utils.Rc.Put(key, uniqueCode, 30*time.Minute)
+		sourceType := source
+		if source == `table` {
+			sourceType = source
+		}
+		token, err = services.GeneralChartToken(sourceType, uniqueCode, 30*time.Minute)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取失败"

+ 69 - 69
controllers/data_manage/chart_info.go

@@ -1442,46 +1442,46 @@ func (this *ChartInfoController) PreviewChartInfoDetail() {
 			return
 		}
 		for i := range markerLines {
-			if markerLines[i].EdbType == 0 && markerLines[i].TimeIntervalType == 0 && markerLines[i].Axis != 3 {
-				// 图上第一个指标且时间区间跟随图表
-				if markerLines[i].MarkLineType == 2 {
-					if edbList[0].IsAxis == 1 {
-						value, err := data.MarkerLineCalculate(markerLines[i], edbList[0].DataList, chartInfo)
-						if err != nil {
-							br.Msg = "标识线配置异常"
-							br.ErrMsg = "标识线配置异常" + err.Error()
-							return
-						}
-						markerLines[i].Value = value
-					} else {
-						// 其他的都走指标计算
-						edbInfo, err := data_manage.GetEdbInfoById(markerLines[i].EdbInfoId)
-						if err != nil {
-							br.Msg = "指标计算标识线获取指标信息异常"
-							br.ErrMsg = "指标计算标识线获取指标信息异常" + err.Error()
-							return
-						}
-						// 判断时间区间不为跟随图表的情况
-						if markerLines[i].TimeIntervalType != 0 {
-							startDate = markerLines[i].StartDate.Date
-							endDate = markerLines[i].EndDate.Date
-						}
-						dataList, err := data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, startDate, endDate)
-						if err != nil {
-							br.Msg = "指标计算标识线获取指标数据异常"
-							br.ErrMsg = "指标计算标识线获取指标数据异常" + err.Error()
-							return
-						}
-						value, err := data.MarkerLineCalculate(markerLines[i], dataList, chartInfo)
-						if err != nil {
-							br.Msg = "标识线配置异常"
-							br.ErrMsg = "标识线配置异常" + err.Error()
-							return
-						}
-						markerLines[i].Value = value
+			//if markerLines[i].EdbType == 0 && markerLines[i].TimeIntervalType == 0 && markerLines[i].Axis != 3 {
+			// 图上第一个指标且时间区间跟随图表
+			if markerLines[i].MarkLineType == 2 {
+				if edbList[0].IsAxis == 1 {
+					value, err := data.MarkerLineCalculate(markerLines[i], edbList[0].DataList, chartInfo)
+					if err != nil {
+						br.Msg = "标识线配置异常"
+						br.ErrMsg = "标识线配置异常" + err.Error()
+						return
+					}
+					markerLines[i].Value = value
+				} else {
+					// 其他的都走指标计算
+					edbInfo, err := data_manage.GetEdbInfoById(markerLines[i].EdbInfoId)
+					if err != nil {
+						br.Msg = "指标计算标识线获取指标信息异常"
+						br.ErrMsg = "指标计算标识线获取指标信息异常" + err.Error()
+						return
+					}
+					// 判断时间区间不为跟随图表的情况
+					if markerLines[i].TimeIntervalType != 0 {
+						startDate = markerLines[i].StartDate.Date
+						endDate = markerLines[i].EndDate.Date
+					}
+					dataList, err := data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, startDate, endDate)
+					if err != nil {
+						br.Msg = "指标计算标识线获取指标数据异常"
+						br.ErrMsg = "指标计算标识线获取指标数据异常" + err.Error()
+						return
+					}
+					value, err := data.MarkerLineCalculate(markerLines[i], dataList, chartInfo)
+					if err != nil {
+						br.Msg = "标识线配置异常"
+						br.ErrMsg = "标识线配置异常" + err.Error()
+						return
 					}
+					markerLines[i].Value = value
 				}
 			}
+			//}
 		}
 
 		markerLineStr, err := json.Marshal(markerLines)
@@ -3526,42 +3526,42 @@ func (this *ChartInfoController) PreviewBarChartInfo() {
 			return
 		}
 		for i := range markerLines {
-			if markerLines[i].EdbType == 0 && markerLines[i].TimeIntervalType == 0 && markerLines[i].Axis != 3 {
+			//if markerLines[i].EdbType == 0 && markerLines[i].TimeIntervalType == 0 && markerLines[i].Axis != 3 {
+			// 图上第一个指标且时间区间跟随图表
+			if markerLines[i].MarkLineType == 2 {
 				// 图上第一个指标且时间区间跟随图表
-				if markerLines[i].MarkLineType == 2 {
-					// 图上第一个指标且时间区间跟随图表
-					if edbList[0].IsAxis == 1 {
-						value, err := data.MarkerLineCalculate(markerLines[i], edbList[0].DataList, chartInfo)
-						if err != nil {
-							br.Msg = "标识线配置异常"
-							br.ErrMsg = "标识线配置异常" + err.Error()
-							return
-						}
-						markerLines[i].Value = value
-					} else {
-						// 其他的都走指标计算
-						edbInfo, err := data_manage.GetEdbInfoById(markerLines[i].EdbInfoId)
-						if err != nil {
-							br.Msg = "指标计算标识线获取指标信息异常"
-							br.ErrMsg = "指标计算标识线获取指标信息异常" + err.Error()
-							return
-						}
-						dataList, err := data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, "", "")
-						if err != nil {
-							br.Msg = "指标计算标识线获取指标数据异常"
-							br.ErrMsg = "指标计算标识线获取指标数据异常" + err.Error()
-							return
-						}
-						value, err := data.MarkerLineCalculate(markerLines[i], dataList, chartInfo)
-						if err != nil {
-							br.Msg = "标识线配置异常"
-							br.ErrMsg = "标识线配置异常" + err.Error()
-							return
-						}
-						markerLines[i].Value = value
+				if edbList[0].IsAxis == 1 {
+					value, err := data.MarkerLineCalculate(markerLines[i], edbList[0].DataList, chartInfo)
+					if err != nil {
+						br.Msg = "标识线配置异常"
+						br.ErrMsg = "标识线配置异常" + err.Error()
+						return
 					}
+					markerLines[i].Value = value
+				} else {
+					// 其他的都走指标计算
+					edbInfo, err := data_manage.GetEdbInfoById(markerLines[i].EdbInfoId)
+					if err != nil {
+						br.Msg = "指标计算标识线获取指标信息异常"
+						br.ErrMsg = "指标计算标识线获取指标信息异常" + err.Error()
+						return
+					}
+					dataList, err := data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, "", "")
+					if err != nil {
+						br.Msg = "指标计算标识线获取指标数据异常"
+						br.ErrMsg = "指标计算标识线获取指标数据异常" + err.Error()
+						return
+					}
+					value, err := data.MarkerLineCalculate(markerLines[i], dataList, chartInfo)
+					if err != nil {
+						br.Msg = "标识线配置异常"
+						br.ErrMsg = "标识线配置异常" + err.Error()
+						return
+					}
+					markerLines[i].Value = value
 				}
 			}
+			//}
 		}
 
 		markerLineStr, err := json.Marshal(markerLines)

+ 32 - 3
controllers/data_manage/edb_info.go

@@ -3469,6 +3469,13 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 		}
 	}
 
+	// 只看我的
+	var sysUserId int
+	mine, _ := this.GetBool("IsShowMe")
+	if mine {
+		sysUserId = this.SysUser.AdminId
+	}
+
 	// 是否走ES
 	isEs := false
 	if keyWord != "" {
@@ -3480,10 +3487,14 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 
 		// 普通的搜索
 		if !isAddPredictEdb {
-			total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 0, frequency, noPermissionEdbInfoIdList)
+			if mine {
+				total, edbInfoList, err = elastic.SearchEdbInfoDataByAdminId(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 0, frequency, sysUserId)
+			} else {
+				total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 0, frequency, noPermissionEdbInfoIdList)
+			}
 		} else {
 			// 允许添加预测指标的搜索
-			total, edbInfoList, err = elastic.SearchAddPredictEdbInfoData(utils.DATA_INDEX_NAME, keyWord, noPermissionEdbInfoIdList, startSize, pageSize)
+			total, edbInfoList, err = elastic.SearchAddPredictEdbInfoData(utils.DATA_INDEX_NAME, keyWord, noPermissionEdbInfoIdList, startSize, pageSize, sysUserId)
 		}
 		isEs = true
 	} else {
@@ -3529,6 +3540,11 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 			condition += ` AND frequency in ("日度","周度","月度") `
 		}
 
+		if mine {
+			condition += ` AND sys_user_id = ? `
+			pars = append(pars, sysUserId)
+		}
+
 		total, edbInfoList, err = data_manage.GetEdbInfoFilterList(condition, pars, startSize, pageSize)
 	}
 	if err != nil {
@@ -4917,6 +4933,9 @@ func (this *EdbInfoController) AllEdbInfoByEs() {
 		}
 	}
 
+	// 只看我的
+	mine, _ := this.GetBool("IsShowMe")
+
 	// 是否走ES
 	isEs := false
 	if keyWord != "" {
@@ -4927,7 +4946,12 @@ func (this *EdbInfoController) AllEdbInfoByEs() {
 		keyWordArr = append(keyWordArr, newKeyWord...)
 
 		// 普通的搜索
-		total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, -1, frequency, noPermissionEdbInfoIdList)
+		if mine {
+			total, edbInfoList, err = elastic.SearchEdbInfoDataByAdminId(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 1, frequency, this.SysUser.AdminId)
+		} else {
+			total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, -1, frequency, noPermissionEdbInfoIdList)
+		}
+
 		isEs = true
 	} else {
 		var condition string
@@ -4968,6 +4992,11 @@ func (this *EdbInfoController) AllEdbInfoByEs() {
 			condition += ` AND frequency in ("日度","周度","月度") `
 		}
 
+		if mine {
+			condition += ` AND sys_user_id = ? `
+			pars = append(pars, this.SysUser.AdminId)
+		}
+
 		total, edbInfoList, err = data_manage.GetEdbInfoFilterList(condition, pars, startSize, pageSize)
 	}
 	if err != nil {

+ 26 - 0
controllers/data_manage/excel/excel_info.go

@@ -125,6 +125,18 @@ func (c *ExcelInfoController) Add() {
 		req.ExcelClassifyId = parentExcelInfo.ExcelClassifyId
 	}
 
+	// 额外配置(表格冻结行列等)
+	var extraConfig string
+	if req.ExtraConfig != nil {
+		b, e := json.Marshal(req.ExtraConfig)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("操作失败, %v", e)
+			return
+		}
+		extraConfig = string(b)
+	}
+
 	var condition string
 	var pars []interface{}
 	condition += " AND excel_classify_id=? AND parent_id=?"
@@ -261,6 +273,7 @@ func (c *ExcelInfoController) Add() {
 		UpdateUserId:       sysUser.AdminId,
 		UpdateUserRealName: sysUser.RealName,
 		SourcesFrom:        req.SourcesFrom,
+		ExtraConfig:        extraConfig,
 	}
 
 	excelEdbMappingList := make([]*excel3.ExcelEdbMapping, 0)
@@ -297,6 +310,7 @@ func (c *ExcelInfoController) Add() {
 			//ParentId:           req.ParentId,
 			UpdateUserId:       sysUser.AdminId,
 			UpdateUserRealName: sysUser.RealName,
+			ExtraConfig:        extraConfig,
 		}
 	}
 	err = excel3.AddExcelInfo(excelInfo, excelEdbMappingList, childExcel)
@@ -1059,6 +1073,18 @@ func (c *ExcelInfoController) Edit() {
 		updateExcelInfoParams = []string{"ModifyTime", "ExcelName", "ExcelType", "ExcelClassifyId", "Content", "SourcesFrom"}
 	}
 
+	// 额外配置(表格冻结行列等)
+	if req.ExtraConfig != nil {
+		b, e := json.Marshal(req.ExtraConfig)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("操作失败, %v", e)
+			return
+		}
+		excelInfo.ExtraConfig = string(b)
+		updateExcelInfoParams = append(updateExcelInfoParams, "ExtraConfig")
+	}
+
 	excelEdbMappingList := make([]*excel3.ExcelEdbMapping, 0)
 	if len(edbInfoIdList) > 0 {
 		for _, edbInfoId := range edbInfoIdList {

+ 27 - 0
controllers/english_report/report.go

@@ -66,6 +66,8 @@ func (this *EnglishReportController) Add() {
 
 	var contentSub string
 	if req.Content != "" {
+		req.Content = services.HandleReportContent(req.Content, "del", nil)
+
 		e := utils.ContentXssCheck(req.Content)
 		if e != nil {
 			br.Msg = "存在非法标签"
@@ -225,6 +227,7 @@ func (this *EnglishReportController) Edit() {
 	}
 	var contentSub string
 	if req.Content != "" {
+		req.Content = services.HandleReportContent(req.Content, "del", nil)
 		e := utils.ContentXssCheck(req.Content)
 		if e != nil {
 			br.Msg = "存在非法标签"
@@ -348,6 +351,17 @@ func (this *EnglishReportController) Detail() {
 	item.Content = html.UnescapeString(item.Content)
 	item.ContentSub = html.UnescapeString(item.ContentSub)
 
+	businessConf, err := models.GetBusinessConfByKey(models.BusinessConfIsOpenChartExpired)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取配置失败,Err:" + err.Error()
+		return
+	}
+	if businessConf.ConfVal == `true` {
+		tokenMap := make(map[string]string)
+		item.Content = services.HandleReportContent(item.Content, "add", tokenMap)
+	}
+
 	classifyNameMap := make(map[int]*models.EnglishClassifyFullName)
 	if item.ClassifyIdSecond > 0 {
 		nameList, tErr := models.GetEnglishClassifyFullNameByIds([]int{item.ClassifyIdSecond})
@@ -995,6 +1009,7 @@ func (this *EnglishReportController) SaveReportContent() {
 	}
 
 	if noChangeFlag != 1 {
+		req.Content = services.HandleReportContent(req.Content, "del", nil)
 		content := req.Content
 		if content == "" {
 			content = this.GetString("Content")
@@ -1076,6 +1091,18 @@ func (this *EnglishReportController) ClassifyIdDetail() {
 		item.Content = html.UnescapeString(item.Content)
 		item.ContentSub = html.UnescapeString(item.ContentSub)
 
+		businessConf, err := models.GetBusinessConfByKey(models.BusinessConfIsOpenChartExpired)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取配置失败,Err:" + err.Error()
+			return
+		}
+
+		if businessConf.ConfVal == `true` {
+			tokenMap := make(map[string]string)
+			item.Content = services.HandleReportContent(item.Content, "add", tokenMap)
+		}
+
 		classifyNameMap := make(map[int]*models.EnglishClassifyFullName)
 		if item.ClassifyIdSecond > 0 {
 			nameList, tErr := models.GetEnglishClassifyFullNameByIds([]int{item.ClassifyIdSecond})

+ 1 - 1
controllers/eta_forum/eta_forum.go

@@ -32,7 +32,7 @@ func (this *EtaForumController) UserChartList() {
 		br.Ret = 408
 		return
 	}
-	keyword := this.GetString("keyword")
+	keyword := this.GetString("Keyword")
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
 	businessCode := utils.BusinessCode

+ 18 - 0
controllers/report_chapter.go

@@ -364,6 +364,7 @@ func (this *ReportController) EditDayWeekChapter() {
 	// 更新章节及指标
 	contentSub := ""
 	if req.Content != "" {
+		req.Content = services.HandleReportContent(req.Content, "del", nil)
 		e := utils.ContentXssCheck(req.Content)
 		if e != nil {
 			br.Msg = "存在非法标签"
@@ -404,6 +405,10 @@ func (this *ReportController) EditDayWeekChapter() {
 	reportChapterInfo.LastModifyAdminId = sysUser.AdminId
 	reportChapterInfo.LastModifyAdminName = sysUser.RealName
 	reportChapterInfo.ContentModifyTime = time.Now()
+
+	if req.ContentStruct != `` {
+		req.ContentStruct = services.HandleReportContentStruct(req.ContentStruct, "del", nil)
+	}
 	reportChapterInfo.ContentStruct = html.EscapeString(req.ContentStruct)
 
 	updateCols = append(updateCols, "Author", "Content", "ContentSub", "IsEdit", "ModifyTime")
@@ -776,6 +781,19 @@ func (this *ReportController) GetDayWeekChapter() {
 	chapterItem.ContentSub = html.UnescapeString(chapterItem.ContentSub)
 	chapterItem.ContentStruct = html.UnescapeString(chapterItem.ContentStruct)
 
+	businessConf, err := models.GetBusinessConfByKey(models.BusinessConfIsOpenChartExpired)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取配置失败,Err:" + err.Error()
+		return
+	}
+
+	if businessConf.ConfVal == `true` {
+		tokenMap := make(map[string]string)
+		chapterItem.Content = services.HandleReportContent(chapterItem.Content, "add", tokenMap)
+		chapterItem.ContentStruct = services.HandleReportContentStruct(chapterItem.ContentStruct, "add", tokenMap)
+	}
+
 	// 授权用户列表map
 	chapterGrantIdList := make([]int, 0)
 	// 关联品种id列表map

+ 41 - 9
controllers/report_v2.go

@@ -394,6 +394,7 @@ func (this *ReportController) Add() {
 
 	var contentSub string
 	if req.Content != "" {
+		req.Content = services.HandleReportContent(req.Content, "del", nil)
 		e := utils.ContentXssCheck(req.Content)
 		if e != nil {
 			br.Msg = "存在非法标签"
@@ -415,6 +416,10 @@ func (this *ReportController) Add() {
 		}
 	}
 
+	if req.ContentStruct != `` {
+		req.ContentStruct = services.HandleReportContentStruct(req.ContentStruct, "del", nil)
+	}
+
 	// 报告期数
 	maxStage, err := models.GetReportStage(req.ClassifyIdFirst, req.ClassifyIdSecond, req.ClassifyIdThird)
 	if err != nil {
@@ -591,6 +596,8 @@ func (this *ReportController) Edit() {
 		return
 	}
 
+	req.Content = services.HandleReportContent(req.Content, "del", nil)
+	req.ContentStruct = services.HandleReportContentStruct(req.ContentStruct, "del", nil)
 	// 编辑报告信息
 	err, errMsg := services.EditReport(reportInfo, req, sysUser)
 	if err != nil {
@@ -682,24 +689,46 @@ func (this *ReportController) Detail() {
 
 	if item.HeadResourceId > 0 {
 		headResource, err := smart_report.GetResourceItemById(item.HeadResourceId)
-		if err != nil {
+		if err != nil && err.Error() != utils.ErrNoRow() {
 			br.Msg = "操作失败"
 			br.ErrMsg = "获取资源库版头失败, Err: " + err.Error()
 			return
 		}
-		item.HeadImg = headResource.ImgUrl
-		item.HeadStyle = headResource.Style
+		if headResource != nil && headResource.ResourceId > 0 {
+			item.HeadImg = headResource.ImgUrl
+			item.HeadStyle = headResource.Style
+		}
 	}
 
 	if item.EndResourceId > 0 {
 		endResource, err := smart_report.GetResourceItemById(item.EndResourceId)
-		if err != nil {
+		if err != nil && err.Error() != utils.ErrNoRow() {
 			br.Msg = "操作失败"
-			br.ErrMsg = "获取资源库版失败, Err: " + err.Error()
+			br.ErrMsg = "获取资源库版失败, Err: " + err.Error()
 			return
 		}
-		item.EndImg = endResource.ImgUrl
-		item.EndStyle = endResource.Style
+		if endResource != nil && endResource.ResourceId > 0 {
+			item.EndImg = endResource.ImgUrl
+			item.EndStyle = endResource.Style
+		}
+	}
+
+	businessConf, err := models.GetBusinessConfByKey(models.BusinessConfIsOpenChartExpired)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取配置失败,Err:" + err.Error()
+		return
+	}
+
+	if businessConf.ConfVal == `true` {
+		tokenMap := make(map[string]string)
+		item.Content = services.HandleReportContent(item.Content, "add", tokenMap)
+		item.ContentStruct = services.HandleReportContentStruct(item.ContentStruct, "add", tokenMap)
+		for _, v := range chapterList {
+			v.Content = services.HandleReportContent(v.Content, "add", tokenMap)
+			v.ContentStruct = services.HandleReportContentStruct(v.ContentStruct, "add", tokenMap)
+		}
+
 	}
 
 	resp := &models.ReportDetailView{
@@ -780,14 +809,15 @@ func (this *ReportController) SaveReportContent() {
 		if content == "" {
 			content = this.GetString("Content")
 		}
+		content = services.HandleReportContent(content, "del", nil)
 		if content != "" {
-			e := utils.ContentXssCheck(req.Content)
+			e := utils.ContentXssCheck(content)
 			if e != nil {
 				br.Msg = "存在非法标签"
 				br.ErrMsg = "存在非法标签, Err: " + e.Error()
 				return
 			}
-			contentClean, e := services.FilterReportContentBr(req.Content)
+			contentClean, e := services.FilterReportContentBr(content)
 			if e != nil {
 				br.Msg = "内容去除前后空格失败"
 				br.ErrMsg = "内容去除前后空格失败, Err: " + e.Error()
@@ -795,6 +825,8 @@ func (this *ReportController) SaveReportContent() {
 			}
 			content = contentClean
 
+			req.ContentStruct = services.HandleReportContentStruct(req.ContentStruct, "del", nil)
+
 			contentSub, err := services.GetReportContentSub(content)
 			if err != nil {
 				go alarm_msg.SendAlarmMsg("解析 ContentSub 失败,Err:"+err.Error(), 3)

+ 12 - 7
controllers/smart_report/smart_report.go

@@ -391,24 +391,29 @@ func (this *SmartReportController) Detail() {
 	resp := smart_report.FormatSmartReport2Item(item)
 	if resp.HeadResourceId > 0 {
 		headResource, err := smart_report.GetResourceItemById(resp.HeadResourceId)
-		if err != nil {
+		if err != nil && err.Error() != utils.ErrNoRow() {
 			br.Msg = "操作失败"
-			br.ErrMsg = "获取资源库版失败, Err: " + err.Error()
+			br.ErrMsg = "获取资源库版失败, Err: " + err.Error()
 			return
 		}
-		resp.HeadImg = headResource.ImgUrl
-		resp.HeadStyle = headResource.Style
+		if headResource != nil && headResource.ResourceId > 0 {
+			resp.HeadImg = headResource.ImgUrl
+			resp.HeadStyle = headResource.Style
+		}
 	}
 
 	if resp.EndResourceId > 0 {
 		endResource, err := smart_report.GetResourceItemById(resp.EndResourceId)
-		if err != nil {
+		if err != nil && err.Error() != utils.ErrNoRow() {
 			br.Msg = "操作失败"
 			br.ErrMsg = "获取资源库版头失败, Err: " + err.Error()
 			return
 		}
-		resp.EndImg = endResource.ImgUrl
-		resp.EndStyle = endResource.Style
+		if endResource != nil && endResource.ResourceId > 0 {
+			resp.EndImg = endResource.ImgUrl
+			resp.EndStyle = endResource.Style
+		}
+
 	}
 	br.Ret = 200
 	br.Success = true

+ 16 - 1
models/data_manage/excel/excel_info.go

@@ -34,7 +34,7 @@ type ExcelInfo struct {
 	RelExcelInfoId     int       `description:"平衡表里静态表关联的动态表excel id"`
 	VersionName        string    `description:"静态表版本名称"`
 	SourcesFrom        string    `description:"图表来源"`
-	ExtraConfig        string    `description:"额外配置:如多空分析、相关性表格参数"`
+	ExtraConfig        string    `description:"额外配置"`
 }
 
 // Update 更新 excel表格基础信息
@@ -843,3 +843,18 @@ type SearchExcelInfo struct {
 	CanEdit       bool                  `description:"是否可编辑"`
 	Editor        string                `description:"编辑人"`
 }
+
+// ExcelCommonExtraConfig 表格额外配置
+type ExcelCommonExtraConfig struct {
+	TableFreeze ExcelInfoFreeze `description:"表格冻结"`
+}
+
+// ExcelInfoFreeze 表格冻结
+type ExcelInfoFreeze struct {
+	FreezeFirstRow bool `description:"冻结首行"`
+	FreezeFirstCol bool `description:"冻结首列"`
+	FreezeStartRow int  `description:"冻结开始行"`
+	FreezeEndRow   int  `description:"冻结结束行"`
+	FreezeStartCol int  `description:"冻结开始列"`
+	FreezeEndCol   int  `description:"冻结结束列"`
+}

+ 25 - 20
models/data_manage/excel/request/excel_info.go

@@ -1,6 +1,9 @@
 package request
 
-import "encoding/json"
+import (
+	"encoding/json"
+	"eta/eta_api/models/data_manage/excel"
+)
 
 // MoveExcelInfoReq 移动excel表格请求
 type MoveExcelInfoReq struct {
@@ -17,29 +20,31 @@ type DeleteExcelInfoReq struct {
 
 // AddExcelInfoReq 新增表格请求
 type AddExcelInfoReq struct {
-	ExcelInfoId     int         `description:"表格ID"`
-	ExcelName       string      `description:"表格名称"`
-	Source          int         `description:"表格来源,1:excel插件的表格,2:自定义表格,5平衡表,默认:1"`
-	ExcelType       int         `description:"表格类型,1:指标列,2:日期列,默认:1"`
-	ExcelImage      string      `description:"表格截图"`
-	ExcelClassifyId int         `description:"分类id"`
-	Content         string      `description:"Excel表格内容"`
-	TableData       interface{} `description:"自定义表格的数据内容"`
-	ParentId        int         `description:"表格的父级id"`
-	SourcesFrom     string      `description:"图表来源"`
+	ExcelInfoId     int                           `description:"表格ID"`
+	ExcelName       string                        `description:"表格名称"`
+	Source          int                           `description:"表格来源,1:excel插件的表格,2:自定义表格,5平衡表,默认:1"`
+	ExcelType       int                           `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelImage      string                        `description:"表格截图"`
+	ExcelClassifyId int                           `description:"分类id"`
+	Content         string                        `description:"Excel表格内容"`
+	TableData       interface{}                   `description:"自定义表格的数据内容"`
+	ParentId        int                           `description:"表格的父级id"`
+	SourcesFrom     string                        `description:"图表来源"`
+	ExtraConfig     *excel.ExcelCommonExtraConfig `description:"表格额外配置"`
 }
 
 // EditExcelInfoReq 编辑表格请求
 type EditExcelInfoReq struct {
-	ExcelInfoId     int         `description:"ETA表格ID"`
-	ExcelType       int         `description:"表格类型,1:指标列,2:日期列,默认:1"`
-	ExcelName       string      `description:"表格名称"`
-	ExcelImage      string      `description:"表格截图"`
-	ExcelClassifyId int         `description:"分类id"`
-	Content         string      `description:"Excel表格内容"`
-	TableData       interface{} `description:"自定义表格的数据内容"`
-	SourcesFrom     string      `description:"图表来源"`
-	IsColChange     bool        `description:"是否修改过行列,true时清空引用"`
+	ExcelInfoId     int                           `description:"ETA表格ID"`
+	ExcelType       int                           `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelName       string                        `description:"表格名称"`
+	ExcelImage      string                        `description:"表格截图"`
+	ExcelClassifyId int                           `description:"分类id"`
+	Content         string                        `description:"Excel表格内容"`
+	TableData       interface{}                   `description:"自定义表格的数据内容"`
+	SourcesFrom     string                        `description:"图表来源"`
+	IsColChange     bool                          `description:"是否修改过行列,true时清空引用"`
+	ExtraConfig     *excel.ExcelCommonExtraConfig `description:"表格额外配置"`
 }
 
 // SetExcelInfoImageReq 设置excel表格图片请求

+ 30 - 29
models/data_manage/excel/response/excel_info.go

@@ -66,35 +66,36 @@ type TableDetailResp struct {
 
 // ExcelInfoDetail excel表格详情(前端使用)
 type ExcelInfoDetail struct {
-	ExcelInfoId        int                          `orm:"column(excel_info_id);pk"`
-	Source             int                          `description:"表格来源,1:excel插件的表格,2:自定义表格,默认:1"`
-	ExcelType          int                          `description:"表格类型,1:指标列,2:日期列,默认:1"`
-	ExcelName          string                       `description:"表格名称"`
-	UniqueCode         string                       `description:"表格唯一编码"`
-	ExcelClassifyId    int                          `description:"表格分类id"`
-	SysUserId          int                          `description:"操作人id"`
-	SysUserRealName    string                       `description:"操作人真实姓名"`
-	Content            string                       `description:"表格内容"`
-	ExcelImage         string                       `description:"表格图片"`
-	FileUrl            string                       `description:"表格下载地址"`
-	Sort               int                          `description:"排序字段,数字越小越排前面"`
-	IsDelete           int                          `description:"是否删除,0:未删除,1:已删除"`
-	ModifyTime         time.Time                    `description:"最近修改日期"`
-	CreateTime         time.Time                    `description:"创建日期"`
-	TableData          interface{}                  `description:"表格内容"`
-	Button             excel2.ExcelInfoDetailButton `description:"操作权限"`
-	CanEdit            bool                         `description:"是否可编辑"`
-	Editor             string                       `description:"编辑人"`
-	IsJoinPermission   int                          `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
-	HaveOperaAuth      bool                         `description:"是否有数据权限"`
-	ParentId           int                          `description:"表格的父级id"`
-	BalanceType        int                          `description:"平衡表类型:0 动态表,1静态表"`
-	UpdateUserId       int                          `description:"更新人id"`
-	UpdateUserRealName string                       `description:"更新人真实姓名"`
-	RelExcelInfoId     int                          `description:"平衡表里静态表关联的动态表excel id"`
-	SourcesFrom        string                       `description:"图表来源"`
-	ExcelSource        string                       `description:"表格来源str"`
-	ExcelSourceEn      string                       `description:"表格来源(英文)"`
+	ExcelInfoId        int                           `orm:"column(excel_info_id);pk"`
+	Source             int                           `description:"表格来源,1:excel插件的表格,2:自定义表格,默认:1"`
+	ExcelType          int                           `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelName          string                        `description:"表格名称"`
+	UniqueCode         string                        `description:"表格唯一编码"`
+	ExcelClassifyId    int                           `description:"表格分类id"`
+	SysUserId          int                           `description:"操作人id"`
+	SysUserRealName    string                        `description:"操作人真实姓名"`
+	Content            string                        `description:"表格内容"`
+	ExcelImage         string                        `description:"表格图片"`
+	FileUrl            string                        `description:"表格下载地址"`
+	Sort               int                           `description:"排序字段,数字越小越排前面"`
+	IsDelete           int                           `description:"是否删除,0:未删除,1:已删除"`
+	ModifyTime         time.Time                     `description:"最近修改日期"`
+	CreateTime         time.Time                     `description:"创建日期"`
+	TableData          interface{}                   `description:"表格内容"`
+	Button             excel2.ExcelInfoDetailButton  `description:"操作权限"`
+	CanEdit            bool                          `description:"是否可编辑"`
+	Editor             string                        `description:"编辑人"`
+	IsJoinPermission   int                           `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth      bool                          `description:"是否有数据权限"`
+	ParentId           int                           `description:"表格的父级id"`
+	BalanceType        int                           `description:"平衡表类型:0 动态表,1静态表"`
+	UpdateUserId       int                           `description:"更新人id"`
+	UpdateUserRealName string                        `description:"更新人真实姓名"`
+	RelExcelInfoId     int                           `description:"平衡表里静态表关联的动态表excel id"`
+	SourcesFrom        string                        `description:"图表来源"`
+	ExcelSource        string                        `description:"表格来源str"`
+	ExcelSourceEn      string                        `description:"表格来源(英文)"`
+	ExtraConfig        excel2.ExcelCommonExtraConfig `description:"表格额外配置"`
 }
 
 type BalanceChildTableResp struct {

+ 1 - 1
services/data/area_graph/processor_business_logic.go

@@ -390,7 +390,7 @@ func (f *FillWithNextStrategy) Deal(tmpConfig data_manage.AreaExtraConf, edbData
 							EdbInfoId:     v.EdbInfoId,
 							DataTime:      nextDay,
 							DataTimestamp: toTime.UnixMilli(),
-							Value:         afterIndexData.Value,
+							Value:         beforeIndexData.Value,
 						}
 
 						// 将补充数据加入补充数据列表

+ 5 - 1
services/data/chart_info.go

@@ -1272,6 +1272,10 @@ func GetSeasonEdbInfoDataListByXDateNong(result *data_manage.EdbDataResult, late
 				Value:         item.Value,
 			}
 			dataTimeT, _ := time.Parse(utils.FormatDate, item.DataTime)
+			year := dataTimeT.Year()
+			newItemDate := dataTimeT.AddDate(nowYear-year, 0, 0)
+			timestamp := newItemDate.UnixNano() / 1e6
+			tmpVal.DataTimestamp = timestamp
 			if (startTmpT.Before(dataTimeT) && endTmpT.After(dataTimeT)) || startTmpT == dataTimeT || endTmpT == dataTimeT {
 				tmpV := &tmpVal
 				if findVal, ok := quarterMap[name]; !ok {
@@ -4295,7 +4299,7 @@ func SeasonChartData(dataList []*data_manage.ChartEdbInfoMapping, seasonExtraCon
 			valueMap := make(map[time.Time]float64)
 
 			samePeriodStandardDeviationList := make([]*data_manage.MaxMinLimitsData, 0)
-			for i := len(quarterDataList) - 1; i > len(quarterDataList)-seasonConfig.SamePeriodAverage.Year-1 && i > 0; i-- {
+			for i := len(quarterDataList) - 1; i > len(quarterDataList)-seasonConfig.SamePeriodStandardDeviation.Year-1 && i > 0; i-- {
 				// 插值成日度
 				dataTimeList, _, err = HandleDataByLinearRegressionToListV2(quarterDataList[i].DataList, handleDataMap)
 				if err != nil {

+ 8 - 0
services/data/excel/excel_info.go

@@ -108,6 +108,14 @@ func formatExcelInfo2Detail(excelInfo *excel.ExcelInfo, sysUserId int, lang stri
 		SourcesFrom:        excelInfo.SourcesFrom,
 	}
 
+	// 额外配置(表格冻结行列等)
+	if excelInfo.ExtraConfig != "" {
+		if e := json.Unmarshal([]byte(excelInfo.ExtraConfig), &excelDetail.ExtraConfig); e != nil {
+			err = fmt.Errorf("额外配置解析失败, %v", e)
+			return
+		}
+	}
+
 	// 无权限,不需要返回数据
 	if !haveOperaAuth {
 		return

+ 1 - 0
services/data/excel/excel_op.go

@@ -198,6 +198,7 @@ func Copy(oldExcelInfo *excelModel.ExcelInfo, excelClassifyId int, excelName str
 		IsDelete:        0,
 		ModifyTime:      time.Now(),
 		CreateTime:      time.Now(),
+		ExtraConfig:     oldExcelInfo.ExtraConfig,
 	}
 
 	// 如果不是自定义分析,那么直接加主表就好了

+ 1 - 1
services/document_manage_service/document_manage_service.go

@@ -241,7 +241,7 @@ func RuiSiReportList(classifyIdFirst, classifyIdSecond, classifyIdThird int, cha
 	}
 
 	// 作者为 全球市场战略研究中心 PCI Research
-	condition += ` and a.author = '战研中心 PCIR'`
+	//condition += ` and a.author = '战研中心 PCIR'`
 	// 已发布的报告
 	condition += ` and a.state = 2`
 

+ 17 - 8
services/elastic/elastic.go

@@ -73,7 +73,7 @@ func EsAddOrEditEdbInfoData(indexName, docId string, item *data_manage.EdbInfoLi
 	}()
 	client := utils.EsClient
 
-	resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
+	resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Refresh("true").Do(context.Background())
 	if err != nil {
 		fmt.Println("新增失败:", err.Error())
 		return err
@@ -690,7 +690,7 @@ func SearchEdbInfoDataBak(indexName, keywordStr string, from, size, filterSource
 }
 
 // SearchAddPredictEdbInfoData 查询允许添加预测指标的数据
-func SearchAddPredictEdbInfoData(indexName, keywordStr string, noPermissionEdbInfoIdList []int, from, size int) (total int64, list []*data_manage.EdbInfoList, err error) {
+func SearchAddPredictEdbInfoData(indexName, keywordStr string, noPermissionEdbInfoIdList []int, from, size, sysUserId int) (total int64, list []*data_manage.EdbInfoList, err error) {
 	list = make([]*data_manage.EdbInfoList, 0)
 	defer func() {
 		if err != nil {
@@ -729,6 +729,15 @@ func SearchAddPredictEdbInfoData(indexName, keywordStr string, noPermissionEdbIn
 		},
 	})
 
+	// 只看我的
+	if sysUserId > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"SysUserId": sysUserId,
+			},
+		})
+	}
+
 	//关键字匹配
 	//shouldMap := map[string]interface{}{
 	//	"should": []interface{}{
@@ -925,7 +934,7 @@ func EsDeleteEdbInfoData(indexName, docId string) (err error) {
 	}()
 	client := utils.EsClient
 
-	resp, err := client.Delete().Index(indexName).Id(docId).Do(context.Background())
+	resp, err := client.Delete().Index(indexName).Id(docId).Refresh(`true`).Do(context.Background())
 	fmt.Println(resp)
 	if err != nil {
 		return
@@ -1054,7 +1063,7 @@ func EsAddOrEditChartInfoData(indexName, docId string, item *data_manage.ChartIn
 	}()
 	client := utils.EsClient
 
-	resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
+	resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Refresh("true").Do(context.Background())
 	if err != nil {
 		fmt.Println("新增失败:", err.Error())
 		return err
@@ -1078,7 +1087,7 @@ func EsDeleteDataV2(indexName, docId string) (err error) {
 	}()
 	client := utils.EsClient
 
-	resp, err := client.Delete().Index(indexName).Id(docId).Do(context.Background())
+	resp, err := client.Delete().Index(indexName).Id(docId).Refresh("true").Do(context.Background())
 	fmt.Println(resp)
 	if err != nil {
 		return
@@ -1303,7 +1312,7 @@ func EsAddOrEditDataInterface(indexName, docId string, item interface{}) (err er
 	}()
 	client := utils.EsClient
 
-	resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
+	resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Refresh("true").Do(context.Background())
 	if err != nil {
 		fmt.Println("新增失败:", err.Error())
 		return err
@@ -1751,7 +1760,7 @@ func EsAddOrEditExcelInfoData(indexName, docId string, item *excel.ExcelInfo) (e
 	}()
 	client := utils.EsClient
 
-	resp, e := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
+	resp, e := client.Index().Index(indexName).Id(docId).BodyJson(item).Refresh("true").Do(context.Background())
 	if e != nil {
 		err = fmt.Errorf("resp err, %v", e)
 		return
@@ -1930,7 +1939,7 @@ func EsAddOrEditDataSourceIndex(indexName, docId string, item *dataSourceModel.S
 	}()
 	client := utils.EsClient
 
-	resp, e := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
+	resp, e := client.Index().Index(indexName).Id(docId).BodyJson(item).Refresh("true").Do(context.Background())
 	if e != nil {
 		err = fmt.Errorf("resp err, %v", e)
 		return

+ 295 - 0
services/eta_forum/eta_trial.go

@@ -0,0 +1,295 @@
+package eta_forum
+
+import (
+	"encoding/json"
+	"eta/eta_api/models"
+	"eta/eta_api/models/eta_trial"
+	"eta/eta_api/services/alarm_msg"
+	"fmt"
+)
+
+// EtaTrialUserReq 更新试用客户最后登录时间和次数请求体
+type EtaTrialUserReq struct {
+	Mobile string `description:"手机号"`
+}
+
+// UpdateEtaTrialUserLogin eta_forum_hub服务-更新试用客户最后登录时间和次数
+func UpdateEtaTrialUserLogin(pars EtaTrialUserReq) (res bool, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("GetEtaTrialMobileCount, 新增试用客户手工录入权限失败, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_login")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = true
+	return
+}
+
+// GetEtaTrialUserReq 获取试用客户请求体
+type GetEtaTrialUserReq struct {
+	Mobile string `description:"手机号"`
+}
+
+type EtaTrialUserResp struct {
+	Ret     int
+	Msg     string
+	ErrMsg  string
+	ErrCode string
+	Data    eta_trial.EtaTrialUserItem
+	Success bool `description:"true 执行成功,false 执行失败"`
+}
+
+// GetEtaTrialUser eta_forum_hub服务-获取试用客户信息
+func GetEtaTrialUser(pars GetEtaTrialUserReq) (res eta_trial.EtaTrialUserItem, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("GetEtaTrialUser, 获取试用客户信息, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/mobile_fetch")
+	resp := new(EtaTrialUserResp)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = resp.Data
+	return
+}
+
+// DisableEtaTrialUser eta_forum_hub服务-禁用试用客户
+func DisableEtaTrialUser(pars EtaTrialUserReq) (res bool, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("DisableEtaTrialUser eta_forum_hub服务-禁用试用客户, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/disable")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = true
+	return
+}
+
+// RemoveEtaTrialUser eta_forum_hub服务-删除试用客户
+func RemoveEtaTrialUser(pars EtaTrialUserReq) (res bool, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("RemoveEtaTrialUser eta_forum_hub服务-删除试用客户失败, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/remove")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = true
+	return
+}
+
+// EtaTrialUserEditReq 更新用户信息请求体
+type EtaTrialUserEditReq struct {
+	RealName string `description:"姓名"`
+	Position string `description:"职务"`
+	Mobile   string `description:"手机号"`
+	Enabled  int    `description:"禁启用"`
+}
+
+// EditEtaTrialUser eta_forum_hub服务-编辑试用客户
+func EditEtaTrialUser(pars EtaTrialUserEditReq) (res bool, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("EditEtaTrialUser eta_forum_hub服务-编辑试用客户失败, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/edit")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = true
+	return
+}
+
+// UpdateUserIndexNum eta_forum_hub服务-更新用户累计新增指标数
+func UpdateUserIndexNum(pars EtaTrialUserReq) (res bool, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf(" UpdateUserIndexNum eta_forum_hub服务-更新用户累计新增指标数失败, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_index_num")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = true
+	return
+}
+
+// UpdateUserChartNum eta_forum_hub服务-更新用户累计新增图表数
+func UpdateUserChartNum(pars EtaTrialUserReq) (res bool, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("UpdateUserChartNum eta_forum_hub服务-更新用户累计新增图表数失败, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_chart_num")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = true
+	return
+}
+
+// UpdateEtaTrialUserActiveTimeReq 更新试用客户活跃时长请求体
+type UpdateEtaTrialUserActiveTimeReq struct {
+	Mobile     string `description:"手机号"`
+	UserName   string `description:"用户姓名"`
+	ActiveTime int    `description:"活跃时长, 单位秒"`
+	Part       string `description:"活跃板块"`
+}
+
+// UpdateEtaTrialUserActiveTime eta_forum_hub服务-更新试用客户活跃时长
+func UpdateEtaTrialUserActiveTime(pars UpdateEtaTrialUserActiveTimeReq) (res bool, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("UpdateEtaTrialUserActiveTime eta_forum_hub服务-更新试用客户活跃时长失败, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_active_time")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = true
+	return
+}
+
+// UpdateEtaTrialUserLoginDurationReq 更新试用客户登录时长请求体
+type UpdateEtaTrialUserLoginDurationReq struct {
+	Mobile     string `description:"手机号"`
+	UserName   string `description:"用户姓名"`
+	ActiveTime int    `description:"活跃时长, 单位秒"`
+}
+
+// UpdateEtaTrialUserLoginDuration eta_forum_hub服务-更新试用客户登录时长
+func UpdateEtaTrialUserLoginDuration(pars UpdateEtaTrialUserLoginDurationReq) (res bool, err error) {
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("UpdateEtaTrialUserLoginDuration eta_forum_hub服务-更新试用客户登录时长失败, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
+	if e != nil {
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
+		return
+	}
+
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_login_duration")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
+		return
+	}
+	res = true
+	return
+}

+ 189 - 382
services/eta_trial/user.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"eta/eta_api/models"
 	"eta/eta_api/models/eta_trial"
+	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/utils"
 	"fmt"
 	"io/ioutil"
@@ -16,57 +17,28 @@ type EtaTrialUserReq struct {
 	Mobile string `description:"手机号"`
 }
 
-// UpdateEtaTrialUserLogin CRM_ETA服务-更新试用客户最后登录时间和次数
+// UpdateEtaTrialUserLogin eta_forum_hub服务-更新试用客户最后登录时间和次数
 func UpdateEtaTrialUserLogin(pars EtaTrialUserReq) (res bool, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/update_login")
-	params, e := json.Marshal(pars)
-	if e != nil {
-		err = fmt.Errorf("data json marshal err: %s", e.Error())
-		return
-	}
-
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
-		return
-	}
-
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
-		return
-	}
 	defer func() {
-		_ = resp.Body.Close()
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("GetEtaTrialMobileCount, 新增试用客户手工录入权限失败, ErrMsg: %s", err.Error()), 3)
+		}
 	}()
-	b, e := ioutil.ReadAll(resp.Body)
+
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
-		return
-	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
-	}
 
-	result := new(models.ResultData)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_login")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
 		return
 	}
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
 	res = true
@@ -79,185 +51,89 @@ type GetEtaTrialUserReq struct {
 }
 
 type EtaTrialUserResp struct {
-	Code   int                        `json:"code" description:"状态码"`
-	Msg    string                     `json:"msg" description:"提示信息"`
-	Data   eta_trial.EtaTrialUserItem `json:"data" description:"返回数据"`
-	ErrMsg string                     `json:"-" description:"错误信息,不用返回给前端,只是做日志记录"`
+	Ret     int
+	Msg     string
+	ErrMsg  string
+	ErrCode string
+	Data    eta_trial.EtaTrialUserItem
+	Success bool `description:"true 执行成功,false 执行失败"`
 }
 
-// GetEtaTrialUser CRM_ETA服务-获取试用客户信息
+// GetEtaTrialUser eta_forum_hub服务-获取试用客户信息
 func GetEtaTrialUser(pars GetEtaTrialUserReq) (res eta_trial.EtaTrialUserItem, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/mobile_fetch")
-	params, e := json.Marshal(pars)
-	if e != nil {
-		err = fmt.Errorf("data json marshal err: %s", e.Error())
-		return
-	}
-
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
-		return
-	}
-
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
-		return
-	}
 	defer func() {
-		_ = resp.Body.Close()
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("GetEtaTrialUser, 获取试用客户信息, ErrMsg: %s", err.Error()), 3)
+		}
 	}()
-	b, e := ioutil.ReadAll(resp.Body)
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
-		return
-	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
-	}
 
-	//result := new(models.ResultData)
-	result := new(EtaTrialUserResp)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/mobile_fetch")
+	resp := new(EtaTrialUserResp)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
 		return
 	}
-	utils.FileLog.Info("%s", string(b))
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
-	res = result.Data
-	//r, ok := result.Data.(eta_trial.EtaTrialUserResp)
-	//if !ok {
-	//	err = fmt.Errorf("result data err")
-	//	return
-	//}
-	//res = r
+	res = resp.Data
 	return
 }
 
-// DisableEtaTrialUser CRM_ETA服务-禁用试用客户
+// DisableEtaTrialUser eta_forum_hub服务-禁用试用客户
 func DisableEtaTrialUser(pars EtaTrialUserReq) (res bool, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/disable")
-	params, e := json.Marshal(pars)
-	if e != nil {
-		err = fmt.Errorf("data json marshal err: %s", e.Error())
-		return
-	}
-
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
-		return
-	}
-
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
-		return
-	}
 	defer func() {
-		_ = resp.Body.Close()
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("DisableEtaTrialUser eta_forum_hub服务-禁用试用客户, ErrMsg: %s", err.Error()), 3)
+		}
 	}()
-	b, e := ioutil.ReadAll(resp.Body)
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
-		return
-	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
-	}
 
-	result := new(models.ResultData)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/disable")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
 		return
 	}
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
 	res = true
 	return
 }
 
-// RemoveEtaTrialUser CRM_ETA服务-删除试用客户
+// RemoveEtaTrialUser eta_forum_hub服务-删除试用客户
 func RemoveEtaTrialUser(pars EtaTrialUserReq) (res bool, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/remove")
-	params, e := json.Marshal(pars)
-	if e != nil {
-		err = fmt.Errorf("data json marshal err: %s", e.Error())
-		return
-	}
-
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
-		return
-	}
-
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
-		return
-	}
 	defer func() {
-		_ = resp.Body.Close()
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("RemoveEtaTrialUser eta_forum_hub服务-删除试用客户失败, ErrMsg: %s", err.Error()), 3)
+		}
 	}()
-	b, e := ioutil.ReadAll(resp.Body)
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
-		return
-	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
-	}
 
-	result := new(models.ResultData)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/remove")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
 		return
 	}
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
 	res = true
@@ -272,171 +148,81 @@ type EtaTrialUserEditReq struct {
 	Enabled  int    `description:"禁启用"`
 }
 
-// EditEtaTrialUser CRM_ETA服务-编辑试用客户
+// EditEtaTrialUser eta_forum_hub服务-编辑试用客户
 func EditEtaTrialUser(pars EtaTrialUserEditReq) (res bool, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/edit")
-	params, e := json.Marshal(pars)
-	if e != nil {
-		err = fmt.Errorf("data json marshal err: %s", e.Error())
-		return
-	}
-
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
-		return
-	}
-
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
-		return
-	}
 	defer func() {
-		_ = resp.Body.Close()
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("EditEtaTrialUser eta_forum_hub服务-编辑试用客户失败, ErrMsg: %s", err.Error()), 3)
+		}
 	}()
-	b, e := ioutil.ReadAll(resp.Body)
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
-		return
-	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
-	}
 
-	result := new(models.ResultData)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/edit")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
 		return
 	}
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
 	res = true
 	return
 }
 
-// UpdateUserIndexNum CRM_ETA服务-更新用户累计新增指标数
+// UpdateUserIndexNum eta_forum_hub服务-更新用户累计新增指标数
 func UpdateUserIndexNum(pars EtaTrialUserReq) (res bool, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/update_index_num")
-	params, e := json.Marshal(pars)
-	if e != nil {
-		err = fmt.Errorf("data json marshal err: %s", e.Error())
-		return
-	}
-
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
-		return
-	}
-
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
-		return
-	}
 	defer func() {
-		_ = resp.Body.Close()
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf(" UpdateUserIndexNum eta_forum_hub服务-更新用户累计新增指标数失败, ErrMsg: %s", err.Error()), 3)
+		}
 	}()
-	b, e := ioutil.ReadAll(resp.Body)
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
-		return
-	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
-	}
 
-	result := new(models.ResultData)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_index_num")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
 		return
 	}
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
 	res = true
 	return
 }
 
-// UpdateUserChartNum CRM_ETA服务-更新用户累计新增图表数
+// UpdateUserChartNum eta_forum_hub服务-更新用户累计新增图表数
 func UpdateUserChartNum(pars EtaTrialUserReq) (res bool, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/update_chart_num")
-	params, e := json.Marshal(pars)
-	if e != nil {
-		err = fmt.Errorf("data json marshal err: %s", e.Error())
-		return
-	}
-
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
-		return
-	}
-
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
-		return
-	}
 	defer func() {
-		_ = resp.Body.Close()
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("UpdateUserChartNum eta_forum_hub服务-更新用户累计新增图表数失败, ErrMsg: %s", err.Error()), 3)
+		}
 	}()
-	b, e := ioutil.ReadAll(resp.Body)
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
-		return
-	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
-	}
 
-	result := new(models.ResultData)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_chart_num")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
 		return
 	}
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
 	res = true
@@ -451,57 +237,27 @@ type UpdateEtaTrialUserActiveTimeReq struct {
 	Part       string `description:"活跃板块"`
 }
 
-// UpdateEtaTrialUserActiveTime CRM_ETA服务-更新试用客户活跃时长
+// UpdateEtaTrialUserActiveTime eta_forum_hub服务-更新试用客户活跃时长
 func UpdateEtaTrialUserActiveTime(pars UpdateEtaTrialUserActiveTimeReq) (res bool, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/update_active_time")
-	params, e := json.Marshal(pars)
-	if e != nil {
-		err = fmt.Errorf("data json marshal err: %s", e.Error())
-		return
-	}
-
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
-		return
-	}
-
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
-		return
-	}
 	defer func() {
-		_ = resp.Body.Close()
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("UpdateEtaTrialUserActiveTime eta_forum_hub服务-更新试用客户活跃时长失败, ErrMsg: %s", err.Error()), 3)
+		}
 	}()
-	b, e := ioutil.ReadAll(resp.Body)
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
-		return
-	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
-	}
 
-	result := new(models.ResultData)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_active_time")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
 		return
 	}
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
 	res = true
@@ -515,59 +271,110 @@ type UpdateEtaTrialUserLoginDurationReq struct {
 	ActiveTime int    `description:"活跃时长, 单位秒"`
 }
 
-// UpdateEtaTrialUserLoginDuration CRM_ETA服务-更新试用客户登录时长
+// UpdateEtaTrialUserLoginDuration eta_forum_hub服务-更新试用客户登录时长
 func UpdateEtaTrialUserLoginDuration(pars UpdateEtaTrialUserLoginDurationReq) (res bool, err error) {
-	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta_trial/user/update_login_duration")
-	params, e := json.Marshal(pars)
+	defer func() {
+		if err != nil {
+			alarm_msg.SendAlarmMsg(fmt.Sprintf("UpdateEtaTrialUserLoginDuration eta_forum_hub服务-更新试用客户登录时长失败, ErrMsg: %s", err.Error()), 3)
+		}
+	}()
+	reqJson, e := json.Marshal(pars)
 	if e != nil {
 		err = fmt.Errorf("data json marshal err: %s", e.Error())
 		return
 	}
 
-	body := ioutil.NopCloser(strings.NewReader(string(params)))
-	client := &http.Client{}
-	req, e := http.NewRequest("POST", url, body)
-	if e != nil {
-		err = fmt.Errorf("http create request err: %s", e.Error())
+	_, resultByte, err := post(string(reqJson), "/v1/eta_trial/user/update_login_duration")
+	resp := new(models.BaseResponse)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	if resp.Ret != 200 {
+		err = fmt.Errorf("result: %s, errmsg: %s", resp.Msg, resp.ErrMsg)
 		return
 	}
+	res = true
+	return
+}
 
-	contentType := "application/json;charset=utf-8"
-	req.Header.Set("Content-Type", contentType)
-	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
-	resp, e := client.Do(req)
-	if e != nil {
-		err = fmt.Errorf("http client do err: %s", e.Error())
+// post
+func post(paramStr string, urlStr string) (resp *models.BaseResponse, result []byte, err error) {
+	if utils.ETA_FORUM_HUB_URL == "" {
+		err = fmt.Errorf("ETA社区桥接服务地址为空")
 		return
 	}
-	defer func() {
-		_ = resp.Body.Close()
-	}()
-	b, e := ioutil.ReadAll(resp.Body)
-	if e != nil {
-		err = fmt.Errorf("resp body read err: %s", e.Error())
+	postUrl := utils.ETA_FORUM_HUB_URL + urlStr
+	result, err = HttpPost(postUrl, paramStr, "application/json")
+	if err != nil {
+		err = fmt.Errorf("调用ETA社区桥接服务接口失败 error:%s", err.Error())
 		return
 	}
-	if len(b) == 0 {
-		err = fmt.Errorf("resp body is empty")
+	err = json.Unmarshal(result, &resp)
+	if err != nil {
 		return
 	}
-	// 生产环境解密, 注意有个坑前后的双引号
-	if utils.RunMode == "release" {
-		str := string(b)
-		str = strings.Trim(str, `"`)
-		b = utils.DesBase64Decrypt([]byte(str), utils.CrmEtaServerDes3Key)
+
+	return
+}
+
+func HttpPost(url, postData string, params ...string) ([]byte, error) {
+	body := ioutil.NopCloser(strings.NewReader(postData))
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", url, body)
+	if err != nil {
+		return nil, err
 	}
+	contentType := "application/x-www-form-urlencoded;charset=utf-8"
+	if len(params) > 0 && params[0] != "" {
+		contentType = params[0]
+	}
+	req.Header.Set("Content-Type", contentType)
+	req.Header.Set("authorization", utils.MD5(utils.ETA_FORUM_HUB_NAME_EN+utils.ETA_FORUM_HUB_MD5_KEY))
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	b, err := ioutil.ReadAll(resp.Body)
+	utils.FileLog.Debug("HttpPost:" + string(b))
+	return b, err
+}
 
-	result := new(models.ResultData)
-	if e = json.Unmarshal(b, &result); e != nil {
-		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
+// get
+func get(paramStr string, urlStr string) (resp *models.BaseResponse, result []byte, err error) {
+	if utils.ETA_FORUM_HUB_URL == "" {
+		err = fmt.Errorf("ETA社区桥接服务地址为空")
 		return
 	}
-	if result.Code != 200 {
-		err = fmt.Errorf("result: %s", string(b))
+	urlStr = urlStr + "?" + paramStr
+	getUrl := utils.ETA_FORUM_HUB_URL + urlStr
+	result, err = HttpGet(getUrl)
+	if err != nil {
+		err = fmt.Errorf("调用ETA社区桥接服务接口失败 error:%s", err.Error())
 		return
 	}
-	res = true
+	err = json.Unmarshal(result, &resp)
+	if err != nil {
+		return
+	}
+
 	return
 }
+
+func HttpGet(url string) ([]byte, error) {
+	client := &http.Client{}
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("authorization", utils.MD5(utils.ETA_FORUM_HUB_NAME_EN+utils.ETA_FORUM_HUB_MD5_KEY))
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	b, err := ioutil.ReadAll(resp.Body)
+	utils.FileLog.Debug("HttpPost:" + string(b))
+	return b, err
+}

+ 17 - 0
services/ppt.go

@@ -11,6 +11,7 @@ import (
 	"eta/eta_api/utils"
 	"fmt"
 	"sort"
+	"strings"
 	"time"
 )
 
@@ -236,9 +237,25 @@ func pptContent2Html(content string, isEnglish bool) (htm string, err error) {
 				case ElementsTypeChart:
 					if isEnglish {
 						// 英文研报图表src多加一个fromPage=en, 表格暂时没有区分
+						if strings.HasPrefix(v.ChartId, "isETAForumChart_") {
+							chartIdInfo := strings.Split(v.ChartId, "_")
+							if len(chartIdInfo) == 2 {
+								v.ChartId = chartIdInfo[1]
+							}
+							htmlContent += fmt.Sprintf(`<iframe src="%s/chartshow?code=%s&fromPage=en&isETAForumChart=true" width="100%%" height="350" style="border-width:0px; min-height:350px;"></iframe>`, chartRoot, v.ChartId)
+							break
+						}
 						htmlContent += fmt.Sprintf(`<iframe src="%s/chartshow?code=%s&fromPage=en" width="100%%" height="350" style="border-width:0px; min-height:350px;"></iframe>`, chartRoot, v.ChartId)
 						break
 					}
+					if strings.HasPrefix(v.ChartId, "isETAForumChart_") {
+						chartIdInfo := strings.Split(v.ChartId, "_")
+						if len(chartIdInfo) == 2 {
+							v.ChartId = chartIdInfo[1]
+						}
+						htmlContent += fmt.Sprintf(`<iframe src="%s/chartshow?code=%s&isETAForumChart=true" width="100%%" height="350" style="border-width:0px; min-height:350px;"></iframe>`, chartRoot, v.ChartId)
+						break
+					}
 					htmlContent += fmt.Sprintf(`<iframe src="%s/chartshow?code=%s" width="100%%" height="350" style="border-width:0px; min-height:350px;"></iframe>`, chartRoot, v.ChartId)
 				case ElementsTypeSheet:
 					htmlContent += fmt.Sprintf(`<iframe src="%s/sheetshow?code=%s" class="iframe%s" width="100%%" height="%s" style="border-width:0px;"></iframe>`, chartRoot, v.SheetId, v.SheetId, v.SheetHeight)

+ 232 - 2
services/report_v2.go

@@ -2,6 +2,7 @@ package services
 
 import (
 	"archive/zip"
+	"encoding/json"
 	"errors"
 	"eta/eta_api/models"
 	"eta/eta_api/models/company"
@@ -12,7 +13,11 @@ import (
 	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/utils"
 	"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"
@@ -22,8 +27,6 @@ import (
 	"github.com/beego/beego/v2/server/web"
 	"github.com/beego/beego/v2/server/web/context"
 	"github.com/go-redis/redis/v8"
-	"github.com/rdlucklib/rdluck_tools/file"
-	"github.com/rdlucklib/rdluck_tools/http"
 )
 
 // AddReportAndChapter
@@ -1712,3 +1715,230 @@ func ResetMiniProgramReportDetailCover(reportId int) (err error) {
 	}
 	return
 }
+
+// HandleReportContent
+// @Description: 处理报告内容(动态图表/表格添加授权token)
+// @author: Roc
+// @datetime 2025-01-07 10:03:15
+// @param body string
+// @return newBody string
+func HandleReportContent(body string, opType string, tokenMap map[string]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
+	}
+
+	replaceIframeSrc(doc, opType, tokenMap)
+
+	// 输出修改后的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 replaceIframeSrc(n *html2.Node, opType string, tokenMap map[string]string) {
+	if n.Type == html2.ElementNode && n.Data == "iframe" {
+		for i, attr := range n.Attr {
+			if attr.Key == "src" {
+				newLink := attr.Val
+				// 处理链接
+				switch opType {
+				case `add`:
+					newLink = linkAddToken(attr.Val, tokenMap)
+				case `del`:
+					newLink = linkDelToken(attr.Val)
+				}
+				// 替换原来的链接
+				n.Attr[i].Val = newLink
+				break
+			}
+		}
+	}
+	// 递归处理子节点
+	for c := n.FirstChild; c != nil; c = c.NextSibling {
+		replaceIframeSrc(c, opType, tokenMap)
+	}
+}
+
+// linkAddToken 链接添加token
+func linkAddToken(link string, tokenMap map[string]string) 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()
+
+	// 先移除authToken参数,避免莫名其妙的这个值入库了
+	queryParams.Del("authToken")
+
+	// 获取code参数
+	code := queryParams.Get("code")
+	if code == "" {
+		return link
+	}
+
+	showType := `chart`
+	if strings.Contains(parsedURL.Path, "sheetshow") {
+		showType = `excel`
+	}
+
+	// 避免报告里面一个图表/表格重复生成token
+	key := fmt.Sprint(showType, `:`, code)
+	if tokenMap != nil {
+		if token, ok := tokenMap[key]; ok {
+			// 在链接后面添加一个token值
+			return link + "&authToken=" + token
+		}
+	}
+
+	token, err := GeneralChartToken(showType, code, 30*time.Minute)
+	if err != nil {
+		return link
+	}
+
+	if tokenMap != nil {
+		tokenMap[key] = token
+	}
+
+	// 在链接后面添加一个token值
+	return link + "&authToken=" + token
+}
+
+// linkDelToken 链接添加token
+func linkDelToken(link string) 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()
+
+	// 移除authToken参数
+	queryParams.Del("authToken")
+
+	// 更新URL的查询参数
+	parsedURL.RawQuery = queryParams.Encode()
+
+	return parsedURL.String()
+}
+
+// GeneralChartToken
+// @Description: 生产图表/表格授权token
+// @author: Roc
+// @datetime 2025-01-07 10:41:36
+// @param showType string
+// @param uniqueCode string
+// @param expireTime time.Duration
+// @return token string
+// @return err error
+func GeneralChartToken(showType, uniqueCode string, expireTime time.Duration) (token string, err error) {
+	// 缓存key
+	token = utils.MD5(fmt.Sprint(showType+`:`, uniqueCode, time.Now().UnixNano()/1e6))
+	key := fmt.Sprint(utils.CACHE_CHART_AUTH, token)
+	err = utils.Rc.Put(key, uniqueCode, expireTime)
+
+	return
+}
+
+// HandleReportContentStruct
+// @Description: 处理内容组件的链接
+// @author: Roc
+// @datetime 2025-01-07 13:38:39
+// @param body string
+// @param opType string
+// @return newBody string
+func HandleReportContentStruct(body string, opType string, tokenMap map[string]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 := processMap(jsonData[i], opType, tokenMap); 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
+}
+
+// processMap 递归处理map中的content字段
+func processMap(data map[string]interface{}, opType string, tokenMap map[string]string) error {
+	for key, value := range data {
+		switch v := value.(type) {
+		case string:
+			if key == "content" {
+				newContent := v
+				// 处理链接
+				switch opType {
+				case `add`:
+					newContent = linkAddToken(v, tokenMap)
+				case `del`:
+					newContent = linkDelToken(v)
+				}
+				data[key] = newContent
+			}
+		case map[string]interface{}:
+			if err := processMap(v, opType, tokenMap); err != nil {
+				return err
+			}
+		case []interface{}:
+			for i := range v {
+				if m, ok := v[i].(map[string]interface{}); ok {
+					if err := processMap(m, opType, tokenMap); err != nil {
+						return err
+					}
+				}
+			}
+		}
+	}
+	return nil
+}

+ 1 - 1
utils/constants.go

@@ -264,7 +264,7 @@ const (
 	CACHE_EXCEL_REFRESH = "CACHE_EXCEL_REFRESH" // 表格刷新
 
 	CACHE_DATA_SOURCE_ES_HANDLE = "eta:data_source_es:handle" // 数据源es处理队列
-	CACHE_CHART_AUTH      = "chart:auth:"     //图表数据
+	CACHE_CHART_AUTH      = "chart:auth:"     //图表数据授权
 )
 
 // 模板消息推送类型