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