package erms3 import ( "encoding/hex" "encoding/json" "math" "mtp2_if/db" "mtp2_if/global/app" "mtp2_if/global/e" "mtp2_if/logger" "mtp2_if/models" "mtp2_if/utils" "net/http" "strconv" "strings" "time" "github.com/gin-gonic/gin" ) // spotContract.go 现货合同 // RecordUtcCount UTC计数(毫秒) var RecordUtcCount int = 0 // SecondCount 秒计数 var SecondCount int = 0 // SpotPriceOrder 定价明细 type SpotPriceOrder struct { Price float64 `json:"price" binding:"required"` // 价格 Qty float64 `json:"qty" binding:"required"` // 数量 Amount float64 `json:"amount" binding:"required"` // 金额 } // SpotPointOrder 点价明细 type SpotPointOrder struct { GoodsID int32 `json:"goodsid" binding:"required"` // 商品ID GoodsName string `json:"goodsname"` // 商品名称 Qty float64 `json:"qty" binding:"required"` // 数量 Basic float64 `json:"basic" binding:"required"` // 基差 StartDate string `json:"startdate" binding:"required"` // 点价开始日期 EndDate string `json:"enddate" binding:"required"` // 点价结束日期 } // SoptContractDetail 合同明细信息 type SoptContractDetail struct { WrStandardID int64 `json:"wrstandardid" binding:"required"` // 交易标的ID WrStandardName string `json:"wrstandardname" binding:"required"` // 交易标的名称 ProductType int32 `json:"producttype" binding:"required"` // 产品类型 1:标准仓单 2:等标 3:非标 ProductTypeName string `json:"producttypename"` // 产品类型名称 DeliveryGoodsID int32 `json:"deliverygoodsid" binding:"required"` // 现货品种ID DeliveryGoodsName string `json:"deliverygoodsname"` // 现货品种名称 DeliveryGoodsDesc string `json:"deliverygoodsdesc"` // 现货品种说明 WarehouseID int32 `json:"warehouseid" binding:"required"` // 仓库ID WarehouseName int32 `json:"warehousename"` // 仓库名称 UnitName string `json:"unitname" binding:"required"` // 单位名称 PointDesc string `json:"pointdesc"` // 点价描述 SpotPriceOrderList []SpotPriceOrder `json:"spotPriceOrderList"` // 定价列表 SpotPointOrderVoList []SpotPointOrder `json:"spotPointOrderVoList"` // 点价列表 } // SoptContractDetailSum 合同明细信息汇总(组织JSON使用) type SoptContractDetailSum struct { WrStandardID int64 `json:"wrstandardid" binding:"required"` // 交易标的ID WrStandardName string `json:"wrstandardname" binding:"required"` // 交易标的名称 ProductType int32 `json:"producttype" binding:"required"` // 产品类型 1:标准仓单 2:等标 3:非标 ProductTypeName string `json:"producttypename"` // 产品类型名称 DeliveryGoodsID int32 `json:"deliverygoodsid" binding:"required"` // 现货品种ID DeliveryGoodsName string `json:"deliverygoodsname"` // 现货品种名称 DeliveryGoodsDesc string `json:"deliverygoodsdesc"` // 现货品种说明 WarehouseID int32 `json:"warehouseid" binding:"required"` // 仓库ID WarehouseName int32 `json:"warehousename"` // 仓库名称 UnitName string `json:"unitname" binding:"required"` // 单位名称 PointDesc string `json:"pointdesc"` // 点价描述 SpotPriceOrderList []SpotPriceOrder `json:"spotPriceOrderList"` // 定价列表 SpotPointOrderVoList []SpotPointOrder `json:"spotPointOrderVoList"` // 点价列表 TotalPriceOrderQty float64 `json:"totalPriceOrderQty"` // 定价总数量 TotalPriceOrderPrice float64 `json:"totalPriceOrderPrice"` // 定价总价格 TotalPriceOrderAmount float64 `json:"totalPriceOrderAmount"` // 定价总金额 TotalPointOrderQty float64 `json:"totalPointOrderQty"` // 点价总数量 TotalQty float64 `json:"totalQty"` // 总数量 } // AddSpotContractApplyReq 新增现货合同申请请求 type AddSpotContractApplyReq struct { ContractNo string `json:"contractno" binding:"required"` // 现货合同编号 ContractType int32 `json:"contracttype" binding:"required"` // 现货合同类型 - 1:采购 -1:销售 AreaUserID int32 `json:"areauserid" binding:"required"` // 所属机构 AccountID int64 `json:"accountid" binding:"required"` // 资金账户ID CustomerUserID int32 `json:"customeruserid" binding:"required"` // 客户ID CustomerAccountID int64 `json:"customeraccountid" binding:"required"` // 客户资金账户ID SignDate time.Time `json:"signdate" binding:"required"` // 签订日期 LastDate time.Time `json:"lastdate" binding:"required"` // 交货时间 ContractAttachment string `json:"contractattachment"` // 合同附件 OriMarginPayer int32 `json:"orimarginpayer" binding:"required"` // 初始保证金支付方 -1:买方 2:卖方 OriMargin float64 `json:"orimargin" binding:"required"` // 初始保证金 Remark string `json:"remark"` // 备注 MarketID int32 `json:"marketid" binding:"required"` // 市场ID CreatorID int32 `json:"creatorid"` // 申请人 Details []SoptContractDetail `json:"details" binding:"required"` // 明细 } // AddSpotContractApplyRsp 新增现货合同申请响应 type AddSpotContractApplyRsp struct { SpotContractID int64 `json:"spotcontractid" binging:"required"` // 现货合同ID(345+Unix秒时间戳(10位)+xxxxxx) ContractNo string `json:"contractno" binding:"required"` // 现货合同编号 } // AddSpotContractApply 新增现货合同申请 // @Summary 新增现货合同申请 // @Produce json // @Security ApiKeyAuth // @Param jsonBody body AddSpotContractApplyReq true "申请参数" // @Success 200 {object} AddSpotContractApplyRsp // @Failure 500 {object} app.Response // @Router /Erms3/AddSpotContractApply [post] // @Tags 风险管理v3 func AddSpotContractApply(c *gin.Context) { appG := app.Gin{C: c} // 获取请求参数 var req AddSpotContractApplyReq err := appG.C.ShouldBindJSON(&req) if err != nil { logger.GetLogger().Errorf("AddSpotContractApply failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil) return } // 生成申请ID spotcontractid := GenSpotContractID() // 获取当前交易日 tradedate, err := GetMarketTradeDate(int(req.MarketID)) if err != nil { // 返回失败 logger.GetLogger().Errorf("AddSpotContractApply get market trade date failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil) return } // 根据明细,生成JSON信息 detailjson, err := BuildDetailJSON(req.Details) if err != nil { // 返回失败 logger.GetLogger().Errorf("AddSpotContractApply build detail json failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil) return } // 组建现货合同申请内容 spotContractApply := models.Erms3SpotContractApply{ SpotContractID: spotcontractid, TradeDate: tradedate, ContractNo: req.ContractNo, ContractType: req.ContractType, AreaUserID: req.AreaUserID, AccountID: req.AccountID, CustomerUserID: req.CustomerUserID, CustomerAccountID: req.CustomerAccountID, SignDate: req.SignDate, LastDate: req.LastDate, ContractAttachment: req.ContractAttachment, OriMarginPayer: req.OriMarginPayer, OriMargin: req.OriMargin, Remark: req.Remark, DetailJSON: detailjson, ApplyStatus: 0, ApplySrc: 2, MarketID: req.MarketID, CreatorID: req.CreatorID, } // 调用接口,插入现货合同申请信息 if err := models.AddSpotContractApply(spotContractApply); err != nil { // 插入失败 logger.GetLogger().Errorf("AddSpotContractApply failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil) return } // 组织响应信息 rsp := AddSpotContractApplyRsp{ SpotContractID: spotcontractid, ContractNo: req.ContractNo, } // 插入成功 logger.GetLogger().Debugln("AddSpotContractApply successed: %v", rsp) appG.Response(http.StatusOK, e.SUCCESS, rsp) } // GenSpotContractID 生成现货合同ID func GenSpotContractID() int64 { // 获取当前时间 cur := time.Now() // UnitNano获取的是纳秒,除以1000000获取毫秒级的时间戳 timestamp := cur.UnixNano() / 1000000 // 除以1000获取秒级的时间戳 var curutc int = int(timestamp / 1000) if RecordUtcCount == curutc { SecondCount = SecondCount + 1 } else { RecordUtcCount = curutc SecondCount = 1 } var id int64 = int64(345)*int64(math.Pow(10, 16)) + int64(RecordUtcCount)*int64(math.Pow(10, 6)) + int64(SecondCount) return id } // GetMarketTradeDate 获取市场交易日 func GetMarketTradeDate(marketid int) (string, error) { marketrun, err := models.GetMarketRun(marketid) if err != nil { return "", err } return marketrun.Tradedate, nil } // BuildDetailJSON 组件合同明细JSON func BuildDetailJSON(details []SoptContractDetail) (string, error) { detailsums := make([]SoptContractDetailSum, 0) for _, detail := range details { var totalpriceorderqty float64 = 0 var totalpriceorderprice float64 = 0 var totalpriceorderamount float64 = 0 var totalpointorderqty float64 = 0 var totalqty float64 = 0 for _, spotpriceorder := range detail.SpotPriceOrderList { totalpriceorderqty = totalpriceorderqty + spotpriceorder.Qty totalpriceorderprice = totalpriceorderprice + spotpriceorder.Price totalpriceorderamount = totalpriceorderamount + spotpriceorder.Amount } for _, spotpointorder := range detail.SpotPointOrderVoList { totalpointorderqty = totalpointorderqty + spotpointorder.Qty } totalqty = totalpriceorderqty + totalpointorderqty var detailsum SoptContractDetailSum detailsum = SoptContractDetailSum{ WrStandardID: detail.WrStandardID, WrStandardName: detail.WrStandardName, ProductType: detail.ProductType, ProductTypeName: detail.ProductTypeName, DeliveryGoodsID: detail.DeliveryGoodsID, DeliveryGoodsName: detail.DeliveryGoodsName, DeliveryGoodsDesc: detail.DeliveryGoodsDesc, WarehouseID: detail.WarehouseID, WarehouseName: detail.WarehouseName, UnitName: detail.UnitName, PointDesc: detail.PointDesc, SpotPriceOrderList: detail.SpotPriceOrderList, SpotPointOrderVoList: detail.SpotPointOrderVoList, TotalPriceOrderQty: totalpriceorderqty, TotalPriceOrderPrice: totalpriceorderprice, TotalPriceOrderAmount: totalpriceorderamount, TotalPointOrderQty: totalpointorderqty, TotalQty: totalqty, } detailsums = append(detailsums, detailsum) } jsoninfo, err := json.Marshal(detailsums) if err != nil { return "", err } return string(jsoninfo), nil } // QuerySpotContractAppleFormReq 查询合同申请表单数据请求参数 type QuerySpotContractAppleFormReq struct { UserID int `form:"userID" binding:"required"` } // CustomerInfo 申请单账号信息 type CustomerInfo struct { Userid int64 `json:"userid" binding:"required"` // 用户ID Customername string `json:"customername"` // 名称(企业名称) Mobile string `json:"mobile"` // 手机号码 AccountIDs []int `json:"accountids"` // 资金账户ID列表 } // QuerySpotContractAppleFormRsp 查询合同申请表单数据返回模型 type QuerySpotContractAppleFormRsp struct { OurUser CustomerInfo `json:"ouruser"` // 我方账号 OppositeUsers []CustomerInfo `json:"oppositeusers"` // 对方账号列表 WrStandards []models.Wrstandard `json:"wrstandards"` // 仓单标准列表 WareHouseInfos []models.Warehouseinfo `json:"warehouseinfos"` // 仓库信息列表 Goodses []models.GoodsIDAndName `json:"goodses"` // 合约列表 } // QuerySpotContractAppleForm 查询合同申请表单数据 // @Summary 查询合同申请表单数据 // @Produce json // @Security ApiKeyAuth // @Param userID query int true "用户ID" // @Success 200 {object} QuerySpotContractAppleFormRsp // @Failure 500 {object} app.Response // @Router /Erms3/QuerySpotContractAppleForm [get] // @Tags 风险管理v3 func QuerySpotContractAppleForm(c *gin.Context) { appG := app.Gin{C: c} // 获取请求参数 var req QuerySpotContractAppleFormReq err := appG.C.ShouldBindQuery(&req) if err != nil { logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil) return } rsp := QuerySpotContractAppleFormRsp{} // 获取我方用户信息 ourUser, err := models.GetUserInfo(req.UserID) if err != nil { // 查询失败 logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } rsp.OurUser.Userid = ourUser.Userid rsp.OurUser.Customername = ourUser.Customername key, _ := hex.DecodeString(utils.AESSecretKey) if len(ourUser.Mobile) > 0 { // 手机号码解密 if phonenum, err := hex.DecodeString(ourUser.Mobile); err == nil { // hex -> []byte if mobile, err := utils.AESDecrypt(phonenum, key); err == nil { rsp.OurUser.Mobile = string(mobile) } } } taAccounts, err := models.GetTaAccountsByType(req.UserID, 3) // 获取内部资金账户,现货都使用内部资金账户 if err != nil { // 查询失败 logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } rsp.OurUser.AccountIDs = make([]int, 0) for _, v := range taAccounts { rsp.OurUser.AccountIDs = append(rsp.OurUser.AccountIDs, int(v.Accountid)) } // 获取客户信息 oppositeUsers, err := models.GetUsersByUserType(6) if err != nil { // 查询失败 logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } rsp.OppositeUsers = make([]CustomerInfo, 0) for _, v := range oppositeUsers { // 把自己过滤掉 if int(v.Userid) == req.UserID { continue } userInfo := CustomerInfo{} userInfo.Userid = v.Userid userInfo.Customername = v.Customername if len(v.Mobile) > 0 { // 手机号码解密 if phonenum, err := hex.DecodeString(v.Mobile); err == nil { // hex -> []byte if mobile, err := utils.AESDecrypt(phonenum, key); err == nil { userInfo.Mobile = string(mobile) } } } // 获取客户的资金账户列表 opposTaAccounts, err := models.GetTaAccountsByType(int(v.Userid), 3) // 获取内部资金账户,现货都使用内部资金账户 if err != nil { // 查询失败 logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } userInfo.AccountIDs = make([]int, 0) for _, v := range opposTaAccounts { userInfo.AccountIDs = append(userInfo.AccountIDs, int(v.Accountid)) } rsp.OppositeUsers = append(rsp.OppositeUsers, userInfo) } // 获取交易标的(仓单标准) rsp.WrStandards = make([]models.Wrstandard, 0) wrStandards, err := models.GetWrstandards() if err != nil { // 查询失败 logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } rsp.WrStandards = wrStandards // 获取仓库信息 rsp.WareHouseInfos = make([]models.Warehouseinfo, 0) wareHouseInfos, err := models.GetWareHouseinfos() if err != nil { // 查询失败 logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } rsp.WareHouseInfos = wareHouseInfos // 获取合约信息 rsp.Goodses = make([]models.GoodsIDAndName, 0) goodses, err := models.GetGoodsInfosByTradeModes("15") if err != nil { // 查询失败 logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } rsp.Goodses = goodses // 查询成功 logger.GetLogger().Debugln("QuerySpotContractAppleForm successed: %v", rsp) appG.Response(http.StatusOK, e.SUCCESS, rsp) } // QuerySpotContractInfoReq 查询合同明细请求. type QuerySpotContractInfoReq struct { Accountids string `form:"accountids" binding:"required"` // 资金账号ID列表,逗号分隔. ContractType int32 `form:"contracttype" binding:"required"` // 合同类型,1-采购合同 2-销售合同. ContractMode int32 `form:"contractmode" binding:"required"` // 合同模式,1-普通合同 2-回购销售合同. Status int32 `form:"status"` // 合同状态,0-履约中 1-已完成. } // QuerySpotContractInfoRsp 查询合同明细响应. type QuerySpotContractInfoRsp struct { SpotContractID string `json:"spotcontractid"` // 合同ID CustomerName string `json:"customername"` // 若合同类型为采购合同,表示采购方ID;若合同类型为销售合同,表示销售方ID. AccountID int64 `json:"accountid"` // 表示交易员ID. MatchCustomerName string `json:"matchcustomername"` // 若合同类型为采购合同,表示销售方;若合同类型为销售合同,表示采购方ID. MatchAccountID int64 `json:"matchaccountid"` // 表示业务员ID. WRStandardName string `json:"wrstandardname"` // 表示商品ID. TotalQty float64 `json:"totalqty"` // 表示合同量. PricedQty float64 `json:"priceqty"` // 表示定价量. UnPricedQty float64 `json:"unpricedqty"` // 表示未定价量. DeliveryQty float64 `json:"deliveryqty"` // 表示交收量. CurDeliveryQty float64 `json:"curdeliveryqty"` // 表示未交收量. SignDate string `json:"signdate"` // 表示签订日期. DeliveryGoodsID string `json:"deliverygoodsid"` // 表示品种ID. RelatedBizID string `json:"relatedbizid"` // 表示业务ID. Status int32 `json:"status"` // 表示状态,0-履约中 1-已完成. } // QuerySpotContractDetail 查询合同详细信息. // @Summary 查询合同详细信息 // @Produce json // @Security ApiKeyAuth // @Param accountids query string true "资金账号ID列表,用逗号分隔" // @Param contracttype query int true "合同类型,1-采购合同 2-销售合同" // @Param contractmode query int true "合同模式,1-普通合同 2-回购销售合同" // @Param status query int true "状态,0-履约中 1-已完成" // @Success 200 {array} QuerySpotContractInfoRsp // @Failure 500 {object} app.Response // @Router /Erms3/QuerySpotContractDetail [get] // @Tags 风险管理v3 func QuerySpotContractDetail(c *gin.Context) { appG := app.Gin{C: c} // 获取请求参数 var req QuerySpotContractInfoReq err := appG.C.ShouldBindQuery(&req) if err != nil { logger.GetLogger().Errorf("QuerySpotContractDetail failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil) return } strids := strings.Split(strings.TrimSpace(req.Accountids), ",") accountids := make([]int64, len(strids)) for i := range strids { accountids[i], err = strconv.ParseInt(strids[i], 10, 64) if err != nil { logger.GetLogger().Errorf("ParseInt failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil) return } } // 查询数据. type spotContractDetail struct { models.Erms3Spotcontractdetail `xorm:"extends"` Areauserid int64 `json:"areauserid" xorm:"AREAUSERID"` // 所属机构 Accountid int64 `json:"accountid" xorm:"ACCOUNTID"` // 资金账户ID Customeruserid int64 `json:"customeruserid" xorm:"CUSTOMERUSERID"` // 客户ID Customeraccountid int64 `json:"customeraccountid" xorm:"CUSTOMERACCOUNTID"` // 客户资金账户ID Signdate time.Time `json:"signdate" xorm:"SIGNDATE"` // 签订日期 Closestatus int32 `json:"closestatus" xorm:"CLOSESTATUS"` // 完结状态 - 0:未完结 1:已完结 Relatedbizid string `json:"relatedbizid" xorm:"RELATEDBIZID"` // 关联业务ID Goodunit string `json:"goodunit" xorm:"'GOODUNIT'"` // 报价单位 Wrstandardcode string `json:"wrstandardcode" xorm:"'WRSTANDARDCODE'"` // 仓单标准代码 Wrstandardname string `json:"wrstandardname" xorm:"'WRSTANDARDNAME'"` // 仓单标准名称 Deliverygoodscode string `json:"deliverygoodscode" xorm:"'DELIVERYGOODSCODE'"` // 交割商品代码 Deliverygoodsname string `json:"deliverygoodsname" xorm:"'DELIVERYGOODSNAME'"` // 交割商品名称 } datas := make([]spotContractDetail, 0) engine := db.GetEngine() s := engine.Table("ERMS3_SPOTCONTRACTDETAIL"). Join("LEFT", "ERMS3_SPOTCONTRACT", "ERMS3_SPOTCONTRACTDETAIL.SPOTCONTRACTID = ERMS3_SPOTCONTRACT.SPOTCONTRACTID"). Join("LEFT", "ERMS3_BIZTRADEDETAIL", "ERMS3_BIZTRADEDETAIL.SPOTDETAILID = ERMS3_SPOTCONTRACTDETAIL.SPOTDETAILID"). Join("LEFT", "WRSTANDARD", "WRSTANDARD.WRSTANDARDID = ERMS3_SPOTCONTRACTDETAIL.WRSTANDARDID"). Join("LEFT", "DELIVERYGOODS", "DELIVERYGOODS.DELIVERYGOODSID = WRSTANDARD.DELIVERYGOODSID"). Join("LEFT", "ENUMDICITEM", "WRSTANDARD.UNITID = ENUMDICITEM.ENUMITEMNAME AND ENUMDICITEM.ENUMDICCODE = 'goodsunit'"). Select(`to_char(ERMS3_SPOTCONTRACTDETAIL.SPOTCONTRACTID) SPOTCONTRACTID, ERMS3_SPOTCONTRACT.AREAUSERID, ERMS3_SPOTCONTRACT.ACCOUNTID, ERMS3_SPOTCONTRACT.CUSTOMERUSERID, ERMS3_SPOTCONTRACT.CUSTOMERACCOUNTID, ERMS3_SPOTCONTRACT.CLOSESTATUS, ERMS3_SPOTCONTRACT.SIGNDATE, ERMS3_SPOTCONTRACTDETAIL.*, WRSTANDARD.WRSTANDARDNAME, WRSTANDARD.WRSTANDARDCODE, DELIVERYGOODS.DELIVERYGOODSNAME, DELIVERYGOODS.DELIVERYGOODSCODE, to_char(ERMS3_BIZTRADEDETAIL.RELATEDBIZID) RELATEDBIZID, ENUMDICITEM.ENUMDICNAME GOODUNIT`). Where("ERMS3_SPOTCONTRACT.CONTRACTTYPE = ? AND ERMS3_SPOTCONTRACT.CONTRACTMODE = ? AND ERMS3_SPOTCONTRACT.CLOSESTATUS = ?", req.ContractType, req.ContractMode, req.Status). In("ERMS3_SPOTCONTRACT.ACCOUNTID", accountids). Desc("ERMS3_SPOTCONTRACTDETAIL.SPOTCONTRACTID") if err := s.Find(&datas); err != nil { // 查询失败 logger.GetLogger().Errorf("QuerySpotContract failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } userids := make(map[int64]struct{}) for i := range datas { userids[datas[i].Areauserid] = struct{}{} userids[datas[i].Customeruserid] = struct{}{} } arrayids := make([]int64, 0, len(userids)) for k, _ :=range userids { arrayids = append(arrayids, k) } // 获取所有用户信息. userinfos, err := models.GetUserInfoByIDS(arrayids) if err != nil { // 查询失败 logger.GetLogger().Errorf("QueryUserInfo failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil) return } userid2names := make(map[int64]string, len(userinfos)) for i := range userinfos { userid2names[userinfos[i].Userid] = userinfos[i].Customername } infos := make([]QuerySpotContractInfoRsp, 0, len(datas)) for i := range datas { infos = append(infos, QuerySpotContractInfoRsp{ SpotContractID: datas[i].Spotcontractid, CustomerName: userid2names[datas[i].Areauserid], AccountID: datas[i].Accountid, MatchCustomerName: userid2names[datas[i].Customeruserid], MatchAccountID: datas[i].Customeraccountid, WRStandardName: strings.Join([]string{datas[i].Wrstandardname, datas[i].Wrstandardcode}, "/"), TotalQty: datas[i].Pricedqty - datas[i].Pricedcancelledqty + datas[i].Unpricedqty - datas[i].Unpricedcancelledqty, PricedQty: datas[i].Pricedqty - datas[i].Pricedcancelledqty, UnPricedQty: datas[i].Unpricedqty - datas[i].Unpricedcancelledqty, DeliveryQty: datas[i].Deliveryqty, CurDeliveryQty: datas[i].Curdeliveryqty, SignDate: datas[i].Signdate.Format("2006-01-02"), DeliveryGoodsID: strings.Join([]string{datas[i].Deliverygoodsname, datas[i].Deliverygoodscode}, "/"), RelatedBizID: datas[i].Relatedbizid, Status: datas[i].Closestatus, }) } // 查询成功 logger.GetLogger().Debugln("QuerySpotContractDetail successed: %v", infos) appG.Response(http.StatusOK, e.SUCCESS, infos) }