ermcpUser.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /**
  2. * @Author: zou.yingbin
  3. * @Create : 2021/1/7 17:31
  4. * @Modify : 2021/1/7 17:31
  5. */
  6. package models
  7. import (
  8. "encoding/hex"
  9. "errors"
  10. "fmt"
  11. "mtp2_if/db"
  12. "mtp2_if/logger"
  13. "mtp2_if/utils"
  14. "strconv"
  15. "time"
  16. )
  17. // Hedgeoutmainconfig 外部母账号对冲配置表
  18. // (要在系统参数表额外添加两个全局配置 1: 下单接口平台登录用户名[HedgePlateform_UserName] 2:下单接口平台登录密码[HedgePlateform_PWD])
  19. type Hedgeoutmainconfig struct {
  20. Accountid int64 `json:"accountid" xorm:"'ACCOUNTID'" binding:"required"` // 资金账号ID(母账号)
  21. Channelid int64 `json:"channelid" xorm:"'CHANNELID'"` // 对冲渠道ID
  22. Marketid int64 `json:"marketid" xorm:"'MARKETID'"` // 内部市场ID(母账号的操作
  23. Hedgeaccountcode string `json:"hedgeaccountcode" xorm:"'HEDGEACCOUNTCODE'"` // 对冲账号ID
  24. Hedgeaccountpwd string `json:"hedgeaccountpwd" xorm:"-"` // 对冲账号密码
  25. Channeladdress string `json:"channeladdress" xorm:"'CHANNELADDRESS'"` // 对冲渠道服务地址(多个地址用逗号分隔) -- 192.168.30.10:3000,192.168.30.10:3001
  26. Brokerid string `json:"brokerid" xorm:"'BROKERID'"` // 经纪公司代码
  27. Exchangeratecurrencygroup string `json:"exchangeratecurrencygroup" xorm:"'EXCHANGERATECURRENCYGROUP'"` // 汇率币种组 [易盛]
  28. Accountcurrency string `json:"accountcurrency" xorm:"'ACCOUNTCURRENCY'"` // 资金账户基币 [易盛]
  29. Accountcurrecnygroup string `json:"accountcurrecnygroup" xorm:"'ACCOUNTCURRECNYGROUP'"` // 资金账户币种组 [易盛]
  30. Authcode string `json:"authcode" xorm:"'AUTHCODE'"` // 授权码[易盛]
  31. Status int32 `json:"status" xorm:"'STATUS'"` // 渠道账号状态 1-可买入可卖出 2-可卖出不可买入
  32. Limitnumber int64 `json:"limitnumber" xorm:"'LIMITNUMBER'"` // 挂单笔数限额
  33. Appid string `json:"appid" xorm:"-"` // AppID
  34. Userproductinfo string `json:"userproductinfo" xorm:"'USERPRODUCTINFO'"` // 客户端产品信息
  35. Connectflag int32 `json:"connectflag" xorm:"'CONNECTFLAG'"` // 是否联接外部交易 - 0:不连接 1:连接
  36. Hedgeaccounttype int32 `json:"hedgeaccounttype" xorm:"'HEDGEACCOUNTTYPE'"` // 母账号类型 - 1-交易下单 2-跟单
  37. Fcid int32 `json:"fcid" xorm:"'FCID'"` // 期货公司ID
  38. Fcname string `json:"fcname" xorm:"FCNAME"` // 期货公司名称
  39. }
  40. // TableName is HEDGE_OUTMAINCONFIG
  41. func (Hedgeoutmainconfig) TableName() string {
  42. return "HEDGE_OUTMAINCONFIG"
  43. }
  44. // GetOutAccountStatus 获取目标登录账号当前对冲账号在线状态
  45. func (r *Hedgeoutmainconfig) GetOutAccountStatus(loginID int) ([]Hedgeoutmainconfig, error) {
  46. datas := make([]Hedgeoutmainconfig, 0)
  47. // 获取登录账号相关的所有资金账户
  48. taAccounts, err := GetTaAccountsByLoginID(loginID, 0)
  49. if err != nil {
  50. return nil, err
  51. }
  52. ids := make([]int, 0)
  53. for _, v := range taAccounts {
  54. // 母账户的Parentaccountid就是自己
  55. ids = append(ids, int(v.Parentaccountid))
  56. }
  57. if err := db.GetEngine().Table("HEDGE_OUTMAINCONFIG T").
  58. Select("T.*, F.FCNAME").
  59. Join("LEFT", "ERMCP_FUTURESCOMPANY F", "F.FCID = T.FCID").
  60. In("T.ACCOUNTID", ids).Find(&datas); err != nil {
  61. return nil, err
  62. }
  63. return datas, nil
  64. }
  65. // Hedgemarketopenlog 通道交易市场待开市日志表 - 市场的所有母账户与下单接口平台同步数据成功,市场才为待开市成功;
  66. // 清空上一交易日数据
  67. type Hedgemarketopenlog struct {
  68. Tradedate string `json:"tradedate" xorm:"TRADEDATE"` // 交易日(yyyyMMdd)
  69. Accountid int64 `json:"accountid" xorm:"ACCOUNTID" binding:"required"` // 资金账号[外部母账户]
  70. Marketid int64 `json:"marketid" xorm:"MARKETID"` // 市场ID
  71. Status int32 `json:"status" xorm:"STATUS"` // 状态 - 1:待开市 2:开市 4:手工休市 5:闭市 10:日终处理开始 11:日终处理成功 12:日终处理失败
  72. Updatetime time.Time `json:"updatetime" xorm:"UPDATETIME"` // 更新时间
  73. Handlestatus int32 `json:"handlestatus" xorm:"HANDLESTATUS"` // 处理状态 - 1:登陆Mhp成功 2:登陆Mhp失败 3:登出Mhp
  74. Fcname string `json:"fcname" xorm:"-"` // 期货公司名称
  75. }
  76. // TableName is HEDGE_MARKETOPENLOG
  77. func (Hedgemarketopenlog) TableName() string {
  78. return "HEDGE_MARKETOPENLOG"
  79. }
  80. // GetOutAccountStatus 获取目标登录账号当前对冲账号在线状态
  81. func (r *Hedgemarketopenlog) GetOutAccountStatus(loginID int) ([]Hedgemarketopenlog, error) {
  82. datas := make([]Hedgemarketopenlog, 0)
  83. // 获取登录账号相关的所有资金账户
  84. taAccounts, err := GetTaAccountsByLoginID(loginID, 0)
  85. if err != nil {
  86. return nil, err
  87. }
  88. if len(taAccounts) == 0 {
  89. return nil, errors.New("无对应资金账户")
  90. }
  91. ids := make([]int, 0)
  92. ids_s := ""
  93. for _, v := range taAccounts {
  94. // 母账户的Parentaccountid就是自己
  95. ids = append(ids, int(v.Parentaccountid))
  96. ids_s += "," + strconv.Itoa(int(v.Parentaccountid))
  97. }
  98. ids_s = ids_s[1:]
  99. // 获取通道交易市场(目前只获取tradeMode = 15的第一个市场)
  100. marketRuns, err := GetMarketRunsByTradeMode(15)
  101. if err != nil {
  102. return nil, err
  103. }
  104. if len(marketRuns) == 0 {
  105. return nil, errors.New("无对应市场运行状态")
  106. }
  107. marketID := marketRuns[0].Marketid
  108. tradeDate := marketRuns[0].Tradedate
  109. if err := db.GetEngine().Table("TAACCOUNT T").Select("T.ACCOUNTID, H.TRADEDATE, H.MARKETID, H.STATUS, H.UPDATETIME, H.HANDLESTATUS").
  110. Join("LEFT", "HEDGE_MARKETOPENLOG H", fmt.Sprintf(`H.ACCOUNTID = T.ACCOUNTID
  111. and H.ACCOUNTID in (%s)
  112. and H.MARKETID = %d
  113. and H.TRADEDATE = '%s'`, ids_s, marketID, tradeDate)).
  114. In("T.ACCOUNTID", ids).
  115. Find(&datas); err != nil {
  116. return nil, err
  117. }
  118. for i := range datas {
  119. hedgemarketopenlog := &datas[i]
  120. // 获取期货公司名称
  121. fcnames := make([]string, 0)
  122. if err := db.GetEngine().Table("ERMCP_FUTURESCOMPANY F").Select("F.FCNAME").
  123. Join("INNER", "HEDGE_OUTMAINCONFIG H", "H.FCID = F.FCID").
  124. Where("H.ACCOUNTID = ?", hedgemarketopenlog.Accountid).
  125. And("H.MARKETID = ?", marketID).Find(&fcnames); err != nil {
  126. return nil, err
  127. }
  128. if len(fcnames) > 0 {
  129. hedgemarketopenlog.Fcname = fcnames[0]
  130. }
  131. }
  132. return datas, nil
  133. }
  134. // ErmcpUserModel 客户资料结构
  135. type ErmcpUserModel struct {
  136. USERID int `json:"userid" xorm:"'USERID'"` // 用户ID
  137. MEMBERUSERID int `json:"memberuserid" xorm:"'MEMBERUSERID'"` // 所属机构ID
  138. USERINFOTYPE string `json:"userinfotype" xorm:"'USERINFOTYPE'"` // 客户类型
  139. CUSTOMERNAME string `json:"customername" xorm:"'CUSTOMERNAME'"` // 企业名称
  140. CARDTYPE int32 `json:"cardtype" xorm:"'CARDTYPE'"` // 证件类型
  141. CARDTYPENAME string `json:"cardtypename" xorm:"'CARDTYPENAME'"` // 证件类型名称
  142. CARDNUM string `json:"cardnum" xorm:"'CARDNUM'"` // 证件号码
  143. MOBILE string `json:"mobile" xorm:"'MOBILE'"` // 手机号码
  144. TELPHONE string `json:"telphone" xorm:"'TELPHONE'"` // 联系电话
  145. ADDRESS string `json:"address" xorm:"'ADDRESS'"` // 通讯地址
  146. REMARK string `json:"remark" xorm:"'REMARK'"` // 备注
  147. STATUS int32 `json:"status" xorm:"'STATUS'"` // 账户状态 - 1:待激活 2:待审核 3:待复审 4:正常 5:审核拒绝 6:注销
  148. STATUSDESC string `json:"statusdesc"` // 账户状态中文描述
  149. ATTACHMENT1 string `json:"attachment1" xorm:"'ATTACHMENT1'"` // 附件1
  150. CARDFRONTPHOTOURL string `json:"cardfrontphotourl" xorm:"'CARDFRONTPHOTOURL'"` // 证件正面图片地址
  151. COUNTRYID int32 `json:"countryid" xorm:"'COUNTRYID'"` // 国家
  152. PROVINCEID int32 `json:"provinceid" xorm:"'PROVINCEID'"` // 省
  153. CITYID int32 `json:"cityid" xorm:"'CITYID'"` // 市
  154. DISTRICTID int32 `json:"districtid" xorm:"'DISTRICTID'"` // 区域
  155. CREATETIME string `json:"createtime" xorm:"'CREATETIME'"` // 创建时间
  156. MODIFYTIME string `json:"modifytime" xorm:"'MODIFYTIME'"` // 修改时间
  157. AUDITTIME string `json:"audittime" xorm:"'AUDITTIME'"` // 审核时间
  158. NICKNAME string `json:"nickname" xorm:"'NICKNAME'"` // 昵称
  159. TAXPAYERNUM string `json:"taxpayernum" xorm:"'taxpayernum'"` // 纳税人识别号
  160. LEGALPERSONNAME string `json:"legalpersonname" xorm:"'legalpersonname'"` // 法人姓名(企业)
  161. CONTACTNAME string `json:"contactname" xorm:"'contactname'"` // 联系人
  162. }
  163. func (r *ErmcpUserModel) buildWskhSql(accStatus string) string {
  164. str := "select t.userid," +
  165. " t.memberareaid MEMBERUSERID," +
  166. " t.USERINFOTYPE," +
  167. " t.CUSTOMERNAME," +
  168. " t.NICKNAME," +
  169. " t.CARDTYPE," +
  170. " e.enumdicname CARDTYPENAME," +
  171. " t.CARDNUM," +
  172. " t.mobilephone MOBILE," +
  173. " t.TELPHONE," +
  174. " t.cardaddress ADDRESS," +
  175. " t.REMARK," +
  176. " t.ATTACHMENT1," +
  177. " t.CARDFRONTPHOTOURL," +
  178. " t.userstate status," +
  179. " t.countryid," +
  180. " t.provinceid," +
  181. " t.districtid," +
  182. " to_char(t.createtime,'yyyy-mm-dd hh24:mi:ss') createtime," +
  183. " t.cityid," +
  184. " to_char(t.modifiedtime,'yyyy-mm-dd hh24:mi:ss') modifytime," +
  185. " to_char(t.auditime,'yyyy-mm-dd hh24:mi:ss') audittime," +
  186. " t.taxpayernum," +
  187. " t.legalpersonname," +
  188. " t.contactname" +
  189. " from wskh_userinfo t" +
  190. " left join enumdicitem e" +
  191. " on t.cardtype = e.enumitemname" +
  192. " and e.enumdiccode = 'certificatetype'" +
  193. " where t.userstate in (%v)" +
  194. " and t.usertype = 6" +
  195. " and t.memberareaid = %v" +
  196. " order by t.modifiedtime desc"
  197. return fmt.Sprintf(str, accStatus, r.MEMBERUSERID)
  198. }
  199. func (r *ErmcpUserModel) buildSql(accStatus string) string {
  200. str := "select t.userid," +
  201. " t.memberuserid," +
  202. " u.USERINFOTYPE," +
  203. " u.CUSTOMERNAME," +
  204. " u.NICKNAME," +
  205. " u.CARDTYPEID CARDTYPE," +
  206. " e.enumdicname CARDTYPENAME," +
  207. " u.CARDNUM," +
  208. " u.MOBILE," +
  209. " u.TELPHONE," +
  210. " u.ADDRESS," +
  211. " u.REMARK," +
  212. " u.ATTACHMENT1," +
  213. " u.CARDFRONTPHOTOURL," +
  214. " t.accountstatus status," +
  215. " u.countryid," +
  216. " u.provinceid," +
  217. " u.districtid," +
  218. " u.taxpayernum," +
  219. " u.legalpersonname," +
  220. " u.contactname," +
  221. " to_char(t.createtime,'yyyy-mm-dd hh24:mi:ss') createtime," +
  222. " to_char(t.modifytime,'yyyy-mm-dd hh24:mi:ss') modifytime," +
  223. " to_char(t.audittime,'yyyy-mm-dd hh24:mi:ss') audittime," +
  224. " u.cityid" +
  225. " from useraccount t" +
  226. " left join userinfo u" +
  227. " on t.userid = u.userid" +
  228. " left join enumdicitem e" +
  229. " on u.cardtypeid = e.enumitemname" +
  230. " and e.enumdiccode = 'certificatetype'" +
  231. " where t.usertype = 6" +
  232. " and t.accountstatus in (%v)" +
  233. " and t.memberuserid = %v"
  234. // 查正常状态,按审核时间排序
  235. if accStatus == "4" {
  236. str += " order by t.audittime desc"
  237. } else if accStatus == "6" {
  238. // 停用状态按修改时间排序
  239. str += " order by t.modifytime desc"
  240. }
  241. return fmt.Sprintf(str, accStatus, r.MEMBERUSERID)
  242. }
  243. // DecryptField 解密卡号和电话号码字段
  244. func (r *ErmcpUserModel) DecryptField(isWskh bool) {
  245. key := "0d299ce2d4105282f7471074cb0f9f9d"
  246. key2, _ := hex.DecodeString(key)
  247. fd := func(str string) string {
  248. if str == "" {
  249. return str
  250. }
  251. d, _ := hex.DecodeString(str)
  252. if dst, err := utils.AESDecrypt(d, key2); err == nil {
  253. return string(dst)
  254. }
  255. return str
  256. }
  257. r.CARDNUM = fd(r.CARDNUM)
  258. r.MOBILE = fd(r.MOBILE)
  259. if !isWskh {
  260. // 正式用户表(非网上开户)需要解密电话号码
  261. r.TELPHONE = fd(r.TELPHONE)
  262. }
  263. if isWskh && len(r.ADDRESS) != 0 { // 地址不为空
  264. r.ADDRESS = fd(r.ADDRESS)
  265. }
  266. }
  267. // DecodeStausName 账户状态名称
  268. func (r *ErmcpUserModel) DecodeStausName(queryType int32) {
  269. if queryType == 1 || queryType == 2 {
  270. // 网上开户状态
  271. if r.STATUS == 1 {
  272. r.STATUSDESC = "未提交"
  273. } else if r.STATUS == 2 || r.STATUS == 4 {
  274. r.STATUSDESC = "待审核"
  275. } else if r.STATUS == 3 || r.STATUS == 5 {
  276. r.STATUSDESC = "审核拒绝"
  277. }
  278. } else if queryType == 3 || queryType == 4 {
  279. if r.STATUS == 4 {
  280. r.STATUSDESC = "正常"
  281. } else if r.STATUS == 6 {
  282. r.STATUSDESC = "已注销"
  283. }
  284. }
  285. }
  286. // GetData 查询客户资料
  287. func (r *ErmcpUserModel) GetData(queryType int32) ([]ErmcpUserModel, error) {
  288. sData := make([]ErmcpUserModel, 0)
  289. e := db.GetEngine()
  290. var sqlId string
  291. var isWskh bool = false
  292. switch queryType {
  293. case 1: //未提交
  294. sqlId = r.buildWskhSql("1")
  295. isWskh = true
  296. case 2: //待审核
  297. sqlId = r.buildWskhSql("2,4,5")
  298. isWskh = true
  299. case 3: //正常
  300. sqlId = r.buildSql("4")
  301. case 4: //已停用
  302. sqlId = r.buildSql("6")
  303. }
  304. s := e.SQL(sqlId)
  305. if err := s.Find(&sData); err != nil {
  306. logger.GetLogger().Errorf("ermcp query fail:%v", err)
  307. return sData, err
  308. }
  309. // 解密
  310. for i := range sData {
  311. sData[i].DecryptField(isWskh)
  312. sData[i].DecodeStausName(queryType)
  313. }
  314. return sData, nil
  315. }