commonModels.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. package models
  2. import (
  3. "errors"
  4. "fmt"
  5. "mtp2_if/db"
  6. "mtp2_if/dbmodels"
  7. "mtp2_if/global/utils"
  8. "strconv"
  9. "strings"
  10. )
  11. // QuotePrimaryMenu 报价牌一级分类菜单
  12. type QuotePrimaryMenu struct {
  13. Index int `json:"Index"` // 序号
  14. Key string `json:"Key"` // 键名
  15. Name string `json:"Name"` // 菜单名称
  16. SubTitleType int `json:"SubTitleType"` // 子菜单标题模式:0-市场名称;1-外部交易所名称
  17. TradeModes string `json:"TradeModes"` // 包含市场交易类型
  18. SubMenus []QuoteSecondaryMenu `json:"SubMenus"` // 子菜单
  19. }
  20. // QuoteSecondaryMenu 报价牌二级分类菜单
  21. type QuoteSecondaryMenu struct {
  22. Index int `json:"Index"` // 序号
  23. MarketID int `json:"MarketID"` // 市场ID
  24. TradeMode int `json:"TradeMode"` // 交易模式
  25. MenuTitle string `json:"MenuTitle" xorm:"'ExExchangeName'"` // 菜单标题(市场名称或外部交易所名称)
  26. GoodsGroupIDs []int `json:"GoodsGroupIDs"` // 商品组ID列表
  27. ExExchangeID int `json:"ExExchangeID" xorm:"'ExExchangeID'"` // 外部交易所ID
  28. ExExchangeCode string `json:"ExExchangeCode" xorm:"'ExExchangeCode'"` // 外部交易所代码
  29. }
  30. // OperationPrimaryMenu 一级功能菜单
  31. type OperationPrimaryMenu struct {
  32. Key string `json:"Key"` // 菜单KEY
  33. Label string `json:"Label"` // 菜单标题
  34. Children []OperationSecondaryMenu `json:"Children"` // 二级功能菜单
  35. }
  36. // OperationSecondaryMenu 二级功能菜单
  37. type OperationSecondaryMenu struct {
  38. Key string `json:"Key"` // 菜单KEY
  39. Label string `json:"Label"` // 菜单标题
  40. TabList []OperationTabMenu `json:"TabList"` // 三级功能菜单
  41. }
  42. // OperationTabMenu 三级功能菜单
  43. type OperationTabMenu struct {
  44. Key string `json:"Key"` // 菜单KEY
  45. Label string `json:"Label"` // 菜单标题
  46. }
  47. // GetQuoteMenu 获取行情报价牌分类菜单
  48. func GetQuoteMenu(loginID int) ([]QuotePrimaryMenu, error) {
  49. engine := db.GetEngine()
  50. rst := make([]QuotePrimaryMenu, 0)
  51. // 账户下有权限的市场ID列表
  52. var marketIDs []int
  53. // 获取账户类型 - 1:交易所 2:机构 3:会员子机构 4:经纪人 5:投资者 6:客户 (目前可能登录交易端的账号类型为 2 5)
  54. userAccount := new(dbmodels.Useraccount)
  55. has, err := engine.Join("INNER", "LOGINACCOUNT", "USERACCOUNT.UserID = LOGINACCOUNT.UserID").Where("LOGINACCOUNT.LoginID = ?", loginID).Get(userAccount)
  56. if err != nil || !has {
  57. return nil, err
  58. }
  59. if userAccount.Usertype == 5 {
  60. // 如果账户类型为5(投资者),则需要通过其所属经济会员来获取市场权限(表:AreaRoleMarket, 条件:对应市场状态为正常;角色类型:经济会员)
  61. if err := engine.Table("AREAROLEMARKET").
  62. Cols("AREAROLEMARKET.MARKETID").
  63. Join("INNER", "MARKET", "MARKET.MARKETID = AREAROLEMARKET.MARKETID").
  64. Where("MARKET.MARKETSTATUS = 2 and AREAROLEMARKET.ROLETYPE = 7 and AREAROLEMARKET.AREAUSERID = ?", userAccount.Memberuserid).Find(&marketIDs); err != nil {
  65. return nil, err
  66. }
  67. } else {
  68. // 非投资者账号直接通过资金账号获取市场权限(表:TAAccountMarket)
  69. var taAccounts []string // 账户下所有资金账户
  70. // 先要获取当前登录账户对应的资金账户;如果为外部子资金账号(TaAccount.TaAccountType = 1),则使用TaAccount.FromAccountID来获取市场权限
  71. type taAccount struct {
  72. AccountID int `xorm:"ACCOUNTID"`
  73. TaAccountType int `xorm:"TAACCOUNTTYPE"`
  74. FromAccountID int `xorm:"FROMACCOUNTID"`
  75. }
  76. datas := make([]taAccount, 0)
  77. if err := engine.Table("LOGINTAACCOUNT").
  78. Join("INNER", "TAACCOUNT", "LOGINTAACCOUNT.ACCOUNTID = TAACCOUNT.ACCOUNTID").
  79. Cols("TAACCOUNT.ACCOUNTID", "TAACCOUNT.TAACCOUNTTYPE", "TAACCOUNT.FROMACCOUNTID").
  80. Where("LOGINTAACCOUNT.LOGINID = ?", loginID).Find(&datas); err != nil {
  81. return nil, err
  82. }
  83. // 如果一条记录都没有(未配置自营会员资金账户)则直接通过资金账户表获取
  84. if len(datas) == 0 {
  85. // 这里要注意,TaAccount表与LoginAccount表关联时,要使用TaAccount.RelatedUserID
  86. if err := engine.Table("TAACCOUNT").
  87. Join("INNER", "LOGINACCOUNT", "TAACCOUNT.RELATEDUSERID = LOGINACCOUNT.USERID").
  88. Cols("TAACCOUNT.ACCOUNTID", "TAACCOUNT.TAACCOUNTTYPE", "TAACCOUNT.FROMACCOUNTID").
  89. Where("LOGINACCOUNT.LOGINID = ?", loginID).Find(&datas); err != nil {
  90. return nil, err
  91. }
  92. }
  93. for _, v := range datas {
  94. if v.TaAccountType == 1 {
  95. // 外部资金账户使用TaAccount.FromAccountID来获取市场权限
  96. taAccounts = append(taAccounts, strconv.Itoa(v.FromAccountID))
  97. } else {
  98. taAccounts = append(taAccounts, strconv.Itoa(v.AccountID))
  99. }
  100. }
  101. // 获取资金账户对应的市场权限(有权限的市场ID)
  102. if len(taAccounts) > 0 {
  103. taAccountStr := strings.Join(taAccounts, ",")
  104. if err := engine.Table("TAACCOUNTMARKET").
  105. Join("INNER", "MARKET", "MARKET.MARKETID = TAACCOUNTMARKET.MARKETID").
  106. Cols("TAACCOUNTMARKET.MARKETID").
  107. In("TAACCOUNTMARKET.ACCOUNTID", taAccountStr).
  108. And("MARKET.MARKETSTATUS = 2").Find(&marketIDs); err != nil {
  109. return nil, err
  110. }
  111. }
  112. }
  113. // ********************* 构建行情报价牌菜单 *********************
  114. datas := make([]dbmodels.Funcmenulist, 0)
  115. if err := engine.Join("INNER", "ROLEFUNCMENU", "FUNCMENULIST.RESOURCECODE = ROLEFUNCMENU.RESOURCECODE").
  116. Where("FUNCMENULIST.PARENTCODE = 'trader_master_menu'").
  117. Asc("SORT").
  118. Find(&datas); err != nil {
  119. return nil, err
  120. }
  121. // 构建一级菜单对象
  122. for i, v := range datas {
  123. quotePrimaryMenu := QuotePrimaryMenu{
  124. Index: i,
  125. Key: v.Resourcecode,
  126. Name: v.Resourcename,
  127. SubMenus: make([]QuoteSecondaryMenu, 0),
  128. }
  129. // 跳过自选
  130. if v.Resourcecode == "optional" {
  131. rst = append(rst, quotePrimaryMenu)
  132. continue
  133. }
  134. // URL:模式,0-使用市场名称,1-使用外部交易所名称;Remark:包含市场交易模式
  135. quotePrimaryMenu.SubTitleType, _ = strconv.Atoi(v.URL)
  136. quotePrimaryMenu.TradeModes = v.Remark
  137. // 如果传入的LoginID获取不到有权限的市场ID列表(有可能LoginID是错误的),则不构建二级子菜单
  138. if len(marketIDs) == 0 {
  139. rst = append(rst, quotePrimaryMenu)
  140. continue
  141. }
  142. // 构建二级子菜单对象
  143. marketIDsStr := utils.JoinItoString(marketIDs, ",")
  144. if quotePrimaryMenu.SubTitleType == 0 {
  145. // 获取目标交易模式的市场信息
  146. markets := make([]Market, 0)
  147. if err := engine.Where(fmt.Sprintf(`TradeMode in (%s) and MarketID in (%s)`, quotePrimaryMenu.TradeModes, marketIDsStr)).Find(&markets); err != nil {
  148. return nil, err
  149. }
  150. // 使用市场名称
  151. for mi, mv := range markets {
  152. quoteSecondaryMenu := QuoteSecondaryMenu{
  153. Index: mi,
  154. MarketID: int(mv.Marketid),
  155. TradeMode: int(mv.Trademode),
  156. MenuTitle: mv.Marketname,
  157. GoodsGroupIDs: make([]int, 0),
  158. }
  159. quotePrimaryMenu.SubMenus = append(quotePrimaryMenu.SubMenus, quoteSecondaryMenu)
  160. }
  161. } else {
  162. // 使用外部交易所名称
  163. quoteSecondaryMenus := make([]QuoteSecondaryMenu, 0)
  164. sql := fmt.Sprintf(`select distinct
  165. e.autoid ExExchangeID,
  166. e.ExExchangeName,
  167. e.ExExchangeCode
  168. from ExternalExchange e
  169. inner join goodsgroup g on g.exexchangeid = e.autoid
  170. inner join Market m on g.marketid = m.marketid
  171. where m.trademode in (%s) and m.marketid in (%s)`, quotePrimaryMenu.TradeModes, marketIDsStr)
  172. if err := engine.SQL(sql).Find(&quoteSecondaryMenus); err != nil {
  173. return nil, err
  174. }
  175. // 获取外部交易所对应的商品组信息
  176. for ei, ev := range quoteSecondaryMenus {
  177. q := &quoteSecondaryMenus[ei]
  178. q.Index = ei
  179. // 商品组列表
  180. goodsgroups := make([]Goodsgroup, 0)
  181. if err := engine.Where("Exexchangeid = ?", ev.ExExchangeID).Find(&goodsgroups); err != nil {
  182. return nil, err
  183. }
  184. marketID := 0
  185. var goodsGroupIDs []int
  186. for _, gv := range goodsgroups {
  187. marketID = int(gv.Marketid)
  188. goodsGroupIDs = append(goodsGroupIDs, int(gv.Goodsgroupid))
  189. }
  190. q.MarketID = marketID
  191. q.GoodsGroupIDs = goodsGroupIDs
  192. }
  193. quotePrimaryMenu.SubMenus = quoteSecondaryMenus
  194. }
  195. rst = append(rst, quotePrimaryMenu)
  196. }
  197. return rst, nil
  198. }
  199. // GetOperationMenu 获取功能菜单
  200. func GetOperationMenu() ([]OperationPrimaryMenu, error) {
  201. engine := db.GetEngine()
  202. rst := make([]OperationPrimaryMenu, 0)
  203. // 获取一级功能菜单
  204. opm := make([]dbmodels.Funcmenulist, 0)
  205. if err := engine.Join("INNER", "ROLEFUNCMENU", "FUNCMENULIST.RESOURCECODE = ROLEFUNCMENU.RESOURCECODE").
  206. Where("FUNCMENULIST.PARENTCODE = 'trader_operation_master_menu'").
  207. Asc("SORT").
  208. Find(&opm); err != nil {
  209. return nil, err
  210. }
  211. for _, pv := range opm {
  212. var operationPrimaryMenu = OperationPrimaryMenu{
  213. Key: pv.Resourcecode,
  214. Label: pv.Resourcename,
  215. Children: make([]OperationSecondaryMenu, 0),
  216. }
  217. // 获取二级功能菜单
  218. osm := make([]dbmodels.Funcmenulist, 0)
  219. if err := engine.Join("INNER", "ROLEFUNCMENU", "FUNCMENULIST.RESOURCECODE = ROLEFUNCMENU.RESOURCECODE").
  220. Where("FUNCMENULIST.PARENTCODE = ?", operationPrimaryMenu.Key).
  221. Asc("SORT").
  222. Find(&osm); err != nil {
  223. return nil, err
  224. }
  225. for _, sv := range osm {
  226. var operationSecondaryMenu = OperationSecondaryMenu{
  227. Key: sv.Resourcecode,
  228. Label: sv.Resourcename,
  229. TabList: make([]OperationTabMenu, 0),
  230. }
  231. // 获取三级功能菜单
  232. otm := make([]dbmodels.Funcmenulist, 0)
  233. if err := engine.Join("INNER", "ROLEFUNCMENU", "FUNCMENULIST.RESOURCECODE = ROLEFUNCMENU.RESOURCECODE").
  234. Where("FUNCMENULIST.PARENTCODE = ?", operationSecondaryMenu.Key).
  235. Asc("SORT").
  236. Find(&otm); err != nil {
  237. return nil, err
  238. }
  239. for _, tv := range otm {
  240. var operationTabMenu = OperationTabMenu{
  241. Key: tv.Resourcecode,
  242. Label: tv.Resourcename,
  243. }
  244. operationSecondaryMenu.TabList = append(operationSecondaryMenu.TabList, operationTabMenu)
  245. }
  246. operationPrimaryMenu.Children = append(operationPrimaryMenu.Children, operationSecondaryMenu)
  247. }
  248. rst = append(rst, operationPrimaryMenu)
  249. }
  250. return rst, nil
  251. }
  252. // GetClientTableDefines 获取终端列表定义信息
  253. // tableKey 列表Key
  254. func GetClientTableDefines(tableKey string) ([]dbmodels.Tabledefine, error) {
  255. engine := db.GetEngine()
  256. tableDefiles := make([]dbmodels.Tabledefine, 0)
  257. s := engine.Where("TABLEDEFINE.TableType = 2") // TableType = 2 表示终端专用表定义
  258. if len(tableKey) > 0 {
  259. s = s.And("TABLEDEFINE.TableKey = ?", tableKey)
  260. }
  261. if err := s.Find(&tableDefiles); err != nil {
  262. return nil, err
  263. }
  264. return tableDefiles, nil
  265. }
  266. // GetClientTableColumns 获取客户端指定表的列头信息
  267. // tableKey 列表Key
  268. func GetClientTableColumns(tableKey string) ([]dbmodels.Tablecolumnconfig, error) {
  269. engine := db.GetEngine()
  270. // 获取列表数据
  271. tablecolumnconfigs := make([]dbmodels.Tablecolumnconfig, 0)
  272. // 这里的表名必须要大写 (Oracle的表名都是大写)
  273. if err := engine.Join("INNER", "TABLEDEFINE", "TABLEDEFINE.TableKey = TABLECOLUMNCONFIG.TableKey").
  274. Where("TABLEDEFINE.TableType = 2 and TABLEDEFINE.TableKey = ?", tableKey).Find(&tablecolumnconfigs); err != nil {
  275. return nil, err
  276. }
  277. return tablecolumnconfigs, nil
  278. }
  279. // GetNotices 获取指定账户的通知信息(终端)
  280. // @param loginID int 登录账号
  281. // @param
  282. func GetNotices(loginID, msgType int, onlyUnRead bool) ([]dbmodels.Noticemsg, error) {
  283. engine := db.GetEngine()
  284. rst := make([]dbmodels.Noticemsg, 0)
  285. // 获取登录账号所属会员信息
  286. var userAccount dbmodels.Useraccount
  287. if has, _ := engine.Join("LEFT", "LOGINACCOUNT", "LOGINACCOUNT.USERID = USERACCOUNT.USERID").
  288. Where("LOGINACCOUNT.LOGINID = ?", loginID).Get(&userAccount); !has {
  289. return nil, errors.New("获取登录账号所属会员ID失败")
  290. }
  291. // 获取登录账号已读公告ID, 这里要使用的是个人的UserID来查询
  292. var msgReceivers []int
  293. engine.Table("MSGRECEIVER").Select("AUTOID").Where("RECEIVERTYPE = 2 and MANAGERID = ?", userAccount.Userid).Find(&msgReceivers)
  294. // 查询SENDTYPE = 1的数据
  295. datas1 := make([]dbmodels.Noticemsg, 0)
  296. s := engine.Where("SENDTYPE = 1 and SYSDATE > SCHEDULETIME and SYSDATE < ENDTIME and SENTSTATUS=1").
  297. And("PUBLISHER = ? or PUBLISHER in (select USERACCOUNT.USERID from USERACCOUNT where USERACCOUNT.USERTYPE = 1)", userAccount.Memberuserid)
  298. if msgType > 0 {
  299. s = s.And("MSGTYPE = ?", msgType)
  300. }
  301. if onlyUnRead && len(msgReceivers) > 0 {
  302. s = s.NotIn("AUTOID", msgReceivers)
  303. }
  304. if err := s.Find(&datas1); err != nil {
  305. // 查询失败
  306. return nil, err
  307. }
  308. rst = append(rst, datas1...)
  309. // 查询SENDTYPE = 2的数据
  310. datas2 := make([]dbmodels.Noticemsg, 0)
  311. s = engine.Where(fmt.Sprintf(`AUTOID in (select MEMBERRECV.MSGID from MEMBERRECV where MEMBERRECV.MEMBERID = %d)`, userAccount.Memberuserid)).
  312. And("SENDTYPE = 2 and SYSDATE > SCHEDULETIME and SYSDATE < ENDTIME and SENTSTATUS=1")
  313. if msgType > 0 {
  314. s = s.And("MSGTYPE = ?", msgType)
  315. }
  316. if onlyUnRead && len(msgReceivers) > 0 {
  317. s = s.NotIn("AUTOID", msgReceivers)
  318. }
  319. if err := s.Find(&datas2); err != nil {
  320. // 查询失败
  321. return nil, err
  322. }
  323. rst = append(rst, datas2...)
  324. // 查询SENDTYPE = 3的数据
  325. datas3 := make([]dbmodels.Noticemsg, 0)
  326. s = engine.Where(fmt.Sprintf(`USERID = (SELECT USERID FROM LOGINACCOUNT WHERE LOGINID = %d)`, req.LoginID)).
  327. And("SENDTYPE = 3 and SYSDATE > SCHEDULETIME and SYSDATE < ENDTIME and SENTSTATUS=1")
  328. if msgType > 0 {
  329. s = s.And("MSGTYPE = ?", msgType)
  330. }
  331. if onlyUnRead && len(msgReceivers) > 0 {
  332. s = s.NotIn("AUTOID", msgReceivers)
  333. }
  334. if err := s.Find(&datas3); err != nil {
  335. // 查询失败
  336. return nil, err
  337. }
  338. rst = append(rst, datas3...)
  339. return rst, nil
  340. }