/** * @Author: zou.yingbin * @Create : 2021/1/18 9:26 * @Modify : 2021/1/18 9:26 */ package models import ( "fmt" "github.com/golang/protobuf/proto" "mtp2_if/db" "mtp2_if/mtpcache" "mtp2_if/pb" "mtp2_if/rediscli" ) //实时敞口 type ErmcpRealExposureModel struct { MiddleGoodsID uint32 // 套保品种 AreaUserID uint32 // 所属机构 OriBuyPlanQty float64 // 期初采购计划数量 OriBuyPricedQty float64 // 期初采购合同已定价数量 OriSellPlanQty float64 // 期初销售计划数量 OriSellPricedQty float64 // 期初销售合同已定价数量 OriBuyFutureQty uint64 // 期初买入期货数量 OriSellFutureQty uint64 // 期初卖出期货数量 BuyPlanQty float64 // 采购计划数量 BuyPricedQty float64 // 采购合同已定价数量 SellPlanQty float64 // 销售计划数量 SellPricedQty float64 // 销售合同已定价数量 BuyFutureQty float64 // 买入期货数量 SellFutureQty float64 // 卖出期货数量 TotalSpotQty float64 // 现货数量 TotalFutureQty float64 // 期货数量 TotalExposure float64 // 总敞口 TotalHedgeRatio float64 // 敞口比例 TotalNeedHedgeQty float64 // 期货应套保量 NeedHedgeExposoure float64 // 应套保敞口 NeedHedgeRatio float64 // 应套保敞口比例 //************以下需计算或非redis数据************// MiddleGoodsName string // 套保品种名称 MiddleGoodsCode string // 套保品种代码 MiddleGoodsHedgeRatio float64 // 应套保比例 OriTotalSpotQty float64 // 期初现货数量=(期初销售计划数量-期初销售合同已定价数量)-(期初采购计划数量-期初采购合同已定价数量) OriTotalFutuQty uint64 // 期初期货数量=期初买入期货数量-期初卖出期货数量 } // 计算相关字段 func (r *ErmcpRealExposureModel) calc() { r.OriTotalSpotQty = (r.OriSellPlanQty - r.OriSellPricedQty) - (r.OriBuyPlanQty - r.OriBuyPricedQty) r.OriTotalFutuQty = r.OriBuyFutureQty - r.OriSellFutureQty } func (r *ErmcpRealExposureModel) ParseFromProto(v *pb.ErmcpAreaExposure) { r.MiddleGoodsID = *v.MiddleGoodsID r.AreaUserID = *v.AreaUserID r.OriBuyPlanQty = *v.OriBuyPlanQty r.OriBuyPricedQty = *v.OriBuyPricedQty r.OriSellPlanQty = *v.OriSellPlanQty r.OriSellPricedQty = *v.OriSellPricedQty r.OriBuyFutureQty = *v.OriBuyFutureQty r.OriSellFutureQty = *v.OriSellFutureQty r.BuyPlanQty = *v.BuyPlanQty r.BuyPricedQty = *v.BuyPricedQty r.SellPlanQty = *v.SellPlanQty r.SellPricedQty = *v.SellPricedQty r.BuyFutureQty = *v.BuyFutureQty r.SellFutureQty = *v.SellFutureQty r.TotalSpotQty = *v.TotalSpotQty r.TotalFutureQty = *v.TotalFutureQty r.TotalExposure = *v.TotalExposure r.TotalHedgeRatio = *v.TotalHedgeRatio r.TotalNeedHedgeQty = *v.TotalNeedHedgeQty r.NeedHedgeExposoure = *v.NeedHedgeExposoure r.NeedHedgeRatio = *v.NeedHedgeRatio // 执行相关计算 r.calc() } // 实时敞口数据: Redis数据 + 套保品种信息表 func (r *ErmcpRealExposureModel) GetData() ([]ErmcpRealExposureModel, error) { // 获取关联的套路商品 if sGoods, err := mtpcache.GetMiddleGoodsByUserID(r.AreaUserID); err == nil { sData := make([]ErmcpRealExposureModel, 0) // 从Redis获取数据 for i := range sGoods { key := fmt.Sprintf("ErmcpAreaExposure:%d_%d", sGoods[i].AREAUSERID, sGoods[i].MIDDLEGOODSID) if ret, err := rediscli.GetRedisClient().Get(key).Result(); err == nil { if len(ret) > 0 { var data pb.ErmcpAreaExposure if err := proto.Unmarshal([]byte(ret), &data); err == nil { var m ErmcpRealExposureModel m.ParseFromProto(&data) sData = append(sData, m) } } } } return sData, nil } return nil, nil } /*************敞口明细**************/ //敞口明细结构 type ErmcpExposureDetailModel struct { Createtime string `json:"createtime" xorm:"'createtime'"` // 时间 Areauserid uint32 `json:"areauserid" xorm:"'areauserid'"` // 机构ID Logtype int32 `json:"logtype" xorm:"'logtype'"` // 类型 - 1:套保计划 2:现货合同 Contracttype int32 `json:"contracttype" xorm:"'contracttype'"` // 现货合同类型 - 1:采购 -1:销售 Wrstandardid int32 `json:"wrstandardid" xorm:"'wrstandardid'"` // 现货商品ID Qty float64 `json:"qty" xorm:"'qty'"` // 数量 RelateNo string `json:"relateNo" xorm:"'relateNo'"` // 现货合同/套保计划编号 Middlegoodsname string `json:"middlegoodsname" xorm:"'middlegoodsname'"` // 套保商品名称 Middlegoodscode string `json:"middlegoodscode" xorm:"'middlegoodscode'"` // 套保商品代码 MiddlegoodsId int32 `json:"middlegoodsId" xorm:"'middlegoodsId'"` // 套保商品id Unitid int32 `json:"-" xorm:"'unitid'"` // 现货商品单位ID Wrstandardname string `json:"wrstandardname" xorm:"'wrstandardname'"` // 现货商品名称 Wrstandardcode string `json:"wrstandardcode" xorm:"'wrstandardcode'"` // 现货商品代码 Enumdicname string `json:"enumdicname" xorm:"'enumdicname'"` // 现货商品单位名称 ChangeQty float64 `json:"changeQty" xorm:"'changeQty'"` // 套保变动量 Convertfactor float64 `json:"convertfactor" xorm:"'convertfactor'"` // 标仓系数 Convertratio float64 `json:"convertratio" xorm:"'convertratio'"` // 套保系数 } func (r *ErmcpExposureDetailModel) buildSql() string { str := "with tmp as" + " (select 2 as LogType," + " s.spotcontractid as relatedid," + " s.contractno as relateNo" + " from ermcp_spotcontract s" + " union all" + " select 1, t.hedgeplanid as relateid, t.hedgeplanno as relateNo" + " from ermcp_hedgeplan t)" + "select to_char(t.createtime, 'yyyy-mm-dd hh:mi:ss') createtime," + " t.middlegoodsid," + " t.areauserid," + " t.logtype," + " t.contracttype," + " wc.wrstandardid," + " t.qty," + " t.convertfactor," + " t.convertratio," + " t.qty * t.convertfactor * t.convertratio as changeQty," + " tmp.relateNo," + " m.middlegoodsname," + " m.middlegoodscode," + " w.unitid," + " w.wrstandardname," + " w.wrstandardcode," + " e.enumdicname" + " from ermcp_spotexposurelog t" + " left join erms2_wrsconvertdetail wc" + " on t.wrstandardid = wc.wrstandardid" + " and t.middlegoodsid = wc.middlegoodsid" + " left join erms_middlegoods m" + " on t.middlegoodsid = m.middlegoodsid" + " left join wrstandard w" + " on t.wrstandardid = w.wrstandardid" + " left join enumdicitem e" + " on w.unitid = e.enumitemname" + " and e.enumdiccode = 'goodsunit'" + " left join tmp" + " on t.logtype = tmp.LogType" + " and t.relatedid = tmp.relatedid" + " where t.middlegoodsid=%v and t.areauserid=%v" return fmt.Sprintf(str, r.MiddlegoodsId, r.Areauserid) } // 查询敞口现货明细 func (r *ErmcpExposureDetailModel) GetData() ([]ErmcpExposureDetailModel, error) { e := db.GetEngine() s := e.SQL(r.buildSql()) sData := make([]ErmcpExposureDetailModel, 0) if err := s.Find(&sData); err != nil { return nil, err } return sData, nil }