package data_manage import ( "encoding/json" "eta_gn/eta_api/global" "eta_gn/eta_api/models/data_manage/line_equation/request" "eta_gn/eta_api/models/mgo" "eta_gn/eta_api/services/alarm_msg" "eta_gn/eta_api/utils" "fmt" "strconv" "strings" "time" "gorm.io/gorm" "go.mongodb.org/mongo-driver/bson" "github.com/rdlucklib/rdluck_tools/paging" ) type EdbInfo struct { EdbInfoId int `gorm:"primaryKey" ` EdbInfoType int `description:"指标类型,0:普通指标,1:预测指标"` SourceName string `description:"来源名称"` Source int `description:"来源id"` EdbCode string `description:"指标编码"` EdbName string `description:"指标名称"` EdbNameEn string `description:"英文指标名称"` EdbNameSource string `description:"指标名称来源"` Frequency string `description:"频率"` Unit string `description:"单位"` UnitEn string `description:"英文单位"` StartDate time.Time `description:"起始日期"` EndDate time.Time `description:"终止日期"` ClassifyId int `description:"分类id"` SysUserId int SysUserRealName string UniqueCode string `description:"指标唯一编码"` CreateTime time.Time ModifyTime time.Time BaseModifyTime time.Time MinValue float64 `description:"指标最小值"` MaxValue float64 `description:"指标最大值"` CalculateFormula string `description:"计算公式"` EdbType int `description:"指标类型:1:基础指标,2:计算指标"` Sort int `description:"排序字段"` LatestDate string `description:"数据最新日期(实际日期)"` LatestValue float64 `description:"数据最新值(实际值)"` EndValue float64 `description:"数据的最新值(预测日期的最新值)"` MoveType int `description:"移动方式:1:领先(默认),2:滞后"` MoveFrequency string `description:"移动频度"` NoUpdate int8 `description:"是否停止更新,0:继续更新;1:停止更新"` ServerUrl string `description:"服务器地址"` ChartImage string `description:"图表图片"` Calendar string `description:"公历/农历" orm:"default(公历);"` DataDateType string `orm:"column(data_date_type);size(255);null;default(交易日)"` ManualSave int `description:"是否有手动保存过上下限: 0-否; 1-是"` EmptyType int `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"` MaxEmptyType int `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"` TerminalCode string `description:"终端编码,用于配置在机器上"` DataUpdateTime string `description:"最近一次数据发生变化的时间"` ErDataUpdateDate string `description:"本次更新,数据发生变化的最早日期"` SourceIndexName string `description:"数据源中的指标名称"` SubSource int `description:"子数据来源:0:经济数据库,1:日期序列"` SubSourceName string `description:"子数据来源名称"` IndicatorCode string `description:"指标代码"` StockCode string `description:"证券代码"` Extra string `description:"指标额外配置"` IsJoinPermission int `description:"是否加入权限管控,0:不加入;1:加入;默认:0"` } type EdbInfoFullClassify struct { //*EdbInfo *EdbInfoResp CorrelationStr string `description:"相关性系数字符串"` ClassifyList []*EdbClassifyIdItems HaveOperaAuth bool `description:"是否有数据权限,默认:false"` IsSupplierStop int `description:"是否供应商停更:1:停更,0:未停更"` } func AddEdbInfo(item *EdbInfo) (lastId int64, err error) { err = global.DmSQL["data"].Create(item).Error if err != nil { return } lastId = int64(item.EdbInfoId) return } type BaseEdbNameItem struct { EdbInfoId int `description:"指标id"` EdbInfoType int `description:"指标类型,0:普通指标,1:预测指标"` SourceName string `description:"来源名称"` Source int `description:"来源id"` EdbCode string `description:"指标编码"` EdbName string `description:"指标名称"` EdbNameEn string `description:"指标英文名称"` Frequency string `description:"频率"` Unit string `description:"单位"` UnitEn string `description:"英文单位"` HaveOperaAuth bool `description:"是否有数据权限,默认:false"` } type BaseEdbInfoResp struct { List []*BaseEdbNameItem } // 指标检索数据 type EdbInfoSearch struct { EdbCode string `description:"指标编码"` StartDate string `description:"起始日期"` EndDate string `description:"终止日期"` EdbName string `description:"指标名称"` Unit string `description:"单位"` Frequency string `description:"频率"` DataList []*EdbInfoSearchData StockList []*StockInfo `description:"时序数据"` } type StockInfo struct { StockCode string EdbCode string DataList []*EdbInfoSearchData } type EdbInfoSearchData struct { DataTime string `description:"数据日期"` Value float64 `description:"数据"` } type BaseIndexInfo struct { IndexName string `description:"数据日期"` Unit string `description:"单位"` Frequency string `description:"频率"` } type EdbInfoSearchResp struct { SearchItem *EdbInfoSearch `description:"指标分类"` Status int `description:"1:数据已存在于国能数据库,2:新数据,3:数据已存在于国能数据库,但是当前账号无权限"` ClassifyList []*EdbClassifySimplify StockSearchList []*EdbInfoSearch } type EdbInfoMySteelChemicalCheckResp struct { Status int `description:"1:数据已存在于国能数据库,2:新数据,3:数据已存在于国能数据库,但是当前账号无权限"` } func GetEdbInfoByEdbCode(source int, edbCode string) (item *EdbInfo, err error) { sql := ` SELECT * FROM edb_info WHERE source=? AND edb_code=? ` err = global.DmSQL["data"].Raw(sql, source, edbCode).First(&item).Error return } func GetEdbInfoListByEdbCodes(source int, edbCodes []string) (items []*EdbInfo, err error) { if len(edbCodes) == 0 { return } sql := ` SELECT * FROM edb_info WHERE source=? AND edb_code IN (` + utils.GetOrmInReplace(len(edbCodes)) + `) ` err = global.DmSQL["data"].Raw(sql, source, edbCodes).Scan(&items).Error return } func (e *EdbInfo) AfterFind(db *gorm.DB) error { tmpTime, err := time.Parse(utils.FormatDateWallWithLoc, e.LatestDate) if err != nil { return nil } e.LatestDate = tmpTime.Format(utils.FormatDate) return nil } func GetEdbInfoById(edbInfoId int) (item *EdbInfo, err error) { sql := ` SELECT * FROM edb_info WHERE edb_info_id=? ` err = global.DmSQL["data"].Raw(sql, edbInfoId).First(&item).Error return } // GetEdbInfoByUniqueCode // @Description: 根据uniqueCode获取指标详情 // @author: Roc // @datetime 2024-01-18 13:40:01 // @param uniqueCode string // @return item *EdbInfo // @return err error func GetEdbInfoByUniqueCode(uniqueCode string) (item *EdbInfo, err error) { sql := ` SELECT * FROM edb_info WHERE unique_code=? ` err = global.DmSQL["data"].Raw(sql, uniqueCode).First(&item).Error return } // GetEdbInfoByIdList 根据指标id集合 获取 指标列表 func GetEdbInfoByIdList(edbInfoIdList []int) (items []*EdbInfo, err error) { num := len(edbInfoIdList) if num <= 0 { return } o := global.DmSQL["data"] sql := ` SELECT * FROM edb_info WHERE edb_info_id in (` + utils.GetOrmInReplace(num) + `) ` err = o.Raw(sql, edbInfoIdList).Find(&items).Error return } // MysteelChemicalDataBatchAddCheckReq 钢联化工指标批量添加校验 type MysteelChemicalDataBatchAddCheckReq struct { IndexCodes []string `form:"IndexCodes" description:"全选为false时, 该数组为选中; 全选为true时, 该数组为不选的指标"` } type AddEdbInfoReq struct { Source int `description:"来源id"` EdbCode string `description:"指标编码"` EdbName string `description:"指标名称"` Frequency string `description:"频率"` Unit string `description:"单位"` ClassifyId int `description:"分类id"` StartDate string `description:"起始日期"` EndDate string `description:"终止日期"` } type NameCheckEdbInfoReq struct { EdbCode string `description:"指标编码"` EdbName string `description:"指标名称"` Frequency string `description:"频率"` } func DeleteEdbInfoAndData(edbInfoId, source, subSource int) (err error) { to := global.DmSQL["data"].Begin() defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() // 删除指标信息 sql := ` DELETE FROM edb_info WHERE edb_info_id=? ` err = to.Exec(sql, edbInfoId).Error if err != nil { return } // 删除指标的明细数据 if source == utils.DATA_SOURCE_BUSINESS && utils.UseMongo { err = deleteAllEdbDataByMongo(to, edbInfoId, source, subSource) } else if source == utils.DATA_SOURCE_THS && subSource == utils.DATA_SUB_SOURCE_HIGH_FREQUENCY && utils.UseMongo { mogDataObj := mgo.EdbDataThsHf{} err = mogDataObj.RemoveMany(bson.M{"edb_info_id": edbInfoId}) } else { err = deleteAllEdbDataByMysql(to, edbInfoId, source, subSource) } if err != nil { return } // 删除计算指标的关系 sql = ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id=? ` err = to.Exec(sql, edbInfoId).Error if err != nil { return } // 删除预测指标的配置 sql = ` DELETE FROM predict_edb_conf WHERE predict_edb_info_id=? ` err = to.Exec(sql, edbInfoId).Error if err != nil { return } // 删除跨品种分析标签绑定的指标 sql = ` DELETE FROM chart_tag_variety WHERE edb_info_id=?` err = to.Exec(sql, edbInfoId).Error if err != nil { return } return } // deleteAllEdbDataByMysql // @Description: 删除指标的明细数据(mysql) // @author: Roc // @datetime 2024-05-09 13:31:54 // @param to orm.TxOrmer // @param edbInfoId int // @param source int // @param subSource int // @return err error func deleteAllEdbDataByMysql(to *gorm.DB, edbInfoId, source, subSource int) (err error) { tableName := GetEdbDataTableName(source, subSource) if tableName == `` { return } sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id=? `, tableName) err = to.Exec(sql, edbInfoId).Error return } // deleteAllEdbDataByMongo // @Description: 删除指标的明细数据(mongo) // @author: Roc // @datetime 2024-05-09 13:31:37 // @param to orm.TxOrmer // @param edbInfoId int // @param source int // @param subSource int // @return err error func deleteAllEdbDataByMongo(to *gorm.DB, edbInfoId, source, subSource int) (err error) { mogDataObj := mgo.EdbDataBusiness{} err = mogDataObj.RemoveMany(bson.M{"edb_info_id": edbInfoId}) return } func GetEdbInfoCountByCondition(condition string, pars []interface{}) (count int, err error) { o := global.DmSQL["data"] sql := ` SELECT COUNT(1) AS count FROM edb_info WHERE 1=1 ` if condition != "" { sql += condition } err = o.Raw(sql, pars...).Scan(&count).Error return } type EditEdbInfoReq struct { EdbInfoId int `description:"指标ID"` EdbName string `description:"指标名称"` Frequency string `description:"频率"` Unit string `description:"单位"` ClassifyId int `description:"分类id"` CalculateFormula string `description:"计算公式"` } type EditEdbEnInfoReq struct { EdbInfoId int `description:"指标ID"` EdbNameEn string `description:"英文指标名称"` UnitEn string `description:"英文单位"` } // EditEdbBaseInfoReq // @Description: 修改指标基础信息请求参数 type EditEdbBaseInfoReq struct { EdbInfoId int `description:"指标ID"` EdbName string `description:"指标名称"` Unit string `description:"指标单位"` } // ModifyEdbEnInfo 修改指标英文信息 func ModifyEdbEnInfo(item *EditEdbEnInfoReq) (err error) { o := global.DmSQL["data"] sql := ` UPDATE edb_info SET edb_name_en =?, unit_en = ?, modify_time = NOW() WHERE edb_info_id = ?` err = o.Exec(sql, item.EdbNameEn, item.UnitEn, item.EdbInfoId).Error return } type EdbInfoList struct { EdbInfoId int `orm:"column(edb_info_id);pk" gorm:"primaryKey" ` EdbInfoType int `description:"指标类型,0:普通指标,1:预测指标"` SourceName string `description:"来源名称"` Source int `description:"来源id"` EdbCode string `description:"指标编码"` EdbNameEn string `description:"英文指标名称"` EdbName string `description:"指标名称"` Frequency string `description:"频率"` FrequencyEn string `description:"英文频率"` Unit string `description:"单位"` UnitEn string `description:"英文单位"` StartDate string `description:"起始日期"` EndDate string `description:"终止日期"` LatestDate string `description:"数据最新日期(实际日期)"` LatestValue float64 `description:"数据最新值(实际值)"` EndValue float64 `description:"数据的最新值(预测日期的最新值)"` ClassifyId int `description:"分类id"` UniqueCode string `description:"指标唯一编码"` SysUserId int `description:"创建人id"` SysUserRealName string `description:"创建人姓名"` ModifyTime string `description:"最新修改时间"` CreateTime string `description:"创建时间"` EdbNameAlias string `json:"-" description:"指标名称,别名"` EdbType int `description:"指标类型:1:基础指标,2:计算指标"` ChartImage string `description:"图表图片"` RuleType int `description:"预测规则,1:最新,2:固定值"` FixedValue float64 `description:"固定值"` DataList []*EdbData `gorm:"-" description:"实际指标数据"` PredictDataList []*EdbData `gorm:"-" description:"预测指标数据"` Button EdbClassifyItemsButton `gorm:"-" description:"操作权限"` IsEnEdb bool `description:"是否展示英文标识"` DataInsertConfig EdbDataInsertConfigItem `gorm:"-" description:"指标数据插入配置"` DataDateType string `description:"数据日期类型,枚举值:交易日、自然日"` EmptyType int `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"` MaxEmptyType int `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"` SubSource int `description:"子数据来源:0:经济数据库,1:日期序列"` SubSourceName string `description:"子数据来源名称"` IndicatorCode string `description:"指标代码"` StockCode string `description:"证券代码"` NoUpdate int8 `description:"是否停止更新,0:继续更新;1:停止更新"` IsJoinPermission int `description:"是否加入权限管控,0:不加入;1:加入;默认:0"` HaveOperaAuth bool `description:"是否有数据权限,默认:false"` IsSupplierStop int `description:"是否供应商停更:1:停更,0:未停更"` CollectClassifyIdList []int `description:"所属收藏分类id列表" gorm:"-"` } type EdbDataInsertConfigItem struct { Date string `description:"插入的日期"` RealDate string `description:"实际最晚的日期"` Value string `description:"插入的值"` } type EdbData struct { EdbDataId int `orm:"column(edb_data_id);pk" gorm:"primaryKey" ` EdbInfoId int DataTime string Value float64 } func (e *EdbData) AfterFind(db *gorm.DB) (err error) { tmpDataTime, err := time.Parse(utils.FormatDateWallWithLoc, e.DataTime) if err != nil { return nil } e.DataTime = utils.TimeTransferString(utils.FormatDate, tmpDataTime) return nil } // ConvertToResp // @Description: 转成需要输出的格式 // @receiver m func (e *EdbData) ConvertToResp() { e.DataTime = utils.GormDateStrToDateStr(e.DataTime) return } type EdbInfoListResp struct { Paging *paging.PagingItem Item *EdbInfoList ClassifyList []*EdbClassifyIdItems } type WindEdbInfoList struct { *EdbInfoList ClassifyList []*EdbClassifyIdItems } func (e *EdbInfoList) AfterFind(db *gorm.DB) (err error) { tmpLatestDate, err := time.Parse(utils.FormatDateWallWithLoc, e.LatestDate) if err != nil { return nil } tmpStartDate, err := time.Parse(utils.FormatDateWallWithLoc, e.StartDate) if err != nil { return nil } tmpEndDate, err := time.Parse(utils.FormatDateWallWithLoc, e.EndDate) if err != nil { return nil } tmpCreateTime, err := time.Parse(utils.FormatDateWallWithLoc, e.CreateTime) if err != nil { return nil } tmpModifyTime, err := time.Parse(utils.FormatDateWallWithLoc, e.ModifyTime) if err != nil { return nil } e.LatestDate = utils.TimeTransferString(utils.FormatDate, tmpLatestDate) e.StartDate = utils.TimeTransferString(utils.FormatDate, tmpStartDate) e.EndDate = utils.TimeTransferString(utils.FormatDate, tmpEndDate) e.CreateTime = utils.TimeTransferString(utils.FormatDateTime, tmpCreateTime) e.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, tmpModifyTime) return nil } func GetEdbInfoByCondition(condition string, pars []interface{}) (item *EdbInfoList, err error) { o := global.DmSQL["data"] sql := ` SELECT * FROM edb_info WHERE 1=1 ` if condition != "" { sql += condition } err = o.Raw(sql, pars...).First(&item).Error return } func GetEdbDataCountByCondition(condition string, pars []interface{}, source, subSource int) (count int, err error) { o := global.DmSQL["data"] tableName := GetEdbDataTableName(source, subSource) sql := ` SELECT COUNT(1) AS count FROM %s WHERE 1=1 ` sql = fmt.Sprintf(sql, tableName) if condition != "" { sql += condition } err = o.Raw(sql, pars...).Scan(&count).Error return } func GetEdbDataListByCondition(condition string, pars []interface{}, source, subSource, pageSize, startSize int) (items []*EdbData, err error) { o := global.DmSQL["data"] tableName := GetEdbDataTableName(source, subSource) sql := ` SELECT * FROM %s WHERE 1=1 ` sql = fmt.Sprintf(sql, tableName) if condition != "" { sql += condition } sql += ` ORDER BY data_time DESC ` sql += ` LIMIT ?,? ` pars = append(pars, startSize) pars = append(pars, pageSize) err = o.Raw(sql, pars...).Find(&items).Error if err != nil { return } // 日期处理 for _, v := range items { v.ConvertToResp() } return } // GetAllEdbDataListByCondition 根据条件获取所有的数据 func GetAllEdbDataListByCondition(condition string, pars []interface{}, source, subSource int) (items []*EdbData, err error) { tableName := GetEdbDataTableName(source, subSource) sql := ` SELECT * FROM %s WHERE 1=1 ` sql = fmt.Sprintf(sql, tableName) if condition != "" { sql += condition } sql += ` ORDER BY data_time DESC ` err = global.DmSQL["data"].Raw(sql, pars...).Scan(&items).Error if err != nil { return } // 日期处理 for _, v := range items { v.ConvertToResp() } return } func GetEdbInfoByNewest() (item *EdbInfoList, err error) { sql := ` SELECT * FROM edb_info WHERE 1=1 ORDER BY modify_time DESC LIMIT 1 ` err = global.DmSQL["data"].Raw(sql).Scan(&item).Error return } func ModifyEdbInfoModifyTime(edbInfoId int64) (err error) { sql := ` UPDATE edb_info SET modify_time = NOW() WHERE edb_info_id = ? ` err = global.DmSQL["data"].Exec(sql, edbInfoId).Error return } type MoveEdbInfoReq struct { EdbInfoId int `description:"指标ID"` PrevEdbInfoId int `description:"上一个指标ID"` NextEdbInfoId int `description:"下一个指标ID"` ClassifyId int `description:"分类id"` } func MoveEdbInfo(edbInfoId, classifyId int) (err error) { sql := ` UPDATE edb_info SET classify_id = ? WHERE edb_info_id = ?` err = global.DmSQL["data"].Exec(sql, classifyId, edbInfoId).Error return } func GetChartEdbMappingCount(edbInfoId int) (count int, err error) { sql := ` SELECT COUNT(1) AS count FROM chart_edb_mapping WHERE edb_info_id=? ` err = global.DmSQL["data"].Raw(sql, edbInfoId).Scan(&count).Error return } type ChartEdbInfo struct { EdbInfoId int `description:"指标id"` EdbName string `description:"指标名称"` SourceName string `json:"-"` EdbNameAlias string `json:"-" description:"指标名称,别名"` } func EdbInfoSearchByKeyWord(keyword string) (searchList []*ChartEdbInfo, err error) { pars := make([]interface{}, 0) sql := ` SELECT edb_info_id,edb_name,source_name FROM edb_info WHERE 1=1 AND edb_info_type = 0 ` if keyword != "" { sql += ` AND (edb_name LIKE ? OR edb_code LIKE ? ) ` pars = append(pars, utils.GetLikeKeyword(keyword), utils.GetLikeKeyword(keyword)) } sql += ` ORDER BY create_time DESC ` err = global.DmSQL["data"].Raw(sql, pars...).Scan(&searchList).Error return } type EdbInfoMaxAndMinInfo struct { MinDate string `description:"最小日期"` MaxDate string `description:"最大日期"` MinValue float64 `description:"最小值"` MaxValue float64 `description:"最大值"` LatestValue float64 `description:"最新值"` } // GetEdbInfoMaxAndMinInfo // @Description: 获取指标最大最小值 // @author: Roc // @datetime 2024-05-07 15:34:00 // @param source int // @param subSource int // @param edbCode string // @return item *EdbInfoMaxAndMinInfo // @return err error func GetEdbInfoMaxAndMinInfo(source, subSource int, edbCode string) (item *EdbInfoMaxAndMinInfo, err error) { // 自有数据需要额外处理(从mongo获取) if source == utils.DATA_SOURCE_BUSINESS && utils.UseMongo { return GetEdbInfoMaxAndMinInfoByMongo(source, subSource, edbCode) } if source == utils.DATA_SOURCE_THS && subSource == utils.DATA_SUB_SOURCE_HIGH_FREQUENCY && utils.UseMongo { return GetThsHfEdbInfoMaxAndMinInfoByMongo(source, subSource, edbCode) } // 默认走mysql return GetEdbInfoMaxAndMinInfoByMysql(source, subSource, edbCode) } // GetEdbInfoMaxAndMinInfoByMysql // @Description: 从mysql中获取指标最大最小值 // @author: Roc // @datetime 2024-05-07 15:33:43 // @param source int // @param subSource int // @param edbCode string // @return item *EdbInfoMaxAndMinInfo // @return err error func GetEdbInfoMaxAndMinInfoByMysql(source, subSource int, edbCode string) (item *EdbInfoMaxAndMinInfo, err error) { o := global.DmSQL["data"] sql := `` tableName := GetEdbDataTableName(source, subSource) 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.DmSQL["data"].Raw(sql, edbCode).Scan(&item).Error if err != nil { return } 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 = o.Raw(sql, edbCode).Scan(&latest_value).Error item.LatestValue = latest_value return } // GetEdbInfoMaxAndMinInfoByMongo // @Description: 从mongo中获取指标最大最小值 // @author: Roc // @datetime 2024-05-07 15:33:53 // @param source int // @param subSource int // @param edbCode string // @return item *EdbInfoMaxAndMinInfo // @return err error func GetEdbInfoMaxAndMinInfoByMongo(source, subSource int, edbCode string) (item *EdbInfoMaxAndMinInfo, err error) { mogDataObj := new(mgo.EdbDataBusiness) pipeline := []bson.M{ {"$match": bson.M{"edb_code": edbCode}}, {"$group": bson.M{ "_id": nil, "min_date": bson.M{"$min": "$data_time"}, "max_date": bson.M{"$max": "$data_time"}, "min_value": bson.M{"$min": "$value"}, "max_value": bson.M{"$max": "$value"}, }}, {"$project": bson.M{"_id": 0}}, // 可选,如果不需要_id字段 } result, err := mogDataObj.GetEdbInfoMaxAndMinInfo(pipeline) if err != nil { fmt.Println("EdbDataBusiness getEdbDataBusinessList Err:" + err.Error()) return } if !result.MaxDate.IsZero() { whereQuery := bson.M{"edb_code": edbCode, "data_time": result.MaxDate} selectParam := bson.D{{"value", 1}, {"_id", 0}} latestValue, tmpErr := mogDataObj.GetLatestValue(whereQuery, selectParam) if tmpErr != nil { err = tmpErr return } result.LatestValue = latestValue.Value result.EndValue = latestValue.Value } item = &EdbInfoMaxAndMinInfo{ MinDate: result.MinDate.Format(utils.FormatDate), MaxDate: result.MaxDate.Format(utils.FormatDate), MinValue: result.MinValue, MaxValue: result.MaxValue, LatestValue: result.LatestValue, } 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.DmSQL["data"].Exec(sql, item.MinDate, item.MaxDate, item.MinValue, item.MaxValue, item.MaxDate, item.LatestValue, edbInfoId).Error return } func GetEdbInfoFilter(condition string, pars []interface{}) (list []*EdbInfoList, err error) { sql := ` SELECT * FROM edb_info WHERE 1=1 AND edb_info_type = 0 ` if condition != "" { sql += condition } sql += ` ORDER BY create_time DESC ` err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error return } type AddEdbInfoResp struct { EdbInfoId int `description:"指标ID"` UniqueCode string `description:"指标唯一编码"` ClassifyId int `description:"分类id"` ExistEdbName []string `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.DmSQL["data"].Raw(sql, pars...).Scan(&items).Error return } // GetEdbInfoAllCalculateByEdbInfoIdList 根据指标id集合 获取基础指标对应的所有计算指标 func GetEdbInfoAllCalculateByEdbInfoIdList(fromEdbInfoIdList []int) (list []*EdbInfo, err error) { num := len(fromEdbInfoIdList) if num <= 0 { return } edbEdbInfoIdList := make([]int, 0) sql := ` SELECT DISTINCT b.edb_info_id FROM edb_info_calculate_mapping AS a INNER JOIN edb_info AS b ON a.edb_info_id=b.edb_info_id WHERE a.from_edb_info_id in (` + utils.GetOrmInReplace(num) + `) ORDER BY b.edb_info_id ASC ` err = global.DmSQL["data"].Raw(sql, fromEdbInfoIdList).Scan(&edbEdbInfoIdList).Error if err != nil { return } // 查询来的实际id集合 num = len(edbEdbInfoIdList) if num <= 0 { return } sql = ` SELECT * FROM edb_info WHERE edb_info_id IN (` + utils.GetOrmInReplace(num) + `) ORDER BY edb_info_id ASC ` err = global.DmSQL["data"].Raw(sql, edbEdbInfoIdList).Find(&list).Error return } func GetRefreshEdbInfoFromBase(edbInfoId, source int) (baseEdbInfoArr, calculateInfoArr []*EdbInfo, err error) { calculateList, err := GetEdbInfoCalculateMap(edbInfoId, source) if err != nil && !utils.IsErrNoRow(err) { return } for _, item := range calculateList { if item.EdbInfoId == edbInfoId { // 如果查出来关联的指标就是自己的话,那么就过滤 continue } if item.EdbType == 1 { baseEdbInfoArr = append(baseEdbInfoArr, item) } else { calculateInfoArr = append(calculateInfoArr, item) newBaseEdbInfoArr, newCalculateInfoArr, _ := GetRefreshEdbInfoFromBase(item.EdbInfoId, item.Source) baseEdbInfoArr = append(baseEdbInfoArr, newBaseEdbInfoArr...) calculateInfoArr = append(calculateInfoArr, newCalculateInfoArr...) } } return } func ModifyEdbInfoDataStatus(edbInfoId int64, source, subSource int, edbCode string) (err error) { sql := `` tableName := GetEdbDataTableName(source, subSource) sql = ` UPDATE %s SET edb_info_id=?,modify_time=NOW() WHERE edb_code=? ` sql = fmt.Sprintf(sql, tableName) err = global.DmSQL["data"].Exec(sql, edbInfoId, edbCode).Error return } // GetFirstEdbInfoByClassifyId 获取当前分类下,且排序数相同 的排序第一条的数据 func GetFirstEdbInfoByClassifyId(classifyId int) (item *EdbInfo, err error) { sql := ` SELECT * FROM edb_info WHERE classify_id=? order by sort asc,edb_info_id asc limit 1` err = global.DmSQL["data"].Raw(sql, classifyId).First(&item).Error return } // UpdateEdbInfoSortByClassifyId 根据分类id更新排序 func UpdateEdbInfoSortByClassifyId(classifyId, nowSort int, prevEdbInfoId int, updateSort string) (err error) { sql := ` update edb_info set sort = ` + updateSort + ` WHERE classify_id=?` if prevEdbInfoId > 0 { sql += ` AND ( sort > ? or ( edb_info_id > ` + fmt.Sprint(prevEdbInfoId) + ` and sort=` + fmt.Sprint(nowSort) + ` )) ` } else { sql += ` AND ( sort > ? )` } err = global.DmSQL["data"].Exec(sql, classifyId, nowSort).Error return } // Update 更新指标基础信息 func (edbInfo *EdbInfo) Update(cols []string) (err error) { err = global.DmSQL["data"].Select(cols).Updates(edbInfo).Error return } // UpdateById 更新指标基础信息 func (m *EdbInfo) UpdateById(edbInfoId int, updateMap map[string]interface{}) (err error) { err = global.DmSQL["data"].Model(m).Where("edb_info_id = ? ", edbInfoId).Updates(updateMap).Error return } type EdbInfoDataResp struct { EdbInfo *EdbInfo DataList []*EdbDataList } type EdbInfoDataFullClassifyResp struct { EdbInfo *EdbInfoFullClassify DataList []*EdbDataList } type EdbInfoReplaceReq struct { OldEdbInfoId int `description:"原指标ID"` NewEdbInfoId int `description:"替换为指标ID"` } // ReplaceChartEdb 替换图表中的指标 func ReplaceChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (relationEdbInfoIdList []int, replaceChartTotal, replaceCalculateTotal int, err error) { var errmsg string relationEdbInfoIdList = make([]int, 0) // 关联的指标id logMsg := `` // 记录替换的日志 to := global.DmSQL["data"].Begin() defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() if logMsg != `` { utils.FileLog.Info(fmt.Sprintf("替换指标记录,旧的指标id:%d,新的指标id:%d;%s", oldEdbInfo.EdbInfoId, newEdbInfo.EdbInfoId, logMsg)) } } if errmsg != "" { fmt.Println("errmsg:" + errmsg) } if err != nil && errmsg != "" { go alarm_msg.SendAlarmMsg("替换图表中的指标失败提醒,errmsg:"+errmsg, 3) //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"替换指标失败提醒", "errmsg:"+errmsg, utils.EmailSendToUsers) } }() //替换图表 { chartEdbMappingList := make([]*ChartEdbInfoMapping, 0) csql := `SELECT * FROM chart_edb_mapping WHERE edb_info_id=?` err = to.Raw(csql, oldEdbInfo.EdbInfoId).Scan(&chartEdbMappingList).Error if err != nil { errmsg = "获取指标关联图表信息失败:Err:" + err.Error() return } replaceChartTotal = len(chartEdbMappingList) // 查询所有的相关的图表信息 chartInfoIds := make([]string, 0) if len(chartEdbMappingList) > 0 { for _, chartEdbMapping := range chartEdbMappingList { chartInfoIds = append(chartInfoIds, strconv.Itoa(chartEdbMapping.ChartInfoId)) } } if len(chartInfoIds) > 0 { chartInfoList, e := GetChartInfoListByChartIdList(chartInfoIds) if e != nil { err = e errmsg = "获取图表信息失败:Err:" + e.Error() return } for _, chartInfo := range chartInfoList { updateStr := make([]string, 0) if chartInfo.EdbInfoIds != "" && strings.Contains(chartInfo.EdbInfoIds, strconv.Itoa(oldEdbInfo.EdbInfoId)) { //需要更换 //解析字符串 edbInfoIds := strings.Split(chartInfo.EdbInfoIds, ",") for i, edbInfoId := range edbInfoIds { if edbInfoId == strconv.Itoa(oldEdbInfo.EdbInfoId) { edbInfoIds[i] = strconv.Itoa(newEdbInfo.EdbInfoId) } } chartInfo.EdbInfoIds = strings.Join(edbInfoIds, ",") updateStr = append(updateStr, "EdbInfoIds") } if chartInfo.ExtraConfig != "" || chartInfo.BarConfig != "" { //判断是否是拟合方程或者散点图截面图 if chartInfo.Source == utils.CHART_SOURCE_FUTURE_GOOD { // 商品价格曲线图的一些配置 var barConfig FutureGoodBarChartInfoReq err = json.Unmarshal([]byte(chartInfo.BarConfig), &barConfig) if err != nil { errmsg = "商品价格曲线图配置异常 json.Unmarshal:Err:" + err.Error() return } if barConfig.BaseEdbInfoId == oldEdbInfo.EdbInfoId { barConfig.BaseEdbInfoId = newEdbInfo.EdbInfoId } for k, item := range barConfig.EdbInfoIdList { if item.EdbInfoId == oldEdbInfo.EdbInfoId && item.Source == 1 { barConfig.EdbInfoIdList[k].EdbInfoId = newEdbInfo.EdbInfoId } } // 更新图表配置信息 // 重新序列化 configJson, e := json.Marshal(barConfig) if e != nil { err = e errmsg = "图表配置信息序列化失败:json.Marshal Err: " + e.Error() return } configStr := string(configJson) chartInfo.BarConfig = configStr updateStr = append(updateStr, "BarConfig") } else if chartInfo.Source == utils.CHART_SOURCE_FUTURE_GOOD_PROFIT { // 商品利润曲线图的一些配置 var extraConf FutureGoodProfitChartInfoReq err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &extraConf) if err != nil { errmsg = "商品利润曲线图配置异常 json.Unmarshal:Err:" + err.Error() return } if extraConf.BaseEdbInfoId == oldEdbInfo.EdbInfoId { extraConf.BaseEdbInfoId = newEdbInfo.EdbInfoId } for k, v := range extraConf.EdbInfoIdList { if v == oldEdbInfo.EdbInfoId { extraConf.EdbInfoIdList[k] = newEdbInfo.EdbInfoId } } // 更新图表配置信息 // 重新序列化 configJson, e := json.Marshal(extraConf) if e != nil { err = e errmsg = "图表配置信息序列化失败:json.Marshal Err: " + e.Error() return } configStr := string(configJson) chartInfo.ExtraConfig = configStr updateStr = append(updateStr, "ExtraConfig") } else if chartInfo.Source == utils.CHART_SOURCE_LINE_EQUATION { //解析配置内容 var lineChartInfoConfig request.LineChartInfoReq err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &lineChartInfoConfig) if err != nil { errmsg = "获取图表配置信息失败 json.Unmarshal:Err:" + err.Error() return } xEdbInfoIdList := lineChartInfoConfig.XEdbInfoIdList yEdbInfoIdList := lineChartInfoConfig.YEdbInfoIdList if len(xEdbInfoIdList) > 0 { // 循环判断是否存在 for k, xEdbInfoId := range xEdbInfoIdList { if xEdbInfoId == oldEdbInfo.EdbInfoId { xEdbInfoIdList[k] = newEdbInfo.EdbInfoId } } } if len(yEdbInfoIdList) > 0 { // 循环判断是否存在 for k, yEdbInfoId := range yEdbInfoIdList { if yEdbInfoId == oldEdbInfo.EdbInfoId { yEdbInfoIdList[k] = newEdbInfo.EdbInfoId } } } // 替换新的指标信息 lineChartInfoConfig.XEdbInfoIdList = xEdbInfoIdList lineChartInfoConfig.YEdbInfoIdList = yEdbInfoIdList // 重新序列化 lineChartInfoConfigJson, e := json.Marshal(lineChartInfoConfig) if e != nil { err = e errmsg = "图表配置信息序列化失败:json.Marshal Err: " + e.Error() return } lineChartInfoConfigStr := string(lineChartInfoConfigJson) // 更新图表配置信息 chartInfo.ExtraConfig = lineChartInfoConfigStr updateStr = append(updateStr, "ExtraConfig") } else if chartInfo.ChartType == utils.CHART_TYPE_SECTION_SCATTER { //解析配置内容 var tmpExtraConfig SectionScatterReq err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &tmpExtraConfig) if err != nil { errmsg = "获取截面散点图配置信息失败 json.Unmarshal:Err:" + err.Error() return } //找到指标信息,并替换 if len(tmpExtraConfig.SeriesList) > 0 { for k1, series := range tmpExtraConfig.SeriesList { for k2, item := range series.EdbInfoList { if item.XEdbInfoId == oldEdbInfo.EdbInfoId { tmpExtraConfig.SeriesList[k1].EdbInfoList[k2].XEdbInfoId = newEdbInfo.EdbInfoId } if item.YEdbInfoId == oldEdbInfo.EdbInfoId { tmpExtraConfig.SeriesList[k1].EdbInfoList[k2].YEdbInfoId = newEdbInfo.EdbInfoId } } } } // 重新序列化 sectionScatterConfigJson, e := json.Marshal(tmpExtraConfig) if e != nil { err = e errmsg = "图表配置信息序列化失败:json.Marshal Err: " + e.Error() return } sectionScatterConfigStr := string(sectionScatterConfigJson) // 更新图表配置信息 chartInfo.ExtraConfig = sectionScatterConfigStr updateStr = append(updateStr, "ExtraConfig") } else if chartInfo.ChartType == utils.CHART_TYPE_SECTION_COMBINE { //解析配置内容 var tmpExtraConfig ChartSectionExtraConf err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &tmpExtraConfig) if err != nil { errmsg = "获取截面散点图配置信息失败 json.Unmarshal:Err:" + err.Error() return } //找到指标信息,并替换 if len(tmpExtraConfig.DateConfList) > 0 { for k1, item := range tmpExtraConfig.DateConfList { if item.EdbInfoId > 0 && item.EdbInfoId == oldEdbInfo.EdbInfoId { tmpExtraConfig.DateConfList[k1].EdbInfoId = newEdbInfo.EdbInfoId } } } // 重新序列化 configJson, e := json.Marshal(tmpExtraConfig) if e != nil { err = e errmsg = "图表配置信息序列化失败:json.Marshal Err: " + e.Error() return } configStr := string(configJson) // 更新图表配置信息 chartInfo.ExtraConfig = configStr updateStr = append(updateStr, "ExtraConfig") } } if len(updateStr) > 0 { updateStr = append(updateStr, "ModifyTime") chartInfo.ModifyTime = time.Now() err = chartInfo.Update(updateStr) if err != nil { errmsg = "更新图表信息失败:chartInfo.Update Err: " + err.Error() return } } } } // 查询所有的图表信息 if len(chartEdbMappingList) > 0 { chartInfoIdList := make([]string, 0) for _, mv := range chartEdbMappingList { //获取图表所有指标信息 chartEdbList := make([]*ChartEdbInfoMapping, 0) csql := `SELECT * FROM chart_edb_mapping WHERE chart_info_id=?` err = to.Raw(csql, mv.ChartInfoId).Scan(&chartEdbList).Error if err != nil { errmsg = "获取图表所有指标信息失败:Err:" + err.Error() return } // 查询图表信息 var minData, maxData float64 minData = newEdbInfo.MinValue maxData = newEdbInfo.MaxValue for _, cv := range chartEdbList { if mv.IsAxis == cv.IsAxis { if minData > cv.MinData { minData = cv.MinData } if maxData < cv.MaxData { maxData = cv.MaxData } } } //修改图表关联指标 rsql := ` UPDATE chart_edb_mapping SET edb_info_id=?,max_data=?,min_data=?,modify_time=NOW() WHERE chart_edb_mapping_id=? ` err = to.Exec(rsql, newEdbInfo.EdbInfoId, maxData, minData, mv.ChartEdbMappingId).Error if err != nil { errmsg = "更新图库指标信息失败:Err:" + err.Error() return } rsql = ` UPDATE chart_series_edb_mapping SET edb_info_id=? WHERE edb_info_id=? and chart_info_id=?` err = to.Exec(rsql, newEdbInfo.EdbInfoId, oldEdbInfo.EdbInfoType, mv.ChartInfoId).Error if err != nil { errmsg = "更新图库系列指标信息失败:Err:" + err.Error() return } chartInfoIdList = append(chartInfoIdList, fmt.Sprint(mv.ChartInfoId)) } logMsg += `涉及到的图表id:` + strings.Join(chartInfoIdList, ",") + ";" } } //替换计算指标 { //获取所有包含的计算指标 mappingList := make([]*EdbInfoCalculateMapping, 0) queryList := make([]*EdbInfoCalculateMapping, 0) msql := ` SELECT * FROM edb_info_calculate_mapping WHERE from_edb_info_id = ?` err = to.Raw(msql, oldEdbInfo.EdbInfoId).Find(&queryList).Error if err != nil { errmsg = "获取计算指标关联基础指标信息失败:Err:" + err.Error() return } exists := make(map[int]bool) for _, v := range queryList { if exists[v.EdbInfoId] { continue } exists[v.EdbInfoId] = true mappingList = append(mappingList, v) } replaceCalculateTotal = len(mappingList) //计算指标 if len(mappingList) > 0 { edbInfoIdList := make([]string, 0) for _, mv := range mappingList { //如果即将替换的指标与当前指标id一致,那么就退出当前循环,进入下一循环 if mv.EdbInfoId == newEdbInfo.EdbInfoId { continue } //替换原指标 msql := `UPDATE edb_info_calculate_mapping SET from_edb_info_id=?,from_edb_code=?,from_edb_name=?,from_source=?,from_source_name=? WHERE edb_info_calculate_mapping_id=? ` err = to.Exec(msql, newEdbInfo.EdbInfoId, newEdbInfo.EdbCode, newEdbInfo.EdbName, newEdbInfo.Source, newEdbInfo.SourceName, mv.EdbInfoCalculateMappingId).Error if err != nil { return } relationEdbInfoIdList = append(relationEdbInfoIdList, mv.EdbInfoId) edbInfoIdList = append(edbInfoIdList, fmt.Sprint(mv.EdbInfoId)) } logMsg += `涉及到的指标id:` + strings.Join(edbInfoIdList, ",") + ";" } } // 替换预测指标中的来源指标 { //获取所有包含的计算指标 predictEdbConfList := make([]*PredictEdbConf, 0) queryList := make([]*PredictEdbConf, 0) msql := ` SELECT * FROM predict_edb_conf WHERE source_edb_info_id = ?` err = to.Raw(msql, oldEdbInfo.EdbInfoId).Scan(&predictEdbConfList).Error if err != nil { errmsg = "获取关联的预测指标信息失败:Err:" + err.Error() return } exists := make(map[int]bool) for _, v := range queryList { if exists[v.PredictEdbInfoId] { continue } exists[v.PredictEdbInfoId] = true predictEdbConfList = append(predictEdbConfList, v) } replaceCalculateTotal += len(predictEdbConfList) //替换预测指标的来源指标 msql = `UPDATE predict_edb_conf SET source_edb_info_id=? WHERE source_edb_info_id=? ` err = to.Exec(msql, newEdbInfo.EdbInfoId, oldEdbInfo.EdbInfoId).Error if err != nil { return } if len(predictEdbConfList) > 0 { edbInfoIdList := make([]string, 0) for _, v := range predictEdbConfList { relationEdbInfoIdList = append(relationEdbInfoIdList, v.PredictEdbInfoId) edbInfoIdList = append(edbInfoIdList, fmt.Sprint(v.PredictEdbInfoId)) } logMsg += `涉及到的预测指标id:` + strings.Join(edbInfoIdList, ",") + ";" } } return } type EdbInfoView struct { EdbInfoId int `orm:"column(edb_info_id);pk" gorm:"primaryKey" ` EdbInfoType int `description:"指标类型,0:普通指标,1:预测指标"` SourceName string `description:"来源名称"` Source int `description:"来源id"` EdbCode string `description:"指标编码"` EdbName string `description:"指标名称"` EdbNameSource string `description:"指标名称来源"` Frequency string `description:"频率"` Unit string `description:"单位"` StartDate string `description:"起始日期"` EndDate string `description:"终止日期"` ClassifyId int `description:"分类id"` SysUserId int SysUserRealName string UniqueCode string `description:"指标唯一编码"` CreateTime string ModifyTime string MinValue float64 `description:"指标最小值"` MaxValue float64 `description:"指标最大值"` CalculateFormula string `description:"计算公式"` EdbType int `description:"指标类型:1:基础指标,2:计算指标"` Sort int `description:"排序字段"` IsUpdate int `description:"当天是否已更新,1:未更新,2:已更新"` LatestDate string `description:"数据最新日期(实际日期)"` LatestValue float64 `description:"数据最新值(实际值)"` SubSource int `description:"子数据来源:0:经济数据库,1:日期序列"` SubSourceName string `description:"子数据来源名称"` IndicatorCode string `description:"指标代码"` StockCode string `description:"证券代码"` EndValue float64 `description:"数据的最新值(预测日期的最新值)"` } // EdbInfoFilterDataResp 搜索指标列表数据返回 type EdbInfoFilterDataResp struct { Paging *paging.PagingItem List []*EdbInfoList } // GetEdbInfoFilterList 获取指指标列表数据接口 func GetEdbInfoFilterList(condition string, pars []interface{}, startSize, pageSize int) (total int64, list []*EdbInfoList, err error) { o := global.DmSQL["data"] sql := ` SELECT count(1) total FROM edb_info where 1=1 ` + condition + ` ORDER BY edb_info_id DESC ` err = o.Raw(sql, pars...).Scan(&total).Error if err != nil { return } sql = ` SELECT * FROM edb_info where 1=1 ` + condition + ` ORDER BY edb_info_id DESC LIMIT ?,? ` pars = append(pars, startSize, pageSize) err = o.Raw(sql, pars...).Scan(&list).Error return } // SetEdbInfoImageReq 设置指标图片 type SetEdbInfoImageReq struct { EdbInfoId int `description:"指标ID"` ImageUrl string `description:"指标图片地址"` } // GetNextEdbInfoByCondition 根据条件获取下一个指标 func GetNextEdbInfoByCondition(condition string, pars []interface{}) (item *EdbInfo, err error) { o := global.DmSQL["data"] sql := ` SELECT * FROM edb_info WHERE 1=1 ` if condition != "" { sql += condition } sql += " ORDER BY sort asc , edb_info_id asc LIMIT 1 " err = o.Raw(sql, pars...).First(&item).Error return } // GetNextEdbInfo 根据分类id获取下一个 指标 func GetNextEdbInfo(classifyId, classifySort, classifyType, edbInfoType int) (item *EdbInfo, err error) { o := global.DmSQL["data"] sql := ` SELECT b.* FROM edb_classify AS a INNER JOIN edb_info AS b ON a.classify_id=b.classify_id WHERE (a.sort>? OR (a.sort=? and a.classify_id>?) ) AND a.classify_type=? AND b.edb_info_type=? ORDER BY a.sort ASC,b.sort asc,b.edb_info_id asc LIMIT 1 ` err = o.Raw(sql, classifySort, classifySort, classifyId, classifyType, edbInfoType).Scan(&item).Error return } // GetEdbInfoByEdbCodeList 根据指标code集合获取指标列表 func GetEdbInfoByEdbCodeList(source int, edbCodeList []string) (items []*EdbInfo, err error) { num := len(edbCodeList) if num <= 0 { return } o := global.DmSQL["data"] sql := ` SELECT * FROM edb_info WHERE source=? AND edb_code in (` + utils.GetOrmInReplace(num) + `) ` err = o.Raw(sql, source, edbCodeList).Scan(&items).Error return } // GetEdbInfoByConditionCount 根据条件获取指标列表数据总数 func GetEdbInfoByConditionCount(condition string, pars []interface{}) (count int, err error) { o := global.DmSQL["data"] sql := ` SELECT COUNT(1) AS count FROM edb_info WHERE 1=1 ` if condition != "" { sql += condition } err = o.Raw(sql, pars...).Scan(&count).Error return } // GetEdbInfoListByCondition 根据条件获取指标列表数据 func GetEdbInfoListByCondition(condition string, pars []interface{}, startSize, pageSize int, orderDesc string) (items []*EdbInfoList, err error) { o := global.DmSQL["data"] sql := ` SELECT * FROM edb_info WHERE 1=1 ` if condition != "" { sql += condition } if orderDesc == `` { orderDesc = ` ASC ` } sql += ` ORDER BY edb_info_id ` sql += orderDesc sql += ` LIMIT ?,? ` pars = append(pars, startSize) pars = append(pars, pageSize) err = o.Raw(sql, pars...).Scan(&items).Error return } // GetEdbInfoListByEdbInfoId // @Description: 根据指标id列表获取列表信息 // @param edbIdList // @return items // @return err func GetEdbInfoListByEdbInfoId(edbIdList []string) (items []*EdbInfo, err error) { num := len(edbIdList) if num <= 0 { return } o := global.DmSQL["data"] sql := ` SELECT * FROM edb_info WHERE edb_info_id in (` + utils.GetOrmInReplace(num) + `) ` err = o.Raw(sql, edbIdList).Scan(&items).Error return } // GetEdbInfoListByUserId // @Description: 根据指标id列表获取列表信息 // @param userIdList []int // @param edbInfoType int // @return items // @return err func GetEdbInfoListByUserId(userIdList []int, edbInfoType int) (items []*EdbInfo, err error) { num := len(userIdList) if num <= 0 { return } o := global.DmSQL["data"] sql := ` SELECT * FROM edb_info WHERE edb_info_type = ? AND sys_user_id in (` + utils.GetOrmInReplace(num) + `) ` err = o.Raw(sql, edbInfoType, userIdList).Scan(&items).Error return } // ModifyEdbInfoUserIdByCodeList 根据指标code列表修改创建人 func ModifyEdbInfoUserIdByCodeList(edbIdList []string, userId int, userName string) (err error) { num := len(edbIdList) if num <= 0 { return } o := global.DmSQL["data"] sql := `UPDATE edb_info SET sys_user_id=?,sys_user_real_name=? WHERE edb_info_id in (` + utils.GetOrmInReplace(num) + `) ` err = o.Exec(sql, userId, userName, edbIdList).Error return } // ModifyEdbInfoUserIdByOldUserId // @Description: 根据旧用户id修改新用户id // @author: Roc // @datetime 2024-03-25 19:17:09 // @param edbIdList []string // @param userId int // @param userName string // @return err error func ModifyEdbInfoUserIdByOldUserId(oldUserIdList []int, edbInfoType, userId int, userName string) (err error) { num := len(oldUserIdList) if num <= 0 { return } o := global.DmSQL["data"] sql := `UPDATE edb_info SET sys_user_id=?,sys_user_real_name=? WHERE sys_user_id in (` + utils.GetOrmInReplace(num) + `) and edb_info_type = ?` err = o.Exec(sql, userId, userName, oldUserIdList, edbInfoType).Error return } // MoveEdbChartList 图表/指标信息 type MoveEdbChartList struct { DataId string `description:"指标/图表唯一id"` Code string `description:"指标code"` Name string `description:"指标/图表名称"` NameEn string `description:"指标/图表名称"` ClassifyName string `description:"分类名称"` ClassifyNameEn string `description:"分类名称"` CreateUserId int `description:"创建人id"` CreateUserName string `description:"创建人名称"` } // MoveEdbChartListResp 更改创建人返回数据 type MoveEdbChartListResp struct { Paging *paging.PagingItem List []MoveEdbChartList } type EdbChartClassifyResp struct { List []*EdbChartClassify } type EdbChartClassify struct { ClassifyId int ClassifyName string ParentId int IsJoinPermission int `description:"是否加入权限管控,0:不加入;1:加入;默认:0"` Child []*EdbChartClassify } // EdbInfoDataSeasonalResp 指标季节性数据返回 type EdbInfoDataSeasonalResp struct { EdbInfo *EdbInfo DataList interface{} } // SetEdbDataInsertConfigReq 设置插入规则的请求 type SetEdbDataInsertConfigReq struct { EdbInfoId int `description:"指标ID"` Date string `description:"日期"` Value string `description:"值"` } // GetEdbInfoByClassifyId 用于分类展示 func GetEdbInfoByClassifyId(classifyId, edbInfoType, edbType, adminId int, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList []int) (items []*EdbClassifyItems, err error) { o := global.DmSQL["data"] sql := ` SELECT edb_info_id,classify_id,edb_name AS classify_name,edb_name_en AS classify_name_en,unique_code,source_name,source,sys_user_id,sys_user_real_name,start_date,edb_code,edb_type, sort,is_join_permission FROM edb_info WHERE classify_id = ? AND edb_info_type = ?` pars := []interface{}{classifyId, edbInfoType} // 如果筛选了指标类型,那么就根据条件来 if edbType > 0 { sql += ` AND edb_type = ? ` pars = append(pars, edbType) } // 如果筛选了用户id if adminId > 0 { sql += ` AND sys_user_id = ? ` pars = append(pars, adminId) } noPermissionEdbInfoIdNum := len(noPermissionEdbInfoIdList) if noPermissionEdbInfoIdNum > 0 { sql += ` AND edb_info_id NOT IN (` + utils.GetOrmInReplace(noPermissionEdbInfoIdNum) + `) ` pars = append(pars, noPermissionEdbInfoIdList) } noPermissionClassifyInfoIdNum := len(noPermissionEdbClassifyIdList) if noPermissionClassifyInfoIdNum > 0 { sql += ` AND classify_id NOT IN (` + utils.GetOrmInReplace(noPermissionClassifyInfoIdNum) + `) ` pars = append(pars, noPermissionEdbClassifyIdList) } sql += ` order by sort asc,edb_info_id asc ` err = o.Raw(sql, pars...).Scan(&items).Error return } type EdbAndClassify struct { EdbInfoId int `description:"指标id"` EdbCode string `description:"指标code"` UniqueCode string `description:"唯一code"` EdbName string `description:"指标名称"` ClassifyId int `description:"所属分类id"` FirstClassifyId int `description:"第1级的分类id"` FirstClassifyName string `description:"第1级的分类名称"` SecondClassifyId int `description:"第2级的分类id"` SecondClassifyName string `description:"第2级的分类名称"` } // GetEdbInfoAndClassifyListByEdbIdList 根据指标id列表获取 指标及分类信息 func GetEdbInfoAndClassifyListByEdbIdList(edbIdList []int) (items []*EdbAndClassify, err error) { num := len(edbIdList) if num <= 0 { return } o := global.DmSQL["data"] sql := ` SELECT a.edb_info_id,a.edb_code,a.unique_code,a.edb_name,a.classify_id FROM edb_info AS a WHERE a.edb_info_id in (` + utils.GetOrmInReplace(num) + `) ` err = o.Raw(sql, edbIdList).Scan(&items).Error return } // TraceEdbInfoResp 指标追溯数据返回 type TraceEdbInfoResp struct { EdbInfoId int `description:"指标id"` EdbInfoType int `description:"指标类型: 0-普通指标; 1-预测指标"` EdbName string `description:"指标名称"` EdbNameEn string `description:"指标英文名称"` EdbType int `description:"指标类型: 1-基础指标; 2-计算指标"` RuleTitle string `description:"指标规则"` RuleTitleEn string `description:"指标规则(英文)"` UniqueCode string `description:"唯一编码"` ClassifyId int `description:"分类ID"` Child []TraceEdbInfoResp `description:"下级来源"` IsStop int8 `description:"是否终止"` EdbInfo *EdbInfo `description:"指标信息" json:"-"` HaveOperaAuth bool `description:"是否有数据权限,默认:false"` } // BeforeAndAfterDateDataResp 前后几期数据 type BeforeAndAfterDateDataResp struct { List []*EdbDataList `description:"list"` Date string `description:"实际日期"` ShowValue string `description:"展示值"` } // GetEdbInfoAdminList func GetEdbInfoAdminList(edbType int) (list []int, err error) { o := global.DmSQL["data"] sql := ` SELECT sys_user_id FROM edb_info WHERE edb_info_type = ? GROUP BY sys_user_id ` err = o.Raw(sql, edbType).Scan(&list).Error return } type EdbInfoExistCheckResp struct { IndexExist bool `description:"指标是否存在:true,存在,false:不存在"` ExistStockCodeArr []string `description:"存在的证券代码"` ExistEdbCodeArr []string `description:"存在的指标代码"` ExistClassifyId []int `description:"存在的分类id"` ExistIndexId []int `description:"存在的指标id"` ExistEdbInfo []*EdbInfo `description:"存在的指标"` } type BatchAddEdbInfoReq struct { BatchList []*BatchAddEdbInfo } type BatchAddEdbInfo struct { Source int `description:"来源id"` EdbName string `description:"指标名称"` Frequency string `description:"频率"` Unit string `description:"单位"` ClassifyId int `description:"分类id"` StockCode string `description:"证券代码"` EdbCode string `description:"指标编码"` ApiExtraPars string `description:"API额外参数"` } func GetEdbInfoWsdMaxAndMinInfo(source, subSource int, edbCode string) (item *EdbInfoMaxAndMinInfo, err error) { o := global.DmSQL["data"] sql := `` tableName := GetEdbDataTableNameAndSubSource(source, subSource) 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 = o.Raw(sql, edbCode).Scan(&item).Error if err != nil { return } 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 = o.Raw(sql, edbCode).Scan(&latest_value).Error item.LatestValue = latest_value return } // GetEdbInfoByNames 根据名称获取普通的指标 func GetEdbInfoByNames(edbNames string) (items []*EdbInfoList, err error) { o := global.DmSQL["data"] sql := ` SELECT * FROM edb_info WHERE edb_name IN (` + edbNames + `) AND edb_info_type = 0 ` err = o.Raw(sql).Scan(&items).Error return } // BaseRefreshEdbInfo // @Description: 刷新配置的基础指标信息结构体 type BaseRefreshEdbInfo struct { EdbInfoId int ClassifyId int `description:"钢联化工指标分类id"` IndexCode string `description:"指标编码"` IndexName string `description:"指标名称"` EndDate string `description:"最新日期"` EndValue string `description:"最新值"` SysUserId int `description:"创建人id"` SysUserRealName string `description:"创建人姓名"` Frequency string `description:"频度"` IsStop int `description:"是否停更:1:停更,0:未停更"` TerminalCode string `description:"终端编码"` RefreshTime string `description:"刷新时间"` } // RefreshBaseEdbInfoResp // @Description: 刷新数据源的数据返回 type RefreshBaseEdbInfoResp struct { Paging *paging.PagingItem List []*BaseRefreshEdbInfo } // GetEdbBaseInfoList // @Description: 获取指标库数据列表 // @author: Roc // @datetime 2024-01-10 14:28:22 // @param condition string // @param pars []interface{} // @param orderBy string // @param startSize int // @param pageSize int // @return total int // @return items []*BaseRefreshEdbInfo // @return err error func GetEdbBaseInfoList(condition string, pars []interface{}, orderBy string, startSize, pageSize int) (total int, items []*BaseRefreshEdbInfo, err error) { o := global.DmSQL["data"] // 数量汇总 totalSql := ` SELECT count(1) FROM edb_info WHERE 1=1 ` if condition != "" { totalSql += condition } err = o.Raw(totalSql, pars...).Scan(&total).Error if err != nil { return } // 列表数据 sql := ` SELECT edb_info_id as edb_info_id, classify_id as classify_id,edb_code as index_code,edb_name as index_name,end_date,end_value,sys_user_id,sys_user_real_name,frequency,no_update as is_stop,terminal_code FROM edb_info WHERE 1=1 ` if condition != "" { sql += condition } if orderBy != "" { sql += ` ORDER BY ` + orderBy } else { sql += ` ORDER BY edb_info_id ASC ` } sql += ` LIMIT ?,? ` pars = append(pars, startSize, pageSize) err = o.Raw(sql, pars...).Scan(&items).Error return } // ModifyEdbInfoUpdateStatus // @Description: 修改指标库停更状态 // @author: Roc // @datetime 2024-01-08 16:23:31 // @param edbIdList []int // @param indexCodeList []string // @param isStop int // @return err error func ModifyEdbInfoUpdateStatus(edbIdList []int, isStop int, calculateEdbInfoIds []int) (err error) { idNum := len(edbIdList) if idNum <= 0 { return } o := global.DmSQL["data"].Begin() defer func() { if err != nil { _ = o.Rollback() return } _ = o.Commit() }() // 更改指标的更新状态 sql := ` UPDATE edb_info SET no_update = ? WHERE edb_info_id IN (` + utils.GetOrmInReplace(idNum) + `) ` err = o.Exec(sql, isStop, edbIdList).Error if err != nil { return } if len(calculateEdbInfoIds) > 0 { // 批量更新相关联的指标ID sql = ` UPDATE edb_info SET no_update = ? WHERE edb_info_id IN (` + utils.GetOrmInReplace(len(calculateEdbInfoIds)) + `) ` err = o.Exec(sql, isStop, calculateEdbInfoIds).Error if err != nil { return } } return } func GetEdbInfoCount(source int, edbCode string) (count int, err error) { o := global.DmSQL["data"] sql := ` SELECT COUNT(1) AS count FROM edb_info WHERE source=? AND edb_code = ?` err = o.Raw(sql, source, edbCode).Scan(&count).Error return } // GetEdbInfoByNameArr 根据名称获取指标 func GetEdbInfoByNameArr(names []string, edbInfoType int) (items []*EdbInfo, err error) { if len(names) == 0 { return } o := global.DmSQL["data"] sql := fmt.Sprintf(`SELECT edb_info_id, edb_code, edb_name FROM edb_info WHERE edb_name IN (%s) AND edb_info_type = ? `, utils.GetOrmInReplace(len(names))) err = o.Raw(sql, names, edbInfoType).Scan(&items).Error return } // GetEdbCodesBySource 根据来源获取指标编码 func GetEdbCodesBySource(source int) (items []*EdbInfo, err error) { o := global.DmSQL["data"] sql := ` SELECT edb_info_id, edb_code, unique_code, classify_id FROM edb_info WHERE source = ? ` err = o.Raw(sql, source).Scan(&items).Error return } // GetAllEdbDataListData // @Description: 获取指标的所有数据 // @author: Roc // @datetime 2024-05-07 15:18:27 // @param edbInfoId int // @param source int // @param subSource int // @param startDataTime string // @return dataList []*EdbData // @return err error func GetAllEdbDataListData(edbInfoId, source, subSource int, startDataTime string) (dataList []*EdbData, err error) { // 自有数据需要额外处理(从mongo获取) if source == utils.DATA_SOURCE_BUSINESS && utils.UseMongo { return getAllDataByMongo(edbInfoId, source, subSource, startDataTime) } if source == utils.DATA_SOURCE_THS && subSource == utils.DATA_SUB_SOURCE_HIGH_FREQUENCY && utils.UseMongo { return getThsHfAllDataByMongo(edbInfoId, source, subSource, startDataTime) } // 默认走mysql return getAllDataByMysql(edbInfoId, source, subSource, startDataTime) } // getAllDataByMysql // @Description: 从mysql获取指标的所有数据 // @author: Roc // @datetime 2024-05-07 15:18:41 // @param edbInfoId int // @param source int // @param subSource int // @param startDataTime string // @return dataList []*data_manage.EdbData // @return err error func getAllDataByMysql(edbInfoId, source, subSource int, startDataTime string) (dataList []*EdbData, err error) { dataList = make([]*EdbData, 0) var dataCondition string var dataPars []interface{} dataCondition += ` AND edb_info_id=? ` dataPars = append(dataPars, edbInfoId) // 结束日期 if startDataTime != "" { dataCondition += ` AND data_time > ? ` dataPars = append(dataPars, startDataTime) } // 获取列表数据 dataList, err = GetAllEdbDataListByCondition(dataCondition, dataPars, source, subSource) if err != nil { return } return } // getAllDataByMongo // @Description: 从mongo获取指标的所有数据 // @author: Roc // @datetime 2024-05-07 15:18:53 // @param edbInfoId int // @param source int // @param subSource int // @param startDataTime string // @return dataList []*data_manage.EdbData // @return err error func getAllDataByMongo(edbInfoId, source, subSource int, startDataTime string) (dataList []*EdbData, err error) { dataList = make([]*EdbData, 0) mogDataObj := mgo.EdbDataBusiness{} // 构建查询条件 queryConditions := bson.M{ "edb_info_id": edbInfoId, } // 开始日期 dateCondition, err := mgo.BuildDateCondition(startDataTime, "") if err != nil { return } if len(dateCondition) > 0 { queryConditions["data_time"] = dateCondition } // 获取列表数据 tmpDataList, tmpErr := mogDataObj.GetAllDataList(queryConditions, []string{"-data_time"}) if tmpErr != nil { err = tmpErr return } for k, v := range tmpDataList { dataList = append(dataList, &EdbData{ EdbDataId: k + 1, EdbInfoId: v.EdbInfoId, DataTime: v.DataTime.Format(utils.FormatDate), Value: v.Value, }) } return } // GetEdbClassifyIdListBySource 获取普通指标的分类列表 func GetEdbClassifyIdListBySource(source int) (items []int, err error) { o := global.DmSQL["data"] sql := `SELECT distinct classify_id FROM edb_info WHERE source = ? and edb_info_type=0` err = o.Raw(sql, source).Scan(&items).Error return } // GetEdbInfoByClassifyIdAndSource 用于分类展示 func GetEdbInfoByClassifyIdAndSource(classifyId, edbInfoType, source int) (items []*EdbClassifyItems, err error) { o := global.DmSQL["data"] sql := ` SELECT edb_info_id,classify_id,edb_name AS classify_name,edb_name_en AS classify_name_en,unique_code,source_name,source,sys_user_id,sys_user_real_name,start_date,edb_code,edb_type, sort,is_join_permission FROM edb_info WHERE classify_id = ? AND edb_info_type = ? AND source =?` pars := []interface{}{classifyId, edbInfoType, source} sql += ` order by sort asc,edb_info_id asc ` err = o.Raw(sql, pars...).Scan(&items).Error return } type ReplaceEdbInfoItem struct { OldEdbInfo *EdbInfo NewEdbInfo *EdbInfo } type EdbInfoEditRecord struct { EdbInfoId int `description:"指标ID"` EdbName string `description:"指标名称"` Frequency string `description:"频率"` Unit string `description:"单位"` ClassifyId int `description:"分类id"` CalculateFormula string `description:"计算公式"` OperateUserId int `description:"操作人id"` OperateUserRealName string `description:"操作人姓名"` } func ModifyEdbInfoBaseTimeById(edbInfoId int, cTime time.Time) (err error) { o := global.DmSQL["data"] // 更新修改时间 sql := ` UPDATE edb_info SET base_modify_time = ? WHERE edb_info_id = ? ` err = o.Exec(sql, cTime, edbInfoId).Error return } func GetEdbInfoFieldList(cond string, pars []interface{}, fields []string) (items []*EdbInfo, err error) { field := " * " if len(fields) > 0 { field = strings.Join(fields, ",") } o := global.DmSQL["data"] sql := fmt.Sprintf(`SELECT %s FROM edb_info WHERE 1=1 %s `, field, cond) err = o.Raw(sql, pars...).Scan(&items).Error return } // EdbInfoExtra 指标额外数据-extra字段 type EdbInfoExtra struct { ApiExtraPars string `description:"API-额外参数(如同花顺日期序列)"` } func GetEdbInfoListByCond(condition string, pars []interface{}) (list []*EdbInfoList, err error) { sql := ` SELECT * FROM edb_info WHERE 1=1 ` if condition != "" { sql += condition } sql += ` ORDER BY create_time DESC ` err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error return } func GetThsHfEdbInfoMaxAndMinInfoByMongo(source, subSource int, edbCode string) (item *EdbInfoMaxAndMinInfo, err error) { mogDataObj := new(mgo.EdbDataThsHf) pipeline := []bson.M{ {"$match": bson.M{"edb_code": edbCode}}, {"$group": bson.M{ "_id": nil, "min_date": bson.M{"$min": "$data_time"}, "max_date": bson.M{"$max": "$data_time"}, "min_value": bson.M{"$min": "$value"}, "max_value": bson.M{"$max": "$value"}, }}, {"$project": bson.M{"_id": 0}}, // 可选,如果不需要_id字段 } result, err := mogDataObj.GetEdbInfoMaxAndMinInfo(pipeline) if err != nil { fmt.Println("EdbDataThsHf getEdbDataThsHfList Err:" + err.Error()) return } if !result.MaxDate.IsZero() { whereQuery := bson.M{"edb_code": edbCode, "data_time": result.MaxDate} selectParam := bson.D{{"value", 1}, {"_id", 0}} latestValue, tmpErr := mogDataObj.GetLatestValue(whereQuery, selectParam) if tmpErr != nil { err = tmpErr return } result.LatestValue = latestValue.Value result.EndValue = latestValue.Value } item = &EdbInfoMaxAndMinInfo{ MinDate: result.MinDate.Format(utils.FormatDate), MaxDate: result.MaxDate.Format(utils.FormatDate), MinValue: result.MinValue, MaxValue: result.MaxValue, LatestValue: result.LatestValue, } return } func getThsHfAllDataByMongo(edbInfoId, source, subSource int, startDataTime string) (dataList []*EdbData, err error) { dataList = make([]*EdbData, 0) mogDataObj := mgo.EdbDataThsHf{} // 构建查询条件 queryConditions := bson.M{ "edb_info_id": edbInfoId, } // 开始日期 dateCondition, err := mgo.BuildDateCondition(startDataTime, "") if err != nil { return } if len(dateCondition) > 0 { queryConditions["data_time"] = dateCondition } // 获取列表数据 tmpDataList, tmpErr := mogDataObj.GetAllDataList(queryConditions, []string{"-data_time"}) if tmpErr != nil { err = tmpErr return } for k, v := range tmpDataList { dataList = append(dataList, &EdbData{ EdbDataId: k + 1, EdbInfoId: v.EdbInfoId, DataTime: v.DataTime.Format(utils.FormatDate), Value: v.Value, }) } return } // GetEdbInfoByTypes 根据类型获取所有指标 func GetEdbInfoByTypes(edbInfoType, edbType int) (items []*EdbClassifyItems, err error) { o := global.DmSQL["data"] sql := `SELECT edb_info_id,classify_id,edb_name_source AS classify_name,edb_name_en AS classify_name_en,unique_code,source_name,source,sys_user_id,sys_user_real_name,start_date,edb_code,edb_type FROM edb_info WHERE edb_info_type = ? AND edb_type = ? order by sort asc,edb_info_id asc` err = o.Raw(sql, edbInfoType, edbType).Scan(&items).Error return } // GetIsJoinPermissionEdbInfoIdList // @Description: 获取已经加入指标管控的指标id列表 // @param edbInfoType // @param edbType // @return list // @return err func GetIsJoinPermissionEdbInfoIdList(edbInfoType, edbType int) (list []int, err error) { pars := make([]interface{}, 0) sql := ` SELECT edb_info_id FROM edb_info WHERE 1=1 AND is_join_permission = 1 ` if edbInfoType >= 0 { sql += ` AND edb_info_type = ? ` pars = append(pars, edbInfoType) } if edbInfoType > 0 { sql += ` AND edb_type = ? ` pars = append(pars, edbType) } sql += ` ORDER BY create_time DESC ` err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error return }