ソースを参照

Merge branch 'master' of eta_server/eta_api into custom

xyxie 10 ヶ月 前
コミット
5ab14ade30

+ 523 - 0
controllers/data_manage/bloomberg_data.go

@@ -0,0 +1,523 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/system"
+	"eta/eta_api/services/data"
+	etaTrialService "eta/eta_api/services/eta_trial"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// BloombergDataController 彭博数据源
+type BloombergDataController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 指标列表
+// @Description 指标列表
+// @Param   PageSize  query  int  false  "每页数据量"
+// @Param   CurrentIndex  query  int  false  "页码"
+// @Param   Frequency  query  string  false  "频度"
+// @Param   Keywords  query  string  false  "指标ID/指标名称"
+// @Param   ListAll  query  bool  false  "列表全选"
+// @Param   SortField  query  int  false  "排序字段: 0-默认; 1-开始时间; 2-最新时间; 3-更新时间"
+// @Param   SortRule  query  int  false  "排序方式: 0-默认; 1-正序; 2-倒序"
+// @Success 200 {object} data_manage.BloombergSourceListResp
+// @router /bloomberg_source/list [get]
+func (this *BloombergDataController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	params := new(data_manage.BloombergSourceListReq)
+	if e := this.ParseForm(params); e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+
+	cond := ``
+	pars := make([]interface{}, 0)
+	// 筛选项
+	{
+		params.Keywords = strings.TrimSpace(params.Keywords)
+		if params.Keywords != "" {
+			cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, data_manage.BaseFromBloombergIndexCols.IndexCode, data_manage.BaseFromBloombergIndexCols.IndexName)
+			kw := fmt.Sprint("%", params.Keywords, "%")
+			pars = append(pars, kw, kw)
+		}
+		if params.Frequency != "" {
+			cond += fmt.Sprintf(` AND %s = ?`, data_manage.BaseFromBloombergIndexCols.Frequency)
+			pars = append(pars, params.Frequency)
+		}
+	}
+
+	// 分页列表
+	bloombergOb := new(data_manage.BaseFromBloombergIndex)
+	total, e := bloombergOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取Bloomberg原始指标列表总数失败, Err: " + e.Error()
+		return
+	}
+	var startSize int
+	if params.PageSize <= 0 {
+		params.PageSize = utils.PageSize20
+	}
+	if params.CurrentIndex <= 0 {
+		params.CurrentIndex = 1
+	}
+	startSize = utils.StartIndex(params.CurrentIndex, params.PageSize)
+
+	// 排序, 默认创建时间倒序
+	orderFields := map[int]string{
+		0: data_manage.BaseFromBloombergIndexCols.CreateTime, 1: data_manage.BaseFromBloombergIndexCols.StartDate,
+		2: data_manage.BaseFromBloombergIndexCols.EndDate, 3: data_manage.BaseFromBloombergIndexCols.ModifyTime,
+	}
+	orderType := map[int]string{0: "DESC", 1: "ASC", 2: "DESC"}
+	orderRule := fmt.Sprintf("%s %s", orderFields[params.SortField], orderType[params.SortRule])
+
+	// 列表
+	edbList := make([]*data_manage.BaseFromBloombergIndex, 0)
+	if params.ListAll {
+		list, e := bloombergOb.GetItemsByCondition(cond, pars, []string{}, orderRule, 0)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取Bloomberg原始指标列表失败, Err: " + e.Error()
+			return
+		}
+		edbList = list
+	} else {
+		list, e := bloombergOb.GetPageItemsByCondition(cond, pars, []string{}, orderRule, startSize, params.PageSize)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取Bloomberg原始指标分页列表失败, Err: " + e.Error()
+			return
+		}
+		edbList = list
+	}
+
+	// 获取指标库已有指标
+	existsEdb, e := data_manage.GetEdbCodesBySource(utils.DATA_SOURCE_BLOOMBERG)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取Bloomberg已添加的指标失败, Err: " + e.Error()
+		return
+	}
+	existMap := make(map[string]*data_manage.EdbInfo)
+	for _, v := range existsEdb {
+		existMap[v.EdbCode] = v
+	}
+
+	respList := make([]*data_manage.BaseFromBloombergIndexItem, 0)
+	for _, v := range edbList {
+		t := data_manage.FormatBaseFromBloombergIndex2Item(v)
+		ed := existMap[v.IndexCode]
+		if ed != nil {
+			t.EdbExist = 1
+			t.EdbInfoId = ed.EdbInfoId
+			t.EdbUniqueCode = ed.UniqueCode
+			t.EdbClassifyId = ed.ClassifyId
+		}
+		respList = append(respList, t)
+	}
+	page := paging.GetPaging(params.CurrentIndex, params.PageSize, total)
+	dataResp := new(data_manage.BloombergSourceListResp)
+	dataResp.Paging = page
+	dataResp.List = respList
+
+	br.Data = dataResp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// BatchAdd
+// @Title 批量新增
+// @Description 批量新增
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /bloomberg_source/batch_add [post]
+func (this *BloombergDataController) BatchAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	deleteCache := true
+	cacheKey := "CACHE_EDB_INFO_BATCH_ADD_BLOOMBERG_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			_ = utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req []*data_manage.AddEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if len(req) > 30 {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+	indexNames := make([]string, 0)
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		indexNames = append(indexNames, v.EdbName)
+		v.Frequency = strings.TrimSpace(v.Frequency)
+		if v.Frequency == "" {
+			br.Msg = "请选择频度"
+			return
+		}
+		v.Unit = strings.TrimSpace(v.Unit)
+		if v.Unit == "" {
+			br.Msg = "请输入单位"
+			return
+		}
+		if v.ClassifyId <= 0 {
+			br.Msg = "请选择分类"
+			return
+		}
+	}
+
+	// 限定同一时间最多批量新增30个指标
+	for _, v := range req {
+		var r data.BloombergIndexSource2EdbReq
+		r.EdbCode = v.EdbCode
+		r.EdbName = v.EdbName
+		r.Frequency = v.Frequency
+		r.Unit = v.Unit
+		r.ClassifyId = v.ClassifyId
+		r.AdminId = sysUser.AdminId
+		r.AdminRealName = sysUser.RealName
+
+		edbInfo, e, errMsg, skip := data.BloombergIndexSource2Edb(r)
+		if e != nil {
+			br.Msg = "操作失败"
+			if errMsg != "" {
+				br.Msg = errMsg
+			}
+			br.ErrMsg = e.Error()
+			return
+		}
+		if skip {
+			continue
+		}
+
+		// 试用平台更新用户累计新增指标数
+		if utils.BusinessCode == utils.BusinessCodeSandbox {
+			go func() {
+				adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+				if e != nil {
+					tips := fmt.Sprintf("试用平台更新用户累计新增指标数-获取用户失败, Err: " + e.Error())
+					utils.FileLog.Info(tips)
+					return
+				}
+				if adminItem.DepartmentName != "ETA试用客户" {
+					return
+				}
+				var ur etaTrialService.EtaTrialUserReq
+				ur.Mobile = adminItem.Mobile
+				_, _ = etaTrialService.UpdateUserIndexNum(ur)
+			}()
+		}
+
+		// 新增操作日志
+		{
+			edbLog := new(data_manage.EdbInfoLog)
+			edbLog.EdbInfoId = edbInfo.EdbInfoId
+			edbLog.SourceName = edbInfo.SourceName
+			edbLog.Source = edbInfo.Source
+			edbLog.EdbCode = edbInfo.EdbCode
+			edbLog.EdbName = edbInfo.EdbName
+			edbLog.ClassifyId = edbInfo.ClassifyId
+			edbLog.SysUserId = sysUser.AdminId
+			edbLog.SysUserRealName = sysUser.RealName
+			edbLog.CreateTime = time.Now()
+			edbLog.Content = string(this.Ctx.Input.RequestBody)
+			edbLog.Status = "新增指标"
+			edbLog.Method = this.Ctx.Input.URI()
+			go data_manage.AddEdbInfoLog(edbLog)
+		}
+	}
+
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// NameCheck
+// @Title 重名校验
+// @Description 批量新增
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /bloomberg_source/name_check [post]
+func (this *BloombergDataController) NameCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req []*data_manage.AddEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+
+	type NameCheckResult struct {
+		EdbCode string
+		EdbName string
+		Exist   bool
+	}
+	indexNames := make([]string, 0)
+	resp := make([]*NameCheckResult, 0)
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		indexNames = append(indexNames, v.EdbName)
+		resp = append(resp, &NameCheckResult{
+			EdbCode: v.EdbCode,
+			EdbName: v.EdbName,
+		})
+	}
+
+	// 重名校验
+	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取重名指标失败, Err: " + e.Error()
+		return
+	}
+	nameExists := make(map[string]bool)
+	for _, v := range edbList {
+		nameExists[v.EdbName] = true
+	}
+	if len(nameExists) > 0 {
+		for _, v := range resp {
+			v.Exist = nameExists[v.EdbName]
+		}
+	}
+
+	br.Data = resp
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// AddCheck
+// @Title 新增校验
+// @Description 新增校验
+// @Param	request	body data_manage.BloombergSourceBatchAddCheckReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /bloomberg_source/add_check [post]
+func (this *BloombergDataController) AddCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req *data_manage.BloombergSourceBatchAddCheckReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	codeMax := 30
+	codeLen := len(req.IndexCodes)
+
+	// 排序, 默认创建时间倒序
+	orderFields := map[int]string{
+		0: data_manage.BaseFromBloombergIndexCols.CreateTime, 1: data_manage.BaseFromBloombergIndexCols.StartDate,
+		2: data_manage.BaseFromBloombergIndexCols.EndDate, 3: data_manage.BaseFromBloombergIndexCols.ModifyTime,
+	}
+	orderType := map[int]string{0: "DESC", 1: "ASC", 2: "DESC"}
+	orderRule := fmt.Sprintf("%s %s", orderFields[req.SortField], orderType[req.SortRule])
+
+	// 获取指标库已有指标
+	existsEdb, e := data_manage.GetEdbCodesBySource(utils.DATA_SOURCE_BLOOMBERG)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取Bloomberg已添加的指标失败, Err: " + e.Error()
+		return
+	}
+	existMap := make(map[string]*data_manage.EdbInfo)
+	for _, v := range existsEdb {
+		existMap[v.EdbCode] = v
+	}
+
+	// 非全选-不需要频率等筛选条件
+	bloombergOb := new(data_manage.BaseFromBloombergIndex)
+	if !req.ListAll {
+		if codeLen == 0 {
+			br.Msg = "请选择指标"
+			return
+		}
+		if codeLen > codeMax {
+			br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
+			return
+		}
+
+		// 查询选中的指标
+		cond := fmt.Sprintf(` AND %s IN (%s)`, data_manage.BaseFromBloombergIndexCols.IndexCode, utils.GetOrmInReplace(codeLen))
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.IndexCodes)
+		list, e := bloombergOb.GetItemsByCondition(cond, pars, []string{}, orderRule, 0)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取Bloomberg原始指标列表失败, Err: " + e.Error()
+			return
+		}
+		resp := make([]*data_manage.BaseFromBloombergIndexItem, 0)
+		for _, v := range list {
+			t := data_manage.FormatBaseFromBloombergIndex2Item(v)
+			ed := existMap[v.IndexCode]
+			if ed != nil {
+				t.EdbExist = 1
+				t.EdbInfoId = ed.EdbInfoId
+				t.EdbUniqueCode = ed.UniqueCode
+				t.EdbClassifyId = ed.ClassifyId
+			}
+			resp = append(resp, t)
+		}
+
+		br.Data = resp
+		br.Msg = "校验成功"
+		br.Ret = 200
+		br.Success = true
+		return
+	}
+
+	// 全选-需要频率等筛选条件
+	cond := ``
+	pars := make([]interface{}, 0)
+	// 筛选项
+	req.Keywords = strings.TrimSpace(req.Keywords)
+	if req.Keywords != "" {
+		cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, data_manage.BaseFromBloombergIndexCols.IndexCode, data_manage.BaseFromBloombergIndexCols.IndexName)
+		kw := fmt.Sprint("%", req.Keywords, "%")
+		pars = append(pars, kw, kw)
+	}
+	if req.Frequency != "" {
+		cond += fmt.Sprintf(` AND %s = ?`, data_manage.BaseFromBloombergIndexCols.Frequency)
+		pars = append(pars, req.Frequency)
+	}
+	// 排除对应指标
+	if codeLen > 0 {
+		cond += fmt.Sprintf(` AND %s NOT IN (%s)`, data_manage.BaseFromBloombergIndexCols.IndexCode, utils.GetOrmInReplace(codeLen))
+		pars = append(pars, req.IndexCodes)
+	}
+	// 查询max+1个指标
+	list, e := bloombergOb.GetItemsByCondition(cond, pars, []string{}, orderRule, codeMax+1)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取Bloomberg原始指标列表失败, Err: " + e.Error()
+		return
+	}
+	if len(list) > codeMax {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
+		return
+	}
+
+	resp := make([]*data_manage.BaseFromBloombergIndexItem, 0)
+	for _, v := range list {
+		t := data_manage.FormatBaseFromBloombergIndex2Item(v)
+		ed := existMap[v.IndexCode]
+		if ed != nil {
+			t.EdbExist = 1
+			t.EdbInfoId = ed.EdbInfoId
+			t.EdbUniqueCode = ed.UniqueCode
+			t.EdbClassifyId = ed.ClassifyId
+		}
+		resp = append(resp, t)
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}

+ 372 - 0
controllers/fe_calendar/fe_calendar_matter.go

@@ -0,0 +1,372 @@
+package fe_calendar
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/fe_calendar"
+	"eta/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// FeCalendarMatterController 外汇日历-事项
+type FeCalendarMatterController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 事项列表
+// @Description 事项列表
+// @Param   ChartPermissionId	query	int		true	"品种ID"
+// @Param   StartDate			query	string	true	"开始日期"
+// @Param   EndDate				query   string	true	"结束日期"
+// @Success 200 {object} fe_calendar.FeCalendarMatterListItem
+// @router /matter/list [get]
+func (this *FeCalendarMatterController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	params := new(fe_calendar.FeCalendarMatterListReq)
+	if e := this.ParseForm(params); e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "入参解析失败, Err: " + e.Error()
+		return
+	}
+	if params.ChartPermissionId <= 0 {
+		br.Msg = "请选择品种"
+		return
+	}
+
+	cond := ``
+	pars := make([]interface{}, 0)
+	if params.ChartPermissionId > 0 {
+		cond += fmt.Sprintf(` AND %s = ?`, fe_calendar.FeCalendarMatterCols.ChartPermissionId)
+		pars = append(pars, params.ChartPermissionId)
+	}
+	if params.StartDate != "" && params.EndDate != "" {
+		_, e := time.Parse(utils.FormatDate, params.StartDate)
+		if e != nil {
+			br.Msg = "开始日期格式有误"
+			return
+		}
+		_, e = time.Parse(utils.FormatDate, params.EndDate)
+		if e != nil {
+			br.Msg = "结束日期格式有误"
+			return
+		}
+		cond += fmt.Sprintf(` AND %s >= ? AND %s <= ?`, fe_calendar.FeCalendarMatterCols.MatterDate, fe_calendar.FeCalendarMatterCols.MatterDate)
+		pars = append(pars, params.StartDate, params.EndDate)
+	}
+
+	matterOb := new(fe_calendar.FeCalendarMatter)
+	order := fmt.Sprintf(`%s ASC, %s ASC`, fe_calendar.FeCalendarMatterCols.MatterDate, fe_calendar.FeCalendarMatterCols.Sort)
+	matters, e := matterOb.GetItemsByCondition(cond, pars, []string{}, order)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取事项列表失败, Err: " + e.Error()
+		return
+	}
+
+	dateMatter := make(map[string][]*fe_calendar.FeCalendarMatterItem)
+	for _, v := range matters {
+		d := v.MatterDate.Format(utils.FormatDate)
+		if dateMatter[d] == nil {
+			dateMatter[d] = make([]*fe_calendar.FeCalendarMatterItem, 0)
+		}
+		dateMatter[d] = append(dateMatter[d], fe_calendar.FormatFeCalendarMatter2Item(v))
+	}
+	dateExist := make(map[string]bool)
+	resp := make([]*fe_calendar.FeCalendarMatterListItem, 0)
+	for _, v := range matters {
+		d := v.MatterDate.Format(utils.FormatDate)
+		if dateExist[d] {
+			continue
+		}
+		dateExist[d] = true
+		resp = append(resp, &fe_calendar.FeCalendarMatterListItem{
+			Date:    d,
+			Matters: dateMatter[d],
+		})
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Detail
+// @Title 事项详情
+// @Description 事项详情
+// @Param   ChartPermissionId  query  int  true  "品种ID"
+// @Param   MatterDate  query  string  true  "事项日期"
+// @Success 200 {object} fe_calendar.FeCalendarMatterItem
+// @router /matter/detail [get]
+func (this *FeCalendarMatterController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	permissionId, _ := this.GetInt("ChartPermissionId")
+	if permissionId <= 0 {
+		br.Msg = "请选择品种"
+		return
+	}
+	matterDate := this.GetString("MatterDate")
+	if matterDate == "" {
+		br.Msg = "请选择日期"
+		return
+	}
+	_, e := time.Parse(utils.FormatDate, matterDate)
+	if e != nil {
+		br.Msg = "日期格式有误"
+		return
+	}
+
+	matterOb := new(fe_calendar.FeCalendarMatter)
+	cond := fmt.Sprintf(` AND %s = ? AND %s = ?`, fe_calendar.FeCalendarMatterCols.ChartPermissionId, fe_calendar.FeCalendarMatterCols.MatterDate)
+	pars := make([]interface{}, 0)
+	pars = append(pars, permissionId, matterDate)
+	order := fmt.Sprintf(`%s ASC`, fe_calendar.FeCalendarMatterCols.Sort)
+	matters, e := matterOb.GetItemsByCondition(cond, pars, []string{}, order)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取事项列表失败, Err: " + e.Error()
+		return
+	}
+	resp := make([]*fe_calendar.FeCalendarMatterItem, 0)
+	for _, v := range matters {
+		resp = append(resp, fe_calendar.FormatFeCalendarMatter2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Save
+// @Title 保存事项
+// @Description 保存事项
+// @Param	request	body fe_calendar.FeCalendarMatterSaveReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /matter/save [post]
+func (this *FeCalendarMatterController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req fe_calendar.FeCalendarMatterSaveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	// 参数校验
+	if req.ChartPermissionId <= 0 {
+		br.Msg = "请选择品种"
+		return
+	}
+	if req.MatterDate == "" {
+		br.Msg = "请选择日期"
+		return
+	}
+	var matterMonth string
+	matterDate, e := time.ParseInLocation(utils.FormatDate, req.MatterDate, time.Local)
+	if e != nil {
+		br.Msg = "日期格式有误"
+		return
+	}
+	matterMonth = matterDate.Format("2006-01")
+	if len(req.Matters) > 0 {
+		for _, v := range req.Matters {
+			if v.MatterType != fe_calendar.MatterTypeFree && v.MatterType != fe_calendar.MatterTypeEdb && v.MatterType != fe_calendar.MatterTypePredict {
+				br.Msg = "事项类型有误"
+				br.ErrMsg = fmt.Sprintf("事项类型有误, MatterType: %d", v.MatterType)
+				return
+			}
+			v.Title = strings.TrimSpace(v.Title)
+			if v.Title == "" {
+				br.Msg = "请输入指标/事项名称"
+				return
+			}
+			if len([]rune(v.Title)) > 15 {
+				br.Msg = "名称超出15个字,请重新编辑"
+				return
+			}
+			if v.MatterType == fe_calendar.MatterTypeEdb || v.MatterType == fe_calendar.MatterTypePredict {
+				if v.EdbInfoId <= 0 || v.EdbUniqueCode == "" || v.EdbCode == "" {
+					br.Msg = "指标信息有误"
+					br.ErrMsg = fmt.Sprintf("指标信息有误, EdbInfoId: %d, EdbUniqueCode: %s, EdbCode: %s", v.EdbInfoId, v.EdbUniqueCode, v.EdbCode)
+					return
+				}
+			}
+		}
+	}
+
+	// 品种信息
+	permissionItem, e := models.GetChartPermissionById(req.ChartPermissionId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取品种失败, Err: " + e.Error()
+		return
+	}
+
+	// 获取已有事项
+	matterOb := new(fe_calendar.FeCalendarMatter)
+	cond := fmt.Sprintf(` AND %s = ? AND %s = ?`, fe_calendar.FeCalendarMatterCols.ChartPermissionId, fe_calendar.FeCalendarMatterCols.MatterDate)
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.ChartPermissionId, req.MatterDate)
+	order := fmt.Sprintf(`%s ASC`, fe_calendar.FeCalendarMatterCols.Sort)
+	matters, e := matterOb.GetItemsByCondition(cond, pars, []string{}, order)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取已有事项列表失败, Err: " + e.Error()
+		return
+	}
+
+	addMatters := make([]*fe_calendar.FeCalendarMatter, 0)
+	editMatters := make([]*fe_calendar.FeCalendarMatter, 0)
+	removeMatters := make([]*fe_calendar.FeCalendarMatter, 0)
+	updateCols := []string{fe_calendar.FeCalendarMatterCols.Title, fe_calendar.FeCalendarMatterCols.FontColor, fe_calendar.FeCalendarMatterCols.FillingColor, fe_calendar.FeCalendarMatterCols.FontBold, fe_calendar.FeCalendarMatterCols.Sort, fe_calendar.FeCalendarMatterCols.ChartPermissionName, fe_calendar.FeCalendarMatterCols.ModifyTime}
+
+	editIds := make([]int, 0)
+	editMatterMap := make(map[int]*fe_calendar.FeCalendarMatterSaveItem)
+	for _, v := range req.Matters {
+		// 更新的事项map
+		if v.FeCalendarMatterId > 0 {
+			editIds = append(editIds, v.FeCalendarMatterId)
+			editMatterMap[v.FeCalendarMatterId] = v
+			continue
+		}
+		// 新增事项
+		addMatters = append(addMatters, &fe_calendar.FeCalendarMatter{
+			ChartPermissionId:   req.ChartPermissionId,
+			ChartPermissionName: permissionItem.PermissionName,
+			MatterMonth:         matterMonth,
+			MatterDate:          matterDate,
+			Title:               strings.TrimSpace(v.Title),
+			MatterType:          v.MatterType,
+			EdbInfoId:           v.EdbInfoId,
+			EdbUniqueCode:       v.EdbUniqueCode,
+			EdbCode:             v.EdbCode,
+			FontColor:           v.FontColor,
+			FillingColor:        v.FillingColor,
+			FontBold:            v.FontBold,
+			Sort:                v.Sort,
+			SysUserId:           sysUser.AdminId,
+			SysUserName:         sysUser.RealName,
+			CreateTime:          time.Now().Local(),
+			ModifyTime:          time.Now().Local(),
+		})
+	}
+	for _, v := range matters {
+		// 移除的事项
+		if !utils.InArrayByInt(editIds, v.FeCalendarMatterId) {
+			removeMatters = append(removeMatters, v)
+			continue
+		}
+		// 编辑的事项
+		ed := editMatterMap[v.FeCalendarMatterId]
+		if ed != nil {
+			v.Title = strings.TrimSpace(ed.Title)
+			v.FontColor = ed.FontColor
+			v.FillingColor = ed.FillingColor
+			v.FontBold = ed.FontBold
+			v.Sort = ed.Sort
+			v.ChartPermissionName = permissionItem.PermissionName
+			v.ModifyTime = time.Now().Local()
+			editMatters = append(editMatters, v)
+		}
+	}
+
+	// 保存/删除
+	if e = matterOb.Save(addMatters, editMatters, removeMatters, updateCols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "保存事项失败, Err: " + e.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// PermissionList
+// @Title 品种列表
+// @Description 品种列表
+// @Success 200 {object} models.SimpleChartPermission
+// @router /permission/list [get]
+func (this *FeCalendarMatterController) PermissionList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	permissions, e := models.GetChartPermissionsByProductId()
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取品种列表失败, Err: " + e.Error()
+		return
+	}
+	resp := make([]*models.SimpleChartPermission, 0)
+	parentPermissions := make(map[int][]*models.SimpleChartPermission, 0)
+	for _, v := range permissions {
+		if v.ParentId > 0 {
+			if parentPermissions[v.ParentId] == nil {
+				parentPermissions[v.ParentId] = make([]*models.SimpleChartPermission, 0)
+			}
+			parentPermissions[v.ParentId] = append(parentPermissions[v.ParentId], models.FormatChartPermission2Simple(v))
+			continue
+		}
+		resp = append(resp, models.FormatChartPermission2Simple(v))
+	}
+	for _, v := range resp {
+		v.Children = parentPermissions[v.ChartPermissionId]
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 46 - 0
models/chart_permission.go

@@ -7,6 +7,10 @@ import (
 	"time"
 )
 
+const (
+	FiccProductId = 1
+)
+
 // ChartPermission 报告权限表
 type ChartPermission struct {
 	ChartPermissionId     int       `orm:"column(chart_permission_id);pk" description:"问题ID" json:"chart_permission_id"`
@@ -210,3 +214,45 @@ func (c *ChartPermission) GetFirstChartPermissionByParentId(parentId int) (item
 	err = o.Raw(sql, parentId).QueryRow(&item)
 	return
 }
+
+// GetChartPermissionById 主键获取品种
+func GetChartPermissionById(permissionId int) (item *ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM chart_permission WHERE chart_permission_id = ?`
+	err = o.Raw(sql, permissionId).QueryRow(&item)
+	return
+}
+
+// GetSecondaryChartPermissions 获取二级权限列表
+func GetSecondaryChartPermissions() (list []*ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM chart_permission WHERE product_id = ? AND parent_id > 0 AND enabled = 1 ORDER BY parent_id ASC, sort ASC, created_time ASC`
+	_, err = o.Raw(sql, FiccProductId).QueryRows(&list)
+	return
+}
+
+type SimpleChartPermission struct {
+	ChartPermissionId   int                      `description:"品种ID"`
+	ChartPermissionName string                   `description:"品种名称"`
+	Sort                int                      `description:"排序"`
+	Children            []*SimpleChartPermission `description:"子分类"`
+}
+
+func FormatChartPermission2Simple(origin *ChartPermission) (item *SimpleChartPermission) {
+	if origin == nil {
+		return
+	}
+	item = new(SimpleChartPermission)
+	item.ChartPermissionId = origin.ChartPermissionId
+	item.ChartPermissionName = origin.PermissionName
+	item.Sort = origin.Sort
+	return
+}
+
+// GetChartPermissionsByProductId 获取权限列表
+func GetChartPermissionsByProductId() (list []*ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM chart_permission WHERE product_id = ? AND enabled = 1 ORDER BY parent_id ASC, sort ASC, created_time ASC`
+	_, err = o.Raw(sql, FiccProductId).QueryRows(&list)
+	return
+}

+ 285 - 0
models/data_manage/base_from_bloomberg_index.go

@@ -0,0 +1,285 @@
+package data_manage
+
+import (
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strings"
+	"time"
+)
+
+// BaseFromBloombergIndex 彭博原始指标表
+type BaseFromBloombergIndex struct {
+	BaseFromBloombergIndexId int       `orm:"column(base_from_bloomberg_index_id);pk"`
+	IndexCode                string    `description:"指标编码"`
+	IndexName                string    `description:"指标名称"`
+	Unit                     string    `description:"单位"`
+	Source                   int       `description:"数据来源"`
+	Frequency                string    `description:"频度"`
+	StartDate                time.Time `description:"开始日期"`
+	EndDate                  time.Time `description:"结束日期"`
+	Describe                 string    `description:"指标描述"`
+	Sort                     int       `description:"排序"`
+	IsStop                   int       `description:"是否停更:0-否;1-停更"`
+	EdbExist                 int       `description:"指标库是否已添加:0-否;1-是"`
+	TerminalCode             string    `description:"所属终端编码"`
+	FilePath                 string    `description:"文件存储路径"`
+	CreateTime               time.Time `description:"创建时间"`
+	ModifyTime               time.Time `description:"修改时间"`
+}
+
+var BaseFromBloombergIndexCols = struct {
+	BaseFromBloombergIndexId string
+	IndexCode                string
+	IndexName                string
+	Unit                     string
+	Source                   string
+	Frequency                string
+	StartDate                string
+	EndDate                  string
+	Describe                 string
+	Sort                     string
+	IsStop                   string
+	EdbExist                 string
+	TerminalCode             string
+	FilePath                 string
+	CreateTime               string
+	ModifyTime               string
+}{
+	BaseFromBloombergIndexId: "base_from_bloomberg_index_id",
+	IndexCode:                "index_code",
+	IndexName:                "index_name",
+	Unit:                     "unit",
+	Source:                   "source",
+	Frequency:                "frequency",
+	StartDate:                "start_date",
+	EndDate:                  "end_date",
+	Describe:                 "describe",
+	Sort:                     "sort",
+	IsStop:                   "is_stop",
+	EdbExist:                 "edb_exist",
+	TerminalCode:             "terminal_code",
+	FilePath:                 "file_path",
+	CreateTime:               "create_time",
+	ModifyTime:               "modify_time",
+}
+
+func (m *BaseFromBloombergIndex) TableName() string {
+	return "base_from_bloomberg_index"
+}
+
+func (m *BaseFromBloombergIndex) PrimaryId() string {
+	return BaseFromBloombergIndexCols.BaseFromBloombergIndexId
+}
+
+func (m *BaseFromBloombergIndex) Create() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	id, err := o.Insert(m)
+	if err != nil {
+		return
+	}
+	m.BaseFromBloombergIndexId = int(id)
+	return
+}
+
+func (m *BaseFromBloombergIndex) CreateMulti(items []*BaseFromBloombergIndex) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+func (m *BaseFromBloombergIndex) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(m, cols...)
+	return
+}
+
+func (m *BaseFromBloombergIndex) Del() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	_, err = o.Raw(sql, m.BaseFromBloombergIndexId).Exec()
+	return
+}
+
+func (m *BaseFromBloombergIndex) MultiDel(menuIds []int) (err error) {
+	if len(menuIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.PrimaryId(), utils.GetOrmInReplace(len(menuIds)))
+	_, err = o.Raw(sql, menuIds).Exec()
+	return
+}
+
+func (m *BaseFromBloombergIndex) GetItemById(id int) (item *BaseFromBloombergIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+func (m *BaseFromBloombergIndex) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *BaseFromBloombergIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+func (m *BaseFromBloombergIndex) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func (m *BaseFromBloombergIndex) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, limit int) (items []*BaseFromBloombergIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	if limit > 0 {
+		sql += fmt.Sprintf(` LIMIT %d`, limit)
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func (m *BaseFromBloombergIndex) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*BaseFromBloombergIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// BaseFromBloombergIndexItem 彭博原始指标信息
+type BaseFromBloombergIndexItem struct {
+	BaseFromBloombergIndexId int
+	IndexCode                string `description:"指标编码"`
+	IndexName                string `description:"指标名称"`
+	Unit                     string `description:"单位"`
+	Source                   int    `description:"数据来源"`
+	Frequency                string `description:"频度"`
+	StartDate                string `description:"开始日期"`
+	EndDate                  string `description:"结束日期"`
+	Describe                 string `description:"指标描述"`
+	Sort                     int    `description:"排序"`
+	IsStop                   int    `description:"是否停更:0-否;1-停更"`
+	EdbExist                 int    `description:"指标库是否已添加:0-否;1-是"`
+	CreateTime               string `description:"创建时间"`
+	ModifyTime               string `description:"修改时间"`
+	EdbInfoId                int    `description:"指标库ID"`
+	EdbUniqueCode            string `description:"指标库唯一编码"`
+	EdbClassifyId            int    `description:"指标库分类ID"`
+}
+
+func FormatBaseFromBloombergIndex2Item(origin *BaseFromBloombergIndex) (item *BaseFromBloombergIndexItem) {
+	if origin == nil {
+		return
+	}
+	item = new(BaseFromBloombergIndexItem)
+	item.BaseFromBloombergIndexId = origin.BaseFromBloombergIndexId
+	item.IndexCode = origin.IndexCode
+	item.IndexName = origin.IndexName
+	item.Unit = origin.Unit
+	item.Source = origin.Source
+	item.Frequency = origin.Frequency
+	item.StartDate = utils.TimeTransferString(utils.FormatDate, origin.StartDate)
+	item.EndDate = utils.TimeTransferString(utils.FormatDate, origin.EndDate)
+	item.Describe = origin.Describe
+	item.Sort = origin.Sort
+	item.IsStop = origin.IsStop
+	//item.EdbExist = origin.EdbExist
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	return
+}
+
+// BloombergSourceListReq 指标列表筛选
+type BloombergSourceListReq struct {
+	PageSize     int    `form:"PageSize"`
+	CurrentIndex int    `form:"CurrentIndex"`
+	Frequency    string `form:"Frequency" description:"频度"`
+	Keywords     string `form:"Keywords" description:"指标ID/指标名称"`
+	ListAll      bool   `form:"ListAll" description:"列表全选"`
+	SortField    int    `form:"SortField" description:"排序字段: 0-默认; 1-开始时间; 2-最新时间; 3-更新时间"`
+	SortRule     int    `form:"SortRule" description:"排序方式: 0-默认; 1-正序; 2-倒序"`
+}
+
+// BloombergSourceListResp 指标列表响应体
+type BloombergSourceListResp struct {
+	List   []*BaseFromBloombergIndexItem
+	Paging *paging.PagingItem `description:"分页数据"`
+}
+
+// UpdateEdbExist 标记已添加指标库
+func (m *BaseFromBloombergIndex) UpdateEdbExist(indexCode string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`UPDATE %s SET %s = ? WHERE %s = ? LIMIT 1`, m.TableName(), BaseFromBloombergIndexCols.EdbExist, BaseFromBloombergIndexCols.IndexCode)
+	_, err = o.Raw(sql, 1, indexCode).Exec()
+	return
+}
+
+// BloombergSourceBatchAddCheckReq Bloomberg批量添加校验
+type BloombergSourceBatchAddCheckReq struct {
+	BloombergSourceListReq
+	IndexCodes []string `form:"IndexCodes" description:"全选为false时, 该数组为选中; 全选为true时, 该数组为不选的指标"`
+}
+
+// --------------------------------------------- 以下为测试用 ---------------------------------------------
+
+// BaseFromBloombergData 彭博原始指标表
+//type BaseFromBloombergData struct {
+//	BaseFromBloombergDataId  int       `orm:"column(base_from_bloomberg_data_id);pk"`
+//	BaseFromBloombergIndexId int       `description:"指标ID"`
+//	IndexCode                string    `description:"指标编码"`
+//	DataTime                 time.Time `description:"数据日期"`
+//	Value                    float64   `description:"数据值"`
+//	CreateTime               time.Time `description:"创建时间"`
+//	ModifyTime               time.Time `description:"修改时间"`
+//	DataTimestamp            int       `description:"数据日期时间戳"`
+//}
+//
+//func (m *BaseFromBloombergData) TableName() string {
+//	return "base_from_bloomberg_data"
+//}
+//
+//func (m *BaseFromBloombergData) Create() (err error) {
+//	o := orm.NewOrmUsingDB("data")
+//	id, err := o.Insert(m)
+//	if err != nil {
+//		return
+//	}
+//	m.BaseFromBloombergDataId = int(id)
+//	return
+//}
+//
+//func (m *BaseFromBloombergData) CreateMulti(items []*BaseFromBloombergData) (err error) {
+//	if len(items) == 0 {
+//		return
+//	}
+//	o := orm.NewOrmUsingDB("data")
+//	_, err = o.InsertMulti(len(items), items)
+//	return
+//}

+ 19 - 0
models/data_manage/edb_info.go

@@ -1908,3 +1908,22 @@ func GetEdbInfoCount(source int, edbCode string) (count int, err error) {
 	err = o.Raw(sql, source, edbCode).QueryRow(&count)
 	return
 }
+
+// GetEdbInfoByNameArr 根据名称获取指标
+func GetEdbInfoByNameArr(names []string) (items []*EdbInfo, err error) {
+	if len(names) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT edb_info_id, edb_code, edb_name FROM edb_info WHERE edb_name IN (%s)`, utils.GetOrmInReplace(len(names)))
+	_, err = o.Raw(sql, names).QueryRows(&items)
+	return
+}
+
+// GetEdbCodesBySource 根据来源获取指标编码
+func GetEdbCodesBySource(source int) (items []*EdbInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT edb_info_id, edb_code, unique_code, classify_id FROM edb_info WHERE source = ? `
+	_, err = o.Raw(sql, source).QueryRows(&items)
+	return
+}

+ 11 - 0
models/db.go

@@ -13,6 +13,7 @@ import (
 	"eta/eta_api/models/data_manage/supply_analysis"
 	"eta/eta_api/models/data_stat"
 	"eta/eta_api/models/eta_trial"
+	"eta/eta_api/models/fe_calendar"
 	"eta/eta_api/models/ppt_english"
 	"eta/eta_api/models/report_approve"
 	"eta/eta_api/models/sandbox"
@@ -194,6 +195,9 @@ func init() {
 	// 初始化数据资产权限的一些表
 	initDataMangePerMission()
 
+	// 初始化外汇日历
+	initFeCalendar()
+
 	// 初始化部分数据表变量(直接init会有顺序问题=_=!)
 	data_manage.InitEdbSourceVar()
 }
@@ -595,3 +599,10 @@ func initDataMangePerMission() {
 		new(data_manage_permission.DataPermissionNoAuthRecord),              // 资产数据权限设置记录表
 	)
 }
+
+// initFeCalendar 初始化外汇日历
+func initFeCalendar() {
+	orm.RegisterModel(
+		new(fe_calendar.FeCalendarMatter), // 事项表
+	)
+}

+ 303 - 0
models/fe_calendar/fe_calendar_matter.go

@@ -0,0 +1,303 @@
+package fe_calendar
+
+import (
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+const (
+	MatterTypeFree    = 1 // 事项类型-自定义事项
+	MatterTypeEdb     = 2 // 事项类型-基础指标
+	MatterTypePredict = 3 // 事项类型-预测指标
+)
+
+// FeCalendarMatter 外汇日历-事项表
+type FeCalendarMatter struct {
+	FeCalendarMatterId  int       `orm:"column(fe_calendar_matter_id);pk" description:"事项ID"`
+	ChartPermissionId   int       `description:"品种ID"`
+	ChartPermissionName string    `description:"品种名称"`
+	MatterMonth         string    `description:"事项年月:格式2006-01"`
+	MatterDate          time.Time `description:"事项日期"`
+	Title               string    `description:"标题"`
+	MatterType          int       `description:"事项类型:1-自定义事项;2-基础指标;3-预测指标"`
+	EdbInfoId           int       `description:"指标ID"`
+	EdbUniqueCode       string    `description:"指标唯一编码"`
+	EdbCode             string    `description:"指标编码"`
+	FontColor           string    `description:"字体颜色"`
+	FillingColor        string    `description:"填充颜色"`
+	FontBold            int       `description:"字体加粗:0-否;1-是"`
+	Sort                int       `description:"排序"`
+	SysUserId           int       `description:"创建人ID"`
+	SysUserName         string    `description:"创建人姓名"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"更新时间"`
+}
+
+var FeCalendarMatterCols = struct {
+	FeCalendarMatterId  string
+	ChartPermissionId   string
+	ChartPermissionName string
+	MatterMonth         string
+	MatterDate          string
+	Title               string
+	MatterType          string
+	EdbInfoId           string
+	EdbUniqueCode       string
+	EdbCode             string
+	FontColor           string
+	FillingColor        string
+	FontBold            string
+	Sort                string
+	SysUserId           string
+	SysUserName         string
+	CreateTime          string
+	ModifyTime          string
+}{
+	FeCalendarMatterId:  "fe_calendar_matter_id",
+	ChartPermissionId:   "chart_permission_id",
+	ChartPermissionName: "chart_permission_name",
+	MatterMonth:         "matter_month",
+	MatterDate:          "matter_date",
+	Title:               "title",
+	MatterType:          "matter_type",
+	EdbInfoId:           "edb_info_id",
+	EdbUniqueCode:       "edb_unique_code",
+	EdbCode:             "edb_code",
+	FontColor:           "font_color",
+	FillingColor:        "filling_color",
+	FontBold:            "font_bold",
+	Sort:                "sort",
+	SysUserId:           "sys_user_id",
+	SysUserName:         "sys_user_name",
+	CreateTime:          "create_time",
+	ModifyTime:          "modify_time",
+}
+
+func (m *FeCalendarMatter) TableName() string {
+	return "fe_calendar_matter"
+}
+
+func (m *FeCalendarMatter) PrimaryId() string {
+	return FeCalendarMatterCols.FeCalendarMatterId
+}
+
+func (m *FeCalendarMatter) Create() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	id, err := o.Insert(m)
+	if err != nil {
+		return
+	}
+	m.FeCalendarMatterId = int(id)
+	return
+}
+
+func (m *FeCalendarMatter) CreateMulti(items []*FeCalendarMatter) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+func (m *FeCalendarMatter) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(m, cols...)
+	return
+}
+
+func (m *FeCalendarMatter) Del() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	_, err = o.Raw(sql, m.FeCalendarMatterId).Exec()
+	return
+}
+
+func (m *FeCalendarMatter) MultiDel(menuIds []int) (err error) {
+	if len(menuIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.PrimaryId(), utils.GetOrmInReplace(len(menuIds)))
+	_, err = o.Raw(sql, menuIds).Exec()
+	return
+}
+
+func (m *FeCalendarMatter) GetItemById(id int) (item *FeCalendarMatter, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+func (m *FeCalendarMatter) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *FeCalendarMatter, err error) {
+	o := orm.NewOrmUsingDB("data")
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+func (m *FeCalendarMatter) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func (m *FeCalendarMatter) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*FeCalendarMatter, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := fmt.Sprintf(`ORDER BY %s DESC`, FeCalendarMatterCols.CreateTime)
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func (m *FeCalendarMatter) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*FeCalendarMatter, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := fmt.Sprintf(`ORDER BY %s DESC`, FeCalendarMatterCols.CreateTime)
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+type FeCalendarMatterItem struct {
+	FeCalendarMatterId  int    `description:"事项ID"`
+	ChartPermissionId   int    `description:"品种ID"`
+	ChartPermissionName string `description:"品种名称"`
+	MatterDate          string `description:"事项日期"`
+	Title               string `description:"标题"`
+	MatterType          int    `description:"事项类型:1-自定义事项;2-基础指标;3-预测指标"`
+	EdbInfoId           int    `description:"指标ID"`
+	EdbUniqueCode       string `description:"指标唯一编码"`
+	EdbCode             string `description:"指标编码"`
+	FontColor           string `description:"字体颜色"`
+	FillingColor        string `description:"填充颜色"`
+	FontBold            int    `description:"字体加粗:0-否;1-是"`
+	Sort                int    `description:"排序"`
+}
+
+func FormatFeCalendarMatter2Item(origin *FeCalendarMatter) (item *FeCalendarMatterItem) {
+	if origin == nil {
+		return
+	}
+	item = new(FeCalendarMatterItem)
+	item.FeCalendarMatterId = origin.FeCalendarMatterId
+	item.ChartPermissionId = origin.ChartPermissionId
+	item.ChartPermissionName = origin.ChartPermissionName
+	item.MatterDate = utils.TimeTransferString(utils.FormatDate, origin.MatterDate)
+	item.Title = origin.Title
+	item.MatterType = origin.MatterType
+	item.EdbInfoId = origin.EdbInfoId
+	item.EdbUniqueCode = origin.EdbUniqueCode
+	item.EdbCode = origin.EdbCode
+	item.FontColor = origin.FontColor
+	item.FillingColor = origin.FillingColor
+	item.FontBold = origin.FontBold
+	item.Sort = origin.Sort
+	return
+}
+
+// FeCalendarMatterListReq 事项列表请求体
+type FeCalendarMatterListReq struct {
+	ChartPermissionId int    `form:"ChartPermissionId" description:"品种ID"`
+	StartDate         string `form:"StartDate" description:"开始日期"`
+	EndDate           string `form:"EndDate" description:"结束日期"`
+}
+
+// FeCalendarMatterListItem 事项列表
+type FeCalendarMatterListItem struct {
+	Date    string                  `description:"日期"`
+	Matters []*FeCalendarMatterItem `description:"日期事项"`
+}
+
+// FeCalendarMatterSaveReq 保存事项请求体
+type FeCalendarMatterSaveReq struct {
+	ChartPermissionId int                         `description:"品种ID"`
+	MatterDate        string                      `description:"日期"`
+	Matters           []*FeCalendarMatterSaveItem `description:"事项"`
+}
+
+type FeCalendarMatterSaveItem struct {
+	FeCalendarMatterId int    `description:"事项ID"`
+	Title              string `description:"标题"`
+	MatterType         int    `description:"事项类型:1-自定义事项;2-基础指标;3-预测指标"`
+	EdbInfoId          int    `description:"指标ID"`
+	EdbUniqueCode      string `description:"指标唯一编码"`
+	EdbCode            string `description:"指标编码"`
+	FontColor          string `description:"字体颜色"`
+	FillingColor       string `description:"填充颜色"`
+	FontBold           int    `description:"字体加粗:0-否;1-是"`
+	Sort               int    `description:"排序"`
+}
+
+func (m *FeCalendarMatter) Save(addMatters, editMatters, removeMatters []*FeCalendarMatter, updateCols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	tx, e := o.Begin()
+	if e != nil {
+		err = fmt.Errorf("begin tx err: %s", e.Error())
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	if len(addMatters) > 0 {
+		_, e = tx.InsertMulti(len(addMatters), addMatters)
+		if e != nil {
+			err = fmt.Errorf("insert multi err: %s", e.Error())
+			return
+		}
+	}
+	if len(editMatters) > 0 {
+		for _, v := range editMatters {
+			_, e = tx.Update(v, updateCols...)
+			if e != nil {
+				err = fmt.Errorf("update err: %s", e.Error())
+				return
+			}
+		}
+	}
+	if len(removeMatters) > 0 {
+		p, e := tx.Raw(fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())).Prepare()
+		if e != nil {
+			err = fmt.Errorf("remove prepare err: %s", e.Error())
+			return
+		}
+		defer func() {
+			_ = p.Close()
+		}()
+		for _, v := range removeMatters {
+			_, e = p.Exec(v.FeCalendarMatterId)
+			if e != nil {
+				err = fmt.Errorf("remove exec err: %s", e.Error())
+				return
+			}
+		}
+	}
+	return
+}

+ 72 - 0
routers/commentsRouter.go

@@ -1870,6 +1870,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:BloombergDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:BloombergDataController"],
+        beego.ControllerComments{
+            Method: "AddCheck",
+            Router: `/bloomberg_source/add_check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:BloombergDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:BloombergDataController"],
+        beego.ControllerComments{
+            Method: "BatchAdd",
+            Router: `/bloomberg_source/batch_add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:BloombergDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:BloombergDataController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/bloomberg_source/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:BloombergDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:BloombergDataController"],
+        beego.ControllerComments{
+            Method: "NameCheck",
+            Router: `/bloomberg_source/name_check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartClassifyController"],
         beego.ControllerComments{
             Method: "AddChartClassify",
@@ -5416,6 +5452,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/fe_calendar:FeCalendarMatterController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/fe_calendar:FeCalendarMatterController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/matter/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/fe_calendar:FeCalendarMatterController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/fe_calendar:FeCalendarMatterController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/matter/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/fe_calendar:FeCalendarMatterController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/fe_calendar:FeCalendarMatterController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/matter/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/fe_calendar:FeCalendarMatterController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/fe_calendar:FeCalendarMatterController"],
+        beego.ControllerComments{
+            Method: "PermissionList",
+            Router: `/permission/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/report_approve:ReportApproveController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/report_approve:ReportApproveController"],
         beego.ControllerComments{
             Method: "Approve",

+ 7 - 0
routers/router.go

@@ -23,6 +23,7 @@ import (
 	"eta/eta_api/controllers/data_stat"
 	"eta/eta_api/controllers/english_report"
 	"eta/eta_api/controllers/eta_trial"
+	"eta/eta_api/controllers/fe_calendar"
 	"eta/eta_api/controllers/report_approve"
 	"eta/eta_api/controllers/roadshow"
 	"eta/eta_api/controllers/sandbox"
@@ -167,6 +168,7 @@ func init() {
 				&data_manage.JiaYueEdbSourceController{},
 				&data_manage.ChartThemeController{},
 				&data_manage_permission.DataMangePermissionController{},
+				&data_manage.BloombergDataController{},
 			),
 		),
 		web.NSNamespace("/my_chart",
@@ -366,6 +368,11 @@ func init() {
 				&controllers.MessageController{},
 			),
 		),
+		web.NSNamespace("/fe_calendar",
+			web.NSInclude(
+				&fe_calendar.FeCalendarMatterController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 100 - 0
services/data/base_from_bloomberg.go

@@ -0,0 +1,100 @@
+package data
+
+import (
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/utils"
+	"fmt"
+)
+
+type BloombergIndexSource2EdbReq struct {
+	EdbCode       string
+	EdbName       string
+	Frequency     string
+	Unit          string
+	ClassifyId    int
+	AdminId       int
+	AdminRealName string
+}
+
+// BloombergIndexSource2Edb 新增彭博数据源到指标库
+func BloombergIndexSource2Edb(req BloombergIndexSource2EdbReq) (edb *data_manage.EdbInfo, err error, errMsg string, skip bool) {
+	if req.EdbCode == "" {
+		err = fmt.Errorf("指标ID为空")
+		return
+	}
+	defer func() {
+		if err != nil {
+			tips := fmt.Sprintf("BloombergIndexSource2Edb新增失败, Err: %s", err.Error())
+			fmt.Println(tips)
+			utils.FileLog.Info(tips)
+		}
+	}()
+	source := utils.DATA_SOURCE_BLOOMBERG
+
+	// 是否已有指标数据
+	dataList, e := data_manage.GetEdbDataAllByEdbCode(req.EdbCode, source, utils.DATA_SUB_SOURCE_EDB, utils.EDB_DATA_LIMIT)
+	if e != nil {
+		err = fmt.Errorf("获取指标数据失败, Err: %s", e.Error())
+		return
+	}
+
+	// 新增指标数据
+	if len(dataList) == 0 {
+		res, e := AddEdbData(source, req.EdbCode, req.Frequency)
+		if e != nil {
+			err = fmt.Errorf("index_lib: 新增指标数据失败, Err: %s", e.Error())
+			return
+		}
+		if res == nil {
+			err = fmt.Errorf("index_lib: 新增指标数据失败, res nil")
+			return
+		}
+		if res.Ret != 200 {
+			err = fmt.Errorf("index_lib: 新增指标数据失败, Ret: %d", res.Ret)
+			return
+		}
+	}
+
+	// 是否新增过指标
+	exist, e := data_manage.GetEdbInfoByEdbCode(source, req.EdbCode)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = fmt.Errorf("获取指标是否存在失败, err: %s", e.Error())
+		return
+	}
+	if exist != nil {
+		skip = true
+		return
+	}
+
+	// 开始结束时间
+	var startDate, endDate string
+	minMax, e := data_manage.GetEdbInfoMaxAndMinInfo(source, utils.DATA_SUB_SOURCE_EDB, req.EdbCode)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = fmt.Errorf("MinMax: 获取指标极值失败, err: %s", e.Error())
+		return
+	}
+	if minMax != nil {
+		startDate = minMax.MinDate
+		endDate = minMax.MaxDate
+	}
+
+	// 新增指标库
+	edbInfo, e, msg, _ := EdbInfoAdd(source, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, startDate, endDate, req.AdminId, req.AdminRealName)
+	if e != nil {
+		errMsg = msg
+		err = fmt.Errorf("EdbInfo: 新增指标失败, err: %s", e.Error())
+		return
+	}
+	edb = edbInfo
+
+	// 标记原始指标为已添加
+	indexOb := new(data_manage.BaseFromBloombergIndex)
+	if e = indexOb.UpdateEdbExist(req.EdbCode); e != nil {
+		err = fmt.Errorf("BaseIndex: 标记已添加指标库失败, err: %s", e.Error())
+		return
+	}
+
+	// 新增es
+	go AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+	return
+}

+ 3 - 0
services/data/trade_analysis/trade_analysis.go

@@ -17,6 +17,7 @@ func GetClassifyName() (list trade_analysis.TradeClassifyNameListSort, err error
 		"shanghai":  "上期所",
 		"cffex":     "中金所",
 		"ine":       "上期能源",
+		"guangzhou": "广期所",
 	}
 	exchangesSortMap := map[string]int{
 		"zhengzhou": 1,
@@ -24,6 +25,7 @@ func GetClassifyName() (list trade_analysis.TradeClassifyNameListSort, err error
 		"shanghai":  3,
 		"cffex":     4,
 		"ine":       5,
+		"guangzhou": 6,
 	}
 	//查询所有交易所下的分类
 	classifyExchangeList, tmpErr := trade_analysis.GetAllBaseFromTradeClassify()
@@ -241,6 +243,7 @@ func GetPositionTopDetail(req trade_analysis.GetPositionTopReq) (ret trade_analy
 		"上期所":  "shanghai",
 		"中金所":  "cffex",
 		"上期能源": "ine",
+		"广期所":  "guangzhou",
 	}
 	exchange, ok := exchanges[req.Exchange]
 	if !ok {

+ 57 - 0
services/task.go

@@ -40,6 +40,9 @@ func Task() {
 
 	go AutoInsertAdminOperateRecordToDB()
 
+	// 测试用-生成bloomberg数据
+	//go InsertBloombergIndex()
+
 	// TODO:修复权限
 	//FixEnCompanyPermission()
 	fmt.Println("task end")
@@ -476,3 +479,57 @@ func ModifyEsEnglishReport() {
 	}
 	fmt.Println("结束")
 }
+
+//func InsertBloombergIndex() {
+//	fmt.Println("开始写入")
+//
+//	start := 100000
+//	now := time.Now()
+//	for i := 1; i <= 100; i++ {
+//		fmt.Printf("写入第%d个\n", i)
+//
+//		start += 1
+//		index := new(data_manage.BaseFromBloombergIndex)
+//		index.IndexCode = fmt.Sprintf("BLID%d", start)
+//		index.IndexName = fmt.Sprintf("模拟Bloomberg-%s", index.IndexCode)
+//		index.Unit = "无"
+//		index.Source = utils.DATA_SOURCE_BLOOMBERG
+//		index.Frequency = "日度"
+//		index.StartDate = now.AddDate(0, 0, -i)
+//		index.EndDate = now
+//		index.CreateTime = time.Now().Local()
+//		index.ModifyTime = time.Now().Local()
+//		if e := index.Create(); e != nil {
+//			fmt.Printf("新增指标失败, IndexCode: %s, err: %s", index.IndexCode, e.Error())
+//			return
+//		}
+//
+//		insertData := make([]*data_manage.BaseFromBloombergData, 0)
+//		for ii := 0; ii <= 50; ii++ {
+//			indexData := new(data_manage.BaseFromBloombergData)
+//			indexData.BaseFromBloombergIndexId = index.BaseFromBloombergIndexId
+//			indexData.IndexCode = index.IndexCode
+//			indexData.DataTime = now.AddDate(0, 0, -ii)
+//			va := GenerateRandomFloat64InRange()
+//			va += float64(ii)
+//			indexData.Value = va
+//			indexData.CreateTime = time.Now().Local()
+//			indexData.ModifyTime = time.Now().Local()
+//			indexData.DataTimestamp = int(indexData.DataTime.UnixNano() / 1e6)
+//			insertData = append(insertData, indexData)
+//		}
+//		ob := new(data_manage.BaseFromBloombergData)
+//		if e := ob.CreateMulti(insertData); e != nil {
+//			fmt.Printf("新增指标数据失败, IndexCode: %s, err: %s", index.IndexCode, e.Error())
+//			return
+//		}
+//	}
+//
+//	fmt.Println("结束写入")
+//}
+//
+//func GenerateRandomFloat64InRange() float64 {
+//	var rnd = rand.New(rand.NewSource(time.Now().UnixNano())) // 设置随机数种子
+//
+//	return rnd.Float64()*11000 - 1000
+//}

+ 1 - 0
utils/constants.go

@@ -170,6 +170,7 @@ const (
 	DATA_SOURCE_CALCULATE_RJZ                                   // 日均值计算->75
 	DATA_SOURCE_GFEX                                 = 78       // 广州期货交易所->78
 	DATA_SOURCE_ICPI                                 = 79       // ICPI消费价格指数->79
+	DATA_SOURCE_BLOOMBERG                            = 83       // bloomberg彭博数据
 )
 
 // 数据刷新频率

+ 3 - 3
utils/redis/cluster_redis.go

@@ -149,12 +149,12 @@ func (rc *ClusterRedisClient) Put(key string, val interface{}, timeout time.Dura
 // @param timeout
 // @return bool
 func (rc *ClusterRedisClient) SetNX(key string, val interface{}, timeout time.Duration) bool {
-	result, err := rc.redisClient.SetEX(context.TODO(), key, val, timeout).Result()
-	if err != nil || result != "OK" {
+	result, err := rc.redisClient.SetNX(context.TODO(), key, val, timeout).Result()
+	if err != nil {
 		return false
 	}
 
-	return true
+	return result
 }
 
 // Delete

+ 3 - 3
utils/redis/standalone_redis.go

@@ -141,12 +141,12 @@ func (rc *StandaloneRedisClient) Put(key string, val interface{}, timeout time.D
 // @param timeout
 // @return bool
 func (rc *StandaloneRedisClient) SetNX(key string, val interface{}, timeout time.Duration) bool {
-	result, err := rc.redisClient.SetEX(context.TODO(), key, val, timeout).Result()
-	if err != nil || result != "OK" {
+	result, err := rc.redisClient.SetNX(context.TODO(), key, val, timeout).Result()
+	if err != nil {
 		return false
 	}
 
-	return true
+	return result
 }
 
 // Delete