spotContract.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. package erms3
  2. import (
  3. "encoding/hex"
  4. "encoding/json"
  5. "math"
  6. "mtp2_if/db"
  7. "mtp2_if/global/app"
  8. "mtp2_if/global/e"
  9. "mtp2_if/logger"
  10. "mtp2_if/models"
  11. "mtp2_if/utils"
  12. "net/http"
  13. "strconv"
  14. "strings"
  15. "time"
  16. "github.com/gin-gonic/gin"
  17. )
  18. // spotContract.go 现货合同
  19. // RecordUtcCount UTC计数(毫秒)
  20. var RecordUtcCount int = 0
  21. // SecondCount 秒计数
  22. var SecondCount int = 0
  23. // SpotPriceOrder 定价明细
  24. type SpotPriceOrder struct {
  25. Price float64 `json:"price" binding:"required"` // 价格
  26. Qty float64 `json:"qty" binding:"required"` // 数量
  27. Amount float64 `json:"amount" binding:"required"` // 金额
  28. }
  29. // SpotPointOrder 点价明细
  30. type SpotPointOrder struct {
  31. GoodsID int32 `json:"goodsid" binding:"required"` // 商品ID
  32. GoodsName string `json:"goodsname"` // 商品名称
  33. Qty float64 `json:"qty" binding:"required"` // 数量
  34. Basic float64 `json:"basic" binding:"required"` // 基差
  35. StartDate string `json:"startdate" binding:"required"` // 点价开始日期
  36. EndDate string `json:"enddate" binding:"required"` // 点价结束日期
  37. }
  38. // SoptContractDetail 合同明细信息
  39. type SoptContractDetail struct {
  40. WrStandardID int64 `json:"wrstandardid" binding:"required"` // 交易标的ID
  41. WrStandardName string `json:"wrstandardname" binding:"required"` // 交易标的名称
  42. ProductType int32 `json:"producttype" binding:"required"` // 产品类型 1:标准仓单 2:等标 3:非标
  43. ProductTypeName string `json:"producttypename"` // 产品类型名称
  44. DeliveryGoodsID int32 `json:"deliverygoodsid" binding:"required"` // 现货品种ID
  45. DeliveryGoodsName string `json:"deliverygoodsname"` // 现货品种名称
  46. DeliveryGoodsDesc string `json:"deliverygoodsdesc"` // 现货品种说明
  47. WarehouseID int32 `json:"warehouseid" binding:"required"` // 仓库ID
  48. WarehouseName int32 `json:"warehousename"` // 仓库名称
  49. UnitName string `json:"unitname" binding:"required"` // 单位名称
  50. PointDesc string `json:"pointdesc"` // 点价描述
  51. SpotPriceOrderList []SpotPriceOrder `json:"spotPriceOrderList"` // 定价列表
  52. SpotPointOrderVoList []SpotPointOrder `json:"spotPointOrderVoList"` // 点价列表
  53. }
  54. // SoptContractDetailSum 合同明细信息汇总(组织JSON使用)
  55. type SoptContractDetailSum struct {
  56. WrStandardID int64 `json:"wrstandardid" binding:"required"` // 交易标的ID
  57. WrStandardName string `json:"wrstandardname" binding:"required"` // 交易标的名称
  58. ProductType int32 `json:"producttype" binding:"required"` // 产品类型 1:标准仓单 2:等标 3:非标
  59. ProductTypeName string `json:"producttypename"` // 产品类型名称
  60. DeliveryGoodsID int32 `json:"deliverygoodsid" binding:"required"` // 现货品种ID
  61. DeliveryGoodsName string `json:"deliverygoodsname"` // 现货品种名称
  62. DeliveryGoodsDesc string `json:"deliverygoodsdesc"` // 现货品种说明
  63. WarehouseID int32 `json:"warehouseid" binding:"required"` // 仓库ID
  64. WarehouseName int32 `json:"warehousename"` // 仓库名称
  65. UnitName string `json:"unitname" binding:"required"` // 单位名称
  66. PointDesc string `json:"pointdesc"` // 点价描述
  67. SpotPriceOrderList []SpotPriceOrder `json:"spotPriceOrderList"` // 定价列表
  68. SpotPointOrderVoList []SpotPointOrder `json:"spotPointOrderVoList"` // 点价列表
  69. TotalPriceOrderQty float64 `json:"totalPriceOrderQty"` // 定价总数量
  70. TotalPriceOrderPrice float64 `json:"totalPriceOrderPrice"` // 定价总价格
  71. TotalPriceOrderAmount float64 `json:"totalPriceOrderAmount"` // 定价总金额
  72. TotalPointOrderQty float64 `json:"totalPointOrderQty"` // 点价总数量
  73. TotalQty float64 `json:"totalQty"` // 总数量
  74. }
  75. // AddSpotContractApplyReq 新增现货合同申请请求
  76. type AddSpotContractApplyReq struct {
  77. ContractNo string `json:"contractno" binding:"required"` // 现货合同编号
  78. ContractType int32 `json:"contracttype" binding:"required"` // 现货合同类型 - 1:采购 -1:销售
  79. AreaUserID int32 `json:"areauserid" binding:"required"` // 所属机构
  80. AccountID int64 `json:"accountid" binding:"required"` // 资金账户ID
  81. CustomerUserID int32 `json:"customeruserid" binding:"required"` // 客户ID
  82. CustomerAccountID int64 `json:"customeraccountid" binding:"required"` // 客户资金账户ID
  83. SignDate time.Time `json:"signdate" binding:"required"` // 签订日期
  84. LastDate time.Time `json:"lastdate" binding:"required"` // 交货时间
  85. ContractAttachment string `json:"contractattachment"` // 合同附件
  86. OriMarginPayer int32 `json:"orimarginpayer" binding:"required"` // 初始保证金支付方 -1:买方 2:卖方
  87. OriMargin float64 `json:"orimargin" binding:"required"` // 初始保证金
  88. Remark string `json:"remark"` // 备注
  89. MarketID int32 `json:"marketid" binding:"required"` // 市场ID
  90. CreatorID int32 `json:"creatorid"` // 申请人
  91. Details []SoptContractDetail `json:"details" binding:"required"` // 明细
  92. }
  93. // AddSpotContractApplyRsp 新增现货合同申请响应
  94. type AddSpotContractApplyRsp struct {
  95. SpotContractID int64 `json:"spotcontractid" binging:"required"` // 现货合同ID(345+Unix秒时间戳(10位)+xxxxxx)
  96. ContractNo string `json:"contractno" binding:"required"` // 现货合同编号
  97. }
  98. // AddSpotContractApply 新增现货合同申请
  99. // @Summary 新增现货合同申请
  100. // @Produce json
  101. // @Security ApiKeyAuth
  102. // @Param jsonBody body AddSpotContractApplyReq true "申请参数"
  103. // @Success 200 {object} AddSpotContractApplyRsp
  104. // @Failure 500 {object} app.Response
  105. // @Router /Erms3/AddSpotContractApply [post]
  106. // @Tags 风险管理v3
  107. func AddSpotContractApply(c *gin.Context) {
  108. appG := app.Gin{C: c}
  109. // 获取请求参数
  110. var req AddSpotContractApplyReq
  111. err := appG.C.ShouldBindJSON(&req)
  112. if err != nil {
  113. logger.GetLogger().Errorf("AddSpotContractApply failed: %s", err.Error())
  114. appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
  115. return
  116. }
  117. // 生成申请ID
  118. spotcontractid := GenSpotContractID()
  119. // 获取当前交易日
  120. tradedate, err := GetMarketTradeDate(int(req.MarketID))
  121. if err != nil {
  122. // 返回失败
  123. logger.GetLogger().Errorf("AddSpotContractApply get market trade date failed: %s", err.Error())
  124. appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil)
  125. return
  126. }
  127. // 根据明细,生成JSON信息
  128. detailjson, err := BuildDetailJSON(req.Details)
  129. if err != nil {
  130. // 返回失败
  131. logger.GetLogger().Errorf("AddSpotContractApply build detail json failed: %s", err.Error())
  132. appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil)
  133. return
  134. }
  135. // 组建现货合同申请内容
  136. spotContractApply := models.Erms3SpotContractApply{
  137. SpotContractID: spotcontractid,
  138. TradeDate: tradedate,
  139. ContractNo: req.ContractNo,
  140. ContractType: req.ContractType,
  141. AreaUserID: req.AreaUserID,
  142. AccountID: req.AccountID,
  143. CustomerUserID: req.CustomerUserID,
  144. CustomerAccountID: req.CustomerAccountID,
  145. SignDate: req.SignDate,
  146. LastDate: req.LastDate,
  147. ContractAttachment: req.ContractAttachment,
  148. OriMarginPayer: req.OriMarginPayer,
  149. OriMargin: req.OriMargin,
  150. Remark: req.Remark,
  151. DetailJSON: detailjson,
  152. ApplyStatus: 0,
  153. ApplySrc: 2,
  154. MarketID: req.MarketID,
  155. CreatorID: req.CreatorID,
  156. }
  157. // 调用接口,插入现货合同申请信息
  158. if err := models.AddSpotContractApply(spotContractApply); err != nil {
  159. // 插入失败
  160. logger.GetLogger().Errorf("AddSpotContractApply failed: %s", err.Error())
  161. appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil)
  162. return
  163. }
  164. // 组织响应信息
  165. rsp := AddSpotContractApplyRsp{
  166. SpotContractID: spotcontractid,
  167. ContractNo: req.ContractNo,
  168. }
  169. // 插入成功
  170. logger.GetLogger().Debugln("AddSpotContractApply successed: %v", rsp)
  171. appG.Response(http.StatusOK, e.SUCCESS, rsp)
  172. }
  173. // GenSpotContractID 生成现货合同ID
  174. func GenSpotContractID() int64 {
  175. // 获取当前时间
  176. cur := time.Now()
  177. // UnitNano获取的是纳秒,除以1000000获取毫秒级的时间戳
  178. timestamp := cur.UnixNano() / 1000000
  179. // 除以1000获取秒级的时间戳
  180. var curutc int = int(timestamp / 1000)
  181. if RecordUtcCount == curutc {
  182. SecondCount = SecondCount + 1
  183. } else {
  184. RecordUtcCount = curutc
  185. SecondCount = 1
  186. }
  187. var id int64 = int64(345)*int64(math.Pow(10, 16)) + int64(RecordUtcCount)*int64(math.Pow(10, 6)) + int64(SecondCount)
  188. return id
  189. }
  190. // GetMarketTradeDate 获取市场交易日
  191. func GetMarketTradeDate(marketid int) (string, error) {
  192. marketrun, err := models.GetMarketRun(marketid)
  193. if err != nil {
  194. return "", err
  195. }
  196. return marketrun.Tradedate, nil
  197. }
  198. // BuildDetailJSON 组件合同明细JSON
  199. func BuildDetailJSON(details []SoptContractDetail) (string, error) {
  200. detailsums := make([]SoptContractDetailSum, 0)
  201. for _, detail := range details {
  202. var totalpriceorderqty float64 = 0
  203. var totalpriceorderprice float64 = 0
  204. var totalpriceorderamount float64 = 0
  205. var totalpointorderqty float64 = 0
  206. var totalqty float64 = 0
  207. for _, spotpriceorder := range detail.SpotPriceOrderList {
  208. totalpriceorderqty = totalpriceorderqty + spotpriceorder.Qty
  209. totalpriceorderprice = totalpriceorderprice + spotpriceorder.Price
  210. totalpriceorderamount = totalpriceorderamount + spotpriceorder.Amount
  211. }
  212. for _, spotpointorder := range detail.SpotPointOrderVoList {
  213. totalpointorderqty = totalpointorderqty + spotpointorder.Qty
  214. }
  215. totalqty = totalpriceorderqty + totalpointorderqty
  216. var detailsum SoptContractDetailSum
  217. detailsum = SoptContractDetailSum{
  218. WrStandardID: detail.WrStandardID,
  219. WrStandardName: detail.WrStandardName,
  220. ProductType: detail.ProductType,
  221. ProductTypeName: detail.ProductTypeName,
  222. DeliveryGoodsID: detail.DeliveryGoodsID,
  223. DeliveryGoodsName: detail.DeliveryGoodsName,
  224. DeliveryGoodsDesc: detail.DeliveryGoodsDesc,
  225. WarehouseID: detail.WarehouseID,
  226. WarehouseName: detail.WarehouseName,
  227. UnitName: detail.UnitName,
  228. PointDesc: detail.PointDesc,
  229. SpotPriceOrderList: detail.SpotPriceOrderList,
  230. SpotPointOrderVoList: detail.SpotPointOrderVoList,
  231. TotalPriceOrderQty: totalpriceorderqty,
  232. TotalPriceOrderPrice: totalpriceorderprice,
  233. TotalPriceOrderAmount: totalpriceorderamount,
  234. TotalPointOrderQty: totalpointorderqty,
  235. TotalQty: totalqty,
  236. }
  237. detailsums = append(detailsums, detailsum)
  238. }
  239. jsoninfo, err := json.Marshal(detailsums)
  240. if err != nil {
  241. return "", err
  242. }
  243. return string(jsoninfo), nil
  244. }
  245. // QuerySpotContractAppleFormReq 查询合同申请表单数据请求参数
  246. type QuerySpotContractAppleFormReq struct {
  247. UserID int `form:"userID" binding:"required"`
  248. }
  249. // CustomerInfo 申请单账号信息
  250. type CustomerInfo struct {
  251. Userid int64 `json:"userid" binding:"required"` // 用户ID
  252. Customername string `json:"customername"` // 名称(企业名称)
  253. Mobile string `json:"mobile"` // 手机号码
  254. AccountIDs []int `json:"accountids"` // 资金账户ID列表
  255. }
  256. // QuerySpotContractAppleFormRsp 查询合同申请表单数据返回模型
  257. type QuerySpotContractAppleFormRsp struct {
  258. OurUser CustomerInfo `json:"ouruser"` // 我方账号
  259. OppositeUsers []CustomerInfo `json:"oppositeusers"` // 对方账号列表
  260. WrStandards []models.Wrstandard `json:"wrstandards"` // 仓单标准列表
  261. WareHouseInfos []models.Warehouseinfo `json:"warehouseinfos"` // 仓库信息列表
  262. Goodses []models.GoodsIDAndName `json:"goodses"` // 合约列表
  263. }
  264. // QuerySpotContractAppleForm 查询合同申请表单数据
  265. // @Summary 查询合同申请表单数据
  266. // @Produce json
  267. // @Security ApiKeyAuth
  268. // @Param userID query int true "用户ID"
  269. // @Success 200 {object} QuerySpotContractAppleFormRsp
  270. // @Failure 500 {object} app.Response
  271. // @Router /Erms3/QuerySpotContractAppleForm [get]
  272. // @Tags 风险管理v3
  273. func QuerySpotContractAppleForm(c *gin.Context) {
  274. appG := app.Gin{C: c}
  275. // 获取请求参数
  276. var req QuerySpotContractAppleFormReq
  277. err := appG.C.ShouldBindQuery(&req)
  278. if err != nil {
  279. logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error())
  280. appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
  281. return
  282. }
  283. rsp := QuerySpotContractAppleFormRsp{}
  284. // 获取我方用户信息
  285. ourUser, err := models.GetUserInfo(req.UserID)
  286. if err != nil {
  287. // 查询失败
  288. logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error())
  289. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  290. return
  291. }
  292. rsp.OurUser.Userid = ourUser.Userid
  293. rsp.OurUser.Customername = ourUser.Customername
  294. key, _ := hex.DecodeString(utils.AESSecretKey)
  295. if len(ourUser.Mobile) > 0 {
  296. // 手机号码解密
  297. if phonenum, err := hex.DecodeString(ourUser.Mobile); err == nil { // hex -> []byte
  298. if mobile, err := utils.AESDecrypt(phonenum, key); err == nil {
  299. rsp.OurUser.Mobile = string(mobile)
  300. }
  301. }
  302. }
  303. taAccounts, err := models.GetTaAccountsByType(req.UserID, 3) // 获取内部资金账户,现货都使用内部资金账户
  304. if err != nil {
  305. // 查询失败
  306. logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error())
  307. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  308. return
  309. }
  310. rsp.OurUser.AccountIDs = make([]int, 0)
  311. for _, v := range taAccounts {
  312. rsp.OurUser.AccountIDs = append(rsp.OurUser.AccountIDs, int(v.Accountid))
  313. }
  314. // 获取客户信息
  315. oppositeUsers, err := models.GetUsersByUserType(6)
  316. if err != nil {
  317. // 查询失败
  318. logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error())
  319. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  320. return
  321. }
  322. rsp.OppositeUsers = make([]CustomerInfo, 0)
  323. for _, v := range oppositeUsers {
  324. // 把自己过滤掉
  325. if int(v.Userid) == req.UserID {
  326. continue
  327. }
  328. userInfo := CustomerInfo{}
  329. userInfo.Userid = v.Userid
  330. userInfo.Customername = v.Customername
  331. if len(v.Mobile) > 0 {
  332. // 手机号码解密
  333. if phonenum, err := hex.DecodeString(v.Mobile); err == nil { // hex -> []byte
  334. if mobile, err := utils.AESDecrypt(phonenum, key); err == nil {
  335. userInfo.Mobile = string(mobile)
  336. }
  337. }
  338. }
  339. // 获取客户的资金账户列表
  340. opposTaAccounts, err := models.GetTaAccountsByType(int(v.Userid), 3) // 获取内部资金账户,现货都使用内部资金账户
  341. if err != nil {
  342. // 查询失败
  343. logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error())
  344. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  345. return
  346. }
  347. userInfo.AccountIDs = make([]int, 0)
  348. for _, v := range opposTaAccounts {
  349. userInfo.AccountIDs = append(userInfo.AccountIDs, int(v.Accountid))
  350. }
  351. rsp.OppositeUsers = append(rsp.OppositeUsers, userInfo)
  352. }
  353. // 获取交易标的(仓单标准)
  354. rsp.WrStandards = make([]models.Wrstandard, 0)
  355. wrStandards, err := models.GetWrstandards()
  356. if err != nil {
  357. // 查询失败
  358. logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error())
  359. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  360. return
  361. }
  362. rsp.WrStandards = wrStandards
  363. // 获取仓库信息
  364. rsp.WareHouseInfos = make([]models.Warehouseinfo, 0)
  365. wareHouseInfos, err := models.GetWareHouseinfos()
  366. if err != nil {
  367. // 查询失败
  368. logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error())
  369. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  370. return
  371. }
  372. rsp.WareHouseInfos = wareHouseInfos
  373. // 获取合约信息
  374. rsp.Goodses = make([]models.GoodsIDAndName, 0)
  375. goodses, err := models.GetGoodsInfosByTradeModes("15")
  376. if err != nil {
  377. // 查询失败
  378. logger.GetLogger().Errorf("QuerySpotContractAppleForm failed: %s", err.Error())
  379. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  380. return
  381. }
  382. rsp.Goodses = goodses
  383. // 查询成功
  384. logger.GetLogger().Debugln("QuerySpotContractAppleForm successed: %v", rsp)
  385. appG.Response(http.StatusOK, e.SUCCESS, rsp)
  386. }
  387. // QuerySpotContractInfoReq 查询合同明细请求.
  388. type QuerySpotContractInfoReq struct {
  389. Accountids string `form:"accountids" binding:"required"` // 资金账号ID列表,逗号分隔.
  390. ContractType int32 `form:"contracttype" binding:"required"` // 合同类型,1-采购合同 2-销售合同.
  391. ContractMode int32 `form:"contractmode" binding:"required"` // 合同模式,1-普通合同 2-回购销售合同.
  392. Status int32 `form:"status"` // 合同状态,0-履约中 1-已完成.
  393. }
  394. // QuerySpotContractInfoRsp 查询合同明细响应.
  395. type QuerySpotContractInfoRsp struct {
  396. SpotContractID string `json:"spotcontractid"` // 合同ID
  397. CustomerName string `json:"customername"` // 若合同类型为采购合同,表示采购方ID;若合同类型为销售合同,表示销售方ID.
  398. AccountID int64 `json:"accountid"` // 表示交易员ID.
  399. MatchCustomerName string `json:"matchcustomername"` // 若合同类型为采购合同,表示销售方;若合同类型为销售合同,表示采购方ID.
  400. MatchAccountID int64 `json:"matchaccountid"` // 表示业务员ID.
  401. WRStandardName string `json:"wrstandardname"` // 表示商品ID.
  402. TotalQty float64 `json:"totalqty"` // 表示合同量.
  403. PricedQty float64 `json:"priceqty"` // 表示定价量.
  404. UnPricedQty float64 `json:"unpricedqty"` // 表示未定价量.
  405. DeliveryQty float64 `json:"deliveryqty"` // 表示交收量.
  406. CurDeliveryQty float64 `json:"curdeliveryqty"` // 表示未交收量.
  407. SignDate string `json:"signdate"` // 表示签订日期.
  408. DeliveryGoodsID string `json:"deliverygoodsid"` // 表示品种ID.
  409. RelatedBizID string `json:"relatedbizid"` // 表示业务ID.
  410. Status int32 `json:"status"` // 表示状态,0-履约中 1-已完成.
  411. }
  412. // QuerySpotContractDetail 查询合同详细信息.
  413. // @Summary 查询合同详细信息
  414. // @Produce json
  415. // @Security ApiKeyAuth
  416. // @Param accountids query string true "资金账号ID列表,用逗号分隔"
  417. // @Param contracttype query int true "合同类型,1-采购合同 2-销售合同"
  418. // @Param contractmode query int true "合同模式,1-普通合同 2-回购销售合同"
  419. // @Param status query int true "状态,0-履约中 1-已完成"
  420. // @Success 200 {array} QuerySpotContractInfoRsp
  421. // @Failure 500 {object} app.Response
  422. // @Router /Erms3/QuerySpotContractDetail [get]
  423. // @Tags 风险管理v3
  424. func QuerySpotContractDetail(c *gin.Context) {
  425. appG := app.Gin{C: c}
  426. // 获取请求参数
  427. var req QuerySpotContractInfoReq
  428. err := appG.C.ShouldBindQuery(&req)
  429. if err != nil {
  430. logger.GetLogger().Errorf("QuerySpotContractDetail failed: %s", err.Error())
  431. appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
  432. return
  433. }
  434. strids := strings.Split(strings.TrimSpace(req.Accountids), ",")
  435. accountids := make([]int64, len(strids))
  436. for i := range strids {
  437. accountids[i], err = strconv.ParseInt(strids[i], 10, 64)
  438. if err != nil {
  439. logger.GetLogger().Errorf("ParseInt failed: %s", err.Error())
  440. appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
  441. return
  442. }
  443. }
  444. // 查询数据.
  445. type spotContractDetail struct {
  446. models.Erms3Spotcontractdetail `xorm:"extends"`
  447. Areauserid int64 `json:"areauserid" xorm:"AREAUSERID"` // 所属机构
  448. Accountid int64 `json:"accountid" xorm:"ACCOUNTID"` // 资金账户ID
  449. Customeruserid int64 `json:"customeruserid" xorm:"CUSTOMERUSERID"` // 客户ID
  450. Customeraccountid int64 `json:"customeraccountid" xorm:"CUSTOMERACCOUNTID"` // 客户资金账户ID
  451. Signdate time.Time `json:"signdate" xorm:"SIGNDATE"` // 签订日期
  452. Closestatus int32 `json:"closestatus" xorm:"CLOSESTATUS"` // 完结状态 - 0:未完结 1:已完结
  453. Relatedbizid string `json:"relatedbizid" xorm:"RELATEDBIZID"` // 关联业务ID
  454. Goodunit string `json:"goodunit" xorm:"'GOODUNIT'"` // 报价单位
  455. Wrstandardcode string `json:"wrstandardcode" xorm:"'WRSTANDARDCODE'"` // 仓单标准代码
  456. Wrstandardname string `json:"wrstandardname" xorm:"'WRSTANDARDNAME'"` // 仓单标准名称
  457. Deliverygoodscode string `json:"deliverygoodscode" xorm:"'DELIVERYGOODSCODE'"` // 交割商品代码
  458. Deliverygoodsname string `json:"deliverygoodsname" xorm:"'DELIVERYGOODSNAME'"` // 交割商品名称
  459. }
  460. datas := make([]spotContractDetail, 0)
  461. engine := db.GetEngine()
  462. s := engine.Table("ERMS3_SPOTCONTRACTDETAIL").
  463. Join("LEFT", "ERMS3_SPOTCONTRACT", "ERMS3_SPOTCONTRACTDETAIL.SPOTCONTRACTID = ERMS3_SPOTCONTRACT.SPOTCONTRACTID").
  464. Join("LEFT", "ERMS3_BIZTRADEDETAIL", "ERMS3_BIZTRADEDETAIL.SPOTDETAILID = ERMS3_SPOTCONTRACTDETAIL.SPOTDETAILID").
  465. Join("LEFT", "WRSTANDARD", "WRSTANDARD.WRSTANDARDID = ERMS3_SPOTCONTRACTDETAIL.WRSTANDARDID").
  466. Join("LEFT", "DELIVERYGOODS", "DELIVERYGOODS.DELIVERYGOODSID = WRSTANDARD.DELIVERYGOODSID").
  467. Join("LEFT", "ENUMDICITEM", "WRSTANDARD.UNITID = ENUMDICITEM.ENUMITEMNAME AND ENUMDICITEM.ENUMDICCODE = 'goodsunit'").
  468. Select(`to_char(ERMS3_SPOTCONTRACTDETAIL.SPOTCONTRACTID) SPOTCONTRACTID, ERMS3_SPOTCONTRACT.AREAUSERID, ERMS3_SPOTCONTRACT.ACCOUNTID, ERMS3_SPOTCONTRACT.CUSTOMERUSERID,
  469. ERMS3_SPOTCONTRACT.CUSTOMERACCOUNTID, ERMS3_SPOTCONTRACT.CLOSESTATUS, ERMS3_SPOTCONTRACT.SIGNDATE, ERMS3_SPOTCONTRACTDETAIL.*, WRSTANDARD.WRSTANDARDNAME, WRSTANDARD.WRSTANDARDCODE, DELIVERYGOODS.DELIVERYGOODSNAME, DELIVERYGOODS.DELIVERYGOODSCODE,
  470. to_char(ERMS3_BIZTRADEDETAIL.RELATEDBIZID) RELATEDBIZID, ENUMDICITEM.ENUMDICNAME GOODUNIT`).
  471. Where("ERMS3_SPOTCONTRACT.CONTRACTTYPE = ? AND ERMS3_SPOTCONTRACT.CONTRACTMODE = ? AND ERMS3_SPOTCONTRACT.CLOSESTATUS = ?", req.ContractType, req.ContractMode, req.Status).
  472. In("ERMS3_SPOTCONTRACT.ACCOUNTID", accountids).
  473. Desc("ERMS3_SPOTCONTRACTDETAIL.SPOTCONTRACTID")
  474. if err := s.Find(&datas); err != nil {
  475. // 查询失败
  476. logger.GetLogger().Errorf("QuerySpotContract failed: %s", err.Error())
  477. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  478. return
  479. }
  480. userids := make(map[int64]struct{})
  481. for i := range datas {
  482. userids[datas[i].Areauserid] = struct{}{}
  483. userids[datas[i].Customeruserid] = struct{}{}
  484. }
  485. arrayids := make([]int64, 0, len(userids))
  486. for k, _ :=range userids {
  487. arrayids = append(arrayids, k)
  488. }
  489. // 获取所有用户信息.
  490. userinfos, err := models.GetUserInfoByIDS(arrayids)
  491. if err != nil {
  492. // 查询失败
  493. logger.GetLogger().Errorf("QueryUserInfo failed: %s", err.Error())
  494. appG.Response(http.StatusBadRequest, e.ERROR_QUERY_FAIL, nil)
  495. return
  496. }
  497. userid2names := make(map[int64]string, len(userinfos))
  498. for i := range userinfos {
  499. userid2names[userinfos[i].Userid] = userinfos[i].Customername
  500. }
  501. infos := make([]QuerySpotContractInfoRsp, 0, len(datas))
  502. for i := range datas {
  503. infos = append(infos, QuerySpotContractInfoRsp{
  504. SpotContractID: datas[i].Spotcontractid,
  505. CustomerName: userid2names[datas[i].Areauserid],
  506. AccountID: datas[i].Accountid,
  507. MatchCustomerName: userid2names[datas[i].Customeruserid],
  508. MatchAccountID: datas[i].Customeraccountid,
  509. WRStandardName: strings.Join([]string{datas[i].Wrstandardname, datas[i].Wrstandardcode}, "/"),
  510. TotalQty: datas[i].Pricedqty - datas[i].Pricedcancelledqty + datas[i].Unpricedqty - datas[i].Unpricedcancelledqty,
  511. PricedQty: datas[i].Pricedqty - datas[i].Pricedcancelledqty,
  512. UnPricedQty: datas[i].Unpricedqty - datas[i].Unpricedcancelledqty,
  513. DeliveryQty: datas[i].Deliveryqty,
  514. CurDeliveryQty: datas[i].Curdeliveryqty,
  515. SignDate: datas[i].Signdate.Format("2006-01-02"),
  516. DeliveryGoodsID: strings.Join([]string{datas[i].Deliverygoodsname, datas[i].Deliverygoodscode}, "/"),
  517. RelatedBizID: datas[i].Relatedbizid,
  518. Status: datas[i].Closestatus,
  519. })
  520. }
  521. // 查询成功
  522. logger.GetLogger().Debugf("QuerySpotContractDetail successed: %v", infos)
  523. appG.Response(http.StatusOK, e.SUCCESS, infos)
  524. }