You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
378 lines
13 KiB
378 lines
13 KiB
package data
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/shopspring/decimal"
|
|
"matchmaking-system/internal/biz/structure"
|
|
orders "matchmaking-system/internal/data/convert"
|
|
"matchmaking-system/internal/data/tradedeal/share"
|
|
"matchmaking-system/internal/data/tradedeal/virtual"
|
|
"matchmaking-system/internal/pkg/flags"
|
|
"matchmaking-system/internal/pkg/logging/applogger"
|
|
"matchmaking-system/internal/pkg/logging/common"
|
|
models "matchmaking-system/internal/pkg/model"
|
|
"matchmaking-system/internal/pkg/setting"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// GetBotUserHkdPreStockOrder
|
|
//
|
|
// @Description: 港股新股申购列表查詢
|
|
// @receiver uo
|
|
// @param ctx
|
|
// @param id
|
|
// @return []models.BotUserHkdPreStockOrder
|
|
// @return error
|
|
func (uo *userOrderRepo) GetBotUserHkdPreStockOrder(ctx context.Context, id string) ([]models.BotUserHkdPreStockOrder, error) {
|
|
var botSgd []models.BotUserHkdPreStockOrder
|
|
if err := uo.data.mysqlDB.Table(flags.BotUserHkdPreStockOrder).
|
|
Where("pre_stock_id = ?", id).
|
|
Where("status = 3").
|
|
Find(&botSgd); err != nil {
|
|
applogger.Error("%v GetBotUserHkdPreStockOrder Find:%v", common.ErrSharePre, err)
|
|
return nil, err
|
|
}
|
|
|
|
return botSgd, nil
|
|
}
|
|
|
|
// GetBotUserHkdPreStockOrderByOrderNo
|
|
//
|
|
// @Description: 港股新股申购列表查詢orderNo
|
|
// @receiver uo
|
|
// @param ctx
|
|
// @param code
|
|
// @return []models.BotUserHkdPreStockOrder
|
|
// @return error
|
|
func (uo *userOrderRepo) GetBotUserHkdPreStockOrderByOrderNo(ctx context.Context, code []string) ([]models.BotUserHkdPreStockOrder, error) {
|
|
var botSgd []models.BotUserHkdPreStockOrder
|
|
if err := uo.data.mysqlDB.Table(flags.BotUserHkdPreStockOrder).
|
|
In("order_no", code).
|
|
Where("trade_status = 0").
|
|
Where("status = 3").
|
|
Find(&botSgd); err != nil {
|
|
applogger.Error("%v GetBotUserHkdPreStockOrder Find:%v", common.ErrSharePre, err)
|
|
return nil, err
|
|
}
|
|
|
|
return botSgd, nil
|
|
}
|
|
|
|
// GetBotUserHkdGiveStockOrders
|
|
//
|
|
// @Description:
|
|
// @receiver uo
|
|
// @param ctx
|
|
// @param id
|
|
// @return []models.BotUserHkdGiveStockOrder
|
|
// @return error
|
|
func (uo *userOrderRepo) GetBotUserHkdGiveStockOrders(ctx context.Context, id string) ([]models.BotUserHkdGiveStockOrder, error) {
|
|
var botSgd []models.BotUserHkdGiveStockOrder
|
|
if err := uo.data.mysqlDB.Table(flags.BotUserHkdGiveStockOrder).
|
|
Where("order_no = ?", id).
|
|
Find(&botSgd); err != nil {
|
|
applogger.Error("%v GetBotUserGivePreStockOrders Find:%v", common.ErrSharePre, err)
|
|
return nil, err
|
|
}
|
|
|
|
return botSgd, nil
|
|
}
|
|
|
|
// GetBotStockHkdList
|
|
//
|
|
// @Description: 港股股票代码列表
|
|
// @receiver uo
|
|
// @param ctx
|
|
// @return []models.BotStockHkdList
|
|
// @return error
|
|
func (uo *userOrderRepo) GetBotStockHkdList(ctx context.Context) ([]models.BotStockHkdList, error) {
|
|
var data []models.BotStockHkdList
|
|
if err := uo.data.mysqlDB.Table(flags.BotStockHkdList).Find(&data); err != nil {
|
|
applogger.Error("%v GetBotStockHkdList Find:%v", common.ErrSharePre, err)
|
|
return nil, err
|
|
}
|
|
// 清理股票缓存列表
|
|
for _, value := range data {
|
|
strArray := strings.Split(value.StockCode, ":")
|
|
if len(strArray) >= 2 {
|
|
codeOld := strArray[1]
|
|
Reds.HDel(context.Background(), setting.MarketShareHkd, codeOld)
|
|
Reds.HDel(context.Background(), setting.MarketShareBlkHkd, codeOld)
|
|
}
|
|
}
|
|
|
|
return data, nil
|
|
}
|
|
|
|
// CreateBotUserHkdPreStockOrder
|
|
//
|
|
// @Description: 港股新股申购:开仓--持仓
|
|
// @receiver uo
|
|
// @param ctx
|
|
// @param code
|
|
// @param order
|
|
// @return error
|
|
func (uo *userOrderRepo) CreateBotUserHkdPreStockOrder(ctx context.Context, code string, order []structure.ShareOrder) error {
|
|
// 同步写入股票列表缓存
|
|
SubscribeHkdHSetCodeList(code, false)
|
|
// 处理新股申购数据订单
|
|
session := uo.data.mysqlDB.NewSession()
|
|
defer session.Close()
|
|
err := session.Begin()
|
|
if err != nil {
|
|
applogger.Error("%v CreatBotUserHkdPreStockOrder.Begin:%v", common.ErrSharePre, err)
|
|
return flags.ErrMySqlDB
|
|
}
|
|
// 强平阈值
|
|
flatRatio := GetCacheForcedClosure(flags.StockHKDSystemSetUpKey, code)
|
|
system := &structure.ShareSystem{
|
|
StrongFlatRatio: flatRatio.String(),
|
|
}
|
|
// 获取开盘时间
|
|
closingTime := SystemTimeGenerate(flags.StockMarketList, flags.HkdMarket, time.Now())
|
|
// 初始化订单缓存
|
|
orderMap := make(map[string]share.ShareHkdTallyCache)
|
|
for _, value := range order {
|
|
value.System = system
|
|
// 生成订单ID
|
|
var orderId string
|
|
orderId, err = uo.VerifyBotStockHkdTradeOrderId(session)
|
|
if err != nil {
|
|
applogger.Error("%v CreatBotUserHkdPreStockOrder.VerifyBotStockHkdTradeOrderId:%v", common.ErrSharePre, err)
|
|
continue
|
|
}
|
|
// 查询账户是否存在,再存更新不存在新增
|
|
var check bool
|
|
check, err = uo.CheckStockHkdAmount(ctx, int64(value.UserId), value.StockId, value.OrderNumber, decimal.Zero.String())
|
|
if err != nil || !check {
|
|
applogger.Error("%v CreatBotUserHkdPreStockOrder.CheckStockSgdAmount:%v", common.ErrSharePre, err)
|
|
continue
|
|
}
|
|
// 写入订单数据表
|
|
trade := orders.BotStockHkdTradePre(ctx, int64(value.UserId), orderId, value)
|
|
if err = uo.CreateBotStockHkdTrade(session, trade); err != nil {
|
|
applogger.Error("%v CreatBotUserHkdPreStockOrder.BotStockHkdTradePre:%v", common.ErrSharePre, err)
|
|
continue
|
|
}
|
|
// 写入持仓缓存
|
|
resultMsg := share.ShareHkdTallyCache{
|
|
UserId: int64(value.UserId), // 用户Id
|
|
OrderId: orderId, // 订单ID
|
|
Symbol: value.StockId, // 下单交易对
|
|
OpenPrice: value.LimitPrice, // 开仓价格
|
|
Status: flags.Position, // 订单状态
|
|
Order: value, // 下单信息
|
|
ClosingTime: closingTime, // 平仓时间
|
|
}
|
|
orderMap[orderId] = resultMsg
|
|
}
|
|
|
|
if err = session.Commit(); err != nil {
|
|
applogger.Error("%v CreatBotUserHkdPreStockOrder.Commit:%v", common.ErrSharePre, err)
|
|
return flags.ErrMySqlDB
|
|
}
|
|
// 写入持仓缓存、用户订单订阅缓存、管理员订单订阅缓存
|
|
for _, resultMsg := range orderMap {
|
|
var byteStr []byte
|
|
byteStr, err = json.Marshal(resultMsg)
|
|
if err != nil {
|
|
applogger.Error("%v CreatBotUserHkdPreStockOrder.Marshal:%v", common.ErrSharePre, err)
|
|
continue
|
|
}
|
|
// 写入持仓缓存
|
|
if err = Reds.HSet(context.Background(), setting.MarketShareHkdPosition, resultMsg.OrderId, string(byteStr)).Err(); err != nil {
|
|
continue
|
|
}
|
|
// 写入用户订单订阅缓存
|
|
orderIdKey := virtual.OrderIdListKey(setting.ShareHkdSubscribe, resultMsg.UserId)
|
|
if err = share.ShareHkdHashUserOrder(Reds, orderIdKey, &resultMsg); err != nil {
|
|
applogger.Error("%v CreatBotUserHkdPreStockOrder.ShareHkdHashUserOrder:%v", common.ErrSharePre, err)
|
|
return flags.ErrCacheDB
|
|
}
|
|
// 写入管理员订单订阅缓存
|
|
if err = share.ShareHkdHashUserOrder(Reds, setting.AdminShareHkdSubscribe, &resultMsg); err != nil {
|
|
applogger.Error("%v CreatBotUserHkdPreStockOrder.AdminShareHkdSubscribe:%v", common.ErrSharePre, err)
|
|
return flags.ErrCacheDB
|
|
}
|
|
// TODO: 获取IPO未支付订单缓存,并更新缓存中的持仓订单ID
|
|
keyCache := fmt.Sprintf("%v%v", flags.StockIpoList, resultMsg.Order.OrderNo)
|
|
checkInt, err := Reds.Exists(ctx, keyCache).Result()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if checkInt > 0 {
|
|
if err = Reds.Set(ctx, keyCache, resultMsg.OrderId, 0).Err(); err != nil {
|
|
applogger.Error("CreatBotUserHkdPreStockOrder.Set err:%v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CheckStockHkdAmount
|
|
//
|
|
// @Description: 港股新股申购【创建|更新】用戶资产
|
|
// @receiver uo
|
|
// @param ctx
|
|
// @param userId
|
|
// @param stockId
|
|
// @param usableNum
|
|
// @param frozenNum
|
|
// @return bool
|
|
// @return error
|
|
func (uo *userOrderRepo) CheckStockHkdAmount(ctx context.Context, userId int64, stockId, usableNum, frozenNum string) (bool, error) {
|
|
var botUserStockHkd []models.BotUserStockHkd
|
|
if err := uo.data.mysqlDB.Table(flags.BotUserStockHkd).
|
|
Where("user_id = ?", userId).
|
|
Where("stock_id = ?", stockId).
|
|
Find(&botUserStockHkd); err != nil {
|
|
applogger.Error("%v CheckStockHkdAmount Find:%v", common.ErrSharePre, err)
|
|
return false, err
|
|
}
|
|
var usableNumOld, frozenNumOld decimal.Decimal
|
|
for _, value := range botUserStockHkd {
|
|
usableNumOld = decimal.RequireFromString(value.UsableNum)
|
|
frozenNumOld = decimal.RequireFromString(value.FrozenNum)
|
|
}
|
|
|
|
if len(botUserStockHkd) == 0 {
|
|
// 创建账户
|
|
userStock := orders.CreatBotUserStockHkdPre(ctx, userId, stockId, usableNum, frozenNum)
|
|
_, err := uo.data.mysqlDB.Table(flags.BotUserStockHkd).Insert(&userStock)
|
|
if err != nil {
|
|
applogger.Error("%v CheckStockHkdAmount Insert:%v", common.ErrSharePre, err)
|
|
return false, err
|
|
}
|
|
} else {
|
|
// 更新账户
|
|
usableNumNew := usableNumOld.Add(decimal.RequireFromString(usableNum))
|
|
frozenNumNew := frozenNumOld.Add(decimal.RequireFromString(frozenNum))
|
|
userStock := orders.UpdateBotUserStockHkdPre(ctx, usableNumNew.String(), frozenNumNew.String())
|
|
_, err := uo.data.mysqlDB.Table(flags.BotUserStockHkd).
|
|
Where("user_id = ?", userId).
|
|
Where("stock_id = ?", stockId).
|
|
Update(&userStock)
|
|
if err != nil {
|
|
applogger.Error("%v CheckStockHkdAmount Update:%v", common.ErrSharePre, err)
|
|
return false, err
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
// UpdateShareHkdTradeStockId
|
|
//
|
|
// @Description: 更新-港股新股申购股票stockId
|
|
// @receiver uo
|
|
// @param ctx
|
|
// @param code
|
|
// @param codeOld
|
|
// @param stock
|
|
// @return error
|
|
func (uo *userOrderRepo) UpdateShareHkdTradeStockId(ctx context.Context, code, codeOld string) error {
|
|
// 同步写入股票列表缓存
|
|
SubscribeHkdHSetCodeList(code, false)
|
|
// 新增到港股缓存列表
|
|
if err := Reds.HSet(context.Background(), setting.MarketShareHkd, code, code).Err(); err != nil {
|
|
applogger.Error("%v UpdateShareHkdTradeStockId.HSet.MarketShareBlkHkd:%v", common.ErrSharePre, err)
|
|
return flags.ErrCacheDB
|
|
}
|
|
|
|
session := uo.data.mysqlDB.NewSession()
|
|
defer session.Close()
|
|
err := session.Begin()
|
|
if err != nil {
|
|
applogger.Error("%v UpdateShareHkdTradeStockId.Begin:%v", common.ErrSharePre, err)
|
|
return flags.ErrMySqlDB
|
|
}
|
|
|
|
// 1、更新订单股票代码
|
|
var userStockTrade []models.BotStockHkdTrade
|
|
if err = session.Table(flags.BotStockHkdTrade).Where("stock_id =?", codeOld).Find(&userStockTrade); err != nil {
|
|
return flags.ErrMySqlDB
|
|
}
|
|
for _, value := range userStockTrade {
|
|
value.StockId = code
|
|
// 1、更新订单信息
|
|
inCheck, err := session.Table(flags.BotStockHkdTrade).Where("trade_id =?", value.TradeId).Update(&value)
|
|
if err != nil || inCheck <= 0 {
|
|
continue
|
|
}
|
|
// 2、处理缓存订单
|
|
orderMap, err := Reds.HGet(context.Background(), setting.AdminShareHkdSubscribe, value.OrderId).Result()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
var entrustJson share.ShareHkdTallyCache
|
|
if err = json.Unmarshal([]byte(orderMap), &entrustJson); err != nil {
|
|
continue
|
|
}
|
|
var entrust *share.ShareHkdTallyCache
|
|
entrust = &entrustJson
|
|
if entrust == nil {
|
|
continue
|
|
}
|
|
entrust.Symbol = code
|
|
entrust.Order.StockId = code
|
|
// 3、处理挂单|持仓|用户订阅|管理员订阅缓存数据
|
|
switch value.Status {
|
|
case 0: // 挂单
|
|
if err = share.ShareHkdHashUserOrder(Reds, setting.MarketShareHkdEntrust, entrust); err != nil {
|
|
continue
|
|
}
|
|
case 1: // 持仓
|
|
if err = share.ShareHkdHashUserOrder(Reds, setting.MarketShareHkdPosition, entrust); err != nil {
|
|
continue
|
|
}
|
|
default:
|
|
continue
|
|
}
|
|
// 更新用户订阅缓存
|
|
cacheKey := fmt.Sprintf("%v-%v", setting.ShareHkdSubscribe, entrust.UserId)
|
|
if err = share.ShareHkdHashUserOrder(Reds, cacheKey, entrust); err != nil {
|
|
continue
|
|
}
|
|
// 更新管理员订阅缓存
|
|
if err = share.ShareHkdHashUserOrder(Reds, setting.AdminShareHkdSubscribe, entrust); err != nil {
|
|
continue
|
|
}
|
|
}
|
|
// 2、更新资产表股票代码
|
|
var userStock []models.BotUserStockHkd
|
|
if err = session.Table(flags.BotUserStockHkd).Where("stock_id =?", codeOld).Find(&userStock); err != nil {
|
|
return flags.ErrMySqlDB
|
|
}
|
|
for _, value := range userStock {
|
|
value.StockId = code
|
|
inCheck, err := session.Table(flags.BotUserStockHkd).Where("id =?", value.Id).Update(&value)
|
|
if err != nil || inCheck <= 0 {
|
|
applogger.Error("%v UpdateShareHkdTradeStockId BotUserStockHkd err:%v", common.ErrSharePre, err)
|
|
continue
|
|
}
|
|
}
|
|
// 3、更新资产表日志股票代码
|
|
var userStockLog []models.BotUserStockHkdLog
|
|
if err = session.Table(flags.BotUserStockHkdLog).Where("stock_id =?", codeOld).Find(&userStockLog); err != nil {
|
|
return flags.ErrMySqlDB
|
|
}
|
|
for _, value := range userStockLog {
|
|
value.StockId = code
|
|
inCheck, err := session.Table(flags.BotUserStockHkdLog).Where("id =?", value.Id).Update(&value)
|
|
if err != nil || inCheck <= 0 {
|
|
applogger.Error("%v UpdateShareHkdTradeStockId BotUserStockHkdLog err:%v", common.ErrSharePre, err)
|
|
continue
|
|
}
|
|
}
|
|
|
|
if err = session.Commit(); err != nil {
|
|
applogger.Error("%v UpdateShareHkdTradeStockId.Commit:%v", common.ErrSharePre, err)
|
|
return flags.ErrMySqlDB
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|