Pārlūkot izejas kodu

Merge branch 'chart2.0' of hongze/hongze_yb into master

hsun 3 gadi atpakaļ
vecāks
revīzija
94058017d2
50 mainītis faili ar 10670 papildinājumiem un 337 dzēšanām
  1. 524 0
      controller/chart/chart_info.go
  2. 576 0
      controller/chart/my_chart.go
  3. 18 7
      controller/response/base.go
  4. 1005 127
      docs/docs.go
  5. 1003 124
      docs/swagger.json
  6. 716 57
      docs/swagger.yaml
  7. 4 5
      go.mod
  8. 7 4
      init_serve/router.go
  9. 26 9
      logic/user/user.go
  10. 1 0
      middleware/check_activity_auth.go
  11. 41 0
      middleware/check_chart_auth.go
  12. 1 0
      models/request/user/user.go
  13. 11 0
      models/response/chart_info/chart_info.go
  14. 8 0
      models/response/my_chart/my_chart.go
  15. 6 0
      models/tables/admin/query.go
  16. 50 0
      models/tables/chart_classify/chart_classify.go
  17. 7 0
      models/tables/chart_classify/query.go
  18. 65 0
      models/tables/chart_edb_mapping/chart_edb_mapping.go
  19. 54 0
      models/tables/chart_edb_mapping/query.go
  20. 91 0
      models/tables/chart_info/chart_info.go
  21. 101 0
      models/tables/chart_info/query.go
  22. 50 0
      models/tables/chart_info_log/chart_info_log.go
  23. 9 0
      models/tables/chart_info_log/create.go
  24. 44 0
      models/tables/company_user_chart_classify_permission/company_user_chart_classify_permission.go
  25. 9 0
      models/tables/company_user_chart_classify_permission/query.go
  26. 30 0
      models/tables/edb_data/create.go
  27. 904 0
      models/tables/edb_data/query.go
  28. 52 0
      models/tables/edb_data/update.go
  29. 95 0
      models/tables/edb_info/edb_info.go
  30. 10 0
      models/tables/edb_info/query.go
  31. 34 0
      models/tables/my_chart/my_chart.go
  32. 100 0
      models/tables/my_chart/query.go
  33. 46 0
      models/tables/my_chart_classify/my_chart_classify.go
  34. 41 0
      models/tables/my_chart_classify/query.go
  35. 27 0
      models/tables/my_chart_classify/update.go
  36. 39 0
      models/tables/my_chart_classify_mapping/my_chart_classify_mapping.go
  37. 79 0
      models/tables/my_chart_classify_mapping/query.go
  38. 11 0
      models/tables/my_chart_classify_mapping/update.go
  39. 10 0
      models/tables/my_chart_log/create.go
  40. 46 0
      models/tables/my_chart_log/my_chart_log.go
  41. 2 2
      models/tables/yb_apply_record/query.go
  42. 2 0
      models/tables/yb_apply_record/yb_apply_record.go
  43. 21 0
      routers/chart.go
  44. 584 0
      services/chart/chart_info.go
  45. 3676 0
      services/chart/edb_data.go
  46. 41 0
      services/chart/my_chart.go
  47. 130 1
      services/company/permission.go
  48. 185 0
      services/edb_data/edb_data.go
  49. 21 0
      services/user/user.go
  50. 57 1
      utils/constants.go

+ 524 - 0
controller/chart/chart_info.go

@@ -0,0 +1,524 @@
+package chart
+
+import (
+	"context"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/models/response/chart_info"
+	chartEdbMappingModel "hongze/hongze_yb/models/tables/chart_edb_mapping"
+	chartInfoModel "hongze/hongze_yb/models/tables/chart_info"
+	"hongze/hongze_yb/models/tables/chart_info_log"
+	edbDataModel "hongze/hongze_yb/models/tables/edb_data"
+	edbInfoModel "hongze/hongze_yb/models/tables/edb_info"
+	"hongze/hongze_yb/services"
+	"hongze/hongze_yb/services/chart"
+	edbDataService "hongze/hongze_yb/services/edb_data"
+	"hongze/hongze_yb/services/user"
+	"hongze/hongze_yb/utils"
+	"io/ioutil"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// GetChartInfoDetail 获取图表详情
+// @Tags 图库模块
+// @Summary  获取图表详情
+// @Description 获取图表详情
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param DateType query string false "时间段:1-00年至今; 2-10年至今; 3-15年至今; 4-21年至今; 5-指定区间; 6-指定年月至今; 7-18年至今; 8-19年至今; 9-20年至今"
+// @Param ClassifyId query string false "图表分类ID"
+// @Success 200 {object} chart_info.ChartInfoDetailResp
+// @failure 400 {string} string "图表详情获取失败"
+// @Router /my_chart/getChartInfoDetail [get]
+func GetChartInfoDetail(c *gin.Context)  {
+	// 图表ID
+	reqChartInfoId := c.DefaultQuery("ChartInfoId", "")
+	if reqChartInfoId == "" {
+		response.Fail("参数有误:图表ID", c)
+		return
+	}
+	chartInfoId, _ := strconv.Atoi(reqChartInfoId)
+
+	startDate := c.DefaultQuery("StartDate", "")
+	endDate := c.DefaultQuery("EndDate", "")
+	// 图表样式类型
+	reqChartType := c.DefaultQuery("ChartType", "")
+	chartType, _ := strconv.Atoi(reqChartType)
+	// 季节性图表时间
+	seasonStartDate := c.DefaultQuery("SeasonStartDate", "")
+	seasonEndDate := c.DefaultQuery("SeasonEndDate", "")
+	// 指标ID
+	edbInfoId := c.DefaultQuery("EdbInfoId", "")
+	// 公历/农历
+	calendar := c.DefaultQuery("Calendar", "公历")
+
+	// 获取图表信息
+	var err error
+	chartInfo := new(chartInfoModel.ChartInfoView)
+	chartInfo, err = chartInfoModel.GetChartInfoViewById(chartInfoId)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			response.Fail("图表不存在,请刷新页面", c)
+			return
+		}
+		response.FailMsg("获取失败", "获取图表信息失败, Err:" + err.Error(), c)
+		return
+	}
+	chartType = chartInfo.ChartType
+
+	// 时段筛选
+	reqDateType := c.DefaultQuery("DateType", "")
+	dateType := chartInfo.DateType
+	if reqDateType != "" {
+		dateType, _ = strconv.Atoi(reqDateType)
+	}
+	if dateType <= 0 {
+		dateType = 3	// 默认同后台15年至今
+	}
+	switch dateType {
+	case 1:
+		startDate = "2000-01-01"
+	case 2:
+		startDate = "2010-01-01"
+	case 3:
+		startDate = "2015-01-01"
+	case 4:
+		startDate = "2021-01-01"
+	case 5:
+		startDate = startDate + "-01"
+		endDate = endDate + "-01"
+	case 6:
+		startDate = startDate + "-01"
+	case 7:
+		startDate = "2018-01-01"
+	case 8:
+		startDate = "2019-01-01"
+	case 9:
+		startDate = "2020-01-01"
+	}
+
+	if chartType == 2 {
+		// 季节性图表
+		if seasonStartDate != "" {
+			startDate = seasonStartDate + "-01-01"
+		} else {
+			fivePre := time.Now().AddDate(-4, 0, 0).Year()
+			startDate = strconv.Itoa(fivePre) + "-01-01"
+		}
+		if seasonEndDate != "" {
+			endDate = seasonEndDate + "-12-31"
+		} else {
+			endDate = ""
+		}
+	}
+
+	// 获取图表指标映射
+	mappingList := make([]*chartEdbMappingModel.ChartEdbInfoMapping, 0)
+	if chartInfoId > 0 {
+		mappingList, err = chartEdbMappingModel.GetMappingListByChartInfoId(chartInfoId)
+		if err != nil {
+			response.FailMsg("获取失败", "获取图表指标信息失败4001, Err:" + err.Error(), c)
+			return
+		}
+	} else {
+		if edbInfoId != "" {
+			mappingList, err = chartEdbMappingModel.GetMappingListByEdbInfoId(edbInfoId)
+			if err != nil {
+				response.FailMsg("获取失败", "获取图表指标信息失败4002, Err:" + err.Error(), c)
+				return
+			}
+		}
+	}
+
+	// 指标列表
+	edbList := make([]*chartEdbMappingModel.ChartEdbInfoMapping, 0)
+	for _, v := range mappingList {
+		item := new(chartEdbMappingModel.ChartEdbInfoMapping)
+		item.EdbInfoId = v.EdbInfoId
+		item.SourceName = v.SourceName
+		item.Source = v.Source
+		item.EdbCode = v.EdbCode
+		item.EdbName = v.EdbName
+		item.Frequency = v.Frequency
+		item.Unit = v.Unit
+		item.StartDate = v.StartDate
+		item.EndDate = v.EndDate
+		item.ModifyTime = v.ModifyTime
+		if chartInfoId <= 0 {
+			item.IsAxis = 1
+			item.LeadValue = 0
+			item.LeadUnit = ""
+			item.ChartEdbMappingId = 0
+			item.ChartInfoId = 0
+			item.IsOrder = false
+			item.EdbInfoType = 1
+			item.ChartStyle = ""
+			item.ChartColor = ""
+			item.ChartWidth = 0
+			item.MaxData = v.MaxValue
+			item.MinData = v.MinValue
+		} else {
+			item.IsAxis = v.IsAxis
+			item.EdbInfoType = v.EdbInfoType
+			item.LeadValue = v.LeadValue
+			item.LeadUnit = v.LeadUnit
+			item.ChartEdbMappingId = v.ChartEdbMappingId
+			item.ChartInfoId = v.ChartInfoId
+			item.ChartStyle = v.ChartStyle
+			item.ChartColor = v.ChartColor
+			item.ChartWidth = v.ChartWidth
+			item.IsOrder = v.IsOrder
+			item.MaxData = v.MaxData
+			item.MinData = v.MinData
+		}
+		item.LatestValue = v.LatestValue
+		item.LatestDate = v.LatestDate
+		item.UniqueCode = v.UniqueCode
+
+		var startDateReal string
+		var diffSeconds int64
+		if chartType == 1 {
+			if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 {
+				// 领先指标
+				var startTimeRealTemp time.Time
+				startDateParse, _ := time.Parse(utils.FormatDate, startDate)
+				switch v.LeadUnit {
+				case "天":
+					startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
+				case "月":
+					startTimeRealTemp = startDateParse.AddDate(0, -v.LeadValue, 0)
+				case "季":
+					startTimeRealTemp = startDateParse.AddDate(0, -3*v.LeadValue, 0)
+				case "周":
+					startTimeRealTemp = startDateParse.AddDate(0, 0, -7*v.LeadValue)
+				case "年":
+					startTimeRealTemp = startDateParse.AddDate(-v.LeadValue, 0, 0)
+				}
+				if startTimeRealTemp.Before(startDateParse) {
+					startDateReal = startTimeRealTemp.Format(utils.FormatDate)
+					diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
+				} else {
+					startDateReal = startDate
+					diffSeconds = 0
+				}
+			} else {
+				startDateReal = startDate
+			}
+		} else {
+			startDateReal = startDate
+		}
+		//fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
+		calendarPreYear := 0
+		if calendar == "农历" {
+			newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
+			if err != nil {
+				response.FailMsg("获取失败", "农历时间转换有误4001, Err:" + err.Error(), c)
+				//fmt.Println("time.Parse:" + err.Error())
+				return
+			}
+			calendarPreYear = newStartDateReal.Year() - 1
+			//newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
+			startDateReal = newStartDateReal.Format(utils.FormatDate)
+		}
+		dataList := make([]*edbDataModel.EdbDataList, 0)
+		//fmt.Println("chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
+		dataList, err = edbDataModel.GetEdbDataList(v.Source, v.EdbInfoId, startDateReal, endDate)
+		if err != nil {
+			response.FailMsg("获取失败", "获取图表指标信息失败4003, Err:" + err.Error(), c)
+			return
+		}
+		if diffSeconds != 0 && v.EdbInfoType == 0 {
+			dataListLen := len(dataList)
+			for i := 0; i < dataListLen; i++ {
+				dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
+			}
+		}
+
+		if chartType == 2 {
+			if calendar == "农历" {
+				if len(dataList) <= 0 {
+					result := new(edbDataModel.EdbDataResult)
+					item.DataList = result
+				} else {
+					result, err := edbDataService.AddCalculateQuarter(dataList)
+					if err != nil {
+						response.FailMsg("获取失败", "获取农历数据失败4002, Err:" + err.Error(), c)
+						return
+					}
+					if result.List[0].Year != calendarPreYear {
+						itemList := make([]*edbDataModel.EdbDataList, 0)
+						items := new(edbDataModel.EdbDataItems)
+						//items.Year = calendarPreYear
+						items.Items = itemList
+
+						newResult := new(edbDataModel.EdbDataResult)
+						newResult.List = append(newResult.List, items)
+						newResult.List = append(newResult.List, result.List...)
+						item.DataList = newResult
+					} else {
+						item.DataList = result
+					}
+				}
+
+			} else {
+				currentYear := time.Now().Year()
+				quarterDataList := make([]*edbDataModel.QuarterData, 0)
+				quarterMap := make(map[int][]*edbDataModel.EdbDataList)
+				var quarterArr []int
+				for _, v := range dataList {
+					itemDate, err := time.Parse(utils.FormatDate, v.DataTime)
+					if err != nil {
+						response.FailMsg("获取失败", "季度指标日期转换失败, Err:" + err.Error() + ";DataTime:" + v.DataTime, c)
+						return
+					}
+					year := itemDate.Year()
+					newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
+					timestamp := newItemDate.UnixNano() / 1e6
+					v.DataTimestamp = timestamp
+					if findVal, ok := quarterMap[year]; !ok {
+						quarterArr = append(quarterArr, year)
+						findVal = append(findVal, v)
+						quarterMap[year] = findVal
+					} else {
+						findVal = append(findVal, v)
+						quarterMap[year] = findVal
+					}
+				}
+				for _, v := range quarterArr {
+					itemList := quarterMap[v]
+					quarterItem := new(edbDataModel.QuarterData)
+					quarterItem.Year = v
+					quarterItem.DataList = itemList
+					quarterDataList = append(quarterDataList, quarterItem)
+				}
+				item.DataList = quarterDataList
+			}
+		} else {
+			item.DataList = dataList
+		}
+		edbList = append(edbList, item)
+	}
+
+	/*if chartInfoId > 0 && chartInfo != nil {
+		// 判断是否加入我的图库
+		{
+			var myChartCondition string
+			var myChartPars []interface{}
+			myChartCondition += ` AND a.admin_id = ? `
+			myChartPars = append(myChartPars, userInfo.AdminId)
+			myChartCondition += ` AND a.chart_info_id = ? `
+			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
+
+			myChartList, err := my_chart.GetMyChartByCondition(myChartCondition, myChartPars)
+			if err != nil && err != utils.ErrNoRow {
+				response.FailMsg("获取失败", "获取我的图表信息失败, Err:" + err.Error(), c)
+				return
+			}
+			if myChartList != nil && len(myChartList) > 0 {
+				chartInfo.IsAdd = true
+				chartInfo.MyChartId = myChartList[0].MyChartId
+				chartInfo.MyChartClassifyId = myChartList[0].MyChartClassifyId
+			}
+		}
+	}*/
+
+	resp := new(chart_info.ChartInfoDetailResp)
+	resp.ChartInfo = chartInfo
+	resp.EdbInfoList = edbList
+	response.OkData("获取成功", resp, c)
+}
+
+// RefreshChartInfo 刷新图表信息
+// @Tags 图库模块
+// @Summary  刷新图表信息
+// @Description 刷新图表信息
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param data body chartInfoModel.SaveChartInfoReq true "请求参数"
+// @Success 200 {string} string "操作成功"
+// @failure 400 {string} string "操作失败"
+// @Router /my_chart/refreshChartInfo [post]
+func RefreshChartInfo(c *gin.Context)  {
+	// 参数校验
+	var req chartInfoModel.RefreshChartInfoReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	chartInfoId := req.ChartInfoId
+	if chartInfoId == 0 {
+		response.Fail("参数有误", c)
+		return
+	}
+
+	userInfo := user.GetInfoByClaims(c)
+	ok, _, err := user.GetAdminByUserInfo(userInfo)
+	if err != nil {
+		response.FailMsg("刷新失败", "RefreshChartInfo-获取系统用户信息失败" + err.Error(), c)
+		return
+	}
+	if !ok {
+		// 普通用户刷新频率限制-每个用户/图/天/2次
+		cacheKey := utils.HZ_CHART_LIB_DETAIL + "YB_REFRESH_LIMIT_" + strconv.Itoa(chartInfoId) + "_" + strconv.Itoa(int(userInfo.UserID))
+		fmt.Println("refreshCacheKey:", cacheKey)
+		countUserRefresh, _ := global.Redis.Get(context.TODO(), cacheKey).Int()
+		if countUserRefresh >= 2 {
+			response.Ok("目前已是最新数据", c)
+			return
+		}
+		countUserRefresh += 1
+		now := time.Now()
+		today := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, time.Local)
+		sub := today.Sub(now)
+		_ = global.Redis.SetEX(context.TODO(), cacheKey, countUserRefresh, sub)
+	}
+
+	// 图表信息校验
+	chartInfo, err := chartInfoModel.GetChartInfoById(chartInfoId)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			response.Fail("图表已被删除,无需刷新", c)
+			return
+		}
+		response.FailMsg("刷新失败", "刷新失败, Err:" + err.Error(), c)
+		return
+	}
+
+	// 刷新图表
+	err = chart.RefreshChartInfo(chartInfo.ChartInfoId)
+	if err != nil {
+		{
+			errContent := fmt.Sprint("ErrMsg: 刷新图表关联指标信息失败, " + err.Error())
+			if global.CONFIG.Serve.RunMode == "release" {
+				go services.SendEmail("弘则研报小程序-release-刷新图表报错", errContent, utils.EmailSendToUsers)
+			} else {
+				global.LOG.Info(errContent)
+			}
+		}
+	}
+
+	response.OkData("刷新成功", "", c)
+}
+
+// EditChartInfo 编辑图表信息
+// @Tags 图库模块
+// @Summary  编辑图表信息
+// @Description 编辑图表信息
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param data body chartInfoModel.SaveChartInfoReq true "请求参数"
+// @Success 200 {string} string "操作成功"
+// @failure 400 {string} string "操作失败"
+// @Router /my_chart/editChartInfo [post]
+func EditChartInfo(c *gin.Context)  {
+	// 参数校验
+	var req chartInfoModel.SaveChartInfoReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数异常", c)
+		return
+	}
+
+	if req.ChartInfoId > 0 && len(req.ChartEdbInfoList) <= 0 {
+		response.Fail("参数异常", c)
+		return
+	}
+
+	// 操作权限校验
+	userInfo := user.GetInfoByClaims(c)
+	ok, adminInfo, err := user.GetAdminByUserInfo(userInfo)
+	if err != nil {
+		response.Fail("操作人信息有误", c)
+		return
+	}
+	if !ok {
+		response.Fail("非内部人员无权进行操作", c)
+		return
+	}
+
+	// 图表信息校验
+	chartItem, err := chartInfoModel.GetChartInfoById(req.ChartInfoId)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			response.Fail("图表已被删除,请刷新页面!", c)
+			return
+		}
+		response.FailMsg("操作失败", "获取图表信息失败, Err:" + err.Error(), c)
+		return
+	}
+	if chartItem.ChartType == 2 && len(req.ChartEdbInfoList) > 1 {
+		response.Fail("您选择的图表样式为季节性图表,只支持单指标画图!", c)
+		return
+	}
+	if req.Calendar == "" {
+		req.Calendar = "公历"
+	}
+
+	// 指标信息
+	var edbInfoIdArr []int
+	edbList := make([]*edbInfoModel.EdbInfo, 0)
+
+	for _, v := range req.ChartEdbInfoList {
+		edbInfo, err := edbInfoModel.GetEdbInfoById(v.EdbInfoId)
+		if err != nil {
+			if err == utils.ErrNoRow {
+				response.FailMsg("操作失败", "图表不存在,ChartInfoId:" + strconv.Itoa(v.EdbInfoId), c)
+				return
+			}
+			response.FailMsg("操作失败", "获取图表的指标信息失败,Err:" + err.Error(), c)
+			return
+		}
+		if edbInfo == nil {
+			response.FailMsg("操作失败", "指标不存在,ChartInfoId:" + strconv.Itoa(v.EdbInfoId), c)
+			return
+		}
+		edbInfoIdArr = append(edbInfoIdArr, v.EdbInfoId)
+		edbInfo.EdbNameSource = edbInfo.EdbName
+		edbList = append(edbList, edbInfo)
+	}
+	sort.Ints(edbInfoIdArr)
+	var edbInfoIdArrStr []string
+	for _, v := range edbInfoIdArr {
+		edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
+	}
+	edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
+
+	err = chart.ModifyChartInfoAndMapping(edbInfoIdStr, &req, chartItem.ChartType)
+	if err != nil {
+		response.Fail("图表保存失败, Err:" + err.Error(), c)
+		return
+	}
+
+	// 清除图表缓存
+	cacheKey := utils.HZ_CHART_LIB_DETAIL + chartItem.UniqueCode
+	_ = global.Redis.Del(context.TODO(), cacheKey)
+
+	// 新增操作日志
+	{
+		chartLog := new(chart_info_log.ChartInfoLog)
+		chartLog.ChartName = chartItem.ChartName
+		chartLog.ChartInfoId = req.ChartInfoId
+		chartLog.ChartClassifyId = chartItem.ChartClassifyId
+		chartLog.SysUserId = int(adminInfo.AdminID)
+		chartLog.SysUserRealName = adminInfo.RealName
+		chartLog.UniqueCode = chartItem.UniqueCode
+		chartLog.CreateTime = time.Now()
+		bodyBytes, _ := ioutil.ReadAll(c.Request.Body)
+		chartLog.Content = string(bodyBytes)
+		chartLog.Status = "修改配置项"
+		chartLog.Method = c.Request.URL.String()
+		go chartLog.Create()
+	}
+
+	response.OkData("操作成功", "", c)
+}

+ 576 - 0
controller/chart/my_chart.go

@@ -0,0 +1,576 @@
+package chart
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	"hongze/hongze_yb/models/response/my_chart"
+	chartInfoModel "hongze/hongze_yb/models/tables/chart_info"
+	myChartModel "hongze/hongze_yb/models/tables/my_chart"
+	"hongze/hongze_yb/models/tables/my_chart_classify"
+	myChartClassifyMappingModel "hongze/hongze_yb/models/tables/my_chart_classify_mapping"
+	myChartLogModel "hongze/hongze_yb/models/tables/my_chart_log"
+	"hongze/hongze_yb/services/chart"
+	"hongze/hongze_yb/services/user"
+	"hongze/hongze_yb/utils"
+	"io/ioutil"
+	"strconv"
+	"time"
+)
+
+// GetMyChartChassify 获取图表分类列表
+// @Tags 图库模块
+// @Summary  获取图表分类
+// @Description 获取图表分类列表
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param Keywords query string false "分类名称关键词"
+// @Success 200 {object} my_chart.MyChartClassifyListResp
+// @failure 400 {string} string "分类列表获取失败"
+// @Router /chart/getChartChassify [get]
+func GetMyChartChassify(c *gin.Context) {
+	userInfo := user.GetInfoByClaims(c)
+	publicCondition := make(map[string]interface{})
+	privateCondition := make(map[string]interface{})
+	reqKeywords := c.DefaultQuery("Keywords", "")
+	if reqKeywords != "" {
+		publicCondition["my_chart_classify_name like"] = "%" + reqKeywords + "%"
+		privateCondition["my_chart_classify_name like"] = "%" + reqKeywords + "%"
+	}
+
+	publicClassify, privateClassify, err := chart.GetUserChartClassifyListByCondition(userInfo, publicCondition, privateCondition)
+	if err != nil {
+		response.Fail("获取图表分类失败, Err:" + err.Error(), c)
+		return
+	}
+
+	respData := &my_chart.MyChartClassifyListResp {
+		PublicClassify: publicClassify,
+		PrivateClassify: privateClassify,
+	}
+	response.OkData("获取成功", respData, c)
+}
+
+// GetMyChartList 获取图表列表
+// @Tags 图库模块
+// @Summary  获取图表列表
+// @Description 获取图表列表
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param Keywords query string false "图表名称关键词"
+// @Param ClassifyId query string false "图表分类ID"
+// @Param Page query int false "当前页页码,从1开始"
+// @Param Limit query int false "每页数据量"
+// @Success 200 {object} []my_chart.MyChartList
+// @failure 400 {string} string "图库列表获取失败"
+// @Router /chart/getChartList [get]
+func GetMyChartList(c *gin.Context) {
+	userInfo := user.GetInfoByClaims(c)
+
+	// 筛选
+	var condition string
+	var pars []interface{}
+	reqKeywords := c.DefaultQuery("Keywords", "")
+	reqClassifyId := c.DefaultQuery("ClassifyId", "")
+
+	// 获取用户图表分类权限
+	publicCondition := make(map[string]interface{})
+	privateCondition := make(map[string]interface{})
+	publicClassify, privateClassify, err := chart.GetUserChartClassifyListByCondition(userInfo, publicCondition, privateCondition)
+	if err != nil {
+		response.FailMsg("获取失败", "获取图表分类信息失败, Err:" + err.Error(), c)
+		return
+	}
+
+	if reqClassifyId == "" && reqKeywords == "" {
+		// 内部员工默认取自己的第一个分类
+		classifyId := 0
+		if len(privateClassify) > 0 {
+			classifyId = privateClassify[0].MyChartClassifyId
+		} else {
+			if len(publicClassify) > 0 {
+				classifyId = publicClassify[0].MyChartClassifyId
+			}
+		}
+		condition += " AND d.my_chart_classify_id = ?"
+		pars = append(pars, classifyId)
+	} else if reqKeywords != "" {
+		// 关键词
+		condition += " AND b.chart_name LIKE ?"
+		pars = append(pars, "%" + reqKeywords + "%")
+		// 搜索自己权限内的图表
+		classifyIds := make([]int, 0)
+		for i := 0; i < len(publicClassify); i++ {
+			classifyIds = append(classifyIds, publicClassify[i].MyChartClassifyId)
+		}
+		for i := 0; i < len(privateClassify); i++ {
+			classifyIds = append(classifyIds, privateClassify[i].MyChartClassifyId)
+		}
+		condition += " AND d.my_chart_classify_id IN (?)"
+		pars = append(pars, classifyIds)
+	} else {
+		// 指定分类
+		condition += " AND d.my_chart_classify_id = ?"
+		pars = append(pars, reqClassifyId)
+	}
+
+	// 分页
+	page, _ := strconv.Atoi(c.Query("Page"))
+	limit, _ := strconv.Atoi(c.Query("Limit"))
+	if page == 0 {
+		page = 1
+	}
+	if limit == 0 {
+		limit = 10
+	}
+
+	list, err := myChartModel.GetMyChartListByCondition(condition, pars, page, limit)
+	if err != nil {
+		response.FailMsg("获取失败", "获取图库列表失败, Err:" + err.Error(), c)
+		return
+	}
+
+	response.OkData("获取成功", list, c)
+}
+
+// MoveMyChart 移动我的图表
+// @Tags 图库模块
+// @Summary  移动我的图表
+// @Description 移动我的图表
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param data body myChartModel.MoveMyChartReq true "请求参数"
+// @Success 200 {string} string "操作成功"
+// @failure 400 {string} string "操作失败"
+// @Router /my_chart/moveMyChart [post]
+func MoveMyChart(c *gin.Context) {
+	// 参数校验
+	var req myChartModel.MoveMyChartReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	if req.MyChartId == 0 {
+		response.Fail("图表ID有误", c)
+		return
+	}
+	if req.MyChartClassifyId == 0 {
+		response.Fail("图表分类ID有误", c)
+		return
+	}
+
+	// 操作权限校验
+	userInfo := user.GetInfoByClaims(c)
+	ok, adminInfo, err := user.GetAdminByUserInfo(userInfo)
+	if err != nil {
+		response.Fail("操作人信息有误", c)
+		return
+	}
+	if !ok {
+		response.Fail("非内部人员无权进行操作", c)
+		return
+	}
+	adminId := int(adminInfo.AdminID)
+	myChassify, err := my_chart_classify.GetClassifyById(req.MyChartClassifyId)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			response.FailMsg("操作失败", "图表分类信息有误, Err:" + err.Error(), c)
+			return
+		}
+		response.FailMsg("操作失败", "获取图表分类信息失败, Err:" + err.Error(), c)
+		return
+	}
+	if myChassify.AdminID != adminId {
+		response.Fail("无权移动该图表", c)
+		return
+	}
+
+	// 图表排序
+	step := float64(65536)
+	var newSort float64
+	if req.PrevMyChartId <= 0 {
+		firstMapItem, err := myChartClassifyMappingModel.GetMyChartSort(adminId, req.MyChartClassifyId, 0)
+		if err != nil {
+			response.FailMsg("操作失败", "获取图表排序失败4001, Err:" + err.Error(), c)
+			return
+		}
+		if firstMapItem.Sort <= 0 {
+			firstSort := step / float64(2)
+			err = myChartClassifyMappingModel.MyChartMove(firstSort, adminId, firstMapItem.MyChartId, firstMapItem.MyChartClassifyId)
+			if err != nil {
+				response.FailMsg("操作失败", "移动失败4001, Err:" + err.Error(), c)
+				return
+			}
+			newSort = step / float64(4)
+		} else {
+			newSort = firstMapItem.Sort / float64(2)
+		}
+	} else if req.NextMyChartId <= 0 {
+		latestMapItem, err := myChartClassifyMappingModel.GetMyChartSort(adminId, req.MyChartClassifyId, 1)
+		if err != nil {
+			response.FailMsg("操作失败", "获取图表排序失败4002, Err:" + err.Error(), c)
+			return
+		}
+		if latestMapItem.Sort <= 0 {
+			latestSort := step / float64(2)
+			err = myChartClassifyMappingModel.MyChartMove(latestSort, adminId, latestMapItem.MyChartId, latestMapItem.MyChartClassifyId)
+			if err != nil {
+				response.FailMsg("操作失败", "移动失败4002, Err:" + err.Error(), c)
+				return
+			}
+			newSort = step / float64(4)
+		} else {
+			newSort = latestMapItem.Sort + (step / float64(2)) - 1
+		}
+	} else {
+		preMapItem, err := myChartClassifyMappingModel.GetMyChartClassifyMapping(adminId, req.PrevMyChartId, req.MyChartClassifyId)
+		if err != nil {
+			response.FailMsg("操作失败", "获取上级图表关联信息失败, Err:" + err.Error(), c)
+			return
+		}
+		nextMapItem, err := myChartClassifyMappingModel.GetMyChartClassifyMapping(adminId, req.NextMyChartId, req.MyChartClassifyId)
+		if err != nil {
+			response.FailMsg("操作失败", "获取下级图表关联信息失败, Err:" + err.Error(), c)
+			return
+		}
+		newSort = (preMapItem.Sort + nextMapItem.Sort) / 2
+	}
+	if newSort >= 0 {
+		err = myChartClassifyMappingModel.MyChartMove(newSort, adminId, req.MyChartId, req.MyChartClassifyId)
+		if err != nil {
+			response.FailMsg("操作失败", "移动失败4003, Err:" + err.Error(), c)
+			return
+		}
+	}
+
+	// 新增操作日志
+	{
+		bodyBytes, _ := ioutil.ReadAll(c.Request.Body)
+		requestBodyStr := string(bodyBytes)
+
+		edbLog := new(myChartLogModel.MyChartLog)
+		edbLog.MyChartId = 0
+		edbLog.ChartInfoId = 0
+		edbLog.SysUserId = adminId
+		edbLog.SysUserRealName = adminInfo.RealName
+		edbLog.CreateTime = time.Now()
+		edbLog.Content = requestBodyStr
+		edbLog.Status = "移动我的图表"
+		edbLog.Method = c.Request.URL.String()
+		go edbLog.Create()
+	}
+
+	response.Ok("操作成功", c)
+}
+
+// MoveMyChart 移动我的图表分类
+// @Tags 图库模块
+// @Summary  移动我的图表分类
+// @Description 移动我的图表分类
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param data body myChartModel.MoveMyChartClassifyReq true "请求参数"
+// @Success 200 {string} string "操作成功"
+// @failure 400 {string} string "操作失败"
+// @Router /my_chart/moveMyChartClassify [post]
+func MoveMyChartClassify(c *gin.Context) {
+	// 参数校验
+	var req myChartModel.MoveMyChartClassifyReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	if req.MyChartClassifyId == 0 {
+		response.Fail("图表分类ID有误", c)
+		return
+	}
+
+	// 操作权限校验
+	userInfo := user.GetInfoByClaims(c)
+	ok, adminInfo, err := user.GetAdminByUserInfo(userInfo)
+	if err != nil {
+		response.Fail("操作人信息有误", c)
+		return
+	}
+	if !ok {
+		response.Fail("非内部人员无权进行操作", c)
+		return
+	}
+	adminId := int(adminInfo.AdminID)
+	myChassify, err := my_chart_classify.GetClassifyById(req.MyChartClassifyId)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			response.FailMsg("操作失败", "该图表分类信息有误, Err:", c)
+			return
+		}
+		response.FailMsg("操作失败", "获取图表信息失败" + err.Error(), c)
+		return
+	}
+	if myChassify.AdminID != adminId {
+		response.Fail("无权移动该图表", c)
+		return
+	}
+
+	// 移动分类
+	updateCol := make([]string, 0)
+	if req.PrevClassifyId > 0 {
+		prevClassify, err := my_chart_classify.GetClassifyByIdAndAdminId(adminId, req.PrevClassifyId)
+		if err != nil {
+			response.FailMsg("操作失败", "移动失败, 获取上一个兄弟节点分类信息失败, Err:" + err.Error(), c)
+			return
+		}
+
+		// 如果是移动在两个兄弟节点之间
+		if req.NextClassifyId > 0 {
+			// 下一个兄弟节点
+			nextClassify, err := my_chart_classify.GetClassifyByIdAndAdminId(adminId, req.NextClassifyId)
+			if err != nil {
+				response.FailMsg("操作失败", "移动失败, 获取下一个兄弟节点分类信息失败, Err:" + err.Error(), c)
+				return
+			}
+			// 如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == myChassify.Sort {
+				// 变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+				_ = my_chart_classify.UpdateMyChartClassifySortByClassifyId(adminId, prevClassify.MyChartClassifyId, prevClassify.Sort, updateSortStr)
+			} else {
+				// 如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextClassify.Sort-prevClassify.Sort == 1 {
+					// 变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+					_ = my_chart_classify.UpdateMyChartClassifySortByClassifyId(adminId, 0, prevClassify.Sort, updateSortStr)
+				}
+			}
+		}
+
+		myChassify.Sort = prevClassify.Sort + 1
+		myChassify.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		firstClassify, err := my_chart_classify.GetFirstClassifyByAdminId(adminId)
+		if err != nil && err != utils.ErrNoRow {
+			response.FailMsg("操作失败", "移动失败, 获取获取当前账号下的排序第一条的分类信息失败, Err:" + err.Error(), c)
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = my_chart_classify.UpdateMyChartClassifySortByClassifyId(adminId, firstClassify.MyChartClassifyId-1, 0, updateSortStr)
+		}
+
+		myChassify.Sort = 0 //那就是排在第一位
+		myChassify.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	// 更新
+	if len(updateCol) > 0 {
+		err = my_chart_classify.UpdateClassifySort(adminId, myChassify.MyChartClassifyId, myChassify.Sort, myChassify.ModifyTime)
+		if err != nil {
+			response.FailMsg("操作失败", "更新图表分类排序失败, Err:" + err.Error(), c)
+			return
+		}
+	}
+
+	//新增操作日志
+	{
+		bodyBytes, _ := ioutil.ReadAll(c.Request.Body)
+		requestBodyStr := string(bodyBytes)
+
+		edbLog := new(myChartLogModel.MyChartLog)
+		edbLog.MyChartId = 0
+		edbLog.ChartInfoId = 0
+		edbLog.SysUserId = adminId
+		edbLog.SysUserRealName = adminInfo.RealName
+		edbLog.CreateTime = time.Now()
+		edbLog.Content = requestBodyStr
+		edbLog.Status = "移动分类"
+		edbLog.Method = c.Request.URL.String()
+		go edbLog.Create()
+	}
+
+	response.Ok("操作成功", c)
+}
+
+// GetChartBeforeAndNext 获取当前图表上一张及下一张信息
+// @Tags 图库模块
+// @Summary  获取当前图表上一张及下一张信息
+// @Description 获取当前图表上一张及下一张信息
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param MyChartId query string false "我的图表ID"
+// @Param MyChartClassifyId query string false "我的图表分类ID"
+// @Success 200 {object} chartInfoModel.ChartBeforeNext
+// @failure 400 {string} string "获取失败"
+// @Router /my_chart/getChartBeforeAndNext [get]
+func GetChartBeforeAndNext(c *gin.Context) {
+	// 参数校验
+	reqMyChartId := c.DefaultQuery("MyChartId", "")
+	if reqMyChartId == "" {
+		response.Fail("参数有误:图表ID", c)
+		return
+	}
+	myChartId, _ := strconv.Atoi(reqMyChartId)
+	myChartClassifyId := c.DefaultQuery("MyChartClassifyId", "")
+	if myChartClassifyId == "" {
+		response.Fail("参数有误:图表分类ID", c)
+		return
+	}
+
+	// 当前图表
+	myChartInfo, err := myChartModel.GetMyChartById(myChartId, myChartClassifyId)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			response.Fail("图表已被删除,请刷新当前页面", c)
+			return
+		}
+		response.FailMsg("获取失败", "获取我的图表信息失败, Err:" + err.Error(), c)
+		return
+	}
+
+	// 获取当前图表所在分类的所有图表信息
+	myChartList, err := myChartClassifyMappingModel.GetMyChartSortInfoList(myChartClassifyId, 2)
+	// 找出当前图表前一张及后一张,当前图为最前一张或最后一张时需要取其他分类的图
+	var currentIndex int
+	lastIndex := len(myChartList) - 1
+	for index, item := range myChartList {
+		if myChartInfo.MyChartId == item.MyChartId {
+			currentIndex = index
+			break
+		}
+	}
+	var beforeChart, afterChart *myChartClassifyMappingModel.MyChartSortInfo
+	beforeIndex := currentIndex - 1
+	if beforeIndex >= 0 {
+		// 存在同分类上一张
+		beforeChart = myChartList[beforeIndex]
+	}
+	afterIndex := currentIndex + 1
+	if afterIndex <= lastIndex {
+		// 存在同分类下一张
+		afterChart = myChartList[afterIndex]
+	}
+	// 检索其他分类
+	if beforeIndex < 0 || afterIndex > lastIndex {
+		// 获取当前用户有权限查看的图表分类
+		userInfo := user.GetInfoByClaims(c)
+		publicCondition := make(map[string]interface{})
+		privateCondition := make(map[string]interface{})
+		publicClassify, privateClassify, err := chart.GetUserChartClassifyListByCondition(userInfo, publicCondition, privateCondition)
+		if err != nil {
+			response.FailMsg("获取失败", "获取图表分类失败, Err:" + err.Error(), c)
+			return
+		}
+		// 合并公共及私有分类
+		var classifyList []*my_chart_classify.MyChartClassify
+		for i := 0; i < len(publicClassify); i++ {
+			classifyList = append(classifyList, publicClassify[i])
+		}
+		for i := 0; i < len(privateClassify); i++ {
+			classifyList = append(classifyList, privateClassify[i])
+		}
+		// 获取当前图表分类在所有分类中的位置
+		var currentClassifyIndex int
+		for indexClassify, itemClassify := range classifyList {
+			itemClassifyId := strconv.Itoa(itemClassify.MyChartClassifyId)
+			if myChartClassifyId == itemClassifyId {
+				currentClassifyIndex = indexClassify
+				break
+			}
+		}
+		lastClassifyIndex := len(classifyList) - 1
+
+		// 若图表为分类第一张,则取上一个分类最后一张作为上一张返回
+		beforeClassifyIndex := currentClassifyIndex - 1
+		if beforeIndex < 0 && len(classifyList) > 0 && beforeClassifyIndex >= 0 {
+			beforeClassifyIdStr := strconv.Itoa(classifyList[beforeClassifyIndex].MyChartClassifyId)
+			beforeClassifyChartList, tempErr := myChartClassifyMappingModel.GetMyChartSortInfoList(beforeClassifyIdStr, 1)
+			if tempErr != nil {
+				response.FailMsg("获取失败", "获取上一个分类图表信息失败4101, Err:" + tempErr.Error(), c)
+				return
+			}
+			// 上一个分类没有图则继续向上取最后一张直到所取的分类为第一个分类,依旧无图则到顶
+			SearchPrevChart:
+				if len(beforeClassifyChartList) > 0 {
+					beforeChart = beforeClassifyChartList[0]
+				} else {
+					beforeClassifyIndex -= 1
+					if beforeClassifyIndex >= 0 {
+						beforeClassifyIdStr = strconv.Itoa(classifyList[beforeClassifyIndex].MyChartClassifyId)
+						beforeClassifyChartList, tempErr = myChartClassifyMappingModel.GetMyChartSortInfoList(beforeClassifyIdStr, 1)
+						if tempErr != nil {
+							response.FailMsg("获取失败", "获取上一个分类图表信息失败4102, Err:" + tempErr.Error(), c)
+							return
+						}
+						goto SearchPrevChart
+					}
+				}
+		}
+		// 若图表为分类最后一张,则取下一个分类第一张作为下一张返回
+		afterClassifyIndex := currentClassifyIndex + 1
+		if afterIndex > lastIndex && len(classifyList) > 0 && afterClassifyIndex <= lastClassifyIndex {
+			afterClassifyIdStr := strconv.Itoa(classifyList[afterClassifyIndex].MyChartClassifyId)
+			afterClassifyChartList, tempErr := myChartClassifyMappingModel.GetMyChartSortInfoList(afterClassifyIdStr, 2)
+			if tempErr != nil {
+				response.FailMsg("获取失败", "获取下一个分类图表信息失败4103, Err:" + tempErr.Error(), c)
+				return
+			}
+			// 下一个分类没有图则继续向下取第一张直到所取的分类为最后一个分类,依旧无图则到底
+			SearchNextChart:
+				if len(afterClassifyChartList) > 0 {
+					afterChart = afterClassifyChartList[0]
+				} else {
+					afterClassifyIndex += 1
+					if afterClassifyIndex <= lastClassifyIndex {
+						afterClassifyIdStr = strconv.Itoa(classifyList[afterClassifyIndex].MyChartClassifyId)
+						afterClassifyChartList, tempErr = myChartClassifyMappingModel.GetMyChartSortInfoList(afterClassifyIdStr, 2)
+						if tempErr != nil {
+							response.FailMsg("获取失败", "获取下一个分类图表信息失败4104, Err:" + tempErr.Error(), c)
+							return
+						}
+						goto SearchNextChart
+					}
+				}
+		}
+	}
+
+	var beforeResp, afterResp chartInfoModel.ChartSortInfo
+	if beforeChart != nil {
+		beforeResp.MyChartId = beforeChart.MyChartId
+		beforeResp.MyChartClassifyId = beforeChart.MyChartClassifyId
+		beforeResp.MyChartClassifyName = beforeChart.MyChartClassifyName
+		beforeResp.Sort = int(beforeChart.Sort)
+		beforeResp.UniqueCode = beforeChart.UniqueCode
+		beforeResp.ChartInfoId = beforeChart.ChartInfoId
+		if beforeIndex < 0 {
+			beforeResp.Switch = 1
+		}
+	}
+	if afterChart != nil {
+		afterResp.MyChartId = afterChart.MyChartId
+		afterResp.MyChartClassifyId = afterChart.MyChartClassifyId
+		afterResp.MyChartClassifyName = afterChart.MyChartClassifyName
+		afterResp.Sort = int(afterChart.Sort)
+		afterResp.UniqueCode = afterChart.UniqueCode
+		afterResp.ChartInfoId = afterChart.ChartInfoId
+		if afterIndex > lastIndex {
+			afterResp.Switch = 1
+		}
+	}
+	resp := chartInfoModel.ChartBeforeNext{
+		PrevChart: beforeResp,
+		NextChart: afterResp,
+	}
+
+	response.OkData("获取成功", resp, c)
+}

+ 18 - 7
controller/response/base.go

@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"github.com/gin-gonic/gin"
 	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/utils"
 	"strings"
 )
 
@@ -40,17 +41,17 @@ func result(code int, resultData ResultData, c *gin.Context) {
 	//记录错误日志
 	if resultData.ErrMsg != "" {
 		logSlice = append(logSlice, fmt.Sprint("ErrMsg:", resultData.ErrMsg))
+		global.LOG.Info(strings.Join(logSlice, ";"))
 	}
-	global.LOG.Info(strings.Join(logSlice, ";"))
 
-	//测试环境,数据进行加密
-	/*if global.CONFIG.Serve.RunMode == "debug" {
+	// 测试环境不加密
+	if global.CONFIG.Serve.RunMode == "debug" {
 		c.JSON(code, resultData)
 	} else {
-		responseResult := utils.DesBase64Encrypt(jsonByte)
-		c.JSON(code, responseResult)
-	}*/
-	c.JSON(code, resultData)
+		//global.LOG.Info(strings.Join(logSlice, ";"))
+		encryptResult := utils.DesBase64Encrypt(jsonByte)
+		c.JSON(code, string(encryptResult))
+	}
 	c.Abort()
 }
 
@@ -141,3 +142,13 @@ func SpecificFail(data interface{}, message string, c *gin.Context) {
 	}
 	result(200, resultData, c)
 }
+
+// FailMsg 操作失败
+func FailMsg(msg, errMsg string, c *gin.Context) {
+	resultData := ResultData{
+		Code: FAIL_CODE,
+		Msg:  msg,
+		ErrMsg: errMsg,
+	}
+	result(200, resultData, c)
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1005 - 127
docs/docs.go


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1003 - 124
docs/swagger.json


+ 716 - 57
docs/swagger.yaml

@@ -1,5 +1,63 @@
 basePath: /
 definitions:
+  activity.ActivityList:
+    properties:
+      activityId:
+        type: integer
+      activityName:
+        description: 活动名称
+        type: string
+      activityState:
+        description: 活动状态 1-本周预告 2-进行中 3-已结束
+        type: integer
+      activityTypeId:
+        description: 活动类型ID
+        type: integer
+      activityTypeName:
+        description: 活动类型名称
+        type: string
+      city:
+        description: 城市
+        type: string
+      endTime:
+        description: 活动结束时间
+        type: string
+      firstActivityTypeId:
+        description: 第一级的活动类型ID
+        type: integer
+      firstActivityTypeName:
+        description: 第一级的活动类型名称
+        type: string
+      hasPlayBack:
+        description: 是否有回放
+        type: integer
+      hasRemind:
+        description: 是否已提醒
+        type: integer
+      registerState:
+        description: 报名状态 0-取消报名 1-已报名
+        type: integer
+      speaker:
+        description: 主讲人
+        type: string
+      speakerBackgroundPic:
+        description: 主讲人背景图
+        type: string
+      speakerHeadPic:
+        description: 主讲人头像
+        type: string
+      startTime:
+        description: 活动开始时间
+        type: string
+      voiceList:
+        description: 音频列表
+        items:
+          $ref: '#/definitions/yb_activity_voice.YbActivityVoice'
+        type: array
+      weekString:
+        description: 周几
+        type: string
+    type: object
   activity.RegisterCheckInfo:
     properties:
       msg:
@@ -18,13 +76,365 @@ definitions:
       type:
         type: string
     type: object
+  admin.Admin:
+    properties:
+      adminName:
+        type: string
+      authority:
+        description: 管理权限,0:无,1:部门负责人,2:小组负责人,3:超级管理员
+        type: integer
+      createdTime:
+        description: 创建时间
+        type: string
+      departmentId:
+        description: 部门id
+        type: integer
+      departmentName:
+        description: 部门名称
+        type: string
+      email:
+        type: string
+      enabled:
+        description: 1:有效,0:禁用
+        type: integer
+      groupId:
+        description: 分组id
+        type: integer
+      groupName:
+        description: 分组名称
+        type: string
+      lastLoginTime:
+        description: 最近登陆时间
+        type: string
+      lastUpdatedPasswordTime:
+        type: string
+      lastUpdatedTime:
+        type: string
+      mobile:
+        description: 手机号
+        type: string
+      password:
+        type: string
+      position:
+        description: 职位
+        type: string
+      realName:
+        type: string
+      role:
+        description: 用户角色
+        type: string
+      roleId:
+        description: 角色id
+        type: integer
+      roleName:
+        description: 角色名称
+        type: string
+      roleType:
+        description: 角色类型:1需要录入指标,0:不需要
+        type: integer
+      roleTypeCode:
+        description: 角色编码
+        type: string
+    type: object
+  chart_edb_mapping.ChartEdbInfoMapping:
+    properties:
+      chartColor:
+        type: string
+      chartEdbMappingId:
+        type: integer
+      chartInfoId:
+        type: integer
+      chartStyle:
+        type: string
+      chartWidth:
+        type: number
+      dataList: {}
+      edbCode:
+        type: string
+      edbInfoId:
+        type: integer
+      edbInfoType:
+        type: integer
+      edbName:
+        type: string
+      edbType:
+        type: integer
+      endDate:
+        type: string
+      frequency:
+        type: string
+      isAxis:
+        type: integer
+      isOrder:
+        type: boolean
+      latestDate:
+        type: string
+      latestValue:
+        type: number
+      leadUnit:
+        type: string
+      leadValue:
+        type: integer
+      maxData:
+        type: number
+      minData:
+        type: number
+      modifyTime:
+        type: string
+      source:
+        type: integer
+      sourceName:
+        type: string
+      startDate:
+        type: string
+      uniqueCode:
+        type: string
+      unit:
+        type: string
+    type: object
+  chart_info.ChartInfoDetailResp:
+    properties:
+      chartInfo:
+        $ref: '#/definitions/chart_info.ChartInfoView'
+      edbInfoList:
+        items:
+          $ref: '#/definitions/chart_edb_mapping.ChartEdbInfoMapping'
+        type: array
+    type: object
+  chart_info.ChartInfoView:
+    properties:
+      calendar:
+        type: string
+      chartClassifyId:
+        type: integer
+      chartClassifyName:
+        type: string
+      chartImage:
+        type: string
+      chartInfoId:
+        type: integer
+      chartName:
+        type: string
+      chartType:
+        type: integer
+      createTime:
+        type: string
+      dateType:
+        type: integer
+      edbEndDate:
+        type: string
+      edbInfoIds:
+        type: string
+      endDate:
+        type: string
+      isAdd:
+        type: boolean
+      isSetName:
+        type: integer
+      leftMax:
+        type: string
+      leftMin:
+        type: string
+      modifyTime:
+        type: string
+      myChartClassifyId:
+        type: string
+      myChartId:
+        type: integer
+      rightMax:
+        type: string
+      rightMin:
+        type: string
+      seasonEndDate:
+        type: string
+      seasonStartDate:
+        type: string
+      sort:
+        type: integer
+      startDate:
+        type: string
+      sysUserId:
+        type: integer
+      sysUserRealName:
+        type: string
+      uniqueCode:
+        type: string
+    type: object
+  chart_info.ChartSaveItem:
+    properties:
+      chartColor:
+        type: string
+      chartStyle:
+        type: string
+      chartWidth:
+        type: number
+      edbInfoId:
+        type: integer
+      edbInfoType:
+        type: integer
+      isAxis:
+        type: integer
+      isOrder:
+        type: boolean
+      leadUnit:
+        type: string
+      leadValue:
+        type: integer
+      maxData:
+        type: number
+      minData:
+        type: number
+    type: object
+  chart_info.SaveChartInfoReq:
+    properties:
+      calendar:
+        type: string
+      chartEdbInfoList:
+        items:
+          $ref: '#/definitions/chart_info.ChartSaveItem'
+        type: array
+      chartInfoId:
+        type: integer
+      dateType:
+        type: integer
+      endDate:
+        type: string
+      leftMax:
+        type: string
+      leftMin:
+        type: string
+      rightMax:
+        type: string
+      rightMin:
+        type: string
+      seasonEndDate:
+        type: string
+      seasonStartDate:
+        type: string
+      startDate:
+        type: string
+    type: object
   logic.ApplyVariety:
     properties:
       name:
         type: string
+      permission_name:
+        type: string
       pic_url:
         type: string
     type: object
+  my_chart.MoveMyChartClassifyReq:
+    properties:
+      myChartClassifyId:
+        type: integer
+      nextClassifyId:
+        type: integer
+      prevClassifyId:
+        type: integer
+    type: object
+  my_chart.MoveMyChartReq:
+    properties:
+      myChartClassifyId:
+        type: integer
+      myChartId:
+        type: integer
+      nextMyChartId:
+        type: integer
+      prevMyChartId:
+        type: integer
+    type: object
+  my_chart.MyChartClassifyListResp:
+    properties:
+      private_classify:
+        items:
+          $ref: '#/definitions/my_chart_classify.MyChartClassify'
+        type: array
+      public_classify:
+        items:
+          $ref: '#/definitions/my_chart_classify.MyChartClassify'
+        type: array
+    type: object
+  my_chart.MyChartList:
+    properties:
+      calendar:
+        type: string
+      chartClassifyId:
+        type: integer
+      chartImage:
+        type: string
+      chartInfoId:
+        type: integer
+      chartName:
+        type: string
+      chartType:
+        type: integer
+      createTime:
+        type: string
+      dateType:
+        type: integer
+      edbEndDate:
+        type: string
+      edbInfoIds:
+        type: string
+      endDate:
+        type: string
+      isAdd:
+        type: boolean
+      isSetName:
+        type: integer
+      modifyTime:
+        type: string
+      myChartClassifyId:
+        type: string
+      myChartClassifyName:
+        type: string
+      myChartId:
+        type: integer
+      seasonEndDate:
+        type: string
+      seasonStartDate:
+        type: string
+      sort:
+        type: integer
+      startDate:
+        type: string
+      sysUserId:
+        type: integer
+      sysUserRealName:
+        type: string
+      uniqueCode:
+        type: string
+    type: object
+  my_chart_classify.MyChartClassify:
+    properties:
+      adminId:
+        description: 用户id
+        type: integer
+      companyPublicTime:
+        description: 用户可见公开时间
+        type: string
+      createTime:
+        type: string
+      isCompanyPublic:
+        description: 是否用户可见:0-否 1-是
+        type: integer
+      isPublic:
+        description: 是否所有人可见,0:仅自己可见,1:所有人可见
+        type: integer
+      modifyTime:
+        type: string
+      myChartClassifyId:
+        type: integer
+      myChartClassifyName:
+        description: 分类名称
+        type: string
+      publicTime:
+        description: 公开时间
+        type: string
+      sort:
+        description: 排序字段,值越小,越靠前
+        type: integer
+    type: object
   response.LoginResp:
     properties:
       authorization:
@@ -44,6 +454,8 @@ definitions:
         type: string
       real_name:
         type: string
+      source:
+        type: integer
     type: object
   user.CompanyPermission:
     properties:
@@ -56,10 +468,16 @@ definitions:
     type: object
   user.Detail:
     properties:
+      admin_info:
+        $ref: '#/definitions/admin.Admin'
       company_name:
         type: string
       email:
         type: string
+      is_inner:
+        type: integer
+      is_suspend:
+        type: integer
       mobile:
         type: string
       permission_list:
@@ -68,6 +486,10 @@ definitions:
         type: array
       real_name:
         type: string
+      seal_mobile:
+        type: string
+      seal_name:
+        type: string
       status:
         type: string
     type: object
@@ -184,6 +606,9 @@ definitions:
       reportLink:
         description: 报告链接
         type: string
+      reportName:
+        description: 报告名称
+        type: string
       singaporeTel:
         description: 新加坡拨入
         type: string
@@ -206,59 +631,6 @@ definitions:
         description: 周几
         type: string
     type: object
-  yb_activity.ActivityItem:
-    properties:
-      activityId:
-        type: integer
-      activityName:
-        description: 活动名称
-        type: string
-      activityState:
-        description: 活动状态 1-本周预告 2-进行中 3-已结束
-        type: integer
-      activityTypeId:
-        description: 活动类型ID
-        type: integer
-      activityTypeName:
-        description: 活动类型名称
-        type: string
-      city:
-        description: 城市
-        type: string
-      endTime:
-        description: 活动结束时间
-        type: string
-      firstActivityTypeId:
-        description: 第一级的活动类型ID
-        type: integer
-      firstActivityTypeName:
-        description: 第一级的活动类型名称
-        type: string
-      hasPlayBack:
-        description: 是否有回放
-        type: integer
-      hasRemind:
-        description: 是否已提醒
-        type: integer
-      registerState:
-        description: 报名状态 0-取消报名 1-已报名
-        type: integer
-      speaker:
-        description: 主讲人
-        type: string
-      speakerBackgroundPic:
-        description: 主讲人背景图
-        type: string
-      speakerHeadPic:
-        description: 主讲人头像
-        type: string
-      startTime:
-        description: 活动开始时间
-        type: string
-      weekString:
-        description: 周几
-        type: string
-    type: object
   yb_activity_voice.YbActivityVoice:
     properties:
       activityId:
@@ -388,7 +760,7 @@ paths:
     get:
       consumes:
       - application/json
-      description: 获取报告详情
+      description: 获取活动详情
       parameters:
       - description: Bearer 31a165baebe6dec616b1f8f3207b4273
         in: header
@@ -411,9 +783,39 @@ paths:
             type: string
       security:
       - ApiKeyAuth: []
-      summary: 获取报告详情
+      summary: 获取活动详情
       tags:
-      - 报告接口
+      - 活动模块
+  /activity/getActivityShareImg:
+    get:
+      consumes:
+      - application/json
+      description: 生成活动分享图片
+      parameters:
+      - description: Bearer 31a165baebe6dec616b1f8f3207b4273
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: 活动ID
+        in: query
+        name: activity_id
+        required: true
+        type: integer
+      responses:
+        "200":
+          description: 获取成功
+          schema:
+            type: string
+        "400":
+          description: 获取失败
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 生成活动分享图片
+      tags:
+      - 活动模块
   /activity/getActivityVoices:
     get:
       consumes:
@@ -469,6 +871,10 @@ paths:
         in: query
         name: activity_type
         type: integer
+      - description: 是否查看仅有权限的 0-否 1-是
+        in: query
+        name: has_permission
+        type: integer
       - description: 当前页码
         in: query
         name: page
@@ -482,7 +888,7 @@ paths:
           description: OK
           schema:
             items:
-              $ref: '#/definitions/yb_activity.ActivityItem'
+              $ref: '#/definitions/activity.ActivityList'
             type: array
         "400":
           description: 活动获取失败
@@ -527,6 +933,205 @@ paths:
       summary: 报名活动
       tags:
       - 活动模块
+  /chart/getChartChassify:
+    get:
+      consumes:
+      - application/json
+      description: 获取图表分类列表
+      parameters:
+      - description: Bearer 31a165baebe6dec616b1f8f3207b4273
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: 分类名称关键词
+        in: query
+        name: Keywords
+        type: string
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/my_chart.MyChartClassifyListResp'
+        "400":
+          description: 分类列表获取失败
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 获取图表分类
+      tags:
+      - 图库模块
+  /chart/getChartList:
+    get:
+      consumes:
+      - application/json
+      description: 获取图表列表
+      parameters:
+      - description: Bearer 31a165baebe6dec616b1f8f3207b4273
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: 图表名称关键词
+        in: query
+        name: Keywords
+        type: string
+      - description: 图表分类ID
+        in: query
+        name: ClassifyId
+        type: string
+      - description: 当前页页码,从1开始
+        in: query
+        name: Page
+        type: integer
+      - description: 每页数据量
+        in: query
+        name: Limit
+        type: integer
+      responses:
+        "200":
+          description: OK
+          schema:
+            items:
+              $ref: '#/definitions/my_chart.MyChartList'
+            type: array
+        "400":
+          description: 图库列表获取失败
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 获取图表列表
+      tags:
+      - 图库模块
+  /my_chart/editChartInfo:
+    post:
+      consumes:
+      - application/json
+      description: 编辑图表信息
+      parameters:
+      - description: Bearer 31a165baebe6dec616b1f8f3207b4273
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: 请求参数
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/chart_info.SaveChartInfoReq'
+      responses:
+        "200":
+          description: 操作成功
+          schema:
+            type: string
+        "400":
+          description: 操作失败
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 编辑图表信息
+      tags:
+      - 图库模块
+  /my_chart/getChartInfoDetail:
+    get:
+      consumes:
+      - application/json
+      description: 获取图表详情
+      parameters:
+      - description: Bearer 31a165baebe6dec616b1f8f3207b4273
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: 时间段:1-00年至今; 2-10年至今; 3-15年至今; 4-21年至今; 5-指定区间; 6-指定年月至今; 7-18年至今;
+          8-19年至今; 9-20年至今
+        in: query
+        name: DateType
+        type: string
+      - description: 图表分类ID
+        in: query
+        name: ClassifyId
+        type: string
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/chart_info.ChartInfoDetailResp'
+        "400":
+          description: 图表详情获取失败
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 获取图表详情
+      tags:
+      - 图库模块
+  /my_chart/moveMyChart:
+    post:
+      consumes:
+      - application/json
+      description: 移动我的图表
+      parameters:
+      - description: Bearer 31a165baebe6dec616b1f8f3207b4273
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: 请求参数
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/my_chart.MoveMyChartReq'
+      responses:
+        "200":
+          description: 操作成功
+          schema:
+            type: string
+        "400":
+          description: 操作失败
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 移动我的图表
+      tags:
+      - 图库模块
+  /my_chart/moveMyChartClassify:
+    post:
+      consumes:
+      - application/json
+      description: 移动我的图表分类
+      parameters:
+      - description: Bearer 31a165baebe6dec616b1f8f3207b4273
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: 请求参数
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/my_chart.MoveMyChartClassifyReq'
+      responses:
+        "200":
+          description: 操作成功
+          schema:
+            type: string
+        "400":
+          description: 操作失败
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 移动我的图表分类
+      tags:
+      - 图库模块
   /public/get_apply_variety_list:
     get:
       consumes:
@@ -583,6 +1188,36 @@ paths:
       summary: 文件上传
       tags:
       - 公共模块
+  /report/research_report:
+    get:
+      consumes:
+      - application/json
+      description: 获取报告详情
+      parameters:
+      - description: Bearer 31a165baebe6dec616b1f8f3207b4273
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: 活动ID
+        in: query
+        name: research_report_id
+        required: true
+        type: integer
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/yb_activity.ActivityDetail'
+        "400":
+          description: 获取失败
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 获取报告详情
+      tags:
+      - 报告接口
   /user/apply:
     post:
       consumes:
@@ -779,6 +1414,30 @@ paths:
       summary: 用户登录
       tags:
       - 用户模块
+  /wechat/getEncryptInfo:
+    post:
+      consumes:
+      - application/json
+      description: 消息解密
+      parameters:
+      - description: 加密数据
+        in: query
+        name: encryptedData
+        required: true
+        type: string
+      - description: 加密算法初始向量
+        in: query
+        name: iv
+        required: true
+        type: string
+      responses:
+        "200":
+          description: 获取成功
+          schema:
+            type: string
+      summary: 消息解密
+      tags:
+      - 微信相关接口
   /wechat/login:
     get:
       consumes:

+ 4 - 5
go.mod

@@ -3,36 +3,35 @@ module hongze/hongze_yb
 go 1.15
 
 require (
-	github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
 	github.com/aliyun/aliyun-oss-go-sdk v1.9.8
+	github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220111164937-1b144fa7b40f // indirect
 	github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
 	github.com/fsnotify/fsnotify v1.5.1
 	github.com/gin-gonic/gin v1.7.4
 	github.com/go-playground/validator/v10 v10.9.0 // indirect
 	github.com/go-redis/redis/v8 v8.11.4
-	github.com/go-sql-driver/mysql v1.6.0 // indirect
 	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
-	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/jonboulle/clockwork v0.2.2 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
 	github.com/lestrrat-go/strftime v1.0.5 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19
 	github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
 	github.com/satori/go.uuid v1.2.0 // indirect
+	github.com/shopspring/decimal v1.2.0 // indirect
 	github.com/silenceper/wechat/v2 v2.0.9
 	github.com/spf13/viper v1.9.0
 	github.com/swaggo/gin-swagger v1.3.3
 	github.com/swaggo/swag v1.7.4
+	github.com/yidane/formula v0.0.0-20210902154546-0782e1736717
 	golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
 	golang.org/x/image v0.0.0-20190802002840-cff245a6509b
 	golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 // indirect
 	golang.org/x/text v0.3.7 // indirect
-	google.golang.org/protobuf v1.27.1 // indirect
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gorm.io/driver/mysql v1.1.3
 	gorm.io/gorm v1.22.2
 )

+ 7 - 4
init_serve/router.go

@@ -31,15 +31,18 @@ func InitRouter() (r *gin.Engine) {
 		})
 	})
 	routers.InitTest(r)
-	//微信相关路由
+	// 微信相关路由
 	routers.InitWechat(r)
 	// 活动相关路由
 	routers.InitActivity(r)
-	//用户接口
+	// 用户接口
 	routers.InitUser(r)
-	//公共接口
+	// 公共接口
 	routers.InitPublic(r)
-	//报告接口
+	// 报告接口
 	routers.InitResearchReport(r)
+	// 图库相关路由
+	routers.InitChart(r)
+
 	return
 }

+ 26 - 9
logic/user/user.go

@@ -107,6 +107,8 @@ type Detail struct {
 	SellerName     string              `json:"seal_name" description:"所属销售名称"`
 	SellerMobile   string              `json:"seal_mobile" description:"所属销售手机号"`
 	PermissionList []CompanyPermission `json:"permission_list" description:"权限列表"`
+	IsInner		   int				   `json:"is_inner" description:"是否为内部员工"`
+	AdminInfo      *admin2.Admin	   `json:"admin_info" description:"系统管理员信息"`
 }
 
 // GetUserInfo 获取用户我的页面详情数据
@@ -126,7 +128,7 @@ func GetUserInfo(userInfo user.UserInfo) (userDetail Detail, err error, errMsg s
 				errMsg = "找不到该客户"
 				return
 			}
-			errMsg = "系统异常"
+			errMsg = "系统异常4001"
 			return
 		}
 		companyName = companyInfo.CompanyName
@@ -191,18 +193,32 @@ func GetUserInfo(userInfo user.UserInfo) (userDetail Detail, err error, errMsg s
 		}
 
 	}
-	//if Note
+	// 是否为内部员工
+	isInner := 0
+	ok, adminInfo, err := user.GetAdminByUserInfo(userInfo)
+	if err != nil {
+		err = errors.New("获取用户系统管理员信息失败")
+		errMsg = "系统异常4002"
+		return
+	}
+	if ok {
+		isInner = 1
+	}
+
 	userDetail = Detail{
-		CompanyName:    companyName, //客户名称(公司名称)
-		Status:         status,      //产品状态
-		IsSuspend:      isSuspend,   //是否启用
+		CompanyName:    companyName, 		//客户名称(公司名称)
+		Status:         status,      		//产品状态
+		IsSuspend:      isSuspend,   		//是否启用
 		RealName:       userInfo.RealName,
 		Mobile:         userInfo.Mobile,
 		Email:          userInfo.Email,
 		SellerName:     sellerName,
 		SellerMobile:   sellerMobile,
-		PermissionList: list, //权限列表
+		PermissionList: list,				//权限列表
+		IsInner: 		isInner,			// 是否为内部员工
+		AdminInfo: 		adminInfo,			// 系统管理员信息
 	}
+
 	return
 }
 
@@ -239,7 +255,7 @@ func Apply(userId int, companyId int64, mobile, email string, applyInfo userReq.
 
 	tmpmYbApplyRecord, err := yb_apply_record.GetLastNotOpRecordByUserId(userId)
 	if err == nil {
-		ybApplyRecord = tmpmYbApplyRecord
+		ybApplyRecord = tmpmYbApplyRecord	// 申请来源每一种只存在一条数据
 		return
 	} else {
 		if err != utils.ErrNoRow {
@@ -300,6 +316,7 @@ func Apply(userId int, companyId int64, mobile, email string, applyInfo userReq.
 		CompanyIDPay:    int(companyId),
 		CompanyNamePay:  companyName,
 		CreateTime:      time.Now(),
+		Source: 		 applyInfo.Source,
 	}
 	err = ybApplyRecord.Create()
 	if err != nil {
@@ -322,10 +339,10 @@ func Apply(userId int, companyId int64, mobile, email string, applyInfo userReq.
 	return
 }
 
-// GetUserTabBar 获取最近的一套申请记录
+// GetUserTabBar 获取用户小程序TabBar
 func GetUserTabBar(userInfo user.UserInfo) (list []string, err error) {
 	//buy,report,chart,activity,user
-	list = []string{"activity", "user"}
+	list = []string{"activity", "user", "chart"}
 
 	//companyProduct, err := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)
 	//if err != nil {

+ 1 - 0
middleware/check_activity_auth.go

@@ -0,0 +1 @@
+package middleware

+ 41 - 0
middleware/check_chart_auth.go

@@ -0,0 +1,41 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	"hongze/hongze_yb/services/company"
+	"hongze/hongze_yb/services/user"
+)
+
+// CheckChartAuth 图库权限验证
+func CheckChartAuth() gin.HandlerFunc {
+
+	return func(c *gin.Context) {
+
+		userInfo := user.GetInfoByClaims(c)
+
+		// 是否为内部员工
+		ok, _, err := user.GetAdminByUserInfo(userInfo)
+		if err != nil {
+			response.FailMsg("图库权限验证失败", "获取系统用户信息失败" + err.Error(), c)
+			c.Abort()
+			return
+		}
+
+		if !ok {
+			checkOk, permissionCheckInfo, tempErr := company.CheckUserChartPermission(userInfo.CompanyID, int(userInfo.UserID))
+			if tempErr != nil {
+				response.FailMsg("图库权限验证失败", "图库权限验证失败" + tempErr.Error(), c)
+				c.Abort()
+				return
+			}
+			if !checkOk {
+				response.AuthError(permissionCheckInfo, "暂无权限", c)
+				c.Abort()
+				return
+			}
+		}
+
+		c.Next()
+	}
+}

+ 1 - 0
models/request/user/user.go

@@ -13,4 +13,5 @@ type ApplyReq struct {
 	CompanyName     string `description:"公司名称" json:"company_name"`
 	RealName        string `description:"用户真实姓名" json:"real_name"`
 	Permission      string `description:"用户关注品种,多个品种之间用英文,隔开" json:"permission"`
+	Source			int	   `description:"申请来源:1-我的 2-活动 3-图库"`
 }

+ 11 - 0
models/response/chart_info/chart_info.go

@@ -0,0 +1,11 @@
+package chart_info
+
+import (
+	"hongze/hongze_yb/models/tables/chart_edb_mapping"
+	"hongze/hongze_yb/models/tables/chart_info"
+)
+
+type ChartInfoDetailResp struct {
+	ChartInfo   *chart_info.ChartInfoView
+	EdbInfoList []*chart_edb_mapping.ChartEdbInfoMapping
+}

+ 8 - 0
models/response/my_chart/my_chart.go

@@ -0,0 +1,8 @@
+package my_chart
+
+import "hongze/hongze_yb/models/tables/my_chart_classify"
+
+type MyChartClassifyListResp struct {
+	PublicClassify	[]*my_chart_classify.MyChartClassify	`description:"公共图库" json:"public_classify"`
+	PrivateClassify	[]*my_chart_classify.MyChartClassify	`description:"我的图库" json:"private_classify"`
+}

+ 6 - 0
models/tables/admin/query.go

@@ -9,3 +9,9 @@ func GetByAdminId(adminId int) (item *Admin, err error) {
 	err = global.DEFAULT_MYSQL.Where("admin_id =  ? ", adminId).First(&item).Error
 	return
 }
+
+// GetAdminByMobile 通过手机号获取系统用户信息
+func GetAdminByMobile(mobile string) (item *Admin, err error) {
+	err = global.DEFAULT_MYSQL.Model(Admin{}).Where("mobile = ?", mobile).First(&item).Error
+	return
+}

+ 50 - 0
models/tables/chart_classify/chart_classify.go

@@ -0,0 +1,50 @@
+package chart_classify
+
+import "time"
+
+// ChartClassify 图表分类表
+type ChartClassify struct {
+	ChartClassifyID   int       `gorm:"primaryKey;column:chart_classify_id;type:int(11);not null" json:"-"`
+	ChartClassifyName string    `gorm:"column:chart_classify_name;type:varchar(255);not null;default:''" json:"chartClassifyName"` // 分类名称
+	ParentID          int       `gorm:"column:parent_id;type:int(11);not null;default:0" json:"parentId"`                          // 父级id
+	HasData           int8      `gorm:"column:has_data;type:tinyint(4);default:0" json:"hasData"`                                  // 是否存在指标数据:1有,2:无
+	CreateTime        time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`                                        // 创建时间
+	ModifyTime        time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`                                        // 修改时间
+	SysUserID         int       `gorm:"column:sys_user_id;type:int(11)" json:"sysUserId"`                                          // 创建人id
+	SysUserRealName   string    `gorm:"column:sys_user_real_name;type:varchar(50)" json:"sysUserRealName"`                         // 创建人姓名
+	Level             int       `gorm:"column:level;type:int(11);default:0" json:"level"`                                          // 层级
+	UniqueCode        string    `gorm:"unique;column:unique_code;type:varchar(50);default:''" json:"uniqueCode"`
+	Sort              uint32    `gorm:"column:sort;type:int(9) unsigned;default:10" json:"sort"` // 排序字段,越小越靠前,默认值:10
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *ChartClassify) TableName() string {
+	return "chart_classify"
+}
+
+// ChartClassifyColumns get sql column name.获取数据库列名
+var ChartClassifyColumns = struct {
+	ChartClassifyID   string
+	ChartClassifyName string
+	ParentID          string
+	HasData           string
+	CreateTime        string
+	ModifyTime        string
+	SysUserID         string
+	SysUserRealName   string
+	Level             string
+	UniqueCode        string
+	Sort              string
+}{
+	ChartClassifyID:   "chart_classify_id",
+	ChartClassifyName: "chart_classify_name",
+	ParentID:          "parent_id",
+	HasData:           "has_data",
+	CreateTime:        "create_time",
+	ModifyTime:        "modify_time",
+	SysUserID:         "sys_user_id",
+	SysUserRealName:   "sys_user_real_name",
+	Level:             "level",
+	UniqueCode:        "unique_code",
+	Sort:              "sort",
+}

+ 7 - 0
models/tables/chart_classify/query.go

@@ -0,0 +1,7 @@
+package chart_classify
+
+type ChartClassifyView struct {
+	ChartClassifyId   int       `orm:"column(chart_classify_id);pk"`
+	ChartClassifyName string    `description:"分类名称"`
+	ParentId          int       `description:"父级id"`
+}

+ 65 - 0
models/tables/chart_edb_mapping/chart_edb_mapping.go

@@ -0,0 +1,65 @@
+package chart_edb_mapping
+
+import "time"
+
+// ChartEdbMapping 图表指标映射表
+type ChartEdbMapping struct {
+	ChartEdbMappingId int       `gorm:"primaryKey;column:chart_edb_mapping_id;type:int(11);not null" json:"chartEdbMappingId"`
+	ChartInfoId       int       `gorm:"uniqueIndex:idx_chart_edb;column:chart_info_id;type:int(11);default:0" json:"chartInfoId"` // 图表id
+	EdbInfoId         int       `gorm:"uniqueIndex:idx_chart_edb;column:edb_info_id;type:int(11);default:0" json:"edbInfoId"`     // 指标id
+	CreateTime        time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`                                       // 创建时间
+	ModifyTime        time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`                                       // 修改时间
+	UniqueCode        string    `gorm:"unique;column:unique_code;type:varchar(50);default:''" json:"uniqueCode"`                  // 唯一编码
+	MaxData           float64   `gorm:"column:max_data;type:double;default:0" json:"maxData"`                                     // 上限
+	MinData           float64   `gorm:"column:min_data;type:double;default:0" json:"minData"`                                     // 下限
+	IsOrder           int       `gorm:"column:is_order;type:tinyint(4);default:1" json:"isOrder"`                                 // 1:正序,0:逆序
+	IsAxis            int       `gorm:"column:is_axis;type:tinyint(4);default:1" json:"isAxis"`                                   // 1:左轴,0:右轴
+	EdbInfoType       int       `gorm:"column:edb_info_type;type:tinyint(4);default:1" json:"edbInfoType"`                        // 1:标准指标,0:领先指标
+	LeadValue         int       `gorm:"column:lead_value;type:int(11);default:0" json:"leadValue"`                                // 领先值
+	LeadUnit          string    `gorm:"column:lead_unit;type:varchar(10);default:''" json:"leadUnit"`                             // 领先单位
+	ChartStyle        string    `gorm:"column:chart_style;type:varchar(20);default:''" json:"chartStyle"`                         // 图表类型
+	ChartColor        string    `gorm:"column:chart_color;type:varchar(20);default:''" json:"chartColor"`                         // 颜色
+	ChartWidth        float64   `gorm:"column:chart_width;type:double;default:0" json:"chartWidth"`                               // 线条大小
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *ChartEdbMapping) TableName() string {
+	return "chart_edb_mapping"
+}
+
+// ChartEdbMappingColumns get sql column name.获取数据库列名
+var ChartEdbMappingColumns = struct {
+	ChartEdbMappingID string
+	ChartInfoID       string
+	EdbInfoID         string
+	CreateTime        string
+	ModifyTime        string
+	UniqueCode        string
+	MaxData           string
+	MinData           string
+	IsOrder           string
+	IsAxis            string
+	EdbInfoType       string
+	LeadValue         string
+	LeadUnit          string
+	ChartStyle        string
+	ChartColor        string
+	ChartWidth        string
+}{
+	ChartEdbMappingID: "chart_edb_mapping_id",
+	ChartInfoID:       "chart_info_id",
+	EdbInfoID:         "edb_info_id",
+	CreateTime:        "create_time",
+	ModifyTime:        "modify_time",
+	UniqueCode:        "unique_code",
+	MaxData:           "max_data",
+	MinData:           "min_data",
+	IsOrder:           "is_order",
+	IsAxis:            "is_axis",
+	EdbInfoType:       "edb_info_type",
+	LeadValue:         "lead_value",
+	LeadUnit:          "lead_unit",
+	ChartStyle:        "chart_style",
+	ChartColor:        "chart_color",
+	ChartWidth:        "chart_width",
+}

+ 54 - 0
models/tables/chart_edb_mapping/query.go

@@ -0,0 +1,54 @@
+package chart_edb_mapping
+
+import "hongze/hongze_yb/global"
+
+type ChartEdbInfoMapping struct {
+	EdbInfoId         int     `description:"指标id"`
+	SourceName        string  `description:"来源名称"`
+	Source            int     `description:"来源id"`
+	EdbCode           string  `description:"指标编码"`
+	EdbName           string  `description:"指标名称"`
+	EdbType           int     `description:"指标类型:1:基础指标,2:计算指标"`
+	Frequency         string  `description:"频率"`
+	Unit              string  `description:"单位"`
+	StartDate         string  `description:"起始日期"`
+	EndDate           string  `description:"终止日期"`
+	ModifyTime        string  `description:"指标最后更新时间"`
+	ChartEdbMappingId int     `description:"图表指标id"`
+	ChartInfoId       int     `description:"图表id"`
+	MaxData           float64 `description:"上限"`
+	MinData           float64 `description:"下限"`
+	IsOrder           bool    `description:"true:正序,false:逆序"`
+	IsAxis            int     `description:"1:左轴,0:右轴"`
+	EdbInfoType       int     `description:"1:标准指标,0:领先指标"`
+	LeadValue         int     `description:"领先值"`
+	LeadUnit          string  `description:"领先单位"`
+	ChartStyle        string  `description:"图表类型"`
+	ChartColor        string  `description:"颜色"`
+	ChartWidth        float64 `description:"线条大小"`
+	LatestDate        string  `description:"数据最新日期"`
+	LatestValue       float64 `description:"数据最新值"`
+	UniqueCode        string  `description:"指标唯一编码"`
+	MinValue          float64 `json:"-" description:"最小值"`
+	MaxValue          float64 `json:"-" description:"最大值"`
+	DataList          interface{}
+}
+
+// GetMappingListByChartInfoId 根据图表ID获取指标映射列表
+func GetMappingListByChartInfoId(chartInfoId int) (list []*ChartEdbInfoMapping, err error) {
+	sql := ` SELECT a.*,b.source_name,b.source,b.edb_code,b.edb_name,b.frequency,b.unit,b.start_date,b.end_date,b.modify_time,b.latest_date,b.latest_value,b.unique_code
+             FROM chart_edb_mapping AS a
+			 INNER JOIN edb_info AS b ON a.edb_info_id=b.edb_info_id
+			 WHERE chart_info_id=? 
+             ORDER BY chart_edb_mapping_id ASC `
+	err = global.MYSQL["data"].Raw(sql, chartInfoId).Scan(&list).Error
+
+	return
+}
+
+// GetMappingListByEdbInfoId 根据指标ID获取指标映射列表
+func GetMappingListByEdbInfoId(edbInfoStr string) (list []*ChartEdbInfoMapping, err error) {
+	sql := ` SELECT * FROM edb_info WHERE edb_info_id IN(` + edbInfoStr + `) ORDER BY FIELD(edb_info_id,` + edbInfoStr + `) `
+	err = global.MYSQL["data"].Raw(sql).Scan(&list).Error
+	return
+}

+ 91 - 0
models/tables/chart_info/chart_info.go

@@ -0,0 +1,91 @@
+package chart_info
+
+import (
+	"time"
+)
+
+// ChartInfo 图表信息表
+type ChartInfo struct {
+	ChartInfoId     int       `gorm:"primaryKey;column:chart_info_id;type:int(11);not null" json:"chartInfoId"`
+	ChartName       string    `gorm:"uniqueIndex:idx_chart_name;column:chart_name;type:varchar(500);default:''" json:"chartName"`        // 图表名称
+	UniqueCode      string    `gorm:"unique;column:unique_code;type:varchar(50);default:''" json:"uniqueCode"`                           // 唯一编码
+	ChartClassifyId int       `gorm:"uniqueIndex:idx_chart_name;column:chart_classify_id;type:int(11);default:0" json:"chartClassifyId"` // 分类id
+	SysUserId       int       `gorm:"column:sys_user_id;type:int(11);default:0" json:"sysUserId"`                                        // 创建人id
+	SysUserRealName string    `gorm:"column:sys_user_real_name;type:varchar(100);default:''" json:"sysUserRealName"`                     // 创建人姓名
+	CreateTime      time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`
+	ModifyTime      time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`
+	DateType        int       `gorm:"column:date_type;type:int(11);default:0" json:"dateType"`                     // 日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间,6:起始日期至今
+	StartDate       string    `gorm:"column:start_date;type:varchar(30);default:''" json:"startDate"`              // 自定义开始日期
+	EndDate         string    `gorm:"column:end_date;type:varchar(30);default:''" json:"endDate"`                  // 自定义结束日期
+	IsSetName       int       `gorm:"column:is_set_name;type:tinyint(4);default:0" json:"isSetName"`               // 0:未修改,1:已修改
+	EdbInfoIDs      string    `gorm:"column:edb_info_ids;type:varchar(100);default:''" json:"edbInfoIds"`          // 指标id
+	ChartType       int       `gorm:"column:chart_type;type:tinyint(4);default:1" json:"chartType"`                // 生成样式:1:曲线图,2:季节性图
+	Calendar        string    `gorm:"column:calendar;type:varchar(10);default:''" json:"calendar"`                 // 公历/农历
+	SeasonStartDate string    `gorm:"column:season_start_date;type:varchar(30);default:''" json:"seasonStartDate"` // 季节开始日期
+	SeasonEndDate   string    `gorm:"column:season_end_date;type:varchar(30);default:''" json:"seasonEndDate"`     // 季节结束日期
+	ChartImage      string    `gorm:"column:chart_image;type:varchar(255);default:''" json:"chartImage"`           // 图表图片
+	Sort            int       `gorm:"column:sort;type:int(9);default:0" json:"sort"`                               // 排序字段,数字越小越排前面
+	EdbEndDate      time.Time `gorm:"column:edb_end_date;type:date" json:"edbEndDate"`                             // 指标最后更新日期
+	LeftMin         string    `gorm:"column:left_min;type:varchar(30);default:''" json:"leftMin"`                  // 图表左侧最小值
+	LeftMax         string    `gorm:"column:left_max;type:varchar(30);default:''" json:"leftMax"`                  // 图表左侧最大值
+	RightMin        string    `gorm:"column:right_min;type:varchar(30);default:''" json:"rightMin"`                // 图表右侧最小值
+	RightMax        string    `gorm:"column:right_max;type:varchar(30);default:''" json:"rightMax"`                // 图表右侧最大值
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *ChartInfo) TableName() string {
+	return "chart_info"
+}
+
+// ChartInfoColumns get sql column name.获取数据库列名
+var ChartInfoColumns = struct {
+	ChartInfoID     string
+	ChartName       string
+	UniqueCode      string
+	ChartClassifyID string
+	SysUserID       string
+	SysUserRealName string
+	CreateTime      string
+	ModifyTime      string
+	DateType        string
+	StartDate       string
+	EndDate         string
+	IsSetName       string
+	EdbInfoIDs      string
+	ChartType       string
+	Calendar        string
+	SeasonStartDate string
+	SeasonEndDate   string
+	ChartImage      string
+	Sort            string
+	EdbEndDate      string
+	LeftMin         string
+	LeftMax         string
+	RightMin        string
+	RightMax        string
+}{
+	ChartInfoID:     "chart_info_id",
+	ChartName:       "chart_name",
+	UniqueCode:      "unique_code",
+	ChartClassifyID: "chart_classify_id",
+	SysUserID:       "sys_user_id",
+	SysUserRealName: "sys_user_real_name",
+	CreateTime:      "create_time",
+	ModifyTime:      "modify_time",
+	DateType:        "date_type",
+	StartDate:       "start_date",
+	EndDate:         "end_date",
+	IsSetName:       "is_set_name",
+	EdbInfoIDs:      "edb_info_ids",
+	ChartType:       "chart_type",
+	Calendar:        "calendar",
+	SeasonStartDate: "season_start_date",
+	SeasonEndDate:   "season_end_date",
+	ChartImage:      "chart_image",
+	Sort:            "sort",
+	EdbEndDate:      "edb_end_date",
+	LeftMin:         "left_min",
+	LeftMax:         "left_max",
+	RightMin:        "right_min",
+	RightMax:        "right_max",
+}

+ 101 - 0
models/tables/chart_info/query.go

@@ -0,0 +1,101 @@
+package chart_info
+
+import (
+	"hongze/hongze_yb/global"
+	"time"
+)
+
+type ChartInfoView struct {
+	ChartInfoId       int    `orm:"column(chart_info_id);pk"`
+	ChartName         string `description:"来源名称"`
+	ChartClassifyId   int    `description:"图表分类id"`
+	ChartClassifyName string `description:"图表名称"`
+	SysUserId         int
+	SysUserRealName   string
+	UniqueCode        string `description:"图表唯一编码"`
+	CreateTime        time.Time
+	ModifyTime        time.Time
+	DateType          int    `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate         string `description:"自定义开始日期"`
+	EndDate           string `description:"自定义结束日期"`
+	IsSetName         int    `description:"设置名称"`
+	EdbInfoIds        string `description:"指标id"`
+	ChartType         int    `description:"生成样式:1:曲线图,2:季节性图"`
+	Calendar          string `description:"公历/农历"`
+	SeasonStartDate   string `description:"季节性图开始日期"`
+	SeasonEndDate     string `description:"季节性图开始日期"`
+	ChartImage        string `description:"图表图片"`
+	Sort              int    `description:"排序字段,数字越小越排前面"`
+	IsAdd             bool   `description:"true:已加入我的图库,false:未加入我的图库"`
+	MyChartId         int
+	MyChartClassifyId string `description:"我的图表分类,多个用逗号隔开"`
+	EdbEndDate        string `description:"指标最新更新日期"`
+	LeftMin           string `description:"图表左侧最小值"`
+	LeftMax           string `description:"图表左侧最大值"`
+	RightMin          string `description:"图表右侧最小值"`
+	RightMax          string `description:"图表右侧最大值"`
+	//ChartClassify     []*chart_classify.ChartClassifyView
+}
+
+type SaveChartInfoReq struct {
+	ChartEdbInfoList []*ChartSaveItem `description:"指标及配置信息"`
+	ChartInfoId      int              `description:"图表id,新增时传0"`
+	DateType         int              `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间,6:起始日期至今"`
+	StartDate        string           `description:"自定义开始日期"`
+	EndDate          string           `description:"自定义结束日期"`
+	Calendar         string           `description:"公历/农历"`
+	SeasonStartDate  string           `description:"季节性图开始日期"`
+	SeasonEndDate    string           `description:"季节性图开始日期"`
+	LeftMin          string           `description:"图表左侧最小值"`
+	LeftMax          string           `description:"图表左侧最大值"`
+	RightMin         string           `description:"图表右侧最小值"`
+	RightMax         string           `description:"图表右侧最大值"`
+}
+
+type ChartSaveItem struct {
+	EdbInfoId   int     `description:"指标id"`
+	MaxData     float64 `description:"上限"`
+	MinData     float64 `description:"下限"`
+	IsOrder     bool    `description:"true:正序,false:逆序"`
+	IsAxis      int     `description:"1:左轴,0:右轴"`
+	EdbInfoType int     `description:"1:标准指标,0:领先指标"`
+	LeadValue   int     `description:"领先值"`
+	LeadUnit    string  `description:"领先单位"`
+	ChartStyle  string  `description:"图表类型"`
+	ChartColor  string  `description:"颜色"`
+	ChartWidth  float64 `description:"线条大小"`
+}
+
+type ChartSortInfo struct {
+	ChartInfoId			int		`description:"图表ID"`
+	MyChartId			int		`description:"我的图表ID"`
+	MyChartClassifyId	int		`description:"我的图表分类ID"`
+	MyChartClassifyName	string	`description:"我的图表分类名称"`
+	UniqueCode			string	`description:"图表唯一编码"`
+	Sort				int		`description:"排序"`
+	Switch				int		`description:"是否切换 0-未切换 1-已切换"`
+	//SwitchTips			string	`description:"切换分类提示信息"`
+}
+
+type ChartBeforeNext struct {
+	PrevChart	ChartSortInfo
+	NextChart	ChartSortInfo
+}
+
+type RefreshChartInfoReq struct {
+	ChartInfoId	int
+}
+
+// GetChartInfoViewById 通过Id获取图表展示信息
+func GetChartInfoViewById(chartInfoId int) (item *ChartInfoView, err error) {
+	sql := `SELECT * FROM chart_info WHERE chart_info_id = ? `
+	err = global.MYSQL["data"].Raw(sql, chartInfoId).First(&item).Error
+	//err = global.MYSQL["data"].Model(ChartInfo{}).Where("chart_info_id = ?", chartInfoId).First(&item).Error
+	return
+}
+
+// GetChartInfoViewById 通过ID获取图表数据库信息
+func GetChartInfoById(chartInfoId int) (item *ChartInfo, err error) {
+	err = global.MYSQL["data"].Model(ChartInfo{}).Where("chart_info_id = ?", chartInfoId).First(&item).Error
+	return
+}

+ 50 - 0
models/tables/chart_info_log/chart_info_log.go

@@ -0,0 +1,50 @@
+package chart_info_log
+
+import "time"
+
+// ChartInfoLog 图表操作日志表
+type ChartInfoLog struct {
+	ChartInfoLogId  int       `gorm:"primaryKey;column:chart_info_log_id;type:int(11);not null" json:"-"`
+	ChartInfoId     int       `gorm:"index:idx_chart_info_id;column:chart_info_id;type:int(11);default:0" json:"chartInfoId"`
+	ChartName       string    `gorm:"column:chart_name;type:varchar(500);default:''" json:"chartName"`               // 图表名称
+	UniqueCode      string    `gorm:"column:unique_code;type:varchar(50);default:''" json:"uniqueCode"`              // 唯一编码
+	ChartClassifyId int       `gorm:"column:chart_classify_id;type:int(11);default:0" json:"chartClassifyId"`        // 分类id
+	SysUserId       int       `gorm:"column:sys_user_id;type:int(11);default:0" json:"sysUserId"`                    // 创建人id
+	SysUserRealName string    `gorm:"column:sys_user_real_name;type:varchar(100);default:''" json:"sysUserRealName"` // 创建人姓名
+	CreateTime      time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`
+	Content         string    `gorm:"column:content;type:text" json:"content"`
+	Status          string    `gorm:"column:status;type:varchar(50);default:''" json:"status"`
+	Method          string    `gorm:"column:method;type:varchar(255);default:''" json:"method"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *ChartInfoLog) TableName() string {
+	return "chart_info_log"
+}
+
+// ChartInfoLogColumns get sql column name.获取数据库列名
+var ChartInfoLogColumns = struct {
+	ChartInfoLogID  string
+	ChartInfoID     string
+	ChartName       string
+	UniqueCode      string
+	ChartClassifyID string
+	SysUserID       string
+	SysUserRealName string
+	CreateTime      string
+	Content         string
+	Status          string
+	Method          string
+}{
+	ChartInfoLogID:  "chart_info_log_id",
+	ChartInfoID:     "chart_info_id",
+	ChartName:       "chart_name",
+	UniqueCode:      "unique_code",
+	ChartClassifyID: "chart_classify_id",
+	SysUserID:       "sys_user_id",
+	SysUserRealName: "sys_user_real_name",
+	CreateTime:      "create_time",
+	Content:         "content",
+	Status:          "status",
+	Method:          "method",
+}

+ 9 - 0
models/tables/chart_info_log/create.go

@@ -0,0 +1,9 @@
+package chart_info_log
+
+import "hongze/hongze_yb/global"
+
+func (chartInfo *ChartInfoLog) Create() (chartInfoLogId int, err error) {
+	err = global.MYSQL["data"].Create(chartInfo).Error
+	chartInfoLogId = chartInfo.ChartInfoLogId
+	return
+}

+ 44 - 0
models/tables/company_user_chart_classify_permission/company_user_chart_classify_permission.go

@@ -0,0 +1,44 @@
+package company_user_chart_classify_permission
+
+import (
+	"time"
+)
+
+// CompanyUserChartClassifyPermission 客户联系人-图表分类权限表
+type CompanyUserChartClassifyPermission struct {
+	ID            uint32    `gorm:"primaryKey;column:id;type:int(10) unsigned;not null" json:"-"`                            // 主键ID
+	UserID        uint32    `gorm:"index:idx_user_id;column:user_id;type:int(10) unsigned;not null;default:0" json:"userId"` // 用户ID
+	ChartClassify string    `gorm:"column:chart_classify;type:varchar(255);not null;default:''" json:"chartClassify"`        // 图表分类权限-逗号分隔
+	StartTime     time.Time `gorm:"column:start_time;type:datetime" json:"startTime"`                                        // 起始时间
+	EndTime       time.Time `gorm:"column:end_time;type:datetime" json:"endTime"`                                            // 终止时间
+	Enabled       uint8     `gorm:"column:enabled;type:tinyint(4) unsigned;not null;default:1" json:"enabled"`               // 使用状态 1-开启 0-关闭
+	CreateTime    time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`                                      // 创建时间
+	UpdateTime    time.Time `gorm:"column:update_time;type:datetime" json:"updateTime"`                                      // 更新时间
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *CompanyUserChartClassifyPermission) TableName() string {
+	return "company_user_chart_classify_permission"
+}
+
+// CompanyUserChartClassifyPermissionColumns get sql column name.获取数据库列名
+var CompanyUserChartClassifyPermissionColumns = struct {
+	ID            string
+	UserID        string
+	ChartClassify string
+	StartTime     string
+	EndTime       string
+	Enabled       string
+	CreateTime    string
+	UpdateTime    string
+}{
+	ID:            "id",
+	UserID:        "user_id",
+	ChartClassify: "chart_classify",
+	StartTime:     "start_time",
+	EndTime:       "end_time",
+	Enabled:       "enabled",
+	CreateTime:    "create_time",
+	UpdateTime:    "update_time",
+}
+

+ 9 - 0
models/tables/company_user_chart_classify_permission/query.go

@@ -0,0 +1,9 @@
+package company_user_chart_classify_permission
+
+import "hongze/hongze_yb/global"
+
+// GetPermissionByUserId 获取用户图库分类权限信息
+func GetPermissionByUserId(userId int) (item *CompanyUserChartClassifyPermission, err error) {
+	err = global.DEFAULT_MYSQL.Model(CompanyUserChartClassifyPermission{}).Where("user_id", userId).First(&item).Error
+	return
+}

+ 30 - 0
models/tables/edb_data/create.go

@@ -0,0 +1,30 @@
+package edb_data
+
+import (
+	"hongze/hongze_yb/global"
+)
+
+func AddEdbDataThsBySql(sqlStr string) (err error) {
+	err = global.MYSQL["data"].Exec(sqlStr).Error
+	return
+}
+
+func AddEdbDataWindBySql(sqlStr string) (err error) {
+	err = global.MYSQL["data"].Exec(sqlStr).Error
+	return
+}
+
+func AddEdbDataPb(items []*EdbDataPb) (err error) {
+	err = global.MYSQL["data"].Model(EdbDataPb{}).Create(items).Error
+	return
+}
+
+func AddBaseFromSmmIndex(item *BaseFromSmmIndex) (lastId int64, err error) {
+	err = global.MYSQL["data"].Model(BaseFromSmmIndex{}).Create(item).Error
+	return
+}
+
+func AddBaseFromSmmData(item *BaseFromSmmData) (lastId int64, err error) {
+	err = global.MYSQL["data"].Model(BaseFromSmmData{}).Create(item).Error
+	return
+}

+ 904 - 0
models/tables/edb_data/query.go

@@ -0,0 +1,904 @@
+package edb_data
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/utils"
+	"strconv"
+	"time"
+)
+
+// 指标数据->存储表
+func GetEdbDataTableName(source int) (tableName string) {
+	switch source {
+	case utils.DATA_SOURCE_THS:
+		tableName = "edb_data_ths"
+	case utils.DATA_SOURCE_WIND:
+		tableName = "edb_data_wind"
+	case utils.DATA_SOURCE_PB:
+		tableName = "edb_data_pb"
+	case utils.DATA_SOURCE_CALCULATE:
+		tableName = "edb_data_calculate"
+	case utils.DATA_SOURCE_CALCULATE_LJZZY:
+		tableName = "edb_data_calculate_ljzzy"
+	case utils.DATA_SOURCE_CALCULATE_TBZ:
+		tableName = "edb_data_calculate_tbz"
+	case utils.DATA_SOURCE_CALCULATE_TCZ:
+		tableName = "edb_data_calculate_tcz"
+	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS:
+		tableName = "edb_data_calculate_nszydpjjs"
+	case utils.DATA_SOURCE_MANUAL:
+		tableName = "edb_data_manual"
+	case utils.DATA_SOURCE_LZ:
+		tableName = "edb_data_lz"
+	case utils.DATA_SOURCE_YS:
+		tableName = "edb_data_ys"
+	case utils.DATA_SOURCE_CALCULATE_HBZ:
+		tableName = "edb_data_calculate_hbz"
+	case utils.DATA_SOURCE_CALCULATE_HCZ:
+		tableName = "edb_data_calculate_hcz"
+	case utils.DATA_SOURCE_CALCULATE_BP:
+		tableName = "edb_data_calculate_bp"
+	case utils.DATA_SOURCE_GL:
+		tableName = "edb_data_gl"
+	case utils.DATA_SOURCE_ZZ:
+		tableName = "edb_data_zz"
+	case utils.DATA_SOURCE_DL:
+		tableName = "edb_data_dl"
+	case utils.DATA_SOURCE_SH:
+		tableName = "edb_data_sh"
+	case utils.DATA_SOURCE_CFFEX:
+		tableName = "edb_data_cffex"
+	case utils.DATA_SOURCE_SHFE:
+		tableName = "edb_data_ine"
+	case utils.DATA_SOURCE_GIE:
+		tableName = "edb_data_gie"
+	case utils.DATA_SOURCE_CALCULATE_ZJPJ:
+		tableName = "edb_data_calculate_zjpj"
+	case utils.DATA_SOURCE_CALCULATE_TIME_SHIFT:
+		tableName = "edb_data_calculate_time_shift"
+	case utils.DATA_SOURCE_CALCULATE_LJZTBPJ:
+		tableName = "edb_data_calculate_ljztbpj"
+	case utils.DATA_SOURCE_LT:
+		tableName = "edb_data_lt"
+	default:
+		tableName = ""
+	}
+	return
+}
+
+type EdbDataList struct {
+	EdbDataId     int     `description:" 指标数据ID"`
+	EdbInfoId     int     `description:"指标ID"`
+	DataTime      string  `json:"-" description:"数据日期"`
+	DataTimestamp int64   `description:"数据日期"`
+	Value         float64 `description:"数据值"`
+}
+
+type EdbDataItems struct {
+	Items []*EdbDataList
+	Year  int
+}
+
+type EdbDataResult struct {
+	List []*EdbDataItems
+}
+
+type QuarterData struct {
+	Year     int
+	DataList []*EdbDataList
+}
+
+// GetEdbDataList 获取指标数据
+func GetEdbDataList(source, endInfoId int, startDate, endDate string) (list []*EdbDataList, err error) {
+	tableName := GetEdbDataTableName(source)
+	if tableName == "" {
+		err = errors.New("无效的渠道:" + strconv.Itoa(source))
+		list = make([]*EdbDataList, 0)
+		return list, err
+	}
+	var pars []interface{}
+	pars = append(pars, endInfoId)
+	sql := `SELECT edb_data_id,edb_info_id,data_time,value,data_timestamp FROM %s WHERE edb_info_id = ? `
+	if startDate != "" {
+		sql += ` AND data_time >= ? `
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		sql += ` AND data_time <= ? `
+		pars = append(pars, endDate)
+	}
+	sql += ` ORDER BY data_time ASC `
+	sql = fmt.Sprintf(sql, tableName)
+	err = global.MYSQL["data"].Raw(sql, pars...).Scan(&list).Error
+	// 格式化日期
+	if len(list) > 0 {
+		for _, row := range list {
+			if row.DataTime != "" {
+				row.DataTime = row.DataTime[:10]	// 此处获取的字符串row.DataTime长度有长有短,截取年月日
+				//tempTime, _ := time.Parse("2006-01-02T00:00:00+08:00", row.DataTime)
+				//row.DataTime = tempTime.Format(utils.FormatDate)
+			}
+		}
+	}
+
+	return
+}
+
+
+func GetEdbDataThsByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_ths WHERE edb_code = ? AND data_time = ? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+func GetEdbDataWindByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_wind WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+func GetEdbDataPbByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_pb WHERE edb_code=? AND data_time>=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+type ManualEdbdata struct {
+	TradeCode  string    `gorm:"column:TRADE_CODE" description:"指标编码"`
+	Dt         string    `gorm:"column:DT" description:"日期"`
+	Close      string    `gorm:"column:CLOSE" description:"值"`
+	ModifyTime time.Time `gorm:"column:modify_time:" description:"修改时间"`
+}
+
+func GetEdbdataManualByTradeCode(condition string, pars []interface{}) (item []*ManualEdbdata, err error) {
+	sql := ` SELECT  * FROM edbdata WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY DT DESC `
+	err = global.MYSQL["edb"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+type EdbDataBase struct {
+	EdbDataId     int `gorm:"column:edb_data_id;primaryKey"`
+	EdbInfoId     int
+	EdbCode       string
+	DataTime      string
+	Value         string
+	Status        int
+	CreateTime    time.Time
+	ModifyTime    time.Time
+	DataTimestamp int64
+}
+
+type lzSurveyData struct {
+	DataTime   string `gorm:"column:data_time" description:"日期"`
+	InputValue string `gorm:"column:input_value" description:"值"`
+}
+
+func GetLzSurveyDataByTradeCode(condition string, pars []interface{}) (item []*lzSurveyData, err error) {
+	sql := ` SELECT  a.* FROM longzhong_survey_data AS a
+				INNER JOIN longzhong_survey_product AS b ON a.survey_product_id=b.survey_product_id
+				WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY a.data_time DESC `
+	err = global.MYSQL["edb"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+func GetEdbDataLzByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_lz WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+type EdbDataPb struct {
+	EdbDataId     int `gorm:"column:edb_data_id;primaryKey"`
+	EdbInfoId     int
+	EdbCode       string
+	DataTime      string
+	Value         float64
+	Status        int
+	CreateTime    time.Time
+	ModifyTime    time.Time
+	Ticker        string
+	Field         string
+	DataTimestamp int64
+}
+
+type BaseFromSmm struct {
+	BaseFromSmmId int `gorm:"column:base_from_smm_id;primaryKey"`
+	Aid           int
+	Name          string
+	Interface     string
+	ApiUpdate     int
+	ApiUpdateType string
+	ApiType       int
+	ApiTypeAll    string
+	Type1         string `gorm:"column:type_1"`
+	Type2         string `gorm:"column:type_2"`
+	Type3         string `gorm:"column:type_3"`
+	ApiStartTime  string
+	ApiUpdateTime string
+	StartTime     string
+	FinishTime    string
+	AuthModule    string
+	AuthLang      string
+	ApiLabel      string
+	Enable        string
+	EditPerson    string
+	EditTime      string
+	AuthDur       int
+	AuthDurType   string
+}
+
+type BaseFromSmmIndex struct {
+	BaseFromSmmIndexId int `gorm:"column:base_from_smm_index_id;primaryKey"`
+	Interface          string
+	Name               string
+	IndexCode          string
+	IndexName          string
+	Type1              string `gorm:"column:type_1"`
+	Type2              string `gorm:"column:type_2"`
+	Type3              string `gorm:"column:type_3"`
+	Frequency          string
+	Unit               string
+	ApiStartTime       string
+	ApiUpdateTime      string
+	StartTime          string
+	FinishTime         string
+	CreateTime         time.Time
+	ModifyTime         time.Time
+}
+
+type BaseFromSmmData struct {
+	SmmDataId          int `gorm:"column:smm_data_id;primaryKey"`
+	BaseFromSmmIndexId int
+	IndexCode          string
+	DataTime           string
+	Value              string
+	CreateTime         time.Time
+	ModifyTime         time.Time
+	DataTimestamp      int64
+}
+
+func GetBaseFromSmmBySmmCode(smmCode string) (item *BaseFromSmm, err error) {
+	sql := `SELECT * FROM base_from_smm WHERE interface = ?`
+	err = global.MYSQL["data"].Raw(sql, smmCode).Scan(&item).Error
+
+	return
+}
+
+func GetBaseFromSmmIndexBySmmCode(smmCode string) (list []*BaseFromSmmIndex, err error) {
+	sql := ` SELECT * FROM base_from_smm_index WHERE interface = ? `
+	err = global.MYSQL["data"].Raw(sql, smmCode).Scan(&list).Error
+
+	return
+}
+
+func GetBaseFromSmmDataAllByIndexCode(indexCode string) (list []*BaseFromSmmData, err error) {
+	sql := `SELECT * FROM base_from_smm_data WHERE index_code=? `
+	err = global.MYSQL["data"].Raw(sql, indexCode).Scan(&list).Error
+
+	return
+}
+
+func GetBaseFromSmmMaxOrMinDate(indexCode string) (min_date, max_date string, err error) {
+	sql := ` SELECT MIN(data_time) AS min_date FROM base_from_smm_data WHERE index_code=? `
+	err = global.MYSQL["data"].Raw(sql, indexCode).Scan(&min_date).Error
+	sql = ` SELECT MAX(data_time) AS max_date FROM base_from_smm_data WHERE index_code=? `
+	err = global.MYSQL["data"].Raw(sql, indexCode).Scan(&max_date).Error
+
+	return
+}
+
+type YsResult struct {
+	Code int64 `json:"Code"`
+	Data struct {
+		CompanyList []interface{} `json:"CompanyList"`
+		Content     [][]string    `json:"Content"`
+		Field       []struct {
+			ColIndex   int64  `json:"ColIndex"`
+			ColumnType string `json:"ColumnType"`
+			Info       string `json:"Info"`
+			IsDate     string `json:"IsDate"`
+			Name       string `json:"Name"`
+			Unit       string `json:"Unit"`
+			DBColName  string `json:"db_col_name"`
+		} `json:"Field"`
+		CountPage   int64  `json:"count_page"`
+		CurrentPage int64  `json:"current_page"`
+		Frequency   string `json:"frequency"`
+		Mindate     string `json:"mindate"`
+		PageNum     int64  `json:"page_num"`
+		Status      int64  `json:"status"`
+		TotalNum    int64  `json:"total_num"`
+	} `json:"Data"`
+	Msg string `json:"Msg"`
+}
+
+type BaseFromSmmDataSimple struct {
+	SmmDataId          int `gorm:"column:smm_data_id;primaryKey"`
+	BaseFromSmmIndexId int
+	IndexCode          string
+	DataTime           string
+	Value              string
+}
+
+type BaseFromDlDataSimple struct {
+	Id        int `gorm:"column:base_from_trade_dalian_index_id;primaryKey"`
+	DealCode  string
+	BuyCode   string
+	SoldCode  string
+	DataTime  string
+	DealValue string
+	BuyValue  string
+	SoldValue string
+}
+
+func GetDlDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromDlDataSimple, err error) {
+	sql := ` SELECT * FROM base_from_trade_dalian_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY data_time DESC `
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+func GetEdbDataDlByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_dl WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+type GlData struct {
+	InputValue string `gorm:"column:DATA_VALUE" description:"日期"`
+	DataTime   string `gorm:"column:DATA_DATE" description:"值"`
+}
+
+func GetGlDataByTradeCode(condition string, pars []interface{}) (item []*GlData, err error) {
+	condition += " AND IS_DELETE=0 "
+	sql := ` SELECT * FROM mb_index_main_data WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY PUBLISH_TIME DESC `
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+func GetEdbDataGlByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_gl WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+type EdbDataFromLt struct {
+	Close map[int64]interface{} `json:"CLOSE"`
+}
+
+type BaseFromZzDataSimple struct {
+	Id        int `gorm:"column:base_from_trade_zhengzhou_index_id;primaryKey"`
+	DealCode  string
+	BuyCode   string
+	SoldCode  string
+	DataTime  string
+	DealValue string
+	BuyValue  string
+	SoldValue string
+}
+
+func GetZzDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromZzDataSimple, err error) {
+	sql := ` SELECT * FROM base_from_trade_zhengzhou_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY data_time DESC `
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+func GetEdbDataZzByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_zz WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+	return
+}
+
+type BaseFromShDataSimple struct {
+	Id        int `gorm:"column:base_from_trade_shanghai_index_id;primaryKey"`
+	DealCode  string
+	BuyCode   string
+	SoldCode  string
+	DataTime  string
+	DealValue string
+	BuyValue  string
+	SoldValue string
+}
+
+func GetShDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromShDataSimple, err error) {
+	sql := ` SELECT * FROM base_from_trade_shanghai_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY data_time DESC `
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+func GetEdbDataShByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_sh WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+type BaseFromCffexDataSimple struct {
+	Id        int `gorm:"column:base_from_trade_cffex_index_id;primaryKey"`
+	DealCode  string
+	BuyCode   string
+	SoldCode  string
+	DataTime  string
+	DealValue string
+	BuyValue  string
+	SoldValue string
+}
+
+func GetCffexDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromCffexDataSimple, err error) {
+	sql := ` SELECT * FROM base_from_trade_cffex_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY data_time DESC `
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+func GetEdbDataCffexByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_cffex WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+type BaseFromShfeDataSimple struct {
+	Id        int `gorm:"column:base_from_trade_ine_index_id;primaryKey"`
+	DealCode  string
+	BuyCode   string
+	SoldCode  string
+	DataTime  string
+	DealValue string
+	BuyValue  string
+	SoldValue string
+}
+
+func GetShfeDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromShfeDataSimple, err error) {
+	sql := ` SELECT * FROM base_from_trade_ine_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY data_time DESC `
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+func GetEdbDataShfeByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_ine WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+type BaseFromTradeEicIndex struct {
+	BaseFromEicIndexId     int `gorm:"column:base_from_eic_index_id;primaryKey"`
+	Country                string
+	Type                   string
+	EicCode                string
+	ShortName              string
+	Name                   string
+	Status                 string
+	GasDayStartedOn        string
+	GasInStorage           string
+	GasInStorageCode       string
+	Full                   string
+	FullCode               string
+	Trend                  string
+	TrendCode              string
+	Injection              string
+	InjectionCode          string
+	Withdrawal             string
+	WithdrawalCode         string
+	WorkingGasVolume       string
+	WorkingGasVolumeCode   string
+	InjectionCapacity      string
+	InjectionCapacityCode  string
+	WithdrawalCapacity     string
+	WithdrawalCapacityCode string
+	Info                   string
+	CreateTime             time.Time
+	ModifyTime             time.Time
+}
+
+func GetGieDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromTradeEicIndex, err error) {
+	sql := ` SELECT * FROM base_from_trade_eic_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY gas_day_started_on DESC `
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error
+
+	return
+}
+
+func GetEdbDataGieByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_gie WHERE edb_code=? AND data_time=? `
+	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
+
+	return
+}
+
+type EdbInfoMaxAndMinInfo struct {
+	MinDate     string  `description:"最小日期"`
+	MaxDate     string  `description:"最大日期"`
+	MinValue    float64 `description:"最小值"`
+	MaxValue    float64 `description:"最大值"`
+	LatestValue float64 `description:"最新值"`
+}
+
+func GetEdbInfoMaxAndMinInfo(source int, edbCode string) (item *EdbInfoMaxAndMinInfo, err error) {
+	sql := ``
+	tableName := GetEdbDataTableName(source)
+	sql = ` SELECT MIN(data_time) AS min_date,MAX(data_time) AS max_date,MIN(value) AS min_value,MAX(value) AS max_value FROM %s WHERE edb_code=? `
+	sql = fmt.Sprintf(sql, tableName)
+	err = global.MYSQL["data"].Raw(sql, edbCode).Scan(&item).Error
+
+	var latest_value float64
+	sql = ` SELECT value AS latest_value FROM %s WHERE edb_code=? ORDER BY data_time DESC LIMIT 1 `
+	sql = fmt.Sprintf(sql, tableName)
+	err = global.MYSQL["data"].Raw(sql, edbCode).Scan(&latest_value).Error
+	item.LatestValue = latest_value
+	return
+}
+
+type EdbInfoCalculateDetail struct {
+	EdbInfoCalculateId int       `gorm:"primaryKey;column:edb_info_calculate_id"`
+	EdbInfoId          int       `description:"指标id"`
+	EdbCode            string    `description:"指标编码"`
+	FromEdbInfoId      int       `description:"计算指标id"`
+	FromEdbCode        string    `description:"计算指标编码"`
+	FromEdbName        string    `description:"计算指标名称"`
+	FromSource         int       `description:"计算指标来源"`
+	FromSourceName     string    `description:"计算指标来源名称"`
+	FromTag            string    `description:"来源指标标签"`
+	Sort               int       `description:"计算指标名称排序"`
+	CreateTime         time.Time `description:"创建时间"`
+	ModifyTime         time.Time `description:"修改时间"`
+	StartDate          string    `description:"开始日期"`
+	EndDate            string    `description:"结束日期"`
+	EdbType            int       `description:"指标类型:1:基础指标,2:计算指标"`
+}
+
+func GetEdbInfoCalculateDetail(edbInfoId, source int) (list []*EdbInfoCalculateDetail, err error) {
+	sql := ` SELECT a.*,b.start_date,b.end_date,b.edb_type FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? ORDER BY sort ASC `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&list).Error
+
+	return
+}
+
+type EdbInfoSearchData struct {
+	DataTime string	 `description:"数据日期"`
+	Value    float64 `description:"数据"`
+}
+
+//order:1升序,其余值为降序
+func GetEdbDataListAll(condition string, pars []interface{}, source, order int) (item []*EdbInfoSearchData, err error) {
+	sql := ``
+	tableName := GetEdbDataTableName(source)
+	sql = ` SELECT * FROM %s WHERE 1=1 `
+	sql = fmt.Sprintf(sql, tableName)
+
+	if condition != "" {
+		sql += condition
+	}
+	if order == 1 {
+		sql += ` ORDER BY data_time ASC `
+	} else {
+		sql += ` ORDER BY data_time DESC `
+	}
+	err = global.MYSQL["data"].Raw(sql, pars...).Scan(&item).Error
+	// 格式化日期
+	if len(item) > 0 {
+		for _, row := range item {
+			if row.DataTime != "" {
+				row.DataTime = row.DataTime[:10]
+				//tempTime, _ := time.Parse("2006-01-02T00:00:00", row.DataTime)
+				//row.DataTime = tempTime.Format(utils.FormatDate)
+			}
+		}
+	}
+
+	return
+}
+
+
+type CalculateItems struct {
+	EdbInfoId int
+	DataMap   map[string]float64
+}
+
+type EdbInfoCalculateLjzzyDetail struct {
+	EdbInfoCalculateLjzzyId int       `gorm:"column:edb_info_calculate_ljzzy_id;primaryKey"`
+	EdbInfoId               int       `description:"指标id"`
+	EdbCode                 string    `description:"指标编码"`
+	FromEdbInfoId           int       `description:"计算指标id"`
+	FromEdbCode             string    `description:"计算指标编码"`
+	FromEdbName             string    `description:"计算指标名称"`
+	FromSource              int       `description:"计算指标来源"`
+	FromSourceName          string    `description:"计算指标来源名称"`
+	FromTag                 string    `description:"来源指标标签"`
+	Sort                    int       `description:"计算指标名称排序"`
+	CreateTime              time.Time `description:"创建时间"`
+	ModifyTime              time.Time `description:"修改时间"`
+	StartDate               string    `description:"开始日期"`
+	EndDate                 string    `description:"结束日期"`
+}
+
+func GetEdbInfoCalculateLjzzyDetail(edbInfoId int) (item *EdbInfoCalculateLjzzyDetail, err error) {
+	sql := ` SELECT a.*,b.start_date,b.end_date FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&item).Error
+
+	return
+}
+
+
+type EdbInfoCalculateTbzDetail struct {
+	EdbInfoCalculateTbzId int       `gorm:"column:edb_info_calculate_tbz_id;primaryKey"`
+	EdbInfoId             int       `description:"指标id"`
+	EdbCode               string    `description:"指标编码"`
+	FromEdbInfoId         int       `description:"计算指标id"`
+	FromEdbCode           string    `description:"计算指标编码"`
+	FromEdbName           string    `description:"计算指标名称"`
+	FromSource            int       `description:"计算指标来源"`
+	FromSourceName        string    `description:"计算指标来源名称"`
+	FromTag               string    `description:"来源指标标签"`
+	Sort                  int       `description:"计算指标名称排序"`
+	CreateTime            time.Time `description:"创建时间"`
+	ModifyTime            time.Time `description:"修改时间"`
+	StartDate             string    `description:"开始日期"`
+	EndDate               string    `description:"结束日期"`
+}
+
+func GetEdbInfoCalculateTbzDetail(edbInfoId int) (item *EdbInfoCalculateTbzDetail, err error) {
+	sql := ` SELECT a.*,b.start_date,b.end_date FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).First(&item).Error
+
+	return
+}
+
+type EdbInfoCalculateTczDetail struct {
+	EdbInfoCalculateTczId int       `gorm:"column:edb_info_calculate_tcz_id;primaryKey"`
+	EdbInfoId             int       `description:"指标id"`
+	EdbCode               string    `description:"指标编码"`
+	FromEdbInfoId         int       `description:"计算指标id"`
+	FromEdbCode           string    `description:"计算指标编码"`
+	FromEdbName           string    `description:"计算指标名称"`
+	FromSource            int       `description:"计算指标来源"`
+	FromSourceName        string    `description:"计算指标来源名称"`
+	FromTag               string    `description:"来源指标标签"`
+	Sort                  int       `description:"计算指标名称排序"`
+	CreateTime            time.Time `description:"创建时间"`
+	ModifyTime            time.Time `description:"修改时间"`
+	StartDate             string    `description:"开始日期"`
+	EndDate               string    `description:"结束日期"`
+}
+
+func GetEdbInfoCalculateTczDetail(edbInfoId int) (item *EdbInfoCalculateTczDetail, err error) {
+	sql := ` SELECT a.*,b.start_date,b.end_date FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).First(&item).Error
+
+	return
+}
+
+type EdbInfoCalculateNszydpjjsDetail struct {
+	EdbInfoCalculateNszydpjjsId int       `gorm:"column:edb_info_calculate_nszydpjjs_id;primaryKey"`
+	EdbInfoId                   int       `description:"指标id"`
+	EdbCode                     string    `description:"指标编码"`
+	FromEdbInfoId               int       `description:"计算指标id"`
+	FromEdbCode                 string    `description:"计算指标编码"`
+	FromEdbName                 string    `description:"计算指标名称"`
+	FromSource                  int       `description:"计算指标来源"`
+	FromSourceName              string    `description:"计算指标来源名称"`
+	FromTag                     string    `description:"来源指标标签"`
+	Sort                        int       `description:"计算指标名称排序"`
+	CreateTime                  time.Time `description:"创建时间"`
+	ModifyTime                  time.Time `description:"修改时间"`
+	StartDate                   string    `description:"开始日期"`
+	EndDate                     string    `description:"结束日期"`
+}
+
+func GetEdbInfoCalculateNszydpjjsDetail(edbInfoId int) (item *EdbInfoCalculateNszydpjjsDetail, err error) {
+	sql := ` SELECT a.*,b.start_date,b.end_date FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).First(&item).Error
+
+	return
+}
+
+type EdbInfoCalculateHbzDetail struct {
+	EdbInfoCalculateTbzId int       `gorm:"column:edb_info_calculate_tbz_id;primaryKey"`
+	EdbInfoId             int       `description:"指标id"`
+	EdbCode               string    `description:"指标编码"`
+	FromEdbInfoId         int       `description:"计算指标id"`
+	FromEdbCode           string    `description:"计算指标编码"`
+	FromEdbName           string    `description:"计算指标名称"`
+	FromSource            int       `description:"计算指标来源"`
+	FromSourceName        string    `description:"计算指标来源名称"`
+	FromTag               string    `description:"来源指标标签"`
+	Sort                  int       `description:"计算指标名称排序"`
+	CreateTime            time.Time `description:"创建时间"`
+	ModifyTime            time.Time `description:"修改时间"`
+	StartDate             string    `description:"开始日期"`
+	EndDate               string    `description:"结束日期"`
+}
+
+func GetEdbInfoCalculateHbzDetail(edbInfoId int) (item *EdbInfoCalculateTbzDetail, err error) {
+	sql := ` SELECT a.*,b.start_date,b.end_date FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).First(&item).Error
+
+	return
+}
+
+
+type EdbInfoCalculateHczDetail struct {
+	EdbInfoCalculateHczId int       `gorm:"column:edb_info_calculate_hcz_id;primaryKey"`
+	EdbInfoId             int       `description:"指标id"`
+	EdbCode               string    `description:"指标编码"`
+	FromEdbInfoId         int       `description:"计算指标id"`
+	FromEdbCode           string    `description:"计算指标编码"`
+	FromEdbName           string    `description:"计算指标名称"`
+	FromSource            int       `description:"计算指标来源"`
+	FromSourceName        string    `description:"计算指标来源名称"`
+	FromTag               string    `description:"来源指标标签"`
+	Sort                  int       `description:"计算指标名称排序"`
+	CreateTime            time.Time `description:"创建时间"`
+	ModifyTime            time.Time `description:"修改时间"`
+	StartDate             string    `description:"开始日期"`
+	EndDate               string    `description:"结束日期"`
+}
+
+func GetEdbInfoCalculateHczDetail(edbInfoId int) (item *EdbInfoCalculateHczDetail, err error) {
+	sql := ` SELECT a.*,b.start_date,b.end_date FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).First(&item).Error
+
+	return
+}
+
+
+type EdbInfoCalculateBpDetail struct {
+	EdbInfoCalculateBpId int       `gorm:"column:edb_info_calculate_bp_id;primaryKey"`
+	EdbInfoId            int       `description:"指标id"`
+	EdbCode              string    `description:"指标编码"`
+	FromEdbInfoId        int       `description:"计算指标id"`
+	FromEdbCode          string    `description:"计算指标编码"`
+	FromEdbName          string    `description:"计算指标名称"`
+	FromSource           int       `description:"计算指标来源"`
+	FromSourceName       string    `description:"计算指标来源名称"`
+	FromTag              string    `description:"来源指标标签"`
+	Sort                 int       `description:"计算指标名称排序"`
+	CreateTime           time.Time `description:"创建时间"`
+	ModifyTime           time.Time `description:"修改时间"`
+	StartDate            string    `description:"开始日期"`
+	EndDate              string    `description:"结束日期"`
+}
+
+func GetEdbInfoCalculateBpDetail(edbInfoId int) (item *EdbInfoCalculateTbzDetail, err error) {
+	sql := ` SELECT a.*,b.start_date,b.end_date FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).First(&item).Error
+
+	return
+}
+
+// EdbDataCalculateZjpj 直接拼接数据结构体
+type EdbDataCalculateZjpj struct {
+	EdbDataId     int `gorm:"column:edb_data_id;primaryKey"`
+	EdbInfoId     int
+	EdbCode       string
+	DataTime      string
+	Value         float64
+	Status        int
+	CreateTime    time.Time
+	ModifyTime    time.Time
+	DataTimestamp int64
+}
+
+// GetAllEdbDataCalculateZjpjByEdbInfoId 根据指标id获取全部的数据
+func GetAllEdbDataCalculateZjpjByEdbInfoId(edbInfoId int) (items []*EdbDataCalculateZjpj, err error) {
+	sql := ` SELECT * FROM edb_data_calculate_zjpj WHERE edb_info_id=? ORDER BY data_time DESC `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&items).Error
+
+	return
+}
+
+// EdbInfoCalculateMapping 计算指标于基础指标,关系表
+type EdbInfoCalculateMapping struct {
+	EdbInfoCalculateMappingId int       `gorm:"column:edb_info_calculate_mapping_id;primaryKey"`
+	EdbInfoId                 int       `description:"计算指标id"`
+	Source                    int       `description:"计算指标来源"`
+	SourceName                string    `description:"计算指标来源名称"`
+	EdbCode                   string    `description:"计算指标编码"`
+	FromEdbInfoId             int       `description:"基础指标id"`
+	FromEdbCode               string    `description:"基础指标编码"`
+	FromEdbName               string    `description:"基础指标名称"`
+	FromSource                int       `description:"基础指标来源"`
+	FromSourceName            string    `description:"基础指标来源名称"`
+	FromTag                   string    `description:"来源指标标签"`
+	Sort                      int       `description:"计算指标名称排序"`
+	CreateTime                time.Time `description:"创建时间"`
+	ModifyTime                time.Time `description:"修改时间"`
+}
+
+// GetEdbInfoCalculateListByCondition 获取指标关系列表
+func GetEdbInfoCalculateListByCondition(condition string, pars []interface{}) (items []*EdbInfoCalculateMapping, err error) {
+	sql := ` SELECT * FROM edb_info_calculate_mapping WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&items).Error
+
+	return
+}
+
+// EdbDataCalculateLjztbpj 累计值同比拼接数据结构体
+type EdbDataCalculateLjztbpj struct {
+	EdbDataId     int `gorm:"column:edb_data_id;primaryKey"`
+	EdbInfoId     int
+	EdbCode       string
+	DataTime      string
+	Value         float64
+	Status        int
+	CreateTime    time.Time
+	ModifyTime    time.Time
+	DataTimestamp int64
+}
+
+// GetAllEdbDataCalculateLjztbpjByEdbInfoId 根据指标id获取全部的数据
+func GetAllEdbDataCalculateLjztbpjByEdbInfoId(edbInfoId int) (items []*EdbDataCalculateLjztbpj, err error) {
+	sql := ` SELECT * FROM edb_data_calculate_ljztbpj WHERE edb_info_id=? ORDER BY data_time DESC `
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&items).Error
+
+	return
+}

+ 52 - 0
models/tables/edb_data/update.go

@@ -0,0 +1,52 @@
+package edb_data
+
+import "hongze/hongze_yb/global"
+
+func ModifyEdbDataThs(edbInfoId int64, dataTime string, value float64) (err error) {
+	sql := ` UPDATE edb_data_ths SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+	err = global.MYSQL["data"].Exec(sql, value, edbInfoId, dataTime).Error
+
+	return
+}
+
+func ModifyEdbDataWind(edbInfoId int64, dataTime string, value float64) (err error) {
+	sql := ` UPDATE edb_data_wind SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+	err = global.MYSQL["data"].Exec(sql, value, edbInfoId, dataTime).Error
+
+	return
+}
+
+func ModifyEdbDataPb(edbInfoId int, dataTime string, value float64) (err error) {
+	sql := ` UPDATE edb_data_pb SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+	err = global.MYSQL["data"].Exec(sql, value, edbInfoId, dataTime).Error
+
+	return
+}
+
+func ModifyBaseFromSmmData(smmDataId int, value string) (err error) {
+	sql := `UPDATE base_from_smm_data SET value=?,modify_time=NOW() WHERE smm_data_id=? `
+	err = global.MYSQL["data"].Exec(sql, value, smmDataId).Error
+
+	return
+}
+
+func ModifyBaseFromSmmMinDateAndMaxDate(baseFromSmmIndexId int, minDate, maxDate string) (err error) {
+	sql := ` UPDATE base_from_smm_index SET start_date=?,end_date=?,modify_time=NOW() WHERE base_from_smm_index_id=? `
+	err = global.MYSQL["data"].Exec(sql, minDate, maxDate, baseFromSmmIndexId).Error
+
+	return
+}
+
+func ModifyEdbDataGl(edbInfoId int64, dataTime, value string) (err error) {
+	sql := ` UPDATE edb_data_gl SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+	err = global.MYSQL["data"].Exec(sql, value, edbInfoId, dataTime).Error
+
+	return
+}
+
+func ModifyEdbInfoMaxAndMinInfo(edbInfoId int, item *EdbInfoMaxAndMinInfo) (err error) {
+	sql := ` UPDATE edb_info SET start_date=?,end_date=?,min_value=?,max_value=?,is_update=2,latest_date=?,latest_value=?,modify_time=NOW() WHERE edb_info_id=? `
+	err = global.MYSQL["data"].Exec(sql, item.MinDate, item.MaxDate, item.MinValue, item.MaxValue, item.MaxDate, item.LatestValue, edbInfoId).Error
+
+	return
+}

+ 95 - 0
models/tables/edb_info/edb_info.go

@@ -0,0 +1,95 @@
+package edb_info
+
+import "time"
+
+// EdbInfo 指标信息表
+type EdbInfo struct {
+	EdbInfoId        int       `gorm:"primaryKey;column:edb_info_id;type:int(11);not null" json:"edbInfoId"`							 // 指标id
+	SourceName       string    `gorm:"column:source_name;type:varchar(100)" json:"sourceName"`                                           // 来源名称
+	Source           int       `gorm:"uniqueIndex:idx_code_source;uniqueIndex:idx_edb_name;column:source;type:tinyint(4)" json:"source"` // 来源:1:同花顺,2:wind,3:彭博,4:指标运算,5:累计值转月,6:同比值,7:同差值,8:N数值移动平均计算,9:手工指标,10:隆众,11:有色,12:环比值,13:环差值,14:变频,15:钢联
+	EdbCode          string    `gorm:"uniqueIndex:idx_code_source;unique;column:edb_code;type:varchar(255);default:''" json:"edbCode"`   // 指标编码
+	EdbName          string    `gorm:"uniqueIndex:idx_edb_name;column:edb_name;type:varchar(255);default:''" json:"edbName"`             // 指标名称
+	EdbNameSource    string    `gorm:"column:edb_name_source;type:varchar(255);default:''" json:"edbNameSource"`                         // 指标名称_来源
+	Frequency        string    `gorm:"column:frequency;type:varchar(20);default:''" json:"frequency"`                                    // 频度
+	Unit             string    `gorm:"column:unit;type:varchar(20);default:''" json:"unit"`                                              // 单位
+	StartDate        time.Time `gorm:"column:start_date;type:date" json:"startDate"`                                                     // 更新开始日期
+	EndDate          time.Time `gorm:"column:end_date;type:date" json:"endDate"`                                                         // 更新结束日期
+	ClassifyId       int       `gorm:"index:idx_classify_id;column:classify_id;type:int(11)" json:"classifyId"`                          // 分类id
+	SysUserId        int       `gorm:"column:sys_user_id;type:int(11)" json:"sysUserId"`                                                 // 创建人
+	SysUserRealName  string    `gorm:"column:sys_user_real_name;type:varchar(100)" json:"sysUserRealName"`                               // 创建人姓名
+	CreateTime       time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`                                               // 创建时间
+	ModifyTime       time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`                                               // 修改时间
+	UniqueCode       string    `gorm:"unique;column:unique_code;type:varchar(50);default:''" json:"uniqueCode"`                          // 唯一编码
+	MinValue         float64   `gorm:"column:min_value;type:double;default:0" json:"minValue"`                                           // 最小值
+	MaxValue         float64   `gorm:"column:max_value;type:double;default:0" json:"maxValue"`                                           // 最大值
+	CalculateFormula string    `gorm:"column:calculate_formula;type:varchar(255);default:''" json:"calculateFormula"`                    // 计算公式,N数值移动
+	EdbType          int       `gorm:"column:edb_type;type:tinyint(4);default:1" json:"edbType"`                                         // 指标类型:1:基础指标,2:计算指标
+	IsUpdate         int       `gorm:"column:is_update;type:tinyint(4);default:1" json:"isUpdate"`                                       // 当天是否已更新,1:未更新,2:已更新
+	Sort             int       `gorm:"column:sort;type:int(9);default:0" json:"sort"`                                                    // 排序字段
+	LatestDate       time.Time `gorm:"column:latest_date;type:date" json:"latestDate"`                                                   // 数据最新日期
+	LatestValue      float64   `gorm:"column:latest_value;type:double" json:"latestValue"`                                               // 数据最新值
+	MoveType         int       `gorm:"column:move_type;type:tinyint(4);default:1" json:"moveType"`                                       // 移动方式:1:领先(默认),2:滞后
+	MoveFrequency    string    `gorm:"column:move_frequency;type:varchar(20);default:''" json:"moveFrequency"`                           // 移动频度
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *EdbInfo) TableName() string {
+	return "edb_info"
+}
+
+// EdbInfoColumns get sql column name.获取数据库列名
+var EdbInfoColumns = struct {
+	EdbInfoID        string
+	SourceName       string
+	Source           string
+	EdbCode          string
+	EdbName          string
+	EdbNameSource    string
+	Frequency        string
+	Unit             string
+	StartDate        string
+	EndDate          string
+	ClassifyID       string
+	SysUserID        string
+	SysUserRealName  string
+	CreateTime       string
+	ModifyTime       string
+	UniqueCode       string
+	MinValue         string
+	MaxValue         string
+	CalculateFormula string
+	EdbType          string
+	IsUpdate         string
+	Sort             string
+	LatestDate       string
+	LatestValue      string
+	MoveType         string
+	MoveFrequency    string
+}{
+	EdbInfoID:        "edb_info_id",
+	SourceName:       "source_name",
+	Source:           "source",
+	EdbCode:          "edb_code",
+	EdbName:          "edb_name",
+	EdbNameSource:    "edb_name_source",
+	Frequency:        "frequency",
+	Unit:             "unit",
+	StartDate:        "start_date",
+	EndDate:          "end_date",
+	ClassifyID:       "classify_id",
+	SysUserID:        "sys_user_id",
+	SysUserRealName:  "sys_user_real_name",
+	CreateTime:       "create_time",
+	ModifyTime:       "modify_time",
+	UniqueCode:       "unique_code",
+	MinValue:         "min_value",
+	MaxValue:         "max_value",
+	CalculateFormula: "calculate_formula",
+	EdbType:          "edb_type",
+	IsUpdate:         "is_update",
+	Sort:             "sort",
+	LatestDate:       "latest_date",
+	LatestValue:      "latest_value",
+	MoveType:         "move_type",
+	MoveFrequency:    "move_frequency",
+}

+ 10 - 0
models/tables/edb_info/query.go

@@ -0,0 +1,10 @@
+package edb_info
+
+import "hongze/hongze_yb/global"
+
+// GetEdbInfoById 主键获取指标信息
+func GetEdbInfoById(edbInfoId int) (item *EdbInfo, err error) {
+	err = global.MYSQL["data"].Where("edb_info_id = ? ", edbInfoId).First(&item).Error
+
+	return
+}

+ 34 - 0
models/tables/my_chart/my_chart.go

@@ -0,0 +1,34 @@
+package my_chart
+
+import (
+	"time"
+)
+
+// MyChart 我的图表
+type MyChart struct {
+	MyChartID   int       `gorm:"primaryKey;column:my_chart_id;type:int(11);not null" json:"-"`
+	ChartInfoID int       `gorm:"column:chart_info_id;type:int(11)" json:"chartInfoId"`
+	AdminID     int       `gorm:"column:admin_id;type:int(11)" json:"adminId"`
+	CreateTime  time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`
+	ModifyTime  time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *MyChart) TableName() string {
+	return "my_chart"
+}
+
+// MyChartColumns get sql column name.获取数据库列名
+var MyChartColumns = struct {
+	MyChartID   string
+	ChartInfoID string
+	AdminID     string
+	CreateTime  string
+	ModifyTime  string
+}{
+	MyChartID:   "my_chart_id",
+	ChartInfoID: "chart_info_id",
+	AdminID:     "admin_id",
+	CreateTime:  "create_time",
+	ModifyTime:  "modify_time",
+}

+ 100 - 0
models/tables/my_chart/query.go

@@ -0,0 +1,100 @@
+package my_chart
+
+import (
+	"hongze/hongze_yb/global"
+	"time"
+)
+
+type MyChartList struct {
+	MyChartId           int		`description:"我的图表主键"`
+	ChartInfoId         int
+	ChartName           string	`description:"来源名称"`
+	ChartClassifyId     int		`description:"图表分类id"`
+	SysUserId           int
+	SysUserRealName     string
+	UniqueCode          string	`description:"图表唯一编码"`
+	CreateTime          time.Time
+	ModifyTime          time.Time
+	DateType            int		`description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate           string	`description:"自定义开始日期"`
+	EndDate             string	`description:"自定义结束日期"`
+	IsSetName           int		`description:"设置名称"`
+	EdbInfoIds          string	`description:"指标id"`
+	ChartType           int		`description:"生成样式:1:曲线图,2:季节性图"`
+	Calendar            string	`description:"公历/农历"`
+	SeasonStartDate     string	`description:"季节性图开始日期"`
+	SeasonEndDate       string	`description:"季节性图开始日期"`
+	ChartImage          string	`description:"图表图片"`
+	Sort                float64	`description:"排序字段,数字越小越排前面"`
+	IsAdd               bool	`description:"true:已加入我的图库,false:未加入我的图库"`
+	MyChartClassifyName string	`description:"分类名称,多个用英文逗号分割"`
+	MyChartClassifyId   string	`description:"分类id,多个用英文逗号分割"`
+	EdbEndDate          string	`description:"指标最新更新日期"`
+}
+
+type MyChartView struct {
+	MyChartId         int       `orm:"column(my_chart_id);pk"`
+	ChartInfoId       int       `description:"图表id"`
+	AdminId           int       `description:"用户id"`
+	CreateTime        time.Time `description:"创建时间"`
+	ModifyTime        time.Time `description:"修改时间"`
+	MyChartClassifyId string	`description:"我的图表分类ID"`
+	//Sort			  int		`description:"我的图表排序"`
+}
+
+type MoveMyChartReq struct {
+	MyChartId         int `description:"移动的,我的图表图表ID"`
+	PrevMyChartId     int `description:"移动到的位置,上一级的,我的图表ID,如果没有上一级,则传0"`
+	NextMyChartId     int `description:"移动到的位置,下一级的,我的图表ID,如果没有下一级,则传0"`
+	MyChartClassifyId int `description:"当前分类id"`
+}
+
+type MoveMyChartClassifyReq struct {
+	MyChartClassifyId int `description:"分类id"`
+	PrevClassifyId    int `description:"上一个兄弟节点分类id"`
+	NextClassifyId    int `description:"下一个兄弟节点分类id"`
+}
+
+// GetMyChartListByCondition 条件获取我的图表列表
+func GetMyChartListByCondition(condition string, pars []interface{}, page, limit int) (list []*MyChartList, err error) {
+	sql := ` SELECT a.my_chart_id,c.sort,b.* FROM my_chart AS a
+			INNER JOIN chart_info AS b ON a.chart_info_id=b.chart_info_id
+			INNER JOIN my_chart_classify_mapping AS c ON a.my_chart_id=c.my_chart_id
+			INNER JOIN my_chart_classify AS d ON c.my_chart_classify_id=d.my_chart_classify_id
+			WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += " GROUP BY a.chart_info_id ORDER BY c.sort ASC LIMIT ?,? "
+	offset := (page - 1) * limit
+	pars = append(pars, offset, limit)
+	err = global.MYSQL["data"].Raw(sql, pars...).Scan(&list).Error
+
+	return
+}
+
+// GetMyChartByCondition 条件获取我的图表
+func GetMyChartByCondition(condition string, pars []interface{}) (list []*MyChartView, err error) {
+	sql := ` SELECT a.*,GROUP_CONCAT(c.my_chart_classify_id SEPARATOR ',') AS my_chart_classify_id FROM my_chart AS a
+			LEFT JOIN  my_chart_classify_mapping AS b ON a.my_chart_id=b.my_chart_id AND a.admin_id=b.admin_id
+			LEFT JOIN my_chart_classify AS c ON b.my_chart_classify_id=c.my_chart_classify_id AND b.admin_id=c.admin_id
+			WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY a.chart_info_id  `
+	err = global.MYSQL["data"].Raw(sql, pars).Scan(&list).Error
+
+	return
+}
+
+// GetMyChartById 主键获取我的图表
+func GetMyChartById(myChartId int, myChartClassifyId string) (item *MyChartView, err error) {
+	sql := ` SELECT a.*,b.sort,c.my_chart_classify_id FROM my_chart AS a
+			INNER JOIN my_chart_classify_mapping AS b ON a.my_chart_id=b.my_chart_id AND a.admin_id=b.admin_id
+			INNER JOIN my_chart_classify AS c ON b.my_chart_classify_id=c.my_chart_classify_id AND b.admin_id=c.admin_id
+			WHERE 1=1 AND a.my_chart_id = ? AND b.my_chart_classify_id = ?`
+	err = global.MYSQL["data"].Raw(sql, myChartId, myChartClassifyId).First(&item).Error
+
+	return
+}

+ 46 - 0
models/tables/my_chart_classify/my_chart_classify.go

@@ -0,0 +1,46 @@
+package my_chart_classify
+
+
+import (
+	"time"
+)
+
+// MyChartClassify 我的图表分类
+type MyChartClassify struct {
+	MyChartClassifyId   int       `gorm:"primaryKey;column:my_chart_classify_id;type:int(11);not null" json:"myChartClassifyId"`
+	MyChartClassifyName string    `gorm:"uniqueIndex:idx_my_chart_classify_name;column:my_chart_classify_name;type:varchar(255);default:''" json:"myChartClassifyName"` // 分类名称
+	AdminID             int       `gorm:"uniqueIndex:idx_my_chart_classify_name;column:admin_id;type:int(11)" json:"adminId"`                                           // 用户id
+	Sort                int       `gorm:"column:sort;type:int(9);default:0" json:"sort"`                                                                                // 排序字段,值越小,越靠前
+	IsPublic            uint8     `gorm:"column:is_public;type:tinyint(4) unsigned;default:0" json:"isPublic"`					// 是否所有人可见,0:仅自己可见,1:所有人可见
+	IsCompanyPublic		uint8     `gorm:"column:is_company_public;type:tinyint(4) unsigned;default:0" json:"isCompanyPublic"`	// 是否用户可见:0-否 1-是
+	CreateTime          time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`
+	ModifyTime          time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`
+	PublicTime          time.Time `gorm:"column:public_time;type:datetime" json:"publicTime"`					// 公开时间
+	CompanyPublicTime	time.Time `gorm:"column:company_public_time;type:datetime" json:"companyPublicTime"`	// 用户可见公开时间
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *MyChartClassify) TableName() string {
+	return "my_chart_classify"
+}
+
+// MyChartClassifyColumns get sql column name.获取数据库列名
+var MyChartClassifyColumns = struct {
+	MyChartClassifyID   string
+	MyChartClassifyName string
+	AdminID             string
+	Sort                string
+	IsPublic            string
+	CreateTime          string
+	ModifyTime          string
+	PublicTime          string
+}{
+	MyChartClassifyID:   "my_chart_classify_id",
+	MyChartClassifyName: "my_chart_classify_name",
+	AdminID:             "admin_id",
+	Sort:                "sort",
+	IsPublic:            "is_public",
+	CreateTime:          "create_time",
+	ModifyTime:          "modify_time",
+	PublicTime:          "public_time",
+}

+ 41 - 0
models/tables/my_chart_classify/query.go

@@ -0,0 +1,41 @@
+package my_chart_classify
+
+import (
+	"errors"
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/utils"
+)
+
+// GetClassifyListByCondition 根据条件获取图表分类列表
+func GetClassifyListByCondition(condition map[string]interface{}, sort string) (list []*MyChartClassify, err error) {
+	maps, values, buildErr := utils.WhereBuild(condition)
+	if buildErr != nil {
+		err = errors.New("系统异常,生成查询语句失败")
+		return
+	}
+	err = global.MYSQL["data"].Model(MyChartClassify{}).Where(maps, values...).Order(sort).Scan(&list).Error
+
+	return
+}
+
+// GetClassifyById 根据主键获取分类信息
+func GetClassifyById(chartClassifyId int) (item *MyChartClassify, err error) {
+	err = global.MYSQL["data"].Model(MyChartClassify{}).Where("my_chart_classify_id = ?", chartClassifyId).First(&item).Error
+
+	return
+}
+
+// GetClassifyByIdAndAdminId 根据ID及adminId获取分类信息
+func GetClassifyByIdAndAdminId(adminId, myChartClassifyId int) (item *MyChartClassify, err error) {
+	err = global.MYSQL["data"].Model(MyChartClassify{}).Where("my_chart_classify_id = ? AND admin_id = ?", myChartClassifyId, adminId).First(&item).Error
+
+	return
+}
+
+// GetFirstClassifyByAdminId 获取账号排序第一条的分类数据
+func GetFirstClassifyByAdminId(adminId int) (item *MyChartClassify, err error) {
+	sql := ` SELECT * FROM my_chart_classify WHERE admin_id=? order by sort asc,my_chart_classify_id asc limit 1`
+	err = global.MYSQL["data"].Raw(sql, adminId).Scan(&item).Error
+
+	return
+}

+ 27 - 0
models/tables/my_chart_classify/update.go

@@ -0,0 +1,27 @@
+package my_chart_classify
+
+import (
+	"fmt"
+	"hongze/hongze_yb/global"
+	"time"
+)
+
+// UpdateMyChartClassifySortByClassifyId 根据分类ID更新排序
+func UpdateMyChartClassifySortByClassifyId(adminId, classifyId, nowSort int, updateSort string) (err error) {
+	sql := ` update my_chart_classify set sort = ` + updateSort + ` WHERE admin_id = ? and sort > ? `
+	if classifyId > 0 {
+		sql += ` or ( my_chart_classify_id > ` + fmt.Sprint(classifyId) + ` and sort = ` + fmt.Sprint(nowSort) + `)`
+	}
+	err = global.MYSQL["data"].Exec(sql, adminId, nowSort).Error
+
+	return
+}
+
+// UpdateClassifySort 更新分类排序
+func UpdateClassifySort(adminId, classifyId, nowSort int, modifyTime time.Time) (err error) {
+	err = global.MYSQL["data"].Model(MyChartClassify{}).Select("Sort", "ModifyTime").Where("admin_id = ? AND my_chart_classify_id = ?", adminId, classifyId).Updates(MyChartClassify{
+		Sort: nowSort,
+		ModifyTime: modifyTime,
+	}).Error
+	return
+}

+ 39 - 0
models/tables/my_chart_classify_mapping/my_chart_classify_mapping.go

@@ -0,0 +1,39 @@
+package my_chart_classify_mapping
+
+import "time"
+
+// MyChartClassifyMapping 我的图表及分类关联表
+type MyChartClassifyMapping struct {
+	MyChartClassifyMappingId int       `gorm:"primaryKey;column:my_chart_classify_mapping_id;type:int(11);not null" json:"myChartClassifyMappingId"`
+	AdminId                  int       `gorm:"column:admin_id;type:int(11)" json:"adminId"`
+	MyChartId                int       `gorm:"column:my_chart_id;type:int(11)" json:"myChartId"`
+	MyChartClassifyId        int       `gorm:"column:my_chart_classify_id;type:int(11)" json:"myChartClassifyId"`
+	CreateTime               time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`
+	ModifyTime               time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`
+	Sort                     float64   `gorm:"column:sort;type:double;default:0" json:"sort"` // 排序
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *MyChartClassifyMapping) TableName() string {
+	return "my_chart_classify_mapping"
+}
+
+// MyChartClassifyMappingColumns get sql column name.获取数据库列名
+var MyChartClassifyMappingColumns = struct {
+	MyChartClassifyMappingID string
+	AdminID                  string
+	MyChartID                string
+	MyChartClassifyID        string
+	CreateTime               string
+	ModifyTime               string
+	Sort                     string
+}{
+	MyChartClassifyMappingID: "my_chart_classify_mapping_id",
+	AdminID:                  "admin_id",
+	MyChartID:                "my_chart_id",
+	MyChartClassifyID:        "my_chart_classify_id",
+	CreateTime:               "create_time",
+	ModifyTime:               "modify_time",
+	Sort:                     "sort",
+}
+

+ 79 - 0
models/tables/my_chart_classify_mapping/query.go

@@ -0,0 +1,79 @@
+package my_chart_classify_mapping
+
+import (
+	"hongze/hongze_yb/global"
+)
+
+// GetMyChartSort 获取我的图表排序
+func GetMyChartSort(adminId, myChartClassifyId, sort int) (item *MyChartClassifyMapping, err error) {
+	sql := ` SELECT * FROM my_chart_classify_mapping WHERE 1=1 AND admin_id = ? AND my_chart_classify_id = ? `
+	if sort == 1 {
+		sql += ` ORDER BY sort DESC LIMIT 1 `
+	} else {
+		sql += ` ORDER BY sort ASC LIMIT 1 `
+	}
+	err = global.MYSQL["data"].Raw(sql, adminId, myChartClassifyId).First(&item).Error
+
+	return
+}
+
+// GetMyChartClassifyMapping 获取图表分类关联信息
+func GetMyChartClassifyMapping(adminId, myChartId, myChartClassifyId int) (item *MyChartClassifyMapping, err error) {
+	sql := `SELECT * FROM my_chart_classify_mapping WHERE admin_id=? AND my_chart_id=? AND my_chart_classify_id=? `
+	err = global.MYSQL["data"].Raw(sql, adminId, myChartId, myChartClassifyId).First(&item).Error
+
+	return
+}
+
+type MyChartSortInfo struct {
+	ChartInfoId			int		`description:"图表ID"`
+	MyChartId			int		`description:"我的图表ID"`
+	MyChartClassifyId	int		`description:"我的图表分类ID"`
+	MyChartClassifyName	string	`description:"我的图表分类名称"`
+	UniqueCode			string	`description:"图表唯一编码"`
+	Sort				float64	`description:"排序"`
+}
+
+// GetClassifyChartSort 获取指定分类图表排序
+func GetClassifyChartSort(myChartClassifyId, sort int) (item []*MyChartClassifyMapping, err error) {
+	sql := ` SELECT * FROM my_chart_classify_mapping WHERE 1=1 AND my_chart_classify_id = ? `
+	if sort == 1 {
+		sql += ` ORDER BY sort DESC `
+	} else {
+		sql += ` ORDER BY sort ASC `
+	}
+	err = global.MYSQL["data"].Raw(sql, myChartClassifyId).Scan(&item).Error
+
+	return
+}
+
+// GetMyChartSortInfoList 获取我的图表信息
+func GetMyChartSortInfoList(myChartClassifyId string, sort int) (item []*MyChartSortInfo, err error) {
+	sql := `SELECT
+				a.my_chart_id,
+				a.my_chart_classify_id,
+				a.sort,
+				c.chart_info_id,
+				c.unique_code,
+				d.my_chart_classify_name
+			FROM
+				my_chart_classify_mapping AS a
+			INNER JOIN
+				my_chart AS b ON a.my_chart_id = b.my_chart_id
+			INNER JOIN
+				chart_info AS c ON b.chart_info_id = c.chart_info_id
+			INNER JOIN
+				my_chart_classify AS d ON a.my_chart_classify_id = d.my_chart_classify_id
+			WHERE
+				1 = 1
+			AND a.my_chart_classify_id = ? `
+			//GROUP BY c.chart_info_id `
+	if sort == 1 {
+		sql += ` ORDER BY sort DESC `
+	} else {
+		sql += ` ORDER BY sort ASC `
+	}
+	err = global.MYSQL["data"].Raw(sql, myChartClassifyId).Scan(&item).Error
+
+	return
+}

+ 11 - 0
models/tables/my_chart_classify_mapping/update.go

@@ -0,0 +1,11 @@
+package my_chart_classify_mapping
+
+import "hongze/hongze_yb/global"
+
+// MyChartMove 移动我的图表
+func MyChartMove(sort float64, adminId int, myChartId, myChartClassifyId int) (err error) {
+	sql := ` UPDATE my_chart_classify_mapping SET sort = ?,modify_time=NOW() WHERE admin_id=? AND my_chart_id=? AND my_chart_classify_id=? `
+	err = global.MYSQL["data"].Exec(sql, sort, adminId, myChartId, myChartClassifyId).Error
+
+	return
+}

+ 10 - 0
models/tables/my_chart_log/create.go

@@ -0,0 +1,10 @@
+package my_chart_log
+
+import "hongze/hongze_yb/global"
+
+func (myCharLogInfo *MyChartLog) Create() (myChartInfoLogId int, err error) {
+	err = global.MYSQL["data"].Create(myCharLogInfo).Error
+	myChartInfoLogId = myCharLogInfo.MyChartLogId
+	return
+}
+

+ 46 - 0
models/tables/my_chart_log/my_chart_log.go

@@ -0,0 +1,46 @@
+package my_chart_log
+
+import (
+	"time"
+)
+
+// MyChartLog 我的图表操作日志
+type MyChartLog struct {
+	MyChartLogId    int       `gorm:"primaryKey;column:my_chart_log_id;type:int(11);not null" json:"myChartLogId"`
+	MyChartId       int       `gorm:"index:idx_my_chart_id;column:my_chart_id;type:int(11)" json:"myChartId"`
+	ChartInfoId     int       `gorm:"column:chart_info_id;type:int(11)" json:"chartInfoId"`
+	SysUserId       int       `gorm:"column:sys_user_id;type:int(11)" json:"sysUserId"`
+	CreateTime      time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`
+	SysUserRealName string    `gorm:"column:sys_user_real_name;type:varchar(50);default:''" json:"sysUserRealName"`
+	Content         string    `gorm:"column:content;type:text" json:"content"`
+	Status          string    `gorm:"column:status;type:varchar(50);default:''" json:"status"`
+	Method          string    `gorm:"column:method;type:varchar(255);default:''" json:"method"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *MyChartLog) TableName() string {
+	return "my_chart_log"
+}
+
+// MyChartLogColumns get sql column name.获取数据库列名
+var MyChartLogColumns = struct {
+	MyChartLogID    string
+	MyChartID       string
+	ChartInfoID     string
+	SysUserID       string
+	CreateTime      string
+	SysUserRealName string
+	Content         string
+	Status          string
+	Method          string
+}{
+	MyChartLogID:    "my_chart_log_id",
+	MyChartID:       "my_chart_id",
+	ChartInfoID:     "chart_info_id",
+	SysUserID:       "sys_user_id",
+	CreateTime:      "create_time",
+	SysUserRealName: "sys_user_real_name",
+	Content:         "content",
+	Status:          "status",
+	Method:          "method",
+}

+ 2 - 2
models/tables/yb_apply_record/query.go

@@ -25,6 +25,6 @@ func GetByRecordId(recordId int) (item *YbApplyRecord, err error) {
 
 // GetLastNotOpRecordByUserId 根据用户id获取最近的一条未被操作过的申请记录信息
 func GetLastNotOpRecordByUserId(userId int) (item *YbApplyRecord, err error) {
-	err = global.DEFAULT_MYSQL.Where("user_id =  ? and op_status=0", userId).Order("apply_record_id desc").First(&item).Error
+	err = global.DEFAULT_MYSQL.Where("user_id = ? AND op_status = 0", userId).Order("apply_record_id desc").First(&item).Error
 	return
-}
+}

+ 2 - 0
models/tables/yb_apply_record/yb_apply_record.go

@@ -21,6 +21,8 @@ type YbApplyRecord struct {
 	DealTime        time.Time `gorm:"column:deal_time;type:datetime" json:"dealTime"`                               // 处理时间
 	SysUserID       int       `gorm:"column:sys_user_id;type:int(11);default:0" json:"sysUserId"`                   // 处理人id
 	CreateTime      time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`                           // 创建时间
+	IsMove			int		  `gorm:"column:is_move;type:tinyint(4);default:0" json:"is_move"`						// 是否已移动 0-否 1-是
+	Source			int		  `gorm:"column:source;type:tinyint(4);default:1" json:"source"`						// 申请来源 1-我的 2-活动 3-图库
 }
 
 // TableName get sql table name.获取数据库表名

+ 21 - 0
routers/chart.go

@@ -0,0 +1,21 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/chart"
+	"hongze/hongze_yb/middleware"
+)
+
+func InitChart(r *gin.Engine) {
+	rGroup := r.Group("my_chart").Use(middleware.Token(), middleware.CheckChartAuth())
+	{
+		rGroup.GET("/getChartChassify", chart.GetMyChartChassify)
+		rGroup.GET("/getChartList", chart.GetMyChartList)
+		rGroup.POST("/moveMyChart", chart.MoveMyChart)
+		rGroup.POST("/moveMyChartClassify", chart.MoveMyChartClassify)
+		rGroup.GET("/getChartDetail", chart.GetChartInfoDetail)
+		rGroup.POST("/editChartInfo", chart.EditChartInfo)
+		rGroup.POST("/refreshChartInfo", chart.RefreshChartInfo)
+		rGroup.GET("/getChartBeforeAndNext", chart.GetChartBeforeAndNext)
+	}
+}

+ 584 - 0
services/chart/chart_info.go

@@ -0,0 +1,584 @@
+package chart
+
+import (
+	"fmt"
+	"hongze/hongze_yb/global"
+	chartEdbMappingModel "hongze/hongze_yb/models/tables/chart_edb_mapping"
+	chartInfoModel "hongze/hongze_yb/models/tables/chart_info"
+	edbDataModel "hongze/hongze_yb/models/tables/edb_data"
+	edbInfoModel "hongze/hongze_yb/models/tables/edb_info"
+	"hongze/hongze_yb/utils"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// ModifyChartInfoAndMapping 修改图表信息
+func ModifyChartInfoAndMapping(edbInfoIdStr string, req *chartInfoModel.SaveChartInfoReq, chartType int) (err error) {
+	// 开启事务
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	// 更新图表信息
+	if chartType == 1 {
+		sql := ` UPDATE chart_info
+			SET
+            	edb_info_ids = ?,
+				modify_time = NOW(),
+            	date_type = ?,
+				start_date = ?,
+				end_date = ?,
+ 				left_min = ?,
+				left_max = ?,
+				right_min = ?,
+				right_max = ?
+			WHERE chart_info_id = ?`
+		err = tx.Exec(sql, edbInfoIdStr, req.DateType, req.StartDate, req.EndDate, req.LeftMin, req.LeftMax, req.RightMin, req.RightMax, req.ChartInfoId).Error
+	} else {
+		sql := ` UPDATE chart_info
+			SET
+            	edb_info_ids = ?,
+				modify_time = NOW(),
+				calendar = ?,
+				season_start_date = ?,
+				season_end_date = ?,
+				left_min = ?,
+				left_max = ?,
+				right_min = ?,
+				right_max = ?
+			WHERE chart_info_id = ?`
+		err = tx.Exec(sql, edbInfoIdStr, req.Calendar, req.SeasonStartDate, req.SeasonEndDate, req.LeftMin, req.LeftMax, req.RightMin, req.RightMax, req.ChartInfoId).Error
+	}
+	if err != nil {
+		fmt.Println("UPDATE chart_info Err:", err.Error())
+		return
+	}
+
+	var edbInfoIdArr []string
+	mapList := make([]*chartEdbMappingModel.ChartEdbMapping, 0)
+	for _, v := range req.ChartEdbInfoList {
+		edbInfoIdArr = append(edbInfoIdArr, strconv.Itoa(v.EdbInfoId))
+		var count int
+		csql := ` SELECT COUNT(1) AS count FROM chart_edb_mapping WHERE chart_info_id = ? AND edb_info_id = ? `
+		err = tx.Raw(csql, req.ChartInfoId, v.EdbInfoId).Scan(&count).Error
+		if err != nil {
+			fmt.Println("QueryRow Err:", err.Error())
+			return err
+		}
+		if count > 0 {
+			// 更新指标
+			msql := `UPDATE chart_edb_mapping
+				SET
+                 	modify_time = NOW(),
+				 	max_data = ?,
+				 	min_data = ?,
+				 	is_order = ?,
+				 	is_axis = ?,
+				 	edb_info_type = ?,
+				 	lead_value = ?,
+				 	lead_unit = ?,
+				 	chart_style = ?,
+				 	chart_color = ?,
+				 	chart_width = ? 
+				WHERE chart_info_id =? AND edb_info_id=? `
+
+			err = tx.Exec(msql, v.MaxData, v.MinData, v.IsOrder, v.IsAxis, v.EdbInfoType, v.LeadValue, v.LeadUnit, v.ChartStyle, v.ChartColor, v.ChartWidth, req.ChartInfoId, v.EdbInfoId).Error
+			if err != nil {
+				fmt.Println("chart_edb_mapping Err:" + err.Error())
+				return err
+			}
+		} else {
+			mapItem := new(chartEdbMappingModel.ChartEdbMapping)
+			mapItem.ChartInfoId = req.ChartInfoId
+			mapItem.EdbInfoId = v.EdbInfoId
+			mapItem.CreateTime = time.Now()
+			mapItem.ModifyTime = time.Now()
+			timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+			mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
+			mapItem.MaxData = v.MaxData
+			mapItem.MinData = v.MinData
+			mapItem.IsOrder = 0
+			if v.IsOrder {
+				mapItem.IsOrder = 1
+			}
+			mapItem.IsAxis = v.IsAxis
+			mapItem.EdbInfoType = v.EdbInfoType
+			mapItem.LeadValue = v.LeadValue
+			mapItem.LeadUnit = v.LeadUnit
+			mapItem.ChartStyle = v.ChartStyle
+			mapItem.ChartColor = v.ChartColor
+			mapItem.ChartWidth = v.ChartWidth
+			mapList = append(mapList, mapItem)
+		}
+	}
+
+	// 批量新增指标
+	if len(mapList) > 0 {
+		err = tx.Create(mapList).Error
+		if err != nil {
+			fmt.Println("AddChartEdbMapping Err:" + err.Error())
+			return err
+		}
+	}
+
+	// 清除原图表指标
+	if len(edbInfoIdArr) > 0 {
+		edbInfoIdStr := strings.Join(edbInfoIdArr, ",")
+		if edbInfoIdStr != "" {
+			dsql := `DELETE FROM chart_edb_mapping WHERE chart_info_id=? AND edb_info_id NOT IN(` + edbInfoIdStr + `)`
+			err = tx.Exec(dsql, req.ChartInfoId).Error
+			if err != nil {
+				fmt.Println("delete err:" + err.Error())
+				return err
+			}
+		}
+	}
+
+	return
+}
+
+// RefreshChartInfo 刷新图表
+func RefreshChartInfo(chartInfoId int) (err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			//go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "ChartInfoRefresh:"+errMsg, utils.EmailSendToUsers)
+			fmt.Println("ChartInfoRefresh Err:" + errMsg)
+		}
+	}()
+
+	// 获取需要刷新的指标
+	baseEdbInfoArr, calculateInfoArr, err := GetChartInfoRefreshData(chartInfoId)
+	if err != nil {
+		errMsg = "获取需要刷新的指标失败:Err:" + err.Error()
+		return
+	}
+
+	newBaseEdbInfoArr := make([]*edbInfoModel.EdbInfo, 0)
+	baseMap := make(map[int]*edbInfoModel.EdbInfo)
+	for _, bv := range baseEdbInfoArr {
+		if _, ok := baseMap[bv.EdbInfoId]; !ok {
+			newBaseEdbInfoArr = append(newBaseEdbInfoArr, bv)
+		}
+		baseMap[bv.EdbInfoId] = bv
+	}
+
+	fmt.Println("calculateInfoArr:", len(calculateInfoArr))
+
+	newCalculateInfoArr := make([]*edbInfoModel.EdbInfo, 0)
+	calculateMap := make(map[int]*edbInfoModel.EdbInfo)
+	var calculateArr []int
+	for _, bv := range calculateInfoArr {
+		if _, ok := calculateMap[bv.EdbInfoId]; !ok {
+			newCalculateInfoArr = append(newCalculateInfoArr, bv)
+			calculateArr = append(calculateArr, bv.EdbInfoId)
+		}
+		calculateMap[bv.EdbInfoId] = bv
+	}
+	sort.Ints(calculateArr)
+
+	var startDate string
+	for _, bv := range newBaseEdbInfoArr {
+		source := bv.Source
+		edbInfoId := bv.EdbInfoId
+		edbCode := bv.EdbCode
+		startDate = bv.StartDate.Format(utils.FormatDate)
+		sTime, err := time.Parse(utils.FormatDate, bv.EndDate.Format(utils.FormatDate))
+		if err != nil {
+			return err
+		}
+		startDate = sTime.Format(utils.FormatDate)
+
+		fmt.Println("source:", source)
+
+		if source == utils.DATA_SOURCE_THS {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByThs")
+			err = RefreshEdbDataByThs(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshEdbDataByThs Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_WIND {
+			endDate := time.Now().Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByWind")
+			err = RefreshEdbDataByWind(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshEdbDataByWind Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_PB {
+			startDate := sTime.Format(utils.FormatDateUnSpace)
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDateUnSpace)
+			fmt.Println("DO:RefreshEdbDataByPb")
+			err = RefreshEdbDataByPb(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshEdbDataByPb Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_MANUAL {
+			fmt.Println("DO:RefreshAllEdbDataByManual:" + edbCode)
+			err = RefreshAllEdbDataByManual(edbInfoId, bv.Source, edbCode)
+			if err != nil {
+				errMsg = "RefreshEdbDataByManual Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_LZ {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByLz")
+			err = RefreshEdbDataByLz(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshEdbDataByLz Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_YS {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshAllEdbDataByYs")
+			err = RefreshAllEdbDataByYs(edbInfoId, source, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshEdbDataByYs Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_GL {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByGl")
+			err = RefreshEdbDataByGl(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshEdbDataByGl Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_LT {
+			endDate := time.Now().Format(utils.FormatDate)
+			fmt.Println("DO:RefreshAllEdbDataByLt")
+			err = RefreshAllEdbDataByLt(edbInfoId, source, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllEdbDataByLT Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_ZZ {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByZz")
+			err = RefreshEdbDataByZz(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllEdbDataByZz Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_DL {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByDl")
+			err = RefreshEdbDataByDl(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllEdbDataByDl Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_SH {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataBySh")
+			err = RefreshEdbDataBySh(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllEdbDataBySh Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_CFFEX {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByCffex")
+			err = RefreshEdbDataByCffex(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllEdbDataByCffex Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_SHFE {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByShfe")
+			err = RefreshEdbDataByShfe(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllEdbDataByShfe Err:" + err.Error()
+			}
+		} else if source == utils.DATA_SOURCE_GIE {
+			endDate := time.Now().AddDate(utils.DATA_END_DATE_LIMIT, 0, 0).Format(utils.FormatDate)
+			fmt.Println("DO:RefreshEdbDataByGie")
+			err = RefreshEdbDataByGie(edbInfoId, edbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshEdbDataByGie Err:" + err.Error()
+			}
+		}
+
+		maxAndMinItem, err := edbDataModel.GetEdbInfoMaxAndMinInfo(source, edbCode)
+		if err != nil {
+			return err
+		}
+		if maxAndMinItem != nil {
+			err = edbDataModel.ModifyEdbInfoMaxAndMinInfo(edbInfoId, maxAndMinItem)
+			if err != nil {
+				return err
+			}
+		}
+	}
+
+	endDate := "" //计算指标不限制日期
+	//刷新相关计算指标
+
+	for _, v := range calculateArr {
+		edbInfo := calculateMap[v]
+		if edbInfo == nil {
+			return err
+		}
+		edbInfoId := edbInfo.EdbInfoId
+		source := edbInfo.Source
+		edbCode := edbInfo.EdbCode
+
+		if source == utils.DATA_SOURCE_CALCULATE {
+			startDate = edbInfo.StartDate.Format(utils.FormatDate)
+			sTime, err := time.Parse(utils.FormatDate, edbInfo.EndDate.Format(utils.FormatDate))
+			if err != nil {
+				return err
+			}
+			startDate = sTime.Format(utils.FormatDate)
+
+			var edbInfoIdBytes []string
+			calculateMap, err := edbDataModel.GetEdbInfoCalculateDetail(edbInfoId, edbInfo.Source)
+			if err != nil {
+				errMsg = "GetEdbInfoCalculateDetail Err:" + err.Error()
+				return err
+			}
+			var formulaStr string
+			edbInfoList := make([]*edbInfoModel.EdbInfo, 0)
+
+			for _, v := range calculateMap {
+				formulaStr += v.FromTag + ","
+				edbInfoIdBytes = append(edbInfoIdBytes, v.FromTag)
+				edbInfo, _ := edbInfoModel.GetEdbInfoById(v.FromEdbInfoId)
+				edbInfoList = append(edbInfoList, edbInfo)
+			}
+			fmt.Println("DO:RefreshAllCalculate")
+			err = RefreshAllCalculate(edbInfoList, int(edbInfoId), source, edbInfo.EdbCode, edbInfo.CalculateFormula, startDate, endDate, edbInfoIdBytes)
+			if err != nil {
+				errMsg = "RefreshCalculate Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_LJZZY { //刷新累计值转月值
+			fmt.Println("DO:GetEdbInfoCalculateLjzzyDetail")
+			calculateLjzzy, err := edbDataModel.GetEdbInfoCalculateLjzzyDetail(edbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoCalculateLjzzyDetail Err:" + err.Error()
+				return err
+			}
+			fromEdbInfo, err := edbInfoModel.GetEdbInfoById(calculateLjzzy.FromEdbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoById Err:" + err.Error()
+				return err
+			}
+			startDate = edbInfo.StartDate.Format(utils.FormatDate)
+			endDate = time.Now().Format(utils.FormatDate)
+			fmt.Println("DO:RefreshAllCalculateLjzzy")
+			err = RefreshAllCalculateLjzzy(edbInfoId, source, fromEdbInfo, calculateLjzzy.EdbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllCalculateLjzzy Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_TBZ { //刷新同比值
+			calculateTbz, err := edbDataModel.GetEdbInfoCalculateTbzDetail(edbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoCalculateTbzDetail Err:" + err.Error()
+				return err
+			}
+			fromEdbInfo, err := edbInfoModel.GetEdbInfoById(calculateTbz.FromEdbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoById Err:" + err.Error()
+				return err
+			}
+			startDate = edbInfo.StartDate.Format(utils.FormatDate)
+			endDate = time.Now().Format(utils.FormatDate)
+			fmt.Println("DO:RefreshAllCalculateTbz")
+			err = RefreshAllCalculateTbz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllCalculateTbz Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_TCZ { //同差值
+			calculateTcz, err := edbDataModel.GetEdbInfoCalculateTczDetail(edbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoCalculateTczDetail Err:" + err.Error()
+				return err
+			}
+			fromEdbInfo, err := edbInfoModel.GetEdbInfoById(calculateTcz.FromEdbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoById Err:" + err.Error()
+				return err
+			}
+			startDate = edbInfo.StartDate.Format(utils.FormatDate)
+			endDate = time.Now().Format(utils.FormatDate)
+			fmt.Println("DO:RefreshAllCalculateTcz")
+			err = RefreshAllCalculateTcz(edbInfoId, source, fromEdbInfo, calculateTcz.EdbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshCalculateTcz Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_NSZYDPJJS { //N数值移动平均计算
+			calculateNszydpjjs, err := edbDataModel.GetEdbInfoCalculateNszydpjjsDetail(edbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoCalculateNszydpjjsDetail Err:" + err.Error()
+				return err
+			}
+			fromEdbInfo, err := edbInfoModel.GetEdbInfoById(calculateNszydpjjs.FromEdbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoById Err:" + err.Error()
+				return err
+			}
+			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
+			startDate = edbInfo.StartDate.Format(utils.FormatDate)
+			fmt.Println("DO:RefreshAllCalculateNszydpjjs")
+			err = RefreshAllCalculateNszydpjjs(edbInfoId, edbInfo.Source, formulaInt, fromEdbInfo, calculateNszydpjjs.EdbCode, startDate)
+			if err != nil {
+				errMsg = "RefreshCalculateNszydpjjs Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_HBZ { //刷新环比值
+			calculateTbz, err := edbDataModel.GetEdbInfoCalculateHbzDetail(edbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoCalculateHbzDetail Err:" + err.Error()
+				return err
+			}
+			fromEdbInfo, err := edbInfoModel.GetEdbInfoById(calculateTbz.FromEdbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoById Err:" + err.Error()
+				return err
+			}
+			startDate = edbInfo.StartDate.Format(utils.FormatDate)
+			endDate = time.Now().Format(utils.FormatDate)
+			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
+			fmt.Println("DO:RefreshAllCalculateHbz")
+			err = RefreshAllCalculateHbz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate, formulaInt)
+			if err != nil {
+				errMsg = "RefreshAllCalculateHbz Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_HCZ { //刷新环差值
+			calculateTbz, err := edbDataModel.GetEdbInfoCalculateHczDetail(edbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoCalculateHczDetail Err:" + err.Error()
+				return err
+			}
+			fromEdbInfo, err := edbInfoModel.GetEdbInfoById(calculateTbz.FromEdbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoById Err:" + err.Error()
+				return err
+			}
+			startDate = edbInfo.StartDate.Format(utils.FormatDate)
+			endDate = time.Now().Format(utils.FormatDate)
+			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
+			fmt.Println("DO:RefreshAllCalculateHcz")
+			err = RefreshAllCalculateHcz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate, formulaInt)
+			if err != nil {
+				errMsg = "RefreshAllCalculateHcz Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_BP { //刷新变频
+			calculateTbz, err := edbDataModel.GetEdbInfoCalculateBpDetail(edbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoCalculateTbzDetail Err:" + err.Error()
+				return err
+			}
+			fromEdbInfo, err := edbInfoModel.GetEdbInfoById(calculateTbz.FromEdbInfoId)
+			if err != nil {
+				errMsg = "GetEdbInfoById Err:" + err.Error()
+				return err
+			}
+			startDate = edbInfo.StartDate.Format(utils.FormatDate)
+			endDate = time.Now().Format(utils.FormatDate)
+			fmt.Println("DO:RefreshAllCalculateBp")
+			err = RefreshAllCalculateBp(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate)
+			if err != nil {
+				errMsg = "RefreshAllCalculateBp Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_ZJPJ { //刷新直接拼接数据
+			fmt.Println("DO:RefreshAllCalculateZjpj")
+			err = RefreshAllCalculateZjpj(edbInfo)
+			if err != nil {
+				errMsg = "RefreshAllCalculateZjpj Err:" + err.Error()
+				return err
+			}
+		} else if source == utils.DATA_SOURCE_CALCULATE_LJZTBPJ { //刷新累计值同比拼接数据
+			fmt.Println("DO:RefreshAllCalculateLjztbpj")
+			err = RefreshAllCalculateLjztbpj(edbInfo)
+			if err != nil {
+				errMsg = "RefreshAllCalculateLjztbpj Err:" + err.Error()
+				return err
+			}
+		}
+
+		maxAndMinItem, err := edbDataModel.GetEdbInfoMaxAndMinInfo(source, edbCode)
+		if err != nil {
+			return err
+		}
+
+		if maxAndMinItem != nil {
+			err = edbDataModel.ModifyEdbInfoMaxAndMinInfo(edbInfoId, maxAndMinItem)
+			if err != nil {
+				return err
+			}
+		}
+		fmt.Println("end calculateArr:", v, time.Now())
+	}
+
+	return
+}
+
+// GetChartInfoRefreshData 获取需要刷新的指标
+func GetChartInfoRefreshData(chartInfoId int) (baseEdbInfoArr, calculateInfoArr []*edbInfoModel.EdbInfo, err error) {
+	sql := ` SELECT b.* FROM chart_edb_mapping AS a
+		   INNER JOIN edb_info AS b ON a.edb_info_id=b.edb_info_id 
+		   WHERE a.chart_info_id=? `
+	edbInfoList := make([]*edbInfoModel.EdbInfo, 0)
+	err = global.MYSQL["data"].Raw(sql, chartInfoId).Scan(&edbInfoList).Error
+	if err != nil {
+		return
+	}
+
+	for _, v := range edbInfoList {
+		fmt.Println(v.EdbInfoId, v.EdbType)
+		if v.EdbType == 1 {
+			baseEdbInfoArr = append(baseEdbInfoArr, v)
+		} else {
+			calculateInfoArr = append(calculateInfoArr, v)
+			newBaseEdbInfoArr, newCalculateInfoArr, err := GetChartRefreshEdbInfo(v.EdbInfoId, v.Source, 0)
+			if err != nil {
+				return baseEdbInfoArr, calculateInfoArr, err
+			}
+			baseEdbInfoArr = append(baseEdbInfoArr, newBaseEdbInfoArr...)
+			calculateInfoArr = append(calculateInfoArr, newCalculateInfoArr...)
+		}
+	}
+
+	return
+}
+
+// GetChartRefreshEdbInfo
+func GetChartRefreshEdbInfo(edbInfoId, source, n int) (baseEdbInfoArr, calculateInfoArr []*edbInfoModel.EdbInfo, err error) {
+	calculateList, err := GetEdbInfoCalculateMap(edbInfoId, source)
+	if err != nil && err != utils.ErrNoRow {
+		return
+	}
+	n++
+	for _, item := range calculateList {
+		fmt.Println(item.EdbInfoId)
+		if item.EdbType == 1 {
+			baseEdbInfoArr = append(baseEdbInfoArr, item)
+		} else {
+			calculateInfoArr = append(calculateInfoArr, item)
+			if n > 10 {
+				return
+			}
+			newBaseEdbInfoArr, newCalculateInfoArr, _ := GetChartRefreshEdbInfo(item.EdbInfoId, item.Source, n)
+			baseEdbInfoArr = append(baseEdbInfoArr, newBaseEdbInfoArr...)
+			calculateInfoArr = append(calculateInfoArr, newCalculateInfoArr...)
+		}
+	}
+
+	return
+}
+
+func GetEdbInfoCalculateMap(edbInfoId, source int) (list []*edbInfoModel.EdbInfo, err error) {
+	sql := ` SELECT b.* FROM edb_info_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? ORDER BY sort ASC `
+	err = global.MYSQL["data"].Exec(sql, edbInfoId).Error
+
+	return
+}

+ 3676 - 0
services/chart/edb_data.go

@@ -0,0 +1,3676 @@
+package chart
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"github.com/yidane/formula"
+	"hongze/hongze_yb/global"
+	edbDataModel "hongze/hongze_yb/models/tables/edb_data"
+	edbInfoModel "hongze/hongze_yb/models/tables/edb_info"
+	"hongze/hongze_yb/utils"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type EdbDataFromThs struct {
+	DataVol   int64       	`json:"dataVol"`
+	Errmsg    string      	`json:"errmsg"`
+	Errorcode int64       	`json:"errorcode"`
+	Perf      interface{} 	`json:"perf"`
+	Tables    []struct {
+		ID    []string  	`json:"id"`
+		Time  []string  	`json:"time"`
+		Value []float64 	`json:"value"`
+	}						`json:"tables"`
+}
+
+func RefreshEdbDataByThs(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+	HzServerDataUrl := ""
+	if global.CONFIG.Serve.RunMode == "release" {
+		HzServerDataUrl = "http://172.19.173.231:7000/"
+	} else {
+		HzServerDataUrl = "http://139.196.136.213:7000/"
+	}
+
+	thsUrl := HzServerDataUrl + `edbInfo/ths?EdbCode=%s&StartDate=%s&EndDate=%s`
+	thsUrl = fmt.Sprintf(thsUrl, edbCode, startDate, endDate)
+	//utils.FileLog.Info("thsUrl:%s", thsUrl)
+
+	reqRes, err := http.Get(thsUrl)
+	if err != nil {
+		return
+	}
+	defer reqRes.Body.Close()
+	body, err := ioutil.ReadAll(reqRes.Body)
+	if err != nil {
+		return
+	}
+
+	fmt.Println("GetEdbDataByThs body:")
+	fmt.Println(string(body))
+
+	item := new(EdbDataFromThs)
+	err = json.Unmarshal(body, &item)
+	if err != nil {
+		return
+	}
+	if item.Errorcode != 0 {
+		err = errors.New(string(body))
+		return
+	}
+	if len(item.Tables) > 0 {
+		table := item.Tables[0]
+		dataLen := len(table.Time)
+		addSql := ` INSERT INTO edb_data_ths(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+		nowStr := time.Now().Format(utils.FormatDateTime)
+		var isAdd bool
+		for i := 0; i < dataLen; i++ {
+			eDate := table.Time[i]
+			sValue := table.Value[i]
+
+			count, err := edbDataModel.GetEdbDataThsByCodeAndDate(edbCode, eDate)
+			if err != nil && err != utils.ErrNoRow {
+				return err
+			}
+			if count <= 0 {
+				dataTime, err := time.Parse(utils.FormatDate, eDate)
+				if err != nil {
+
+				}
+				timestamp := dataTime.UnixNano() / 1e6
+				timeStr := fmt.Sprintf("%d", timestamp)
+
+				addSql += "("
+				addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + eDate + "'" + "," + utils.SubFloatToString(sValue, 30) + "," + "'" + nowStr + "'" +
+					"," + "'" + nowStr + "'"
+				addSql += "," + "'" + timeStr + "'"
+				addSql += "),"
+				isAdd = true
+			} else {
+				err = edbDataModel.ModifyEdbDataThs(int64(edbInfoId), eDate, sValue)
+				if err != nil {
+					return err
+				}
+			}
+		}
+
+		if isAdd {
+			addSql = strings.TrimRight(addSql, ",")
+			err = edbDataModel.AddEdbDataThsBySql(addSql)
+			if err != nil {
+				fmt.Println("AddEdbDataThs Err", err.Error())
+				return
+			}
+		}
+	}
+
+	return
+}
+
+type EdbDataFromWind struct {
+	Close  map[string]float64 `json:"CLOSE"`
+	Dt     map[string]int64   `json:"DT"`
+	ErrMsg string
+}
+
+func RefreshEdbDataByWind(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("GetEdbDataByWind Err:" + err.Error())
+		}
+	}()
+
+	fmt.Println("startDate,endDate:",startDate,endDate)
+
+	thsUrl := utils.Hz_Data_Url + `edbInfo/wind?EdbCode=%s&StartDate=%s&EndDate=%s`
+	thsUrl = fmt.Sprintf(thsUrl, edbCode, startDate, endDate)
+	//utils.FileLog.Info("thsUrl:%s", thsUrl)
+
+	reqRes, err := http.Get(thsUrl)
+	if err != nil {
+		return
+	}
+	defer reqRes.Body.Close()
+	body, err := ioutil.ReadAll(reqRes.Body)
+	if err != nil {
+		return
+	}
+	
+	fmt.Println("GetEdbDataByThs body:")
+	fmt.Println(string(body))
+	//utils.FileLog.Info("wind result:"+string(body))
+
+	item := new(EdbDataFromWind)
+	err = json.Unmarshal(body, &item)
+	if err != nil {
+		return
+	}
+	addSql := ` INSERT INTO edb_data_wind(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	nowStr := time.Now().Format(utils.FormatDateTime)
+	var isAdd bool
+	for k, v := range item.Dt {
+		timeStr := fmt.Sprintf("%d", v)
+
+		v = v / 1000
+		t := time.Unix(v, 0)
+		dateTime := t.Format(utils.FormatDate)
+		val := item.Close[k]
+
+		count, err := edbDataModel.GetEdbDataWindByCodeAndDate(edbCode, dateTime)
+		if err != nil && err != utils.ErrNoRow {
+			return err
+		}
+		if count <= 0 {
+			isAdd = true
+			fmt.Println(dateTime)
+			addSql += "("
+			addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + dateTime + "'" + "," + utils.SubFloatToString(val, 30) + "," + "'" + nowStr + "'" +
+				"," + "'" + nowStr + "'"
+			addSql += "," + "'" + timeStr + "'"
+			addSql += "),"
+		} else {
+			err = edbDataModel.ModifyEdbDataWind(int64(edbInfoId), dateTime, val)
+			if err != nil {
+				return err
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = edbDataModel.AddEdbDataWindBySql(addSql)
+		if err != nil {
+			fmt.Println("AddEdbDataWind Err", err.Error())
+			return
+		}
+	}
+	return
+}
+
+type EdbDataFromPb struct {
+	Date   map[string]int64   `json:"date"`
+	Ticker map[string]string  `json:"ticker"`
+	Field  map[string]string  `json:"field"`
+	Value  map[string]float64 `json:"value"`
+}
+
+func RefreshEdbDataByPb(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+	refreshEdbCode := edbCode
+	edbCode = url.QueryEscape(edbCode)
+	bpUrl := utils.Hz_Data_PB_Url + `edbInfo/pb?EdbCode=%s&StartDate=%s&EndDate=%s`
+	bpUrl = fmt.Sprintf(bpUrl, edbCode, startDate, endDate)
+	//utils.FileLog.Info("bpUrl+" + bpUrl)
+
+	reqRes, err := http.Get(bpUrl)
+	if err != nil {
+		return
+	}
+	defer reqRes.Body.Close()
+	body, err := ioutil.ReadAll(reqRes.Body)
+	if err != nil {
+		return
+	}
+	fmt.Println("RefreshEdbDataByPb body:")
+	fmt.Println(string(body))
+	//utils.FileLog.Info("RefreshEdbDataByPb:" + string(body))
+
+	item := new(EdbDataFromPb)
+	err = json.Unmarshal(body, &item)
+	if err != nil {
+		return
+	}
+	if len(item.Date) > 0 {
+		dateMap := item.Date
+		pbList := make([]*edbDataModel.EdbDataPb, 0)
+		for k, v := range dateMap {
+			timestamp := v
+			v = v / 1000
+			t := time.Unix(v, 0)
+			dateTime := t.Format(utils.FormatDate)
+
+			val := item.Value[k]
+			field := item.Field[k]
+			ticker := item.Ticker[k]
+			if field == "PX_LAST" {
+				//判断数据是否已经存在
+				count, err := edbDataModel.GetEdbDataPbByCodeAndDate(refreshEdbCode, dateTime)
+				if err != nil && err != utils.ErrNoRow {
+					return err
+				}
+				fmt.Println("field:", field)
+				if count <= 0 {
+					item := new(edbDataModel.EdbDataPb)
+					item.EdbCode, _ = url.QueryUnescape(edbCode)
+					item.EdbInfoId = edbInfoId
+					item.CreateTime = time.Now()
+					item.ModifyTime = time.Now()
+					item.DataTime = dateTime
+					item.Value = val
+					item.Status = 1
+					item.Field = field
+					item.Ticker = ticker
+					item.DataTimestamp = timestamp
+					pbList = append(pbList, item)
+				} else {
+					err = edbDataModel.ModifyEdbDataPb(edbInfoId, dateTime, val)
+					if err != nil {
+						return err
+					}
+				}
+			}
+		}
+
+		if len(pbList) > 0 {
+			err = edbDataModel.AddEdbDataPb(pbList)
+			if err != nil {
+				fmt.Println("AddEdbDataPb Err", err.Error())
+				return
+			}
+		}
+	}
+
+	return
+}
+
+//刷新手工指标数据
+func RefreshAllEdbDataByManual(edbInfoId, source int, edbCode string) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		condition += " AND TRADE_CODE=? "
+		pars = append(pars, edbCode)
+	}
+
+	manualDataList, err := edbDataModel.GetEdbdataManualByTradeCode(condition, pars)
+	//获取指标所有数据
+	existDataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+
+	existDataMap := make(map[string]*edbDataModel.EdbDataBase)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v
+	}
+
+	addSql := ` INSERT INTO edb_data_manual(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	manualMap := make(map[string]*edbDataModel.ManualEdbdata)
+	for _, v := range manualDataList {
+		item := v
+		if findItem, ok := existDataMap[v.Dt]; !ok {
+			eDate := item.Dt
+			sValue := item.Close
+
+			dataTime, err := time.Parse(utils.FormatDate, eDate)
+			if err != nil {
+				return err
+			}
+			timestamp := dataTime.UnixNano() / 1e6
+			timeStr := fmt.Sprintf("%d", timestamp)
+
+			addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
+			isAdd = true
+		} else {
+			if findItem.Value != item.Close {
+				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				sql = fmt.Sprintf(sql, dataTableName)
+				err = tx.Exec(sql, item.Close, edbInfoId, item.Dt).Error
+				//err = global.MYSQL["data"].Exec(sql, item.Close, edbInfoId, item.Dt).Error
+				//_, err = o.Raw(sql, item.Close, edbInfoId, item.Dt).Exec()
+				if err != nil {
+					return err
+				}
+			}
+		}
+		manualMap[v.Dt] = v
+	}
+	for _, v := range existDataList {
+		if _, ok := manualMap[v.DataTime]; !ok {
+			go func() {
+				sql := ` DELETE FROM %s WHERE edb_data_id=? `
+				tableName := edbDataModel.GetEdbDataTableName(utils.DATA_SOURCE_MANUAL)
+				sql = fmt.Sprintf(sql, tableName)
+				err = tx.Exec(sql, v.EdbInfoId).Error
+				//err = global.MYSQL["data"].Exec(sql, edbDataId).Error
+			}()
+			//go DeleteEdbDataByIdAndSource(v.EdbDataId, utils.DATA_SOURCE_MANUAL)
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			fmt.Println("RefreshAllEdbDataByManual add Err", err.Error())
+			return
+		}
+	}
+	return
+}
+
+func DeleteEdbDataByIdAndSource(edbDataId, source int) (err error) {
+	sql := ` DELETE FROM %s WHERE edb_data_id=? `
+	tableName := edbDataModel.GetEdbDataTableName(source)
+	sql = fmt.Sprintf(sql, tableName)
+	err = global.MYSQL["data"].Exec(sql, edbDataId).Error
+
+	return
+}
+
+func GetAddSql(edbInfoId, edbCode, dataTime, timestampStr string, value string) (addSql string) {
+	nowStr := time.Now().Format(utils.FormatDateTime)
+	addSql += "("
+	addSql += edbInfoId + "," + "'" + edbCode + "'" + "," + "'" + dataTime + "'" + "," + value + "," + "'" + nowStr + "'" +
+		"," + "'" + nowStr + "'"
+	addSql += "," + "'" + timestampStr + "'"
+	addSql += "),"
+	return
+}
+
+//刷新隆众指标数据
+func RefreshEdbDataByLz(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		condition += " AND b.lz_code=? "
+		pars = append(pars, edbCode)
+	}
+
+	if startDate != "" {
+		condition += " AND a.data_time>=? "
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += " AND a.data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	lzDataList, err := edbDataModel.GetLzSurveyDataByTradeCode(condition, pars)
+
+	addSql := ` INSERT INTO edb_data_lz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	for _, v := range lzDataList {
+		item := v
+		count, err := edbDataModel.GetEdbDataLzByCodeAndDate(edbCode, v.DataTime)
+		if err != nil && err != utils.ErrNoRow {
+			return err
+		}
+		if count <= 0 {
+			nowStr := time.Now().Format(utils.FormatDateTime)
+			eDate := item.DataTime
+			sValue := item.InputValue
+			dataTime, err := time.Parse(utils.FormatDate, eDate)
+			if err != nil {
+				return err
+			}
+			timestamp := dataTime.UnixNano() / 1e6
+			timeStr := fmt.Sprintf("%d", timestamp)
+			addSql += "("
+			addSql += edbInfoIdStr + "," + "'" + edbCode + "'" + "," + "'" + eDate + "'" + "," + sValue + "," + "'" + nowStr + "'" +
+				"," + "'" + nowStr + "'" + "," + "'" + timeStr + "'"
+			addSql += "),"
+			isAdd = true
+		} else {
+			//edbInfoId int64, dataTime, value string
+			//o := orm.NewOrm()
+			//o.Using("data")
+			sql := ` UPDATE edb_data_lz SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+			err = tx.Exec(sql, v.InputValue, int64(edbInfoId), v.DataTime).Error
+			//_, err = o.Raw(sql, value, edbInfoId, dataTime).Exec()
+
+			//err = ModifyEdbDataLz(int64(edbInfoId), v.DataTime, v.InputValue)
+			if err != nil {
+				return err
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+
+	return
+}
+
+//全部刷新有色数据
+func RefreshAllEdbDataByYs(edbInfoId, source int, edbCode, startDate, endDate string) (err error) {
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//获取数据
+	err = SyncSmmIndexDataBase(edbCode, startDate, endDate)
+	if err != nil {
+		err = errors.New("SyncSmmIndexDataBase Err:" + err.Error())
+		return err
+	}
+	//获取已存在指标所有数据
+	existDataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	existDataMap := make(map[string]string)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+	}
+
+	smmDateList := make([]*edbDataModel.BaseFromSmmDataSimple, 0)
+	smmSql := ` SELECT * FROM base_from_smm_data WHERE index_code=? AND data_time>=? `
+	err = global.MYSQL["data"].Raw(smmSql, edbCode, startDate).Scan(&existDataList).Error
+	//_, err = o.Raw(smmSql, edbCode, startDate).QueryRows(&smmDateList)
+	if err != nil {
+		return err
+	}
+
+	addSql := ` INSERT INTO edb_data_ys(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	for _, sv := range smmDateList {
+		if existVal, ok := existDataMap[sv.DataTime]; !ok {
+			dataTime, err := time.Parse(utils.FormatDate, sv.DataTime)
+			if err != nil {
+				return err
+			}
+			timestamp := dataTime.UnixNano() / 1e6
+			timeStr := fmt.Sprintf("%d", timestamp)
+			addSql += GetAddSql(edbInfoIdStr, edbCode, sv.DataTime, timeStr, sv.Value)
+			isAdd = true
+		} else {
+			if existVal != sv.Value {
+				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				sql = fmt.Sprintf(sql, dataTableName)
+
+				err = tx.Exec(sql, sv.Value, edbInfoId, sv.DataTime).Error
+				//_, err = o.Raw(sql, sv.Value, edbInfoId, sv.DataTime).Exec()
+				if err != nil {
+					return err
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+const (
+	dataUrl = "https://dataapi.smm.cn/GetData/" //data url (中文)
+	//dataUrl = "https://dataapi.smm.cn/GetDataEn/" //data url (english edition)
+	authUrl = "https://platform.smm.cn/usercenter/auth" // auth url (for all)
+)
+
+type TokenResp struct {
+	Code int       `json:"Code"`
+	Msg  string    `json:"Msg"`
+	Data TokenData `json:"Data"`
+}
+
+type TokenData struct {
+	Token string `json:"Token"`
+}
+
+//获取token
+func getToken(userName string, password string) (string, error) {
+	encryptAuth := md5.New()
+	encryptAuth.Write([]byte(password)) //encrypt password with md5
+	newPassword := hex.EncodeToString(encryptAuth.Sum(nil))
+
+	resp, err := http.PostForm(authUrl, url.Values{"user_name": {userName}, "password": {newPassword}})
+	if err != nil {
+		return "", err
+	}
+
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		fmt.Println("reponse error", err)
+		return "", err
+	}
+
+	var bodyJsonContent TokenResp
+
+	if err = json.Unmarshal([]byte(body), &bodyJsonContent); err != nil {
+		fmt.Println(err, "unmarsal failure")
+		return "", err
+	}
+
+	var token string
+	if bodyJsonContent.Code == 0 {
+		token = bodyJsonContent.Data.Token
+	}
+
+	//print(token)
+	return token, nil
+}
+
+func SyncSmmIndexDataBase(edbCode, startDate, endDate string) (err error) {
+	//utils.FileLog.Info("start:" + time.Now().Format(utils.FormatDateTime))
+
+	var smmCode string
+	if strings.Contains(edbCode, "#") {
+		smmCode = strings.Split(edbCode, "#")[0]
+	} else {
+		smmCode = edbCode
+	}
+	token, err := getToken("pqian@hzinsights.com", "hz123456")
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	baseSmmItem, err := edbDataModel.GetBaseFromSmmBySmmCode(smmCode)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+
+	if baseSmmItem == nil {
+		err = errors.New("GetBaseFromSmmBySmmCode Err:" + err.Error())
+		return
+	}
+
+	smmIndexAll, err := edbDataModel.GetBaseFromSmmIndexBySmmCode(smmCode)
+	if err != nil {
+		fmt.Println("GetBaseFromSmmIndex Err:" + err.Error())
+		return
+	}
+	existIndexMap := make(map[string]*edbDataModel.BaseFromSmmIndex)
+	for _, item := range smmIndexAll {
+		existIndexMap[item.IndexCode] = item
+	}
+
+	ysItem, err := getApiData(token, edbCode, startDate, endDate)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	if ysItem != nil && ysItem.Code == 200 {
+
+		frequency := ysItem.Data.Frequency
+
+		indexMap := make(map[string]int)
+		smmIndexIdMap := make(map[int]int)
+		indexCodeMap := make(map[int]string)
+
+		indexKey := 0
+		var isDateIndex int
+		for fk, fv := range ysItem.Data.Field {
+			if fv.IsDate == "1" {
+				isDateIndex = fk
+			} else {
+				if !strings.Contains(fv.Name, "产品名称") &&
+					!strings.Contains(fv.Name, "单位") &&
+					!strings.Contains(fv.Name, "时间") &&
+					!strings.Contains(fv.Name, "备注") {
+
+					indexMap[fv.DBColName] = fk
+
+					indexKey += 1
+					indexCode := smmCode + "#" + strconv.Itoa(indexKey)
+
+					if findItem, ok := existIndexMap[indexCode]; !ok {
+						ssmIndex := new(edbDataModel.BaseFromSmmIndex)
+						ssmIndex.Interface = smmCode
+						ssmIndex.Name = baseSmmItem.Name
+						ssmIndex.IndexCode = indexCode
+						ssmIndex.IndexName = baseSmmItem.Name + "_" + fv.Name
+						ssmIndex.Type1 = baseSmmItem.Type1
+						ssmIndex.Type2 = baseSmmItem.Type2
+						ssmIndex.Type3 = baseSmmItem.Type3
+						ssmIndex.Frequency = frequency
+						ssmIndex.Unit = fv.Unit
+						ssmIndex.ApiStartTime = baseSmmItem.ApiStartTime
+						ssmIndex.ApiUpdateTime = baseSmmItem.ApiUpdateTime
+						ssmIndex.StartTime = baseSmmItem.StartTime
+						ssmIndex.FinishTime = baseSmmItem.FinishTime
+						ssmIndex.CreateTime = time.Now()
+						ssmIndex.ModifyTime = time.Now()
+						lastIndexId, err := edbDataModel.AddBaseFromSmmIndex(ssmIndex)
+						if err != nil {
+							err = errors.New("AddBaseFromSmmIndex Err:" + err.Error())
+							return err
+						}
+						smmIndexIdMap[fk] = int(lastIndexId)
+						indexCodeMap[fk] = indexCode
+					} else {
+						smmIndexIdMap[fk] = findItem.BaseFromSmmIndexId
+						indexCodeMap[fk] = findItem.IndexCode
+					}
+				}
+			}
+		}
+
+		existDataMap := make(map[string]*edbDataModel.BaseFromSmmData)
+		for _, mv := range indexCodeMap {
+			indexCode := mv
+			dataAllList, err := edbDataModel.GetBaseFromSmmDataAllByIndexCode(indexCode)
+			if err != nil {
+				err = errors.New("GetBaseFromSmmData Err:" + err.Error())
+				return err
+			}
+			for _, item := range dataAllList {
+				key := item.IndexCode + item.DataTime
+				existDataMap[key] = item
+			}
+		}
+
+		addExistDataMap := make(map[string]string)
+
+		for _, dv := range ysItem.Data.Content {
+			var dataTime string
+			dataTime = dv[isDateIndex]
+			if strings.Contains(dataTime, "Q1") {
+				dataTime = strings.Replace(dataTime, "Q1", "-01", -1)
+				dataTime += "-31"
+			}
+			if strings.Contains(dataTime, "Q2") {
+				dataTime = strings.Replace(dataTime, "Q2", "-06", -1)
+				dataTime += "-30"
+			}
+			if strings.Contains(dataTime, "Q3") {
+				dataTime = strings.Replace(dataTime, "Q3", "-09", -1)
+				dataTime += "-30"
+			}
+			if strings.Contains(dataTime, "Q4") {
+				dataTime = strings.Replace(dataTime, "Q4", "-12", -1)
+				dataTime += "-31"
+			}
+
+			if strings.Contains(dataTime, "H1") {
+				dataTime = strings.Replace(dataTime, "H1", "-06", -1)
+				dataTime += "-30"
+			}
+
+			if strings.Contains(dataTime, "H2") {
+				dataTime = strings.Replace(dataTime, "H2", "-12", -1)
+				dataTime += "-31"
+			}
+
+			if frequency == "月" {
+				monthDate, err := time.Parse("2006-01", dataTime)
+				if err != nil {
+					fmt.Println("time.Parse:" + err.Error())
+				}
+				lastTime := monthDate.AddDate(0, 1, -1)
+				lastYear, lastMonth, lastDay := lastTime.Date()
+				var lastDate string
+				if int(lastMonth) < 10 {
+					lastDate = strconv.Itoa(lastYear) + "-" + "0" + strconv.Itoa(int(lastMonth)) + "-" + strconv.Itoa(lastDay)
+				} else {
+					lastDate = strconv.Itoa(lastYear) + "-" + strconv.Itoa(int(lastMonth)) + "-" + strconv.Itoa(lastDay)
+				}
+				dataTime = lastDate
+			} else if frequency == "年" {
+				dataTime = dataTime + "-12-31"
+			}
+			saveDataTime, err := time.Parse(utils.FormatDate, dataTime)
+			if err != nil {
+				err = errors.New("time.Parse Err:" + err.Error())
+				return err
+			}
+			timestamp := saveDataTime.UnixNano() / 1e6
+			//循环指标
+			for _, v := range indexMap {
+
+				indexCode := indexCodeMap[v]
+				smmIndexId := smmIndexIdMap[v]
+				dataVal := dv[v]
+
+				if indexCode != "" {
+
+					key := indexCode + dataTime
+					val := strings.Replace(dataVal, ",", "", -1)
+					if findData, dataOk := existDataMap[key]; !dataOk {
+						if _, addOK := addExistDataMap[key]; !addOK {
+							if val != "" && val != "-" {
+								dataItem := new(edbDataModel.BaseFromSmmData)
+								dataItem.BaseFromSmmIndexId = smmIndexId
+								dataItem.IndexCode = indexCode
+								dataItem.DataTime = dataTime
+								dataItem.Value = val
+								dataItem.CreateTime = time.Now()
+								dataItem.ModifyTime = time.Now()
+								dataItem.DataTimestamp = timestamp
+								_, err = edbDataModel.AddBaseFromSmmData(dataItem)
+								if err != nil && !strings.Contains(err.Error(), "idx_index_code_date") {
+									fmt.Println("AddBaseFromSmmData Err:" + err.Error())
+									err = errors.New("AddBaseFromSmmData Err:" + err.Error())
+									return err
+								}
+							}
+						}
+					} else {
+						if findData != nil && findData.Value != val { //修改
+							if _, addOK := addExistDataMap[key]; !addOK {
+								if val != "" && val != "-" {
+									err = edbDataModel.ModifyBaseFromSmmData(findData.SmmDataId, val)
+									if err != nil {
+										err = errors.New("ModifyBaseFromSmmData Err:" + err.Error())
+										return err
+									}
+								}
+							}
+						}
+					}
+					addExistDataMap[key] = key
+				}
+			}
+		}
+
+		//修改数据开始,结束日期
+		{
+			indexList, err := edbDataModel.GetBaseFromSmmIndexBySmmCode(smmCode)
+			if err != nil {
+				fmt.Println("GetBaseFromSmmIndexBySmmCode Err:" + err.Error())
+			}
+			for _, sv := range indexList {
+				minDate, maxDate, err := edbDataModel.GetBaseFromSmmMaxOrMinDate(sv.IndexCode)
+				if err != nil {
+					fmt.Println("GetEdbDataSmmMaxOrMinDate Err:" + err.Error())
+				} else {
+					err = edbDataModel.ModifyBaseFromSmmMinDateAndMaxDate(sv.BaseFromSmmIndexId, minDate, maxDate)
+					if err != nil {
+						fmt.Println("ModifyBaseFromSmmMinDateAndMaxDate Err:" + err.Error())
+					}
+				}
+			}
+		}
+	}
+
+	return
+}
+
+/*
+ * request data
+ * sdatetime,edatetime ==>format:yyyy-mm-dd,
+ * apiName ==> data.metal.com(for english)/data.smm.cn (for chinese)
+ */
+func getApiData(token string, apiName string, sdatetime string, edatetime string) (item *edbDataModel.YsResult, err error) {
+	reqUrl := dataUrl + apiName
+	resp, err := http.PostForm(reqUrl, url.Values{"token": {token}, "sdatetime": {sdatetime}, "edatetime": {edatetime}})
+	if err != nil {
+		return nil, err
+	}
+
+	defer resp.Body.Close()
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		fmt.Println("response error")
+		return nil, err
+	}
+	//utils.FileLog.Info("ys result:" + string(body))
+	dataJsonContent := new(edbDataModel.YsResult)
+	if err = json.Unmarshal([]byte(body), &dataJsonContent); err != nil {
+		fmt.Println(err, "data unmarshal failure")
+		return nil, err
+	}
+
+	if dataJsonContent.Code == 200 && len(dataJsonContent.Data.Content) > 0 {
+		return dataJsonContent, nil
+	} else {
+		err = errors.New("code:" + strconv.Itoa(int(dataJsonContent.Code)) + "msg:" + dataJsonContent.Msg)
+	}
+	return nil, nil
+}
+
+func RefreshEdbDataByGl(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		condition += " AND INDEX_CODE=? "
+		pars = append(pars, edbCode)
+	}
+
+	if startDate != "" {
+		condition += " AND DATA_DATE>=? "
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += " AND DATA_DATE<=? "
+		pars = append(pars, endDate)
+	}
+
+	glDataList, err := edbDataModel.GetGlDataByTradeCode(condition, pars)
+
+	addSql := ` INSERT INTO edb_data_gl(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	for _, v := range glDataList {
+		item := v
+		if _, ok := existMap[v.DataTime]; !ok {
+			count, err := edbDataModel.GetEdbDataGlByCodeAndDate(edbCode, v.DataTime)
+			if err != nil && err != utils.ErrNoRow {
+				return err
+			}
+			if count <= 0 {
+				eDate := item.DataTime
+				sValue := item.InputValue
+				if sValue != "" {
+					dataTime, err := time.Parse(utils.FormatDate, eDate)
+					if err != nil {
+						return err
+					}
+					timestamp := dataTime.UnixNano() / 1e6
+					timeStr := fmt.Sprintf("%d", timestamp)
+					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
+					isAdd = true
+				}
+			} else {
+				updateSql := ` UPDATE edb_data_gl SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				//err = global.MYSQL["data"].Exec(sql, value, edbInfoId, dataTime).Error
+				err = tx.Exec(updateSql, v.InputValue, edbInfoId, v.DataTime).Error
+				//err = edbDataModel.ModifyEdbDataGl(int64(edbInfoId), v.DataTime, v.InputValue)
+				if err != nil {
+					return err
+				}
+			}
+		}
+		existMap[v.DataTime] = v.InputValue
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+// RefreshEdbDataByZz 刷新路透社数据
+func RefreshAllEdbDataByLt(edbInfoId, source int, edbCode, startDate, endDate string) (err error) {
+	// 获取路透社数据
+	ltDataList, err := QueryEdbDataByLt(edbCode, startDate, endDate)
+	if err != nil {
+		return
+	}
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	//获取指标所有数据
+	dataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = global.MYSQL["data"].Raw(sql, dataTableName).Scan(&dataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&dataList)
+	if err != nil {
+		return err
+	}
+	dataMap := make(map[string]string)
+	for _, v := range dataList {
+		dataMap[v.DataTime] = v.Value
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+
+	addSql := ` INSERT INTO edb_data_lt(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+
+	for timestampInt, edbValue := range ltDataList {
+		dataTime := time.Unix(timestampInt/1000, 0)
+
+		//校验数据类型对不对
+		valType := reflect.TypeOf(edbValue)
+		if valType == nil {
+			continue
+		}
+		if valType.String() != "float64" {
+			continue
+		}
+		sValue := edbValue.(float64)
+
+		eDate := dataTime.Format(utils.FormatDate)
+		if err != nil {
+			return err
+		}
+
+		saveValue := utils.SubFloatToString(sValue, 30)
+		if existVal, ok := dataMap[eDate]; !ok {
+			timestamp := dataTime.UnixNano() / 1e6
+			timeStr := fmt.Sprintf("%d", timestamp)
+
+			addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, saveValue)
+			isAdd = true
+		} else {
+			if existVal != saveValue {
+				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				sql = fmt.Sprintf(sql, dataTableName)
+				err = tx.Exec(sql, sValue, edbInfoId, eDate).Error
+				//_, err = o.Raw(sql, sValue, edbInfoId, eDate).Exec()
+				if err != nil {
+					return err
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			fmt.Println("RefreshAllEdbDataByLt add Err", err.Error())
+			return
+		}
+	}
+	return
+}
+
+// QueryEdbDataByLt 获取路透社数据
+func QueryEdbDataByLt(edbCode, startDate, endDate string) (dataList map[int64]interface{}, err error) {
+	dataList = make(map[int64]interface{})
+
+	ltUrl := utils.Hz_Data_LT_Url + `edbInfo/ek?EdbCode=%s&StartDate=%s&EndDate=%s`
+	ltUrl = fmt.Sprintf(ltUrl, edbCode, startDate, endDate)
+	//utils.FileLogData.Info("ltUrl:%s", ltUrl)
+	//body, err := http.Get(ltUrl)
+
+	reqRes, err := http.Get(ltUrl)
+	if err != nil {
+		return
+	}
+	defer reqRes.Body.Close()
+	body, err := ioutil.ReadAll(reqRes.Body)
+	if err != nil {
+		return
+	}
+
+	//utils.FileLogData.Info("lt result:%s", string(body))
+
+	//if err != nil {
+	//	return
+	//}
+	//fmt.Println(string(body))
+	item := new(edbDataModel.EdbDataFromLt)
+	err = json.Unmarshal(body, &item)
+
+	if err != nil {
+		return
+	}
+	dataList = item.Close
+	return
+}
+
+// RefreshEdbDataByZz 刷新郑商所指标数据
+func RefreshEdbDataByZz(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	var suffix string
+	if strings.Contains(edbCode, "deal") {
+		suffix = "deal"
+	} else if strings.Contains(edbCode, "buy") {
+		suffix = "buy"
+	} else if strings.Contains(edbCode, "sold") {
+		suffix = "sold"
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		if suffix == "deal" {
+			condition += " AND deal_code=? "
+		} else if suffix == "buy" {
+			condition += " AND buy_code=? "
+		} else {
+			condition += " AND sold_code=? "
+		}
+		pars = append(pars, edbCode)
+	}
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	glDataList, err := edbDataModel.GetZzDataByTradeCode(condition, pars)
+
+	addSql := ` INSERT INTO edb_data_zz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	for _, v := range glDataList {
+		var value string
+		if suffix == "deal" {
+			value = v.DealValue
+		} else if suffix == "buy" {
+			value = v.BuyValue
+		} else {
+			value = v.SoldValue
+		}
+		item := v
+		itemValue := value
+		if _, ok := existMap[v.DataTime]; !ok {
+			count, err := edbDataModel.GetEdbDataZzByCodeAndDate(edbCode, v.DataTime)
+			if err != nil && err != utils.ErrNoRow {
+				return err
+			}
+			if count <= 0 {
+				eDate := item.DataTime
+				sValue := itemValue
+				if sValue != "" {
+					dataTime, err := time.Parse(utils.FormatDate, eDate)
+					if err != nil {
+						return err
+					}
+					timestamp := dataTime.UnixNano() / 1e6
+					timeStr := fmt.Sprintf("%d", timestamp)
+					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
+					isAdd = true
+				}
+			} else {
+				updateSql := ` UPDATE edb_data_zz SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				err = tx.Exec(updateSql, value, edbInfoId, v.DataTime).Error
+				if err != nil {
+					return err
+				}
+			}
+		}
+		existMap[v.DataTime] = value
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+func RefreshEdbDataByDl(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	var suffix string
+	if strings.Contains(edbCode, "deal") {
+		suffix = "deal"
+	} else if strings.Contains(edbCode, "buy") {
+		suffix = "buy"
+	} else if strings.Contains(edbCode, "sold") {
+		suffix = "sold"
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		if suffix == "deal" {
+			condition += " AND deal_code=? "
+		} else if suffix == "buy" {
+			condition += " AND buy_code=? "
+		} else {
+			condition += " AND sold_code=? "
+		}
+		pars = append(pars, edbCode)
+	}
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	glDataList, err := edbDataModel.GetDlDataByTradeCode(condition, pars)
+
+	addSql := ` INSERT INTO edb_data_dl(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	for _, v := range glDataList {
+		var value string
+		if suffix == "deal" {
+			value = v.DealValue
+		} else if suffix == "buy" {
+			value = v.BuyValue
+		} else {
+			value = v.SoldValue
+		}
+		item := v
+		itemValue := value
+		if _, ok := existMap[v.DataTime]; !ok {
+			count, err := edbDataModel.GetEdbDataDlByCodeAndDate(edbCode, v.DataTime)
+			if err != nil && err != utils.ErrNoRow {
+				return err
+			}
+			if count <= 0 {
+				eDate := item.DataTime
+				sValue := itemValue
+				if sValue != "" {
+					dataTime, err := time.Parse(utils.FormatDate, eDate)
+					if err != nil {
+						return err
+					}
+					timestamp := dataTime.UnixNano() / 1e6
+					timeStr := fmt.Sprintf("%d", timestamp)
+					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
+					isAdd = true
+				}
+			} else {
+				updataSql := ` UPDATE edb_data_dl SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				err = tx.Exec(updataSql, value, edbInfoId, v.DataTime).Error
+				if err != nil {
+					return err
+				}
+			}
+		}
+		existMap[v.DataTime] = value
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		if err != nil {
+			return err
+		}
+	}
+
+	return
+}
+
+// RefreshEdbDataBySh 刷新上期所指标数据
+func RefreshEdbDataBySh(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	if err != nil {
+		return
+	}
+	var suffix string
+	if strings.Contains(edbCode, "deal") {
+		suffix = "deal"
+	} else if strings.Contains(edbCode, "buy") {
+		suffix = "buy"
+	} else if strings.Contains(edbCode, "sold") {
+		suffix = "sold"
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		if suffix == "deal" {
+			condition += " AND deal_code=? "
+		} else if suffix == "buy" {
+			condition += " AND buy_code=? "
+		} else {
+			condition += " AND sold_code=? "
+		}
+		pars = append(pars, edbCode)
+	}
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	glDataList, err := edbDataModel.GetShDataByTradeCode(condition, pars)
+
+	addSql := ` INSERT INTO edb_data_sh(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	for _, v := range glDataList {
+		var value string
+		if suffix == "deal" {
+			value = v.DealValue
+		} else if suffix == "buy" {
+			value = v.BuyValue
+		} else {
+			value = v.SoldValue
+		}
+		item := v
+		itemValue := value
+		if _, ok := existMap[v.DataTime]; !ok {
+			count, err := edbDataModel.GetEdbDataShByCodeAndDate(edbCode, v.DataTime)
+			if err != nil && err != utils.ErrNoRow {
+				return err
+			}
+			if count <= 0 {
+				eDate := item.DataTime
+				sValue := itemValue
+				if sValue != "" {
+					dataTime, err := time.Parse(utils.FormatDate, eDate)
+					if err != nil {
+						return err
+					}
+					timestamp := dataTime.UnixNano() / 1e6
+					timeStr := fmt.Sprintf("%d", timestamp)
+					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
+					isAdd = true
+				}
+			} else {
+				updataSql := ` UPDATE edb_data_sh SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				err = tx.Exec(updataSql, value, edbInfoId, v.DataTime).Error
+				if err != nil {
+					return err
+				}
+			}
+		}
+		existMap[v.DataTime] = value
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+
+	return
+}
+
+// RefreshEdbDataByCffex 刷新中金所指标数据
+func RefreshEdbDataByCffex(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	if err != nil {
+		return
+	}
+	var suffix string
+	if strings.Contains(edbCode, "deal") {
+		suffix = "deal"
+	} else if strings.Contains(edbCode, "buy") {
+		suffix = "buy"
+	} else if strings.Contains(edbCode, "sold") {
+		suffix = "sold"
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		if suffix == "deal" {
+			condition += " AND deal_code=? "
+		} else if suffix == "buy" {
+			condition += " AND buy_code=? "
+		} else {
+			condition += " AND sold_code=? "
+		}
+		pars = append(pars, edbCode)
+	}
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	glDataList, err := edbDataModel.GetCffexDataByTradeCode(condition, pars)
+
+	addSql := ` INSERT INTO edb_data_cffex(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	for _, v := range glDataList {
+		var value string
+		if suffix == "deal" {
+			value = v.DealValue
+		} else if suffix == "buy" {
+			value = v.BuyValue
+		} else {
+			value = v.SoldValue
+		}
+		item := v
+		itemValue := value
+		if _, ok := existMap[v.DataTime]; !ok {
+			count, err := edbDataModel.GetEdbDataCffexByCodeAndDate(edbCode, v.DataTime)
+			if err != nil && err != utils.ErrNoRow {
+				return err
+			}
+			if count <= 0 {
+				eDate := item.DataTime
+				sValue := itemValue
+				if sValue != "" {
+					dataTime, err := time.Parse(utils.FormatDate, eDate)
+					if err != nil {
+						return err
+					}
+					timestamp := dataTime.UnixNano() / 1e6
+					timeStr := fmt.Sprintf("%d", timestamp)
+					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
+					isAdd = true
+				}
+			} else {
+				updateSql := ` UPDATE edb_data_cffex SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				err = tx.Exec(updateSql, value, edbInfoId, v.DataTime).Error
+
+				if err != nil {
+					return err
+				}
+			}
+		}
+		existMap[v.DataTime] = value
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+// RefreshEdbDataByShfe 刷新上期能源指标数据
+func RefreshEdbDataByShfe(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	var suffix string
+	if strings.Contains(edbCode, "deal") {
+		suffix = "deal"
+	} else if strings.Contains(edbCode, "buy") {
+		suffix = "buy"
+	} else if strings.Contains(edbCode, "sold") {
+		suffix = "sold"
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		if suffix == "deal" {
+			condition += " AND deal_code=? "
+		} else if suffix == "buy" {
+			condition += " AND buy_code=? "
+		} else {
+			condition += " AND sold_code=? "
+		}
+		pars = append(pars, edbCode)
+	}
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	glDataList, err := edbDataModel.GetShfeDataByTradeCode(condition, pars)
+
+	addSql := ` INSERT INTO edb_data_ine(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	for _, v := range glDataList {
+		var value string
+		if suffix == "deal" {
+			value = v.DealValue
+		} else if suffix == "buy" {
+			value = v.BuyValue
+		} else {
+			value = v.SoldValue
+		}
+		item := v
+		itemValue := value
+		if _, ok := existMap[v.DataTime]; !ok {
+			count, err := edbDataModel.GetEdbDataShfeByCodeAndDate(edbCode, v.DataTime)
+			if err != nil && err != utils.ErrNoRow {
+				return err
+			}
+			if count <= 0 {
+				eDate := item.DataTime
+				sValue := itemValue
+				if sValue != "" {
+					dataTime, err := time.Parse(utils.FormatDate, eDate)
+					if err != nil {
+						return err
+					}
+					timestamp := dataTime.UnixNano() / 1e6
+					timeStr := fmt.Sprintf("%d", timestamp)
+					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
+					isAdd = true
+				}
+			} else {
+				updateSql := ` UPDATE edb_data_ine SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				err = tx.Exec(updateSql, value, edbInfoId, v.DataTime).Error
+				if err != nil {
+					return err
+				}
+			}
+		}
+		existMap[v.DataTime] = value
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+// RefreshEdbDataByGie 刷新欧洲天然气指标数据
+func RefreshEdbDataByGie(edbInfoId int, edbCode, startDate, endDate string) (err error) {
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		fmt.Println("refresh err:", err)
+		return
+	}
+	var suffix string
+	l := len(edbCode)
+	if strings.Contains(edbCode[l-2:], "GS") {
+		suffix = "GS"
+	} else if strings.Contains(edbCode[l-1:], "F") {
+		suffix = "F"
+	} else if strings.Contains(edbCode[l-1:], "T") {
+		suffix = "T"
+	} else if strings.Contains(edbCode[l-2:], "In") {
+		suffix = "In"
+	} else if strings.Contains(edbCode[l-3:], "Out") {
+		suffix = "Out"
+	} else if strings.Contains(edbCode[l-3:], "WGV") {
+		suffix = "WGV"
+	} else if strings.Contains(edbCode[l-2:], "IC") {
+		suffix = "IC"
+	} else if strings.Contains(edbCode[l-2:], "WC") {
+		suffix = "WC"
+	} else {
+		suffix = ""
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+	var condition string
+	var pars []interface{}
+
+	if edbCode != "" {
+		condition += " AND eic_code=? "
+		pars = append(pars, edbCode[:l-len(suffix)])
+	}
+
+	if startDate != "" {
+		condition += " AND gas_day_started_on>=? "
+		pars = append(pars, startDate)
+	}
+
+	if endDate != "" {
+		condition += " AND gas_day_started_on<=? "
+		pars = append(pars, endDate)
+	}
+
+	eicDataList, err := edbDataModel.GetGieDataByTradeCode(condition, pars)
+	fmt.Println("eicDataList", len(eicDataList))
+	addSql := ` INSERT INTO edb_data_gie(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	for _, v := range eicDataList {
+		var value string
+		if suffix == "GS" {
+			value = v.GasInStorage
+		} else if suffix == "F" {
+			value = v.Full
+		} else if suffix == "T" {
+			value = v.Trend
+		} else if suffix == "In" {
+			value = v.Injection
+		} else if suffix == "Out" {
+			value = v.Withdrawal
+		} else if suffix == "WGV" {
+			value = v.WorkingGasVolume
+		} else if suffix == "IC" {
+			value = v.InjectionCapacity
+		} else if suffix == "WC" {
+			value = v.WithdrawalCapacity
+		}
+		item := v
+		itemValue := value
+		if _, ok := existMap[v.GasDayStartedOn]; !ok {
+			count, err := edbDataModel.GetEdbDataGieByCodeAndDate(edbCode, v.GasDayStartedOn)
+			if err != nil && err != utils.ErrNoRow {
+				return err
+			}
+			if count <= 0 {
+				eDate := item.GasDayStartedOn
+				sValue := itemValue
+				if sValue != "" {
+					dataTime, err := time.Parse(utils.FormatDate, eDate)
+					if err != nil {
+						return err
+					}
+					timestamp := dataTime.UnixNano() / 1e6
+					timeStr := fmt.Sprintf("%d", timestamp)
+					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValue)
+					isAdd = true
+				}
+			} else {
+				updateSql := ` UPDATE edb_data_gie SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				err = tx.Exec(updateSql, value, edbInfoId, v.GasDayStartedOn).Error
+				if err != nil {
+					return err
+				}
+			}
+		}
+		existMap[v.GasDayStartedOn] = value
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+
+//刷新全部数据
+func RefreshAllCalculate(edbInfoIdArr []*edbInfoModel.EdbInfo, edbInfoId, source int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string) (err error) {
+
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	fmt.Println(startDate, endDate)
+	saveDataMap := make(map[string]map[int]float64)
+	for _, v := range edbInfoIdArr {
+		var condition string
+		var pars []interface{}
+		condition += " AND edb_info_id=? "
+		pars = append(pars, v.EdbInfoId)
+		if startDate != "" {
+			condition += " AND data_time>=? "
+			pars = append(pars, startDate)
+		}
+		if endDate != "" {
+			condition += " AND data_time<=? "
+			pars = append(pars, endDate)
+		}
+		fmt.Println("v.Source:", v.Source)
+		dataList, err := edbDataModel.GetEdbDataListAll(condition, pars, v.Source, 1)
+		if err != nil {
+			return err
+		}
+		dataMap := make(map[string]float64)
+		for _, dv := range dataList {
+			if val, ok := saveDataMap[dv.DataTime]; ok {
+				if _, ok := val[v.EdbInfoId]; !ok {
+					val[v.EdbInfoId] = dv.Value
+				}
+			} else {
+				temp := make(map[int]float64)
+				temp[v.EdbInfoId] = dv.Value
+				saveDataMap[dv.DataTime] = temp
+			}
+		}
+		item := new(edbDataModel.CalculateItems)
+		item.EdbInfoId = v.EdbInfoId
+		item.DataMap = dataMap
+	}
+
+	formulaMap := CheckFormula(formulaStr)
+	addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+
+	//获取指标所有数据
+	dataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&dataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&dataList)
+	if err != nil {
+		return err
+	}
+	dataMap := make(map[string]string)
+	for _, v := range dataList {
+		dataMap[v.DataTime] = v.Value
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	existDataMap := make(map[string]string)
+	for sk, sv := range saveDataMap {
+		fmt.Println(sk, sv)
+		formulaStr = strings.ToUpper(formulaStr)
+		formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
+		if formulaFormStr != "" {
+			//utils.FileLog.Info("formulaFormStr:%s", formulaFormStr)
+			expression := formula.NewExpression(formulaFormStr)
+			calResult, err := expression.Evaluate()
+			if err != nil {
+				err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
+				fmt.Println(err)
+				return err
+			}
+			calVal, err := calResult.Float64()
+			if err != nil {
+				err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
+				fmt.Println(err)
+				return err
+			}
+
+			saveValue := utils.SubFloatToString(calVal, 4)
+			if existVal, ok := dataMap[sk]; !ok {
+				dataTime, _ := time.Parse(utils.FormatDate, sk)
+				timestamp := dataTime.UnixNano() / 1e6
+				timeStr := fmt.Sprintf("%d", timestamp)
+
+				if _, existOk := existDataMap[sk]; !existOk {
+					addSql += GetAddSql(edbInfoIdStr, edbCode, sk, timeStr, saveValue)
+					isAdd = true
+				}
+				existDataMap[sk] = sk
+			} else {
+				if existVal != saveValue {
+					sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+					sql = fmt.Sprintf(sql, dataTableName)
+					err = tx.Exec(sql, saveValue, edbInfoId, sk).Error
+					//_, err = o.Raw(sql, saveValue, edbInfoId, sk).Exec()
+					if err != nil {
+						return err
+					}
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			fmt.Println("RefreshAllCalculate add Err", err.Error())
+			return
+		}
+	}
+	return
+}
+
+func CheckFormula(formula string) map[string]string {
+	mathFormula := []string{"MAX", "MIN", "ABS", "ACOS", "ASIN", "CEIL", "MOD", "POW", "ROUND", "SIGN", "SIN", "TAN", "LOG10", "LOG2", "LOG"}
+
+	str := strings.ToUpper(formula)
+	for _, v := range mathFormula {
+		str = strings.Replace(str, v, "", -1)
+	}
+	str = strings.Replace(str, "(", "", -1)
+	str = strings.Replace(str, ")", "", -1)
+
+	byteMap := make(map[string]string)
+	for i := 0; i < len(str); i++ {
+		byteInt := str[i]
+		if byteInt >= 65 && byteInt <= 90 {
+			byteStr := string(byteInt)
+			if _, ok := byteMap[byteStr]; !ok {
+				byteMap[byteStr] = byteStr
+			}
+		}
+	}
+	return byteMap
+}
+
+func GetFormulaMap() map[string]string {
+	funMap := make(map[string]string)
+	funMap["MAX"] = "[@@]"
+	funMap["MIN"] = "[@!]"
+	funMap["ABS"] = "[@#]"
+	funMap["CEIL"] = "[@$]"
+	funMap["COS"] = "[@%]"
+	funMap["FLOOR"] = "[@^]"
+	funMap["MOD"] = "[@&]"
+	funMap["POW"] = "[@*]"
+	funMap["ROUND"] = "[@(]"
+	return funMap
+}
+
+func ReplaceFormula(edbInfoIdArr []*edbInfoModel.EdbInfo, valArr map[int]float64, formulaMap map[string]string, formulaStr string, edbInfoIdBytes []string) string {
+	funMap := GetFormulaMap()
+	for k, v := range funMap {
+		formulaStr = strings.Replace(formulaStr, k, v, -1)
+	}
+
+	replaceCount := 0
+	for dk, dv := range edbInfoIdArr {
+		if dk == 0 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 1 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 2 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 3 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 4 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 5 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 6 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 7 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 8 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+	}
+	for k, v := range funMap {
+		formulaStr = strings.Replace(formulaStr, v, k, -1)
+	}
+	if replaceCount == len(formulaMap) {
+		return formulaStr
+	} else {
+		return ""
+	}
+}
+
+func RefreshAllCalculateLjzzy(edbInfoId, source int, fromEdbInfo *edbInfoModel.EdbInfo, edbCode, startDate, endDate string) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	fmt.Println(edbInfoIdStr)
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, fromEdbInfo.EdbInfoId)
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	dataList, err := edbDataModel.GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 1)
+	if err != nil {
+		return err
+	}
+
+	yearMap := make(map[int]map[int]*edbDataModel.EdbInfoSearchData)
+	dataLen := len(dataList)
+	for i := 0; i < dataLen; i++ {
+		item := dataList[i]
+		//日其中获取年
+		itemDate, err := time.Parse(utils.FormatDate, item.DataTime)
+		if err != nil {
+			return err
+		}
+		year := itemDate.Year()
+		month := int(itemDate.Month())
+		if monthMap, yok := yearMap[year]; yok {
+			monthMap[month] = item
+			yearMap[year] = monthMap
+		} else {
+			monthMap = make(map[int]*edbDataModel.EdbInfoSearchData)
+			monthMap[month] = item
+			yearMap[year] = monthMap
+		}
+	}
+
+	addSql := ` INSERT INTO edb_data_calculate_ljzzy(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	//获取指标所有数据
+	existDataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	dataMap := make(map[string]string)
+	for _, v := range existDataList {
+		dataMap[v.DataTime] = v.Value
+	}
+	existDataMap := make(map[string]string)
+
+	for yk, yv := range yearMap {
+		_, oneMonthOk := yv[1]
+		_, twoMonthOk := yv[2]
+		if !oneMonthOk && !twoMonthOk {
+			continue
+		}
+		for i := 1; i <= 12; i++ {
+			//fmt.Println(yk, i, yv[i])
+			dataCurrentItem := yv[i]
+			var date string
+			var val float64
+			if i == 1 || i == 2 {
+				if _, mok := yv[1]; mok { //1月有值
+					if i == 1 {
+						date = dataCurrentItem.DataTime
+						val, _ = decimal.NewFromFloat(dataCurrentItem.Value).Float64() //a.Div(b).Float64()
+					}
+					if i == 2 {
+						dataOneItem := yv[1]
+						if dataCurrentItem != nil && dataOneItem != nil {
+							date = dataCurrentItem.DataTime
+							twoMonth := decimal.NewFromFloat(dataCurrentItem.Value)
+							oneMonth := decimal.NewFromFloat(dataOneItem.Value)
+							val, _ = twoMonth.Sub(oneMonth).Float64()
+						}
+					}
+				} else { //1月无值
+					dataTwoItem := yv[2]
+					if i == 1 {
+						date = strconv.Itoa(yk) + "-01-31"
+						a := decimal.NewFromFloat(dataTwoItem.Value)
+						b := decimal.NewFromFloat(2.0)
+						val, _ = a.Div(b).Float64()
+					}
+					if i == 2 {
+						date = dataCurrentItem.DataTime
+						a := decimal.NewFromFloat(dataTwoItem.Value)
+						b := decimal.NewFromFloat(2.0)
+						val, _ = a.Div(b).Float64()
+					}
+				}
+			} else {
+				dataPreItem := yv[i-1]
+				if dataCurrentItem != nil && dataPreItem != nil {
+					date = dataCurrentItem.DataTime
+					//val =  dataCurrentItem.Value - dataPreItem.Value
+					a := decimal.NewFromFloat(dataCurrentItem.Value)
+					b := decimal.NewFromFloat(dataPreItem.Value)
+					val, _ = a.Sub(b).Float64()
+				}
+			}
+			if date != "" {
+				saveValue := utils.SubFloatToString(val, 4)
+				//判断数据是否存在
+				if existVal, ok := dataMap[date]; !ok {
+					dataTime, _ := time.Parse(utils.FormatDate, date)
+					timestamp := dataTime.UnixNano() / 1e6
+					timeStr := fmt.Sprintf("%d", timestamp)
+					if _, existOk := existDataMap[date]; !existOk {
+						addSql += GetAddSql(edbInfoIdStr, edbCode, date, timeStr, saveValue)
+						isAdd = true
+					}
+					existDataMap[date] = date
+				} else {
+					if existVal != saveValue {
+						sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+						sql = fmt.Sprintf(sql, dataTableName)
+						err = tx.Exec(sql, saveValue, edbInfoId, date).Error
+						//_, err = o.Raw(sql, saveValue, edbInfoId, date).Exec()
+						if err != nil {
+							return err
+						}
+					}
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			fmt.Println("RefreshAllCalculateLjzzy add Err", err.Error())
+			return
+		}
+	}
+	return
+}
+
+func RefreshAllCalculateTbz(edbInfoId, source int, fromEdbInfo *edbInfoModel.EdbInfo, edbCode, startDate, endDate string) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, fromEdbInfo.EdbInfoId)
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+	fmt.Println("GetEdbDataListAll--start")
+	dataList, err := edbDataModel.GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	if err != nil {
+		return err
+	}
+	fmt.Println("GetEdbDataListAll--end")
+	var dateArr []string
+	dataMap := make(map[string]*edbDataModel.EdbInfoSearchData)
+	for _, v := range dataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+	}
+	fmt.Println("source:", source)
+	//获取指标所有数据
+	existDataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	fmt.Println("dataTableName:", dataTableName)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	existDataMap := make(map[string]string)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+	}
+	//fmt.Println("existDataMap:", existDataMap)
+	addSql := ` INSERT INTO edb_data_calculate_tbz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existAddDataMap := make(map[string]string)
+	for _, av := range dateArr {
+		currentItem := dataMap[av]
+		if currentItem != nil {
+			//当前日期
+			currentDate, err := time.Parse(utils.FormatDate, av)
+			if err != nil {
+				return err
+			}
+			//上一年的日期
+			preDate := currentDate.AddDate(-1, 0, 0)
+			preDateStr := preDate.Format(utils.FormatDate)
+			if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
+				//dataTime, _ := time.Parse(utils.FormatDate, date)
+				timestamp := currentDate.UnixNano() / 1e6
+				timestampStr := fmt.Sprintf("%d", timestamp)
+				val := TbzDiv(currentItem.Value, findItem.Value)
+				if existVal, ok := existDataMap[av]; !ok {
+					if _, existOk := existAddDataMap[av]; !existOk {
+						addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+						isAdd = true
+					}
+					existAddDataMap[av] = av
+				} else {
+					if existVal != val {
+						sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+						sql = fmt.Sprintf(sql, dataTableName)
+						err = tx.Exec(sql, val, edbInfoId, av).Error
+						//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+						if err != nil {
+							return err
+						}
+					}
+				}
+				continue
+			} else {
+				if fromEdbInfo.Frequency == "月度" { //向上和向下,各找一个月
+					for i := 0; i <= 35; i++ {
+						nextDateDay := preDate.AddDate(0, 0, i)
+						nextDateDayStr := nextDateDay.Format(utils.FormatDate)
+						if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
+							timestamp := currentDate.UnixNano() / 1e6
+							timestampStr := fmt.Sprintf("%d", timestamp)
+							val := TbzDiv(currentItem.Value, findItem.Value)
+
+							if existVal, ok := existDataMap[av]; !ok {
+								if _, existOk := existAddDataMap[av]; !existOk {
+									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+									isAdd = true
+								}
+								existAddDataMap[av] = av
+							} else {
+								if existVal != val {
+									sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+									sql = fmt.Sprintf(sql, dataTableName)
+									err = tx.Exec(sql, val, edbInfoId, av).Error
+									//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+									if err != nil {
+										return err
+									}
+								}
+							}
+							break
+						} else {
+							preDateDay := preDate.AddDate(0, 0, -i)
+							preDateDayStr := preDateDay.Format(utils.FormatDate)
+							if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
+								timestamp := currentDate.UnixNano() / 1e6
+								timestampStr := fmt.Sprintf("%d", timestamp)
+								val := TbzDiv(currentItem.Value, findItem.Value)
+
+								if existVal, ok := existDataMap[av]; !ok {
+									if _, existOk := existAddDataMap[av]; !existOk {
+										addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+										isAdd = true
+									}
+									existAddDataMap[av] = av
+								} else {
+									if existVal != val {
+										sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+										sql = fmt.Sprintf(sql, dataTableName)
+										err = tx.Exec(sql, val, edbInfoId, av).Error
+										//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+										if err != nil {
+											return err
+										}
+									}
+								}
+								break
+							}
+						}
+					}
+				} else if fromEdbInfo.Frequency == "季度" || fromEdbInfo.Frequency == "年度" {
+					if findItem, ok := dataMap[preDateStr]; ok { //上一年同期->下一个月找到
+						timestamp := currentDate.UnixNano() / 1e6
+						timestampStr := fmt.Sprintf("%d", timestamp)
+						val := TbzDiv(currentItem.Value, findItem.Value)
+
+						if existVal, ok := existDataMap[av]; !ok {
+							if _, existOk := existAddDataMap[av]; !existOk {
+								addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+								isAdd = true
+							}
+							existAddDataMap[av] = av
+						} else {
+							if existVal != val {
+								sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+								sql = fmt.Sprintf(sql, dataTableName)
+								err = tx.Exec(sql, val, edbInfoId, av).Error
+								//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+								if err != nil {
+									return err
+								}
+							}
+						}
+						break
+					}
+				} else {
+					nextDateDay := preDate.AddDate(0, 0, 1)
+					nextDateDayStr := nextDateDay.Format(utils.FormatDate)
+
+					preDateDay := preDate.AddDate(0, 0, -1)
+					preDateDayStr := preDateDay.Format(utils.FormatDate)
+
+					for i := 0; i < 35; i++ {
+						if i >= 1 {
+							nextDateDay = nextDateDay.AddDate(0, 0, i)
+							nextDateDayStr = nextDateDay.Format(utils.FormatDate)
+						}
+						if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
+							timestamp := currentDate.UnixNano() / 1e6
+							timestampStr := fmt.Sprintf("%d", timestamp)
+							val := TbzDiv(currentItem.Value, findItem.Value)
+
+							if existVal, ok := existDataMap[av]; !ok {
+								if _, existOk := existAddDataMap[av]; !existOk {
+									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+									isAdd = true
+								}
+								existAddDataMap[av] = av
+							} else {
+								if existVal != val {
+									sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+									sql = fmt.Sprintf(sql, dataTableName)
+									err = tx.Exec(sql, val, edbInfoId, av).Error
+									//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+									if err != nil {
+										return err
+									}
+								}
+							}
+							break
+						} else {
+							if i >= 1 {
+								preDateDay = preDate.AddDate(0, 0, -i)
+								preDateDayStr = nextDateDay.Format(utils.FormatDate)
+							}
+							if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
+								timestamp := currentDate.UnixNano() / 1e6
+								timestampStr := fmt.Sprintf("%d", timestamp)
+								val := TbzDiv(currentItem.Value, findItem.Value)
+
+								if existVal, ok := existDataMap[av]; !ok {
+									if _, existOk := existAddDataMap[av]; !existOk {
+										addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+										isAdd = true
+									}
+									existAddDataMap[av] = av
+								} else {
+									if existVal != val {
+										sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+										sql = fmt.Sprintf(sql, dataTableName)
+										err = tx.Exec(sql, val, edbInfoId, av).Error
+										//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+										if err != nil {
+											return err
+										}
+									}
+								}
+								break
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+func TbzDiv(a, b float64) string {
+	var valStr string
+	if b != 0 {
+		af := decimal.NewFromFloat(float64(a))
+		bf := decimal.NewFromFloat(float64(b))
+		val, _ := af.Div(bf).Float64()
+		val = val - 1
+		valStr = utils.SubFloatToString(val, 4)
+	} else {
+		valStr = "0"
+	}
+	return valStr
+}
+
+//刷新全部同差值数据
+func RefreshAllCalculateTcz(edbInfoId, source int, fromEdbInfo *edbInfoModel.EdbInfo, edbCode, startDate, endDate string) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, fromEdbInfo.EdbInfoId)
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	dataList, err := edbDataModel.GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	if err != nil {
+		return err
+	}
+	var dateArr []string
+	dataMap := make(map[string]*edbDataModel.EdbInfoSearchData)
+	for _, v := range dataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+	}
+	//获取指标所有数据
+	existDataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	existDataMap := make(map[string]string)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+	}
+
+	addSql := ` INSERT INTO edb_data_calculate_tcz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existAddDataMap := make(map[string]string)
+	for _, av := range dateArr {
+		currentItem := dataMap[av]
+		if currentItem != nil {
+			//当前日期
+			currentDate, err := time.Parse(utils.FormatDate, av)
+			if err != nil {
+				return err
+			}
+			//上一年的日期
+			preDate := currentDate.AddDate(-1, 0, 0)
+			preDateStr := preDate.Format(utils.FormatDate)
+			if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
+				//dataTime, _ := time.Parse(utils.FormatDate, date)
+				timestamp := currentDate.UnixNano() / 1e6
+				timestampStr := fmt.Sprintf("%d", timestamp)
+				val := TczSub(currentItem.Value, findItem.Value)
+
+				if existVal, ok := existDataMap[av]; !ok {
+					if _, existOk := existAddDataMap[av]; !existOk {
+						addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+						isAdd = true
+					}
+					existAddDataMap[av] = av
+				} else {
+					if existVal != val {
+						sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+						sql = fmt.Sprintf(sql, dataTableName)
+						err = tx.Exec(sql, val, edbInfoId, av).Error
+						//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+						if err != nil {
+							return err
+						}
+					}
+				}
+				//utils.FileLog.Info("同期找到:" + av + ";" + preDateStr)
+				continue
+			} else {
+				if fromEdbInfo.Frequency == "月度" { //向上和向下,各找一个月
+					for i := 0; i <= 35; i++ {
+						nextDateDay := preDate.AddDate(0, 0, 1)
+						nextDateDayStr := nextDateDay.Format(utils.FormatDate)
+						if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
+							timestamp := currentDate.UnixNano() / 1e6
+							timestampStr := fmt.Sprintf("%d", timestamp)
+							val := TczSub(currentItem.Value, findItem.Value)
+
+							if existVal, ok := existDataMap[av]; !ok {
+								if _, existOk := existAddDataMap[av]; !existOk {
+									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+									isAdd = true
+								}
+								existAddDataMap[av] = av
+							} else {
+								if existVal != val {
+									sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+									sql = fmt.Sprintf(sql, dataTableName)
+									err = tx.Exec(sql, val, edbInfoId, av).Error
+									//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+									if err != nil {
+										return err
+									}
+								}
+							}
+							break
+						} else {
+							preDateDay := preDate.AddDate(0, 0, -1)
+							preDateDayStr := preDateDay.Format(utils.FormatDate)
+							if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
+								timestamp := currentDate.UnixNano() / 1e6
+								timestampStr := fmt.Sprintf("%d", timestamp)
+								val := TczSub(currentItem.Value, findItem.Value)
+
+								if existVal, ok := existDataMap[av]; !ok {
+									if _, existOk := existAddDataMap[av]; !existOk {
+										addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+										isAdd = true
+									}
+									existAddDataMap[av] = av
+								} else {
+									if existVal != val {
+										sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+										sql = fmt.Sprintf(sql, dataTableName)
+										err = tx.Exec(sql, val, edbInfoId, av).Error
+										//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+										if err != nil {
+											return err
+										}
+									}
+								}
+								break
+							}
+						}
+					}
+				} else if fromEdbInfo.Frequency == "季度" || fromEdbInfo.Frequency == "年度" {
+					if findItem, ok := dataMap[preDateStr]; ok { //上一年同期->下一个月找到
+						timestamp := currentDate.UnixNano() / 1e6
+						timestampStr := fmt.Sprintf("%d", timestamp)
+						val := TczSub(currentItem.Value, findItem.Value)
+
+						if existVal, ok := existDataMap[av]; !ok {
+							if _, existOk := existAddDataMap[av]; !existOk {
+								addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+								isAdd = true
+							}
+							existAddDataMap[av] = av
+						} else {
+							if existVal != val {
+								sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+								sql = fmt.Sprintf(sql, dataTableName)
+								err = tx.Exec(sql, val, edbInfoId, av).Error
+								//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+								if err != nil {
+									return err
+								}
+							}
+						}
+						break
+					}
+				} else {
+					for i := 0; i < 35; i++ {
+						nextDateDay := preDate.AddDate(0, 0, 1)
+						nextDateDayStr := nextDateDay.Format(utils.FormatDate)
+						if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
+							timestamp := currentDate.UnixNano() / 1e6
+							timestampStr := fmt.Sprintf("%d", timestamp)
+							val := TczSub(currentItem.Value, findItem.Value)
+
+							if existVal, ok := existDataMap[av]; !ok {
+								if _, existOk := existAddDataMap[av]; !existOk {
+									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+									isAdd = true
+								}
+								existAddDataMap[av] = av
+							} else {
+								if existVal != val {
+									sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+									sql = fmt.Sprintf(sql, dataTableName)
+									err = tx.Exec(sql, val, edbInfoId, av).Error
+									//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+									if err != nil {
+										return err
+									}
+								}
+							}
+							break
+						} else {
+							preDateDay := preDate.AddDate(0, 0, -1)
+							preDateDayStr := preDateDay.Format(utils.FormatDate)
+							if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
+								timestamp := currentDate.UnixNano() / 1e6
+								timestampStr := fmt.Sprintf("%d", timestamp)
+								val := TczSub(currentItem.Value, findItem.Value)
+
+								if existVal, ok := existDataMap[av]; !ok {
+									if _, existOk := existAddDataMap[av]; !existOk {
+										addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+										isAdd = true
+									}
+									existAddDataMap[av] = av
+								} else {
+									if existVal != val {
+										sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+										sql = fmt.Sprintf(sql, dataTableName)
+										err = tx.Exec(sql, val, edbInfoId, av).Error
+										//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+										if err != nil {
+											return err
+										}
+									}
+								}
+								break
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+func TczSub(a, b float64) string {
+	af := decimal.NewFromFloat(float64(a))
+	fmt.Println(af)
+	bf := decimal.NewFromFloat(float64(b))
+	val, _ := af.Sub(bf).Float64()
+	valStr := utils.SubFloatToString(val, 4)
+	return valStr
+}
+
+//刷新全部N数值移动平均计算
+func RefreshAllCalculateNszydpjjs(edbInfoId, source, formulaInt int, fromEdbInfo *edbInfoModel.EdbInfo, edbCode, startDate string) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			fmt.Println("RefreshCalculateNszydpjjs Err:" + err.Error())
+			//utils.FileLog.Info("RefreshCalculateNszydpjjs Err:" + err.Error())
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	fmt.Println(edbInfoIdStr)
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, edbInfoId)
+
+	existDataList, err := edbDataModel.GetEdbDataListAll(condition, pars, source, 0)
+	if err != nil {
+		fmt.Println("existDataList GetEdbDataListAll Err:" + err.Error())
+		return err
+	}
+
+	existDataMap := make(map[string]*edbDataModel.EdbInfoSearchData)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v
+	}
+
+	//计算来源数据
+	var fromCondition string
+	var fromPars []interface{}
+	fromCondition += " AND edb_info_id=? "
+	fromPars = append(fromPars, fromEdbInfo.EdbInfoId)
+	fromCondition += " AND data_time>=? "
+	fromPars = append(fromPars, startDate)
+
+	fmt.Println("fromPars:", fromPars)
+	fromDataList, err := edbDataModel.GetEdbDataListAll(fromCondition, fromPars, fromEdbInfo.Source, 0)
+	if err != nil {
+		fmt.Println("from GetEdbDataListAll Err:" + err.Error())
+		return err
+	}
+
+	var fromDateArr []string
+	fromDataMap := make(map[string]*edbDataModel.EdbInfoSearchData)
+	for _, v := range fromDataList {
+		fromDateArr = append(fromDateArr, v.DataTime)
+		fromDataMap[v.DataTime] = v
+	}
+
+	addSql := ` INSERT INTO edb_data_calculate_nszydpjjs(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	arrLen := len(fromDateArr)
+	existAddDataMap := make(map[string]string)
+	for ak, av := range fromDateArr {
+		//处理第一个值
+		var valArr []float64
+		if findItem, ok := fromDataMap[av]; ok {
+			valArr = append(valArr, findItem.Value)
+		} else {
+			continue
+		}
+		if ak+1 != arrLen {
+			//处理除第一个值之外的N-1个值
+			for i := 1; i < formulaInt; i++ {
+				arrIndex := ak + i
+				if arrIndex >= arrLen {
+					break
+				}
+				arrVal := fromDateArr[arrIndex]
+				if findItem, ok := fromDataMap[arrVal]; ok {
+					valArr = append(valArr, findItem.Value)
+				} else {
+					continue
+				}
+			}
+		}
+		valArrLen := len(valArr)
+		//var totalVal float64
+		totalVal := decimal.NewFromFloat(0.00)
+		for _, v := range valArr {
+			newDecimal := decimal.NewFromFloat(v)
+			totalVal = totalVal.Add(newDecimal)
+		}
+		af := totalVal //decimal.NewFromFloat(totalVal)
+		bf := decimal.NewFromFloat(float64(valArrLen))
+		val, _ := af.Div(bf).Float64()
+		valStr := utils.SubFloatToString(val, 4)
+
+		if existVal, existOk := existDataMap[av]; !existOk {
+			currentDate, err := time.Parse(utils.FormatDate, av)
+			if err != nil {
+				return err
+			}
+			timestamp := currentDate.UnixNano() / 1e6
+			timestampStr := fmt.Sprintf("%d", timestamp)
+			if _, existOk := existAddDataMap[av]; !existOk {
+				addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, valStr)
+				isAdd = true
+			}
+			existAddDataMap[av] = av
+		} else {
+			saveValue := utils.SubFloatToString(existVal.Value, 30)
+			if saveValue != valStr {
+				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				sql = fmt.Sprintf(sql, dataTableName)
+				err = tx.Exec(sql, val, edbInfoId, av).Error
+				//_, err = o.Raw(sql, val, edbInfoId, av).Exec()
+				if err != nil {
+					return err
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		//utils.FileLog.Info("addSql:" + addSql)
+		//_, err = o.Raw(addSql).Exec()
+		err = tx.Exec(addSql).Error
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+//刷新所有环比值数据
+func RefreshAllCalculateHbz(edbInfoId, source int, fromEdbInfo *edbInfoModel.EdbInfo, edbCode, startDate, endDate string, formulaInt int) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, fromEdbInfo.EdbInfoId)
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	dataList, err := edbDataModel.GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	if err != nil {
+		return err
+	}
+	var dateArr []string
+	dataMap := make(map[string]*edbDataModel.EdbInfoSearchData)
+	for _, v := range dataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+	}
+	fmt.Println("source:", source)
+	//获取指标所有数据
+	existDataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	fmt.Println("dataTableName:", dataTableName)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	existDataMap := make(map[string]string)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+	}
+	addSql := ` INSERT INTO edb_data_calculate_hbz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	dataLen := len(dataList)
+	fmt.Println("dataLen:", dataLen)
+	for i := 0; i < dataLen; i++ {
+		j := i + formulaInt
+		if j < dataLen {
+			//当期
+			currentItem := dataList[i]
+			preItem := dataList[j]
+			if currentItem != nil && preItem != nil {
+				existKey := edbCode + currentItem.DataTime
+
+				if _, ok := existMap[existKey]; !ok {
+					currentDate, _ := time.Parse(utils.FormatDate, currentItem.DataTime)
+					timestamp := currentDate.UnixNano() / 1e6
+					timestampStr := fmt.Sprintf("%d", timestamp)
+					val := HbzDiv(currentItem.Value, preItem.Value)
+					if val != "" {
+						if existVal, findOk := existDataMap[currentItem.DataTime]; !findOk {
+							addSql += GetAddSql(edbInfoIdStr, edbCode, currentItem.DataTime, timestampStr, val)
+							isAdd = true
+						} else {
+							if existVal != val {
+								sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+								sql = fmt.Sprintf(sql, dataTableName)
+								err = tx.Exec(sql, val, edbInfoId, currentItem.DataTime).Error
+								//_, err = o.Raw(sql, val, edbInfoId, currentItem.DataTime).Exec()
+								if err != nil {
+									return err
+								}
+							}
+						}
+					}
+				}
+				existMap[existKey] = currentItem.DataTime
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+//环比值,current:当期,pre:上期 公式: (当期-上期)/上期
+func HbzDiv(current, pre float64) string {
+	if pre == 0 {
+		return ""
+	}
+	currentVal := decimal.NewFromFloat(float64(current))
+	preVal := decimal.NewFromFloat(float64(pre))
+	val, _ := currentVal.Sub(preVal).Div(preVal).Float64()
+	valStr := utils.SubFloatToString(val, 4)
+	return valStr
+}
+
+
+//刷新所有环差值数据
+func RefreshAllCalculateHcz(edbInfoId, source int, fromEdbInfo *edbInfoModel.EdbInfo, edbCode, startDate, endDate string, formulaInt int) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, fromEdbInfo.EdbInfoId)
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	dataList, err := edbDataModel.GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	if err != nil {
+		return err
+	}
+	var dateArr []string
+	dataMap := make(map[string]*edbDataModel.EdbInfoSearchData)
+	for _, v := range dataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+	}
+	fmt.Println("source:", source)
+	//获取指标所有数据
+	existDataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	fmt.Println("dataTableName:", dataTableName)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = global.MYSQL["data"].Raw(sql, edbInfoId).Scan(&existDataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	existDataMap := make(map[string]string)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+	}
+	//fmt.Println("existDataMap:", existDataMap)
+	addSql := ` INSERT INTO edb_data_calculate_hcz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existMap := make(map[string]string)
+	dataLen := len(dataList)
+	fmt.Println("dataLen:", dataLen)
+	for i := 0; i < dataLen; i++ {
+		j := i + formulaInt
+		if j < dataLen {
+			//当期
+			currentItem := dataList[i]
+			preItem := dataList[j]
+			if currentItem != nil && preItem != nil {
+				existKey := edbCode + currentItem.DataTime
+				if _, ok := existMap[existKey]; !ok {
+					currentDate, _ := time.Parse(utils.FormatDate, currentItem.DataTime)
+					timestamp := currentDate.UnixNano() / 1e6
+					timestampStr := fmt.Sprintf("%d", timestamp)
+					val := HczDiv(currentItem.Value, preItem.Value)
+					if val != "" {
+						if existVal, findOk := existDataMap[currentItem.DataTime]; !findOk {
+							addSql += GetAddSql(edbInfoIdStr, edbCode, currentItem.DataTime, timestampStr, val)
+							isAdd = true
+						} else {
+							if existVal != val {
+								sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+								sql = fmt.Sprintf(sql, dataTableName)
+								err = tx.Exec(sql, val, edbInfoId, currentItem.DataTime).Error
+								//_, err = o.Raw(sql, val, edbInfoId, currentItem.DataTime).Exec()
+								if err != nil {
+									return err
+								}
+							}
+						}
+					}
+				}
+				existMap[existKey] = currentItem.DataTime
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+//环差值,current:当期,pre:上期 公式:当期-上期
+func HczDiv(current, pre float64) string {
+	if pre == 0 {
+		return ""
+	}
+	currentVal := decimal.NewFromFloat(current)
+	preVal := decimal.NewFromFloat(pre)
+	val, _ := currentVal.Sub(preVal).Float64()
+	valStr := utils.SubFloatToString(val, 4)
+	return valStr
+}
+
+
+//刷新所有变频数据
+func RefreshAllCalculateBp(edbInfoId, source int, fromEdbInfo *edbInfoModel.EdbInfo, edbCode, startDate, endDate string) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	if err != nil {
+		return
+	}
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, fromEdbInfo.EdbInfoId)
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		condition += " AND data_time<=? "
+		pars = append(pars, endDate)
+	}
+
+	dataList, err := edbDataModel.GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	if err != nil {
+		return err
+	}
+	var dateArr []string
+	dataMap := make(map[string]*edbDataModel.EdbInfoSearchData)
+	for _, v := range dataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+	}
+	fmt.Println("source:", source)
+	//获取指标所有数据
+	existDataList := make([]*edbDataModel.EdbDataBase, 0)
+	dataTableName := edbDataModel.GetEdbDataTableName(source)
+	fmt.Println("dataTableName:", dataTableName)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	err = tx.Raw(sql, edbInfoId).Scan(&existDataList).Error
+	//_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	existDataMap := make(map[string]string)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+	}
+	//fmt.Println("existDataMap:", existDataMap)
+	addSql := ` INSERT INTO edb_data_calculate_bp(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+
+	existMap := make(map[string]string)
+	dataLen := len(dataList)
+	for i := 0; i < dataLen; i++ {
+		//当期
+		currentItem := dataList[i]
+		currentDate, _ := time.Parse(utils.FormatDate, currentItem.DataTime)
+		var day int
+		var preItem *edbDataModel.EdbInfoSearchData
+		var preDate time.Time
+		if i == 0 {
+			day = int(time.Now().Sub(currentDate).Hours() / float64(24))
+			preDate = time.Now()
+		} else {
+			j := i + 1
+			if j < dataLen {
+				preItem = dataList[j]
+				preDate, _ = time.Parse(utils.FormatDate, preItem.DataTime)
+				day = int(currentDate.Sub(preDate).Hours() / float64(24))
+			}
+		}
+		for k := 0; k <= day; k++ {
+			needDay := preDate.AddDate(0, 0, -k)
+			needDayStr := needDay.Format(utils.FormatDate)
+			existKey := edbCode + needDayStr
+			if _, ok := existMap[existKey]; !ok {
+				timestamp := needDay.UnixNano() / 1e6
+				timestampStr := fmt.Sprintf("%d", timestamp)
+				valStr := decimal.NewFromFloat(currentItem.Value).String()
+				if existVal, ok := existDataMap[needDayStr]; !ok {
+					addSql += GetAddSql(edbInfoIdStr, edbCode, needDayStr, timestampStr, valStr)
+				} else {
+					if existVal != valStr {
+						sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+						sql = fmt.Sprintf(sql, dataTableName)
+						err = tx.Exec(sql, valStr, edbInfoId, needDay).Error
+						//_, err = o.Raw(sql, valStr, edbInfoId, needDay).Exec()
+						if err != nil {
+							return err
+						}
+					}
+				}
+			}
+			existMap[existKey] = needDayStr
+		}
+		existKey := edbCode + currentItem.DataTime
+		if _, ok := existMap[existKey]; !ok {
+			currentDate, _ := time.Parse(utils.FormatDate, currentItem.DataTime)
+			timestamp := currentDate.UnixNano() / 1e6
+			timestampStr := fmt.Sprintf("%d", timestamp)
+			valStr := decimal.NewFromFloat(currentItem.Value).String()
+			if existVal, ok := existDataMap[currentItem.DataTime]; !ok {
+				addSql += GetAddSql(edbInfoIdStr, edbCode, currentItem.DataTime, timestampStr, valStr)
+			} else {
+				if existVal != valStr {
+					sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+					sql = fmt.Sprintf(sql, dataTableName)
+					err = tx.Exec(sql, valStr, edbInfoId, currentItem.DataTime).Error
+					//_, err = o.Raw(sql, valStr, edbInfoId, currentItem.DataTime).Exec()
+					if err != nil {
+						return err
+					}
+				}
+			}
+		}
+		existMap[existKey] = currentItem.DataTime
+	}
+
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		err = tx.Exec(addSql).Error
+		//_, err = o.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+
+
+// RefreshAllCalculateZjpj 刷新所有 直接拼接 数据
+func RefreshAllCalculateZjpj(edbInfo *edbInfoModel.EdbInfo) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	//查询当前指标现有的数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, edbInfo.EdbInfoId)
+
+	dataList, err := edbDataModel.GetAllEdbDataCalculateZjpjByEdbInfoId(edbInfo.EdbInfoId)
+	if err != nil {
+		return err
+	}
+	var dateArr []string
+	dataMap := make(map[string]*edbDataModel.EdbDataCalculateZjpj)
+	removeDataTimeMap := make(map[string]int) //需要移除的日期数据
+	for _, v := range dataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+		removeDataTimeMap[v.DataTime] = 1
+	}
+
+	//查询关联指标信息
+	var existCondition string
+	var existPars []interface{}
+	existCondition += " AND edb_info_id=? "
+	existPars = append(existPars, edbInfo.EdbInfoId)
+	existList, err := edbDataModel.GetEdbInfoCalculateListByCondition(existCondition, existPars)
+	if err != nil {
+		err = errors.New("判断指标是否改变失败,Err:" + err.Error())
+		return
+	}
+
+	var existItemA, existItemB *edbDataModel.EdbInfoCalculateMapping
+	for _, existItem := range existList {
+		if existItem.FromTag == "A" {
+			existItemA = existItem
+		} else if existItem.FromTag == "B" {
+			existItemB = existItem
+		}
+	}
+
+	addDataList := make([]*edbDataModel.EdbDataCalculateZjpj, 0)
+	//第一个指标
+	{
+		var condition string
+		var pars []interface{}
+
+		condition += " AND data_time < ? AND edb_info_id=? "
+		pars = append(pars, edbInfo.CalculateFormula, existItemA.FromEdbInfoId)
+
+		//第一个指标的数据列表
+		firstDataList, tmpErr := edbDataModel.GetEdbDataListAll(condition, pars, existItemA.FromSource, 0)
+		if tmpErr != nil {
+			return tmpErr
+		}
+
+		for _, v := range firstDataList {
+			//校验待删除日期数据里面是否存在该元素,如果存在的话,那么移除该元素
+			if _, ok := removeDataTimeMap[v.DataTime]; ok {
+				delete(removeDataTimeMap, v.DataTime)
+			}
+			//时间戳
+			if edbData, ok := dataMap[v.DataTime]; ok {
+				if edbData.Value != v.Value {
+					//更新指标数据
+					edbData.Value = v.Value
+					tempErr := tx.Model(edbDataModel.EdbDataCalculateZjpj{}).Where("edb_data_id = ?", edbData.EdbDataId).Updates(edbDataModel.EdbDataCalculateZjpj{Value: v.Value}).Error
+					if tempErr != nil {
+						fmt.Println("tmpErr:", tmpErr)
+					}
+					//o.Update(edbData, "Value")
+				}
+			} else {
+				//时间戳
+				currentDate, _ := time.Parse(utils.FormatDate, v.DataTime)
+				timestamp := currentDate.UnixNano() / 1e6
+
+				edbDataZjpj := &edbDataModel.EdbDataCalculateZjpj{
+					EdbInfoId:     edbInfo.EdbInfoId,
+					EdbCode:       edbInfo.EdbCode,
+					DataTime:      v.DataTime,
+					Value:         v.Value,
+					Status:        1,
+					CreateTime:    time.Now(),
+					ModifyTime:    time.Now(),
+					DataTimestamp: timestamp,
+				}
+				addDataList = append(addDataList, edbDataZjpj)
+			}
+		}
+	}
+
+	//第二个指标
+	{
+		condition = ``
+		pars = make([]interface{}, 0)
+
+		condition += " AND data_time >= ? AND edb_info_id = ? "
+		pars = append(pars, edbInfo.CalculateFormula, existItemB.FromEdbInfoId)
+
+		//第二个指标的数据列表
+		secondDataList, tmpErr := edbDataModel.GetEdbDataListAll(condition, pars, existItemB.FromSource, 0)
+		if tmpErr != nil {
+			return tmpErr
+		}
+
+		for _, v := range secondDataList {
+			//校验待删除日期数据里面是否存在该元素,如果存在的话,那么移除该元素
+			if _, ok := removeDataTimeMap[v.DataTime]; ok {
+				delete(removeDataTimeMap, v.DataTime)
+			}
+
+			if edbData, ok := dataMap[v.DataTime]; ok {
+				if edbData.Value != v.Value {
+					//更新指标数据
+					edbData.Value = v.Value
+					edbData.ModifyTime = time.Now()
+					tempErr := tx.Model(edbDataModel.EdbDataCalculateZjpj{}).Where("edb_data_id = ?", edbData.EdbDataId).Updates(edbDataModel.EdbDataCalculateZjpj{Value: v.Value, ModifyTime: time.Now()}).Error
+					if tempErr != nil {
+						fmt.Println("tmpErr:", tmpErr)
+					}
+					//_, tmpErr := o.Update(edbData, "Value", "ModifyTime")
+					//if tmpErr != nil {
+					//	fmt.Println("tmpErr:", tmpErr)
+					//}
+				}
+			} else {
+				//时间戳
+				currentDate, _ := time.Parse(utils.FormatDate, v.DataTime)
+				timestamp := currentDate.UnixNano() / 1e6
+
+				edbDataZjpj := &edbDataModel.EdbDataCalculateZjpj{
+					EdbInfoId:     edbInfo.EdbInfoId,
+					EdbCode:       edbInfo.EdbCode,
+					DataTime:      v.DataTime,
+					Value:         v.Value,
+					Status:        1,
+					CreateTime:    time.Now(),
+					ModifyTime:    time.Now(),
+					DataTimestamp: timestamp,
+				}
+				addDataList = append(addDataList, edbDataZjpj)
+			}
+		}
+	}
+
+	//删除已经不存在的累计同比拼接指标数据(由于同比值当日的数据删除了)
+	{
+		removeDateList := make([]string, 0)
+		for dateTime := range removeDataTimeMap {
+			removeDateList = append(removeDateList, dateTime)
+		}
+		if len(removeDateList) > 0 {
+			removeDateStr := strings.Join(removeDateList, `","`)
+			removeDateStr = `"` + removeDateStr + `"`
+			//如果拼接指标变更了,那么需要删除所有的指标数据
+			tableName := edbDataModel.GetEdbDataTableName(edbInfo.Source)
+			sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? and data_time in (%s) `, tableName, removeDateStr)
+
+			err = tx.Exec(sql, edbInfo.EdbInfoId).Error
+			//_, err = o.Raw(sql, edbInfo.EdbInfoId).Exec()
+			if err != nil {
+				err = errors.New("删除不存在的直接拼接指标数据失败,Err:" + err.Error())
+				return
+			}
+		}
+	}
+
+	//数据入库
+	tmpAddDataList := make([]*edbDataModel.EdbDataCalculateZjpj, 0)
+	for _, v := range addDataList {
+		tmpAddDataList = append(tmpAddDataList, v)
+
+		if len(tmpAddDataList) >= 200 {
+			tmpErr := tx.Create(tmpAddDataList).Error
+			//_, tmpErr := o.InsertMulti(len(tmpAddDataList), tmpAddDataList)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			//重新初始化需要加入的数据切片
+			tmpAddDataList = make([]*edbDataModel.EdbDataCalculateZjpj, 0)
+		}
+	}
+	//最后如果还有需要新增的数据,那么就统一入库
+	if len(tmpAddDataList) > 0 {
+		tmpErr := tx.Create(tmpAddDataList).Error
+		//_, tmpErr := o.InsertMulti(len(tmpAddDataList), tmpAddDataList)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+	}
+	return
+}
+
+// RefreshAllCalculateLjztbpj 刷新所有 累计值同比拼接 数据
+func RefreshAllCalculateLjztbpj(edbInfo *edbInfoModel.EdbInfo) (err error) {
+	tx := global.MYSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	//查询当前指标现有的数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, edbInfo.EdbInfoId)
+
+	//所有的数据
+	dataList, err := edbDataModel.GetAllEdbDataCalculateLjztbpjByEdbInfoId(edbInfo.EdbInfoId)
+	if err != nil {
+		return err
+	}
+
+	//待拼接指标map
+	pjDataMap := make(map[string]float64)     //需要入库的数据
+	nowEdbDataMap := make(map[string]float64) //当前指标的数据(已经在库里了,不需要重新)
+	//拼接指标的日期切片数据
+	pjEdbDataTimeList := make([]string, 0)
+
+	dataMap := make(map[string]*edbDataModel.EdbDataCalculateLjztbpj)
+	for _, v := range dataList {
+		pjEdbDataTimeList = append(pjEdbDataTimeList, v.DataTime)
+		dataMap[v.DataTime] = v
+		nowEdbDataMap[v.DataTime] = v.Value
+	}
+
+	//查询关联指标信息
+	var existCondition string
+	var existPars []interface{}
+	existCondition += " AND edb_info_id=? "
+	existPars = append(existPars, edbInfo.EdbInfoId)
+	existList, err := edbDataModel.GetEdbInfoCalculateListByCondition(existCondition, existPars)
+	if err != nil {
+		err = errors.New("判断指标是否改变失败,Err:" + err.Error())
+		return
+	}
+
+	var existItemA, existItemB *edbDataModel.EdbInfoCalculateMapping
+	for _, existItem := range existList {
+		if existItem.FromTag == "A" {
+			existItemA = existItem
+		} else if existItem.FromTag == "B" {
+			existItemB = existItem
+		}
+	}
+	// 原数据开始计算日期
+	startCalculationDate, _ := time.ParseInLocation(utils.FormatDate, edbInfo.CalculateFormula, time.Local)
+
+	//待拼接指标
+	{
+		var condition string
+		var pars []interface{}
+
+		condition += " AND data_time <= ? AND edb_info_id=? "
+		pars = append(pars, startCalculationDate, existItemA.FromEdbInfoId)
+
+		//第一个指标的数据列表
+		firstDataList, tmpErr := edbDataModel.GetEdbDataListAll(condition, pars, existItemA.FromSource, 0)
+		if tmpErr != nil {
+			return tmpErr
+		}
+
+		for _, v := range firstDataList {
+			//时间戳
+			if edbData, ok := dataMap[v.DataTime]; ok {
+				if edbData.Value != v.Value {
+					//更新指标数据
+					edbData.Value = v.Value
+					//tempErr := tx.Model()
+					//o.Update(edbData, "Value")
+					tempErr := tx.Model(edbDataModel.EdbDataCalculateLjztbpj{}).Where("edb_data_id = ?", edbData.EdbDataId).Updates(edbDataModel.EdbDataCalculateLjztbpj{Value: v.Value}).Error
+					if tempErr != nil {
+						fmt.Println("tmpErr:", tmpErr)
+					}
+
+					//将新的数据存入已入库指标map里面,以便后续计算
+					nowEdbDataMap[edbData.DataTime] = v.Value
+				}
+			}
+		}
+	}
+
+	//同比值指标map
+	tbzEdbDataMap := make(map[string]float64)
+
+	//同比值日期切片列表
+	tbzEdbDataTimeList := make([]string, 0)
+
+	//同比值指标
+	{
+		var condition string
+		var pars []interface{}
+
+		condition += " AND data_time > ? AND edb_info_id = ? "
+		pars = append(pars, startCalculationDate, existItemB.FromEdbInfoId)
+
+		//第二个指标的数据列表
+		secondDataList, tmpErr := edbDataModel.GetEdbDataListAll(condition, pars, existItemB.FromSource, 0)
+		if tmpErr != nil {
+			return tmpErr
+		}
+
+		for _, v := range secondDataList {
+			tbzEdbDataMap[v.DataTime] = v.Value
+			tbzEdbDataTimeList = append(tbzEdbDataTimeList, v.DataTime)
+		}
+	}
+
+	sort.Strings(tbzEdbDataTimeList)
+
+	// 遍历现有的数据,判断拼接指标中是否存在该日期数据,如果拼接指标无此数据,那么需要删除该日期数据(日期的判断:需要在开始计算日期之后)
+	removeDateList := make([]string, 0)
+	for nowEdbDate := range nowEdbDataMap {
+		nowEdbDateTime, _ := time.ParseInLocation(utils.FormatDate, nowEdbDate, time.Local)
+		//校验日期 需要 大于 拼接前日期
+		if startCalculationDate.Before(nowEdbDateTime) {
+			if _, ok := tbzEdbDataMap[nowEdbDate]; !ok {
+				// 同比指标中,不存在该日期数据,那么需要移除 现有数据 中该日期的数据
+				removeDateList = append(removeDateList, nowEdbDate)
+			}
+		}
+	}
+
+	//待修改的指标数据map(index:日期,value:值)
+	updateEdbDataMap := make(map[string]float64)
+	for _, v := range tbzEdbDataTimeList {
+		tbzDataTime, _ := time.ParseInLocation(utils.FormatDate, v, time.Local)
+
+		//获取拼接指标上一年同一天的数据
+		var pjDataTime time.Time
+		if tbzDataTime.Month() == 2 {
+			pjDataTime = tbzDataTime.AddDate(0, -11, 0)
+			pjDataTime = time.Date(pjDataTime.Year(), pjDataTime.Month(), 1, 0, 0, 0, 0, time.Now().Location()).AddDate(0, 0, -1)
+		} else {
+			pjDataTime = tbzDataTime.AddDate(-1, 0, 0)
+		}
+
+		//校验现有数据中,是否存在该日期的数据,如果存在的话,那么就要去校验 最新计算数据 与 现有数据 是否一致
+		if nowEdbDataValue, isHas := nowEdbDataMap[v]; isHas {
+			//获取去年今日的数据,获取到后,然后是去修改该日期的数据
+			if lastYearEdbDataValue, ok := nowEdbDataMap[pjDataTime.Format(utils.FormatDate)]; ok {
+
+				if v == "2021-08-31" {
+					fmt.Println("进来了")
+				}
+				tbzDataValue := tbzEdbDataMap[v] //同比值
+				currValue := lastYearEdbDataValue * (1 + tbzDataValue/100)
+				currValue, _ = decimal.NewFromFloat(currValue).Truncate(4).Float64() //保留4位小数
+				//如果计算出来的值与库里面的值不匹配,那么就去修改该值
+				if nowEdbDataValue != currValue {
+					//将计算后的数据存入待拼接指标map里面,以便后续计算
+					updateEdbDataMap[v] = currValue
+				}
+			}
+		} else {
+			//因为 现有数据中 不存在该日期数据,那么需要做新增数据处理
+
+			//如果去年今日存在该数据,那么就去计算当前的数据
+			if pjDataValue, ok := nowEdbDataMap[pjDataTime.Format(utils.FormatDate)]; ok {
+				tbzDataValue := tbzEdbDataMap[v] //同比值
+				currValue := pjDataValue * (1 + tbzDataValue/100)
+
+				currValue, _ = decimal.NewFromFloat(currValue).Truncate(4).Float64()
+				//将计算后的数据存入已入库指标map里面,以便后续计算
+				nowEdbDataMap[v] = currValue
+
+				//将计算后的数据存入待拼接指标map里面,以便后续入库
+				pjDataMap[v] = currValue
+				pjEdbDataTimeList = append(pjEdbDataTimeList, v)
+			}
+		}
+	}
+
+	//新增的数据入库
+	{
+		addDataList := make([]*edbDataModel.EdbDataCalculateLjztbpj, 0)
+		for dataTime, dataValue := range pjDataMap {
+			//时间戳
+			currentDate, _ := time.Parse(utils.FormatDate, dataTime)
+			timestamp := currentDate.UnixNano() / 1e6
+
+			edbDataLjztbpj := &edbDataModel.EdbDataCalculateLjztbpj{
+				EdbInfoId:     edbInfo.EdbInfoId,
+				EdbCode:       edbInfo.EdbCode,
+				DataTime:      dataTime,
+				Value:         dataValue,
+				Status:        1,
+				CreateTime:    time.Now(),
+				ModifyTime:    time.Now(),
+				DataTimestamp: timestamp,
+			}
+			addDataList = append(addDataList, edbDataLjztbpj)
+		}
+
+		tmpAddDataList := make([]*edbDataModel.EdbDataCalculateLjztbpj, 0)
+		for _, v := range addDataList {
+			tmpAddDataList = append(tmpAddDataList, v)
+
+			if len(tmpAddDataList) >= 200 {
+				tmpErr := tx.Create(tmpAddDataList).Error
+				//_, tmpErr := o.InsertMulti(len(tmpAddDataList), tmpAddDataList)
+				if tmpErr != nil {
+					err = tmpErr
+					return
+				}
+				//重新初始化需要加入的数据切片
+				tmpAddDataList = make([]*edbDataModel.EdbDataCalculateLjztbpj, 0)
+			}
+		}
+		//最后如果还有需要新增的数据,那么就统一入库
+		if len(tmpAddDataList) > 0 {
+			tmpErr := tx.Create(tmpAddDataList).Error
+			//_, tmpErr := o.InsertMulti(len(tmpAddDataList), tmpAddDataList)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+		}
+	}
+
+	//删除已经不存在的累计同比拼接指标数据(由于同比值当日的数据删除了)
+	{
+		if len(removeDateList) > 0 {
+			removeDateStr := strings.Join(removeDateList, `","`)
+			removeDateStr = `"` + removeDateStr + `"`
+			//如果拼接指标变更了,那么需要删除所有的指标数据
+			tableName := edbDataModel.GetEdbDataTableName(edbInfo.Source)
+			sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? and data_time in (%s) `, tableName, removeDateStr)
+
+			err = tx.Exec(sql, edbInfo.EdbInfoId).Error
+			//_, err = o.Raw(sql, edbInfo.EdbInfoId).Exec()
+			if err != nil {
+				err = errors.New("删除不存在的累计值同比拼接指标数据失败,Err:" + err.Error())
+				return
+			}
+		}
+	}
+
+	//修改现有的数据中对应的值
+	{
+		tableName := edbDataModel.GetEdbDataTableName(edbInfo.Source)
+		for edbDate, edbDataValue := range updateEdbDataMap {
+			sql := fmt.Sprintf(` UPDATE  %s set value = ?,modify_time=now() WHERE edb_info_id = ? and data_time = ? `, tableName)
+
+			err = tx.Exec(sql, edbDataValue, edbInfo.EdbInfoId, edbDate).Error
+			//_, err = o.Raw(sql, edbDataValue, edbInfo.EdbInfoId, edbDate).Exec()
+			if err != nil {
+				err = errors.New("更新现有的累计值同比拼接指标数据失败,Err:" + err.Error())
+				return
+			}
+		}
+	}
+	return
+}

+ 41 - 0
services/chart/my_chart.go

@@ -0,0 +1,41 @@
+package chart
+
+import (
+	"errors"
+	"hongze/hongze_yb/models/tables/my_chart_classify"
+	"hongze/hongze_yb/services/user"
+)
+
+// GetUserChartClassifyListByCondition 获取用户图表分类列表
+func GetUserChartClassifyListByCondition(userInfo user.UserInfo, publicCondition, privateCondition map[string]interface{}) (publicClassify, privateClassify []*my_chart_classify.MyChartClassify, err error) {
+	// 判断是否为内部人员
+	isInner, adminInfo, err := user.GetAdminByUserInfo(userInfo)
+	if err != nil {
+		err = errors.New("用户信息有误, Err:" + err.Error())
+		return
+	}
+
+	if isInner {
+		// 内部人员
+		publicCondition["is_public"] = 1
+		publicCondition["admin_id !="] = adminInfo.AdminID
+		privateCondition["admin_id"] = adminInfo.AdminID
+		privateClassify, err = my_chart_classify.GetClassifyListByCondition(privateCondition, "sort ASC, my_chart_classify_id ASC")
+		if err != nil {
+			err = errors.New("获取我的图表分类失败, Err:" + err.Error())
+			return
+		}
+	} else {
+		// 用户
+		publicCondition["is_public"] = 1
+		publicCondition["is_company_public"] = 1
+	}
+
+	publicClassify, err = my_chart_classify.GetClassifyListByCondition(publicCondition, "public_time ASC")
+	if err != nil {
+		err = errors.New("获取公共图表分类失败, Err:" + err.Error())
+		return
+	}
+
+	return
+}

+ 130 - 1
services/company/permission.go

@@ -7,9 +7,11 @@ import (
 	"hongze/hongze_yb/models/tables/company"
 	"hongze/hongze_yb/models/tables/company_product"
 	"hongze/hongze_yb/models/tables/company_report_permission"
+	"hongze/hongze_yb/models/tables/company_user_chart_classify_permission"
 	"hongze/hongze_yb/models/tables/wx_user"
 	"hongze/hongze_yb/models/tables/yb_apply_record"
 	"hongze/hongze_yb/utils"
+	"time"
 )
 
 // GetClassNameListByProductId 根据权限id获取权限分类
@@ -128,7 +130,10 @@ func CheckPermissionByPermissionIdList2Ficc(companyId int64, userId int, permiss
 			ok, _ = checkPermissionByPermissionIdList2Rai(companyId, permissionIdList)
 		}
 		if ok == false && permissionCheckInfo.Type == "apply" {
-			_, err = yb_apply_record.GetLastNotOpRecordByUserId(userId)
+			_, err = yb_apply_record.GetLastNotOpRecordByUserId(userId)	// 从来源我的/活动申请的记录
+			if err != nil && err != utils.ErrNoRow {
+				return
+			}
 			//查询是否有申请过,如果有申请过的话,那么err是nil
 			if err == nil {
 				permissionCheckInfo.CustomerInfo.HasApply = true
@@ -276,3 +281,127 @@ func checkPermissionByPermissionIdList2Rai(companyId int64, permissionIdList []i
 
 	return
 }
+
+// ChartPermissionCheckInfo 图表权限验证信息
+type ChartPermissionCheckInfo struct {
+	Name         	string       	`json:"name" description:"销售名称"`
+	Mobile       	string       	`json:"mobile" description:"手机号"`
+	Type			string			`json:"type" description:"无权限,需要前端处理的类型,枚举值:expired, apply, contact"`
+	CustomerInfo	CustomerInfo 	`json:"customer_info" description:"客户信息"`
+}
+
+// CheckUserChartPermission 验证用户/联系人的图库权限
+func CheckUserChartPermission(companyId int64, userId int) (ok bool, permissionCheckInfo ChartPermissionCheckInfo, err error) {
+	defer func() {
+		// 如果无权限,那么就去查询是否申请过
+		if ok == false && permissionCheckInfo.Type == "apply" {
+			_, err = yb_apply_record.GetLastNotOpRecordByUserId(userId)	// 图库申请
+			// 查询是否有申请过,如果有申请过的话,那么err是nil
+			if err != nil {
+				if err == utils.ErrNoRow {
+					err = nil
+					return
+				}
+				return
+			}
+			permissionCheckInfo.CustomerInfo.HasApply = true
+		}
+	}()
+
+	var productId int64
+	productId = 1
+	if companyId > 1 {
+		// 查询是否开通FICC
+		companyProductInfo, tmpErr := company_product.GetByCompany2ProductId(companyId, productId)
+		if tmpErr != nil {
+			// 没有开通FICC
+			if tmpErr == utils.ErrNoRow {
+				permissionCheckInfo.Type = "apply"
+				return
+			}
+			err = tmpErr
+			return
+		}
+
+		wxUser, tmpErr := wx_user.GetByUserId(userId)
+		if tmpErr != nil {
+			permissionCheckInfo.Type = "apply"
+			err = tmpErr
+			return
+		}
+
+		// 客户信息
+		companyInfo, tmpErr := company.GetByCompanyId(companyId)
+		if tmpErr != nil {
+			// 没有开通FICC
+			if tmpErr == utils.ErrNoRow {
+				permissionCheckInfo.Type = "apply"
+				return
+			}
+			err = tmpErr
+			return
+		}
+		customerInfo := CustomerInfo{
+			CompanyName: companyInfo.CompanyName,
+			Status:      companyProductInfo.Status,
+			Name:        wxUser.RealName,
+			IsSuspend:   companyProductInfo.IsSuspend,
+			Mobile:      wxUser.Mobile,
+		}
+		permissionCheckInfo.CustomerInfo = customerInfo
+
+		// 如果客户FICC产品的状态是流失-申请
+		if companyProductInfo.Status == "流失" {
+			permissionCheckInfo.Type = "apply"
+			return
+		}
+
+		// 查找对应客户的销售信息
+		adminInfo, tmpErr := admin.GetByAdminId(companyProductInfo.SellerID)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		// 客户状态为冻结/试用暂停-联系销售
+		permissionCheckInfo.Name = adminInfo.RealName
+		permissionCheckInfo.Mobile = adminInfo.Mobile
+		if companyProductInfo.Status == "冻结" || (companyProductInfo.Status == "试用" && companyProductInfo.IsSuspend == 1) {
+			permissionCheckInfo.Type = "contact"
+			return
+		}
+
+		// 验证用户的图表权限
+		permissionInfo, tmpErr := company_user_chart_classify_permission.GetPermissionByUserId(userId)
+		if tmpErr != nil {
+			if tmpErr == utils.ErrNoRow {
+				// 无权限-联系销售
+				permissionCheckInfo.Type = "contact"
+				return
+			}
+			err = tmpErr
+			return
+		}
+		nowTime := time.Now()
+		if permissionInfo.Enabled != 1 {
+			// 权限被禁用-联系销售
+			permissionCheckInfo.Type = "contact"
+			return
+		}
+		endTime := permissionInfo.EndTime.Add(23 * time.Hour + 59 * time.Minute + 59 * time.Second)
+		if nowTime.After(permissionInfo.StartTime) && nowTime.Before(endTime) {
+			ok = true
+		} else {
+			// 权限已到期
+			permissionCheckInfo.Type = "expired"
+			return
+		}
+
+		// 都不是默认联系销售
+		permissionCheckInfo.Type = "contact"
+	} else {
+		permissionCheckInfo.Type = "apply"
+	}
+
+	return
+}

+ 185 - 0
services/edb_data/edb_data.go

@@ -0,0 +1,185 @@
+package edb_data
+
+import (
+	"fmt"
+	"github.com/nosixtools/solarlunar"
+	edbDataModel "hongze/hongze_yb/models/tables/edb_data"
+	"hongze/hongze_yb/utils"
+	"strconv"
+	"time"
+)
+
+// AddCalculateQuarter 指标季度数据计算(公历转农历)
+func AddCalculateQuarter(dataList []*edbDataModel.EdbDataList) (result *edbDataModel.EdbDataResult, err error) {
+	var errMsg string
+	defer func() {
+		if errMsg != "" {
+			fmt.Println("errMsg:", errMsg)
+		}
+	}()
+
+	endDate := dataList[len(dataList)-1].DataTime
+	endDateForm, err := time.Parse(utils.FormatDate, endDate)
+	if err != nil {
+		return result, err
+	}
+	thisMonth := int(endDateForm.Month())
+
+	result = new(edbDataModel.EdbDataResult)
+	var yearArr []int
+	yearMap := make(map[int]int)
+	var cureentDate time.Time
+	if thisMonth < 11 {
+		for k, v := range dataList {
+			dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+			if err != nil {
+				errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+				return result, err
+			}
+			if k == len(dataList)-1 {
+				cureentDate = dateTime
+			}
+			year := dateTime.Year()
+			if _, ok := yearMap[year]; !ok {
+				yearArr = append(yearArr, year)
+			}
+			yearMap[year] = year
+		}
+	} else {
+		for k, v := range dataList {
+			dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+			if err != nil {
+				errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+				return result, err
+			}
+			if k == len(dataList)-1 {
+				cureentDate = dateTime
+			}
+			year := dateTime.Year() + 1
+			if _, ok := yearMap[year]; !ok {
+				yearArr = append(yearArr, year)
+			}
+			yearMap[year] = year
+		}
+	}
+	//排序
+	//fmt.Println("yearArr:", yearArr)
+	thisYear := cureentDate.Year()
+	//thisMonth := int(cureentDate.Month())
+
+	//fmt.Println("thisMonth:", thisMonth)
+	for ky, vy := range yearArr {
+		//fmt.Println("line 432:", ky, vy, thisYear, thisMonth)
+		if thisMonth < 11 {
+			currentYearCjnl := strconv.Itoa(thisYear) + "-01-01"               //当前年份春节农历
+			currentYearCjgl := solarlunar.LunarToSolar(currentYearCjnl, false) //当前年份春节公历
+			currentYearCjglDate, err := time.Parse(utils.FormatDate, currentYearCjgl)
+			if err != nil {
+				errMsg = "生成当前春节失败,Err:" + err.Error()
+				return result, err
+			}
+
+			preYear := vy
+			preYearCjnl := strconv.Itoa(preYear) + "-01-01"            //之前年份春节农历
+			preYearCjgl := solarlunar.LunarToSolar(preYearCjnl, false) //之前年份春节公历
+			preYearCjglDate, err := time.Parse(utils.FormatDate, preYearCjgl)
+			if err != nil {
+				errMsg = "生成历史年份春节失败,Err:" + err.Error()
+				return result, err
+			}
+			day := currentYearCjglDate.Sub(preYearCjglDate).Hours() / float64(24)
+
+			items := new(edbDataModel.EdbDataItems)
+			items.Year = preYear
+			for _, v := range dataList {
+				dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+				if err != nil {
+					errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+					return result, err
+				}
+				newDate := dateTime.AddDate(0, 0, int(day))
+				selectDateStr := strconv.Itoa(thisYear) + "-11" + "-30"
+				selectDate, _ := time.Parse(utils.FormatDate, selectDateStr)
+				if newDate.Before(selectDate) || newDate == selectDate {
+					timestamp := newDate.UnixNano() / 1e6
+					item := new(edbDataModel.EdbDataList)
+					item.DataTime = newDate.Format(utils.FormatDate)
+					item.EdbInfoId = v.EdbInfoId
+					item.Value = v.Value
+					item.EdbDataId = v.EdbDataId
+					item.DataTimestamp = timestamp
+					items.Items = append(items.Items, item)
+				}
+			}
+			result.List = append(result.List, items)
+		} else {
+			nextYear := thisYear + 1
+			nextYearCjnl := strconv.Itoa(nextYear) + "-01-01"            //当前年份春节农历
+			nextYearCjgl := solarlunar.LunarToSolar(nextYearCjnl, false) //当前年份春节公历
+
+			nextYearCjglDate, err := time.Parse(utils.FormatDate, nextYearCjgl)
+			if err != nil {
+				errMsg = "生成当前春节失败,Err:" + err.Error()
+				return result, err
+			}
+			preYear := vy
+			preYearCjnl := strconv.Itoa(preYear) + "-01-01"            //之前年份春节农历
+			preYearCjgl := solarlunar.LunarToSolar(preYearCjnl, false) //之前年份春节公历
+			preYearCjglDate, err := time.Parse(utils.FormatDate, preYearCjgl)
+			if err != nil {
+				errMsg = "生成历史年份春节失败,Err:" + err.Error()
+				return result, err
+			}
+			day := nextYearCjglDate.Sub(preYearCjglDate).Hours() / float64(24)
+
+			//fmt.Println("day:", day, nextYearCjglDate, preYearCjglDate)
+
+			items := new(edbDataModel.EdbDataItems)
+			items.Year = preYear - 1
+			//fmt.Println("preYear:", preYear, "ky:", ky, "yearArrLen:", len(yearArr))
+			if ky+1 < len(yearArr) {
+				for _, v := range dataList {
+					dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+					if err != nil {
+						errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+						return result, err
+					}
+					newDate := dateTime.AddDate(0, 0, int(day))
+					selectDateStr := strconv.Itoa(nextYear) + "-05" + "-31"
+					selectDate, _ := time.Parse(utils.FormatDate, selectDateStr)
+
+					if newDate.Before(selectDate) || newDate == selectDate {
+						timestamp := newDate.UnixNano() / 1e6
+						item := new(edbDataModel.EdbDataList)
+						item.DataTime = newDate.Format(utils.FormatDate)
+						item.EdbInfoId = v.EdbInfoId
+						item.Value = v.Value
+						item.EdbDataId = v.EdbDataId
+						item.DataTimestamp = timestamp
+						items.Items = append(items.Items, item)
+					}
+				}
+				result.List = append(result.List, items)
+			} else {
+				for _, v := range dataList {
+					dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+					if err != nil {
+						errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+						return result, err
+					}
+					timestamp := dateTime.UnixNano() / 1e6
+					item := new(edbDataModel.EdbDataList)
+					item.DataTime = dateTime.Format(utils.FormatDate)
+					item.EdbInfoId = v.EdbInfoId
+					item.Value = v.Value
+					item.EdbDataId = v.EdbDataId
+					item.DataTimestamp = timestamp
+					items.Items = append(items.Items, item)
+				}
+				result.List = append(result.List, items)
+			}
+		}
+	}
+
+	return
+}

+ 21 - 0
services/user/user.go

@@ -5,6 +5,7 @@ import (
 	"errors"
 	"github.com/gin-gonic/gin"
 	"github.com/silenceper/wechat/v2/miniprogram/auth"
+	admin2 "hongze/hongze_yb/models/tables/admin"
 	"hongze/hongze_yb/models/tables/rddp/session"
 	"hongze/hongze_yb/models/tables/user_record"
 	"hongze/hongze_yb/models/tables/wx_user"
@@ -415,3 +416,23 @@ func GetInfoByClaims(c *gin.Context) (userInfo UserInfo) {
 	userInfo = claims.(UserInfo)
 	return
 }
+
+// GetAdminByUserId 判断当前用户是否为内部人员
+func GetAdminByUserInfo(userInfo UserInfo) (ok bool, adminInfo *admin2.Admin, err error) {
+	mobile := userInfo.Mobile
+	if mobile == "" {
+		// 用户有可能是通过邮箱登录
+		return
+	}
+	adminInfo, err = admin2.GetAdminByMobile(mobile)
+	if err != nil {
+		if err == utils.ErrNoRow {
+			err = nil
+			return
+		}
+		return
+	}
+	ok = true
+
+	return
+}

+ 57 - 1
utils/constants.go

@@ -25,7 +25,7 @@ const (
 const (
 	APPNAME = "弘则研报"
 	//EmailSendToUsers = "glji@hzinsights.com;pyan@hzinsights.com;cxzhang@hzinsights.com"
-	EmailSendToUsers = "pyan@hzinsights.com"
+	EmailSendToUsers = "glji@hzinsights.com;pyan@hzinsights.com;hsun@hzinsights.com"
 )
 
 //聚合短信
@@ -40,3 +40,59 @@ var (
 const (
 	key = "zDeESsxsXuionhqSLZYHWcDJ" //全局加密KEY
 )
+
+//数据来源渠道
+const (
+	DATA_SOURCE_THS                  = iota + 1 //同花顺
+	DATA_SOURCE_WIND                            //wind
+	DATA_SOURCE_PB                              //彭博
+	DATA_SOURCE_CALCULATE                       //指标运算
+	DATA_SOURCE_CALCULATE_LJZZY                 //累计值转月
+	DATA_SOURCE_CALCULATE_TBZ                   //同比值
+	DATA_SOURCE_CALCULATE_TCZ                   //同差值
+	DATA_SOURCE_CALCULATE_NSZYDPJJS             //N数值移动平均计算
+	DATA_SOURCE_MANUAL                          //手工指标
+	DATA_SOURCE_LZ                              //隆众
+	DATA_SOURCE_YS                              //有色
+	DATA_SOURCE_CALCULATE_HBZ                   //环比值->12
+	DATA_SOURCE_CALCULATE_HCZ                   //环差值->13
+	DATA_SOURCE_CALCULATE_BP                    //变频->14
+	DATA_SOURCE_GL                              //钢联->15
+	DATA_SOURCE_ZZ                              //郑商所->16
+	DATA_SOURCE_DL                              //大商所->17
+	DATA_SOURCE_SH                              //上期所->18
+	DATA_SOURCE_CFFEX                           //中金所->19
+	DATA_SOURCE_SHFE                            //上期能源->20
+	DATA_SOURCE_GIE                             //欧洲天然气->21
+	DATA_SOURCE_CALCULATE_TIME_SHIFT            //时间移位->22
+	DATA_SOURCE_CALCULATE_ZJPJ                  //直接拼接->23
+	DATA_SOURCE_CALCULATE_LJZTBPJ               //累计值同比拼接->24
+	DATA_SOURCE_LT                              //路透->25
+
+)
+
+const (
+	HZ_CHART_LIB_DETAIL = "HZ_CHART_LIB_DETAIL_"
+)
+
+//var (
+//	Hz_Server_Data_Url string //同花顺,万得接口服务地址(阿里云windows服务器地址)
+//)
+
+const (
+	DATA_PREFIX  = "hz_data"
+	CHART_PREFIX = "hz_chart"
+)
+
+//数据刷新频率
+const (
+	DATA_REFRESH        = 7 //7个单位,日/周/月/季度/年
+	DATA_END_DATE_LIMIT = 4 //数据结束日期为,当前日期,加上4年时间
+)
+
+const (
+	Hz_Data_Url    = "http://datawind.hzinsights.com:8040/" //同花顺,万得接口服务地址
+	Hz_Data_PB_Url = "http://datapb.hzinsights.com:8040/"   //彭博接口地址
+	Hz_Data_LT_Url = "http://dataek.hzinsights.com:8040/"   //路透社接口地址
+	EDB_DATA_LIMIT = 10
+)

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels