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

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"
)
// GetBotUserInPreStockOrder
//
// @Description: 印度股新股申购列表查詢
// @receiver uo
// @param ctx
// @param id
// @return []models.BotUserInPreStockOrder
// @return error
func (uo *userOrderRepo) GetBotUserInPreStockOrder(ctx context.Context, id string) ([]models.BotUserInPreStockOrder, error) {
var botTha []models.BotUserInPreStockOrder
if err := uo.data.mysqlDB.Table(flags.BotUserInPreStockOrder).
Where("pre_stock_id = ?", id).
Where("status = 3").
Find(&botTha); err != nil {
applogger.Error("%v GetBotUserInPreStockOrder Find:%v", common.ErrSharePre, err)
return nil, err
}
return botTha, nil
}
// GetBotUserInPreStockOrderByOrderNo
//
// @Description: 印度股新股申购列表查詢orderNo
// @receiver uo
// @param ctx
// @param code
// @return []models.BotUserInPreStockOrder
// @return error
func (uo *userOrderRepo) GetBotUserInPreStockOrderByOrderNo(ctx context.Context, code []string) ([]models.BotUserInPreStockOrder, error) {
var botTha []models.BotUserInPreStockOrder
if err := uo.data.mysqlDB.Table(flags.BotUserInPreStockOrder).
In("order_no", code).
Where("trade_status = 0").
Where("status = 3").
Find(&botTha); err != nil {
applogger.Error("%v GetBotUserInPreStockOrder Find:%v", common.ErrSharePre, err)
return nil, err
}
return botTha, nil
}
// GetBotUserInGiveStockOrders
//
// @Description: 印度股赠股
// @receiver uo
// @param ctx
// @param
func (uo *userOrderRepo) GetBotUserInGiveStockOrders(ctx context.Context, id string) ([]models.BotUserInGiveStockOrder, error) {
var botTha []models.BotUserInGiveStockOrder
if err := uo.data.mysqlDB.Table(flags.BotUserInGiveStockOrder).
Where("order_no = ?", id).
Find(&botTha); err != nil {
applogger.Error("%v GetBotUserInGiveStockOrders Find:%v", common.ErrSharePre, err)
return nil, err
}
return botTha, nil
}
// GetBotStockInList
//
// @Description: 印度股股票代码列表
// @receiver uo
// @param ctx
// @return []models.BotStockInList
// @return error
func (uo *userOrderRepo) GetBotStockInList(ctx context.Context) ([]models.BotStockInList, error) {
var data []models.BotStockInList
if err := uo.data.mysqlDB.Table(flags.BotStockInList).Find(&data); err != nil {
applogger.Error("%v GetBotStockInList 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.MarketShareInr, codeOld)
Reds.HDel(context.Background(), setting.MarketShareBlkInr, codeOld)
}
}
return data, nil
}
// CreateBotUserInPreStockOrder
//
// @Description: 印度股新股申购:开仓--持仓
// @receiver uo
// @param ctx
// @param code
// @param order
// @return error
func (uo *userOrderRepo) CreateBotUserInPreStockOrder(ctx context.Context, code string, order []structure.ShareOrder) error {
// 同步写入股票列表缓存
SubscribeInrHSetCodeList(code, false)
// 处理新股申购数据订单
session := uo.data.mysqlDB.NewSession()
defer session.Close()
err := session.Begin()
if err != nil {
applogger.Error("%v CreatBotUserInPreStockOrder.Begin:%v", common.ErrSharePre, err)
return flags.ErrMySqlDB
}
// 强平阈值
flatRatio := GetCacheForcedClosure(flags.StockYDSystemSetUpKey, code)
system := &structure.ShareSystem{
StrongFlatRatio: flatRatio.String(),
}
// 获取开盘时间
closingTime := SystemTimeGenerate(flags.StockMarketList, flags.InrMarket, time.Now())
// 初始化订单缓存map
orderMap := make(map[string]share.ShareInrTallyCache)
for _, value := range order {
value.System = system
// 生成订单ID
var orderId string
orderId, err = uo.VerifyBotStockInTradeOrderId(session)
if err != nil {
applogger.Error("%v CreatBotUserInPreStockOrder.VerifyBotStockThaTradeOrderId:%v", common.ErrSharePre, err)
continue
}
// 查询账户是否存在,再存更新不存在新增
var check bool
check, err = uo.CheckStockInAmount(ctx, int64(value.UserId), value.StockId, value.OrderNumber, decimal.Zero.String())
if err != nil || !check {
applogger.Error("%v CreatBotUserInPreStockOrder.CheckStockThaAmount:%v", common.ErrSharePre, err)
continue
}
// 写入订单数据表
trade := orders.BotStockInTradePre(ctx, int64(value.UserId), orderId, value)
if err = uo.CreateBotStockInTrade(session, trade); err != nil {
applogger.Error("%v CreatBotUserInPreStockOrder.CreateBotStockThaTrade:%v", common.ErrSharePre, err)
continue
}
// 写入持仓缓存
resultMsg := share.ShareInrTallyCache{
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 CreatBotUserInPreStockOrder.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 CreatBotUserInPreStockOrder.Marshal:%v", common.ErrSharePre, err)
continue
}
// 写入持仓缓存
if err = Reds.HSet(context.Background(), setting.MarketShareInrPosition, resultMsg.OrderId, string(byteStr)).Err(); err != nil {
continue
}
// 写入用户订单订阅缓存
orderIdKey := virtual.OrderIdListKey(setting.ShareInrSubscribe, resultMsg.UserId)
if err = share.ShareInrHashUserOrder(Reds, orderIdKey, &resultMsg); err != nil {
applogger.Error("%v CreatBotUserInPreStockOrder.ShareThaSubscribe:%v", common.ErrSharePre, err)
return flags.ErrCacheDB
}
// 写入管理员订单订阅缓存
if err = share.ShareInrHashUserOrder(Reds, setting.AdminShareInrSubscribe, &resultMsg); err != nil {
applogger.Error("%v CreatBotUserInPreStockOrder.AdminShareThaSubscribe:%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 {
applogger.Error("CreatBotUserInPreStockOrder.Exists err:%v", err)
continue
}
if checkInt > 0 {
applogger.Debug("用户ID:%v,Ipo未支付OrderNo:%v,订单号:%v", resultMsg.UserId, resultMsg.Order.OrderNo, resultMsg.OrderId)
if err = Reds.Set(ctx, keyCache, resultMsg.OrderId, 0).Err(); err != nil {
applogger.Error("CreatBotUserInPreStockOrder.Set err:%v", err)
}
}
}
return nil
}
// CheckStockInAmount
//
// @Description: 印度股新股申购【创建|更新】用戶资产
// @receiver uo
// @param ctx
// @param userId
// @param stockId
// @param usableNum
// @param frozenNum
// @return bool
// @return error
func (uo *userOrderRepo) CheckStockInAmount(ctx context.Context, userId int64, stockId, usableNum, frozenNum string) (bool, error) {
var botUserStockIn []models.BotUserStockIn
if err := uo.data.mysqlDB.Table(flags.BotUserStockIn).
Where("user_id = ?", userId).
Where("stock_id = ?", stockId).
Find(&botUserStockIn); err != nil {
applogger.Error("%v CheckStockInAmount Find:%v", common.ErrSharePre, err)
return false, err
}
var usableNumOld, frozenNumOld decimal.Decimal
for _, value := range botUserStockIn {
usableNumOld = decimal.RequireFromString(value.UsableNum)
frozenNumOld = decimal.RequireFromString(value.FrozenNum)
}
if len(botUserStockIn) == 0 {
// 创建账户
userStock := orders.CreatBotUserStockInPre(ctx, userId, stockId, usableNum, frozenNum)
_, err := uo.data.mysqlDB.Table(flags.BotUserStockIn).Insert(&userStock)
if err != nil {
applogger.Error("%v CheckStockInAmount Insert:%v", common.ErrSharePre, err)
return false, err
}
} else {
// 更新账户
usableNumNew := usableNumOld.Add(decimal.RequireFromString(usableNum))
frozenNumNew := frozenNumOld.Add(decimal.RequireFromString(frozenNum))
userStock := orders.UpdateBotUserStockInPre(ctx, usableNumNew.String(), frozenNumNew.String())
_, err := uo.data.mysqlDB.Table(flags.BotUserStockIn).
Where("user_id = ?", userId).
Where("stock_id = ?", stockId).
Update(&userStock)
if err != nil {
applogger.Error("%v CheckStockInAmount Update:%v", common.ErrSharePre, err)
return false, err
}
}
return true, nil
}
// UpdateShareInTradeStockId
//
// @Description: 更新-印度股新股申购股票stockId
// @receiver uo
// @param ctx
// @param code
// @param codeOld
// @param stock
// @return error
func (uo *userOrderRepo) UpdateShareInTradeStockId(ctx context.Context, code, codeOld string) error {
// 同步写入股票列表缓存
SubscribeInrHSetCodeList(code, false)
// 新增到印度股缓存列表
if err := Reds.HSet(context.Background(), setting.MarketShareInr, code, code).Err(); err != nil {
applogger.Error("%v UpdateShareInTradeStockId.HSet.MarketShareInr:%v", common.ErrSharePre, err)
return flags.ErrCacheDB
}
session := uo.data.mysqlDB.NewSession()
defer session.Close()
err := session.Begin()
if err != nil {
applogger.Error("%v UpdateShareInTradeStockId.Begin:%v", common.ErrSharePre, err)
return flags.ErrMySqlDB
}
// 1、更新订单股票代码
var userStockTrade []models.BotStockInTrade
if err = session.Table(flags.BotStockInTrade).Where("stock_id =?", codeOld).Find(&userStockTrade); err != nil {
return flags.ErrMySqlDB
}
for _, value := range userStockTrade {
value.StockId = code
// 1、更新订单信息
inCheck, err := session.Table(flags.BotStockInTrade).Where("trade_id =?", value.TradeId).Update(&value)
if err != nil || inCheck <= 0 {
continue
}
// 2、处理缓存订单
orderMap, err := Reds.HGet(context.Background(), setting.AdminShareInrSubscribe, value.OrderId).Result()
if err != nil {
continue
}
var entrustJson share.ShareInrTallyCache
if err = json.Unmarshal([]byte(orderMap), &entrustJson); err != nil {
continue
}
var entrust *share.ShareInrTallyCache
entrust = &entrustJson
if entrust == nil {
continue
}
entrust.Symbol = code
entrust.Order.StockId = code
// 3、处理挂单|持仓|用户订阅|管理员订阅缓存数据
switch value.Status {
case 0: // 挂单
if err = share.ShareInrHashUserOrder(Reds, setting.MarketShareInrEntrust, entrust); err != nil {
continue
}
case 1: // 持仓
if err = share.ShareInrHashUserOrder(Reds, setting.MarketShareInrPosition, entrust); err != nil {
continue
}
default:
continue
}
// 更新用户订阅缓存
cacheKey := fmt.Sprintf("%v-%v", setting.ShareInrSubscribe, entrust.UserId)
if err = share.ShareInrHashUserOrder(Reds, cacheKey, entrust); err != nil {
continue
}
// 更新管理员订阅缓存
if err = share.ShareInrHashUserOrder(Reds, setting.AdminShareInrSubscribe, entrust); err != nil {
continue
}
}
// 2、更新资产表股票代码
var userStock []models.BotUserStockIn
if err = session.Table(flags.BotUserStockIn).Where("stock_id =?", codeOld).Find(&userStock); err != nil {
return flags.ErrMySqlDB
}
for _, value := range userStock {
value.StockId = code
inCheck, err := session.Table(flags.BotUserStockIn).Where("id =?", value.Id).Update(&value)
if err != nil || inCheck <= 0 {
applogger.Error("%v UpdateShareInTradeStockId BotUserStockIn err:%v", common.ErrSharePre, err)
continue
}
}
// 3、更新资产表日志股票代码
var userStockLog []models.BotUserStockInLog
if err = session.Table(flags.BotUserStockInLog).Where("stock_id =?", codeOld).Find(&userStockLog); err != nil {
return flags.ErrMySqlDB
}
for _, value := range userStockLog {
value.StockId = code
inCheck, err := session.Table(flags.BotUserStockInLog).Where("id =?", value.Id).Update(&value)
if err != nil || inCheck <= 0 {
applogger.Error("%v UpdateShareInTradeStockId BotUserStockInLog err:%v", common.ErrSharePre, err)
continue
}
}
if err = session.Commit(); err != nil {
applogger.Error("%v UpdateShareInTradeStockId.Commit:%v", common.ErrSharePre, err)
return flags.ErrMySqlDB
}
return nil
}