Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
T
ts-api-demo
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wmvm
ts-api-demo
Commits
37363b2d
Commit
37363b2d
authored
Oct 22, 2024
by
ml
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加 现货、U、币合约费率相关定时任务 部分接口逻辑修改
parent
76b495db
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
2628 additions
and
44 deletions
+2628
-44
task.fee.rate.log.model.ts
cron/model/task.fee.rate.log.model.ts
+261
-0
task.fee.setting.status.update.model.ts
cron/model/task.fee.setting.status.update.model.ts
+110
-0
marketMakerMgr.service.ts
cron/service/marketMakerMgr.service.ts
+1094
-0
task.fee.setting.status.update.service.ts
cron/service/task.fee.setting.status.update.service.ts
+104
-0
coinAndPairSetting.ts
cron/task/coinAndPairSetting.ts
+1
-1
task_fee_rate_base_coin_contract_log.ts
cron/task/task_fee_rate_base_coin_contract_log.ts
+290
-0
task_fee_rate_contract_log.ts
cron/task/task_fee_rate_contract_log.ts
+293
-0
task_fee_rate_spot_log.ts
cron/task/task_fee_rate_spot_log.ts
+330
-0
task_fee_setting_status_update.ts
cron/task/task_fee_setting_status_update.ts
+30
-0
task_market_maker_statis.ts
cron/task/task_market_maker_statis.ts
+24
-0
commonUserFeeSetting.service.ts
src/functional/mvc/service/commonUserFeeSetting.service.ts
+89
-39
notice.service.ts
src/functional/mvc/service/notice.service.ts
+2
-4
No files found.
cron/model/task.fee.rate.log.model.ts
0 → 100644
View file @
37363b2d
/**
* 原文件:b024-spot.rpc.utils.js
*/
import
{
ormDB
,
userInfo
,
coinType
,
mainUserAsset
,
userInfoSon
,
feeRateSpotLog
,
feeRateContractLog
,
commonUserFeeSetting
,
feeRateBaseCoinContractLog
,
spotPairs
,
contractPairs
}
from
"@madex/ex-ts-dao"
;
import
{
FEE_RATE_LOG_STATUS
}
from
"../../src/constant/feeRateLogConst"
;
import
{
changeTradingFee
,
getPairFromCore
}
from
"../../src/utils/coreSystemUtils"
;
let
BigNumber
=
require
(
'bignumber.js'
);
const
logger
=
require
(
'@madex/ex-js-public'
).
logger
;
let
user_info
=
userInfo
.
prototype
;
let
coin_type
=
coinType
.
prototype
;
let
fee_rate_spot_log
=
feeRateSpotLog
.
prototype
;
let
feeRateCheckStatus
=
FEE_RATE_LOG_STATUS
;
let
WHITE_LIST
:
any
=
[];
const
sleep
=
ms
=>
new
Promise
((
res
)
=>
setTimeout
(
res
,
ms
));
/**
* 检查交易对是否存在
* @param pair
* @param type 1 现货 2 U本位合约 3 币本位合约
*/
let
checkPair
=
async
function
(
pair
:
string
,
type
:
number
)
{
let
_func_name_
=
'task.fee.rate.log.model.checkPair'
;
if
(
!
pair
||
!
type
)
{
throw
'3000'
;
}
let
dbPair
:
any
;
if
(
type
==
1
)
{
//现货
dbPair
=
await
spotPairs
.
prototype
.
findOne
({
attributes
:
[
'id'
],
where
:
{
symbol
:
String
(
pair
),
status
:
2
,
//提交成功
},
raw
:
true
,
});
}
else
{
//U、币本位合约
dbPair
=
await
contractPairs
.
prototype
.
findOne
({
attributes
:
[
'id'
],
where
:
{
symbol
:
String
(
pair
),
status
:
2
,
//提交成功
},
raw
:
true
,
})
}
if
(
!
dbPair
)
{
logger
.
warn
(
_func_name_
,
`spot_pairs or contract_pairs no found
${
pair
}
or no push core`
);
throw
'3000'
;
}
return
dbPair
;
};
let
checkUser
=
async
function
(
user_id
)
{
let
_func_name_
=
'task.fee.rate.log.model.checkUser'
;
if
(
!
user_id
||
isNaN
(
user_id
))
{
throw
'3000'
;
}
let
dbinfo
=
await
user_info
.
findOne
({
attributes
:
[
'user_id'
],
where
:
{
user_id
:
Number
(
user_id
),
},
raw
:
true
,
});
if
(
!
dbinfo
)
{
logger
.
warn
(
_func_name_
,
`user_info no found
${
user_id
}
`
);
throw
'3000'
;
}
return
dbinfo
;
};
let
checkFeeModel
=
async
function
(
fee_model
)
{
let
_func_name_
=
'task.fee.rate.log.model.checkFeeModel'
;
let
validFeeModel
=
{
fixed
:
1
,
fixedingain
:
1
,
tered
:
1
,
tieredingain
:
1
,
fixedingainuser
:
1
,
};
if
(
!
validFeeModel
[
fee_model
])
{
logger
.
warn
(
_func_name_
,
`fee_model error
${
fee_model
}
`
);
throw
'3000'
;
}
};
let
cancelIfSpotFeeExist
=
async
function
(
user_id
,
pair
,
maker_fee
,
taker_fee
,
logId
)
{
//TODO:原来获取正在生效的用户费率查此表 现在 ???
/* let dbFee = await DAO.spotUserFee.prototype.findOne({
where: {
user_id,
pair,
},
raw: true,
});*/
let
feeExist
=
false
;
/*if (dbFee) {
if (dbFee.maker_fee == maker_fee && dbFee.taker_fee == taker_fee) {
feeExist = true;
}
}
else if (maker_fee == 0.001 && taker_fee == 0.002) {
feeExist = true;
}*/
if
(
feeExist
)
{
throw
'fee exist'
;
}
}
let
checkFeeRate
=
async
function
(
fee_rate
)
{
let
_func_name_
=
'spotRpcUtils.checkFeeRate'
;
if
(
isNaN
(
fee_rate
)
||
Math
.
abs
(
Number
(
fee_rate
))
>
0.005
||
fee_rate
<
0
)
{
logger
.
warn
(
_func_name_
,
`fee_rate error
${
fee_rate
}
`
);
throw
'3000'
;
}
};
let
cancelIfContractFeeExist
=
async
function
(
user_id
,
pair
,
maker_fee
,
taker_fee
,
logId
)
{
//TODO:原来获取正在生效的用户费率查此表 现在 ???
/*let dbFee = await baseUUser.prototype.findOne({
where : {
user_id,
pair,
},
raw : true,
});*/
let
feeExist
=
false
;
/*if (dbFee) {
if (dbFee.maker_fee == maker_fee && dbFee.taker_fee == taker_fee) {
feeExist = true;
}
} else if (maker_fee == 0.0004 && taker_fee == 0.00060){
feeExist = true;
}*/
if
(
feeExist
)
{
throw
'fee exist'
;
}
}
export
const
changeUserSpotFee
=
async
function
(
user_id
,
symbol
,
fee_model
,
maker_fee
,
taker_fee
,
logId
)
{
let
is_success
=
true
;
await
checkFeeModel
(
fee_model
);
try
{
await
cancelIfSpotFeeExist
(
user_id
,
symbol
,
maker_fee
,
taker_fee
,
logId
);
}
catch
(
error
)
{
if
(
error
==
'fee exist'
)
{
return
is_success
;
}
}
let
asset
=
await
mainUserAsset
.
prototype
.
findOne
({
where
:
{
user_id
},
raw
:
true
})
if
(
!
asset
)
{
return
is_success
;
}
if
(
isNaN
(
maker_fee
)
||
Math
.
abs
(
Number
(
maker_fee
))
>
0.005
)
{
// maker (-0.005, 0.005); // 正负千五
logger
.
warn
(
' task.fee.rate.log.model.changeUserSpotFee '
,
` maker_fee fee_rate error
${
maker_fee
}
`
);
throw
'3000'
;
}
if
(
isNaN
(
taker_fee
)
||
taker_fee
<
0
||
taker_fee
>
0.005
)
{
// taker 最小为0
logger
.
warn
(
' task.fee.rate.log.model.changeUserSpotFee '
,
` taker_fee fee_rate error
${
taker_fee
}
`
);
throw
'3000'
;
}
await
checkPair
(
symbol
,
1
);
await
checkUser
(
user_id
);
await
sleep
(
1000
);
//请求撮合 修改费率
let
res
=
await
changeTradingFee
(
symbol
,
user_id
,
maker_fee
,
taker_fee
);
return
res
.
is_success
;
};
export
const
changeUserContractFee
=
async
function
(
user_id
,
symbol
,
fee_model
,
maker_fee
,
taker_fee
,
logId
)
{
let
_func_name_
=
'task.fee.rate.log.model.changeUserContractFee'
;
let
is_success
=
true
;
await
checkPair
(
symbol
,
2
);
try
{
await
cancelIfContractFeeExist
(
user_id
,
symbol
,
maker_fee
,
taker_fee
,
logId
);
}
catch
(
error
)
{
if
(
error
==
'fee exist'
)
{
return
is_success
;
}
}
let
asset
=
await
mainUserAsset
.
prototype
.
findOne
({
where
:
{
user_id
},
raw
:
true
})
if
(
!
asset
)
{
return
is_success
;
}
if
(
maker_fee
<
-
0.0003
)
{
// 最大返0.0003
logger
.
warn
(
_func_name_
,
`fee_rate error
${
maker_fee
}
`
);
throw
'3000'
;
}
if
(
taker_fee
<
0
||
taker_fee
>
0.005
)
{
logger
.
warn
(
_func_name_
,
`fee_rate error
${
taker_fee
}
`
);
throw
'3000'
;
}
maker_fee
=
new
BigNumber
(
String
(
maker_fee
)).
toFixed
(
7
);
taker_fee
=
new
BigNumber
(
String
(
taker_fee
)).
toFixed
(
7
);
await
checkUser
(
user_id
);
await
sleep
(
1000
);
//请求撮合 修改费率
let
res
=
await
changeTradingFee
(
symbol
,
user_id
,
maker_fee
,
taker_fee
);
return
res
.
is_success
;
};
export
const
isWhiteListUser
=
async
function
(
user_id
:
number
)
{
let
father_id
=
await
getMainAccountUserId
(
user_id
);
if
(
WHITE_LIST
.
includes
(
father_id
)
||
Number
(
father_id
)
<
100000
)
{
return
true
;
}
return
false
;
}
async
function
getMainAccountUserId
(
user_id
:
number
)
{
let
dbSon
=
await
userInfoSon
.
prototype
.
findOne
({
where
:
{
user_id
:
Number
(
user_id
)
}
});
let
father_id
=
dbSon
?
dbSon
.
father_id
:
user_id
;
return
father_id
;
}
cron/model/task.fee.setting.status.update.model.ts
0 → 100644
View file @
37363b2d
import
{
ormDB
,
feeRateSpotLog
,
feeRateContractLog
,
commonUserFeeSetting
,
feeRateBaseCoinContractLog
}
from
"@madex/ex-ts-dao"
;
import
{
FEE_STATUS
}
from
"../../src/constant/marketMakerConst"
;
const
logger
=
require
(
'@bibox/bibox_public'
).
logger
;
let
OP
=
ormDB
.
Op
;
let
fee_rate_spot_log
=
feeRateSpotLog
.
prototype
;
let
fee_rate_contract_log
=
feeRateContractLog
.
prototype
;
let
fee_rate_base_coin_contract_log
=
feeRateBaseCoinContractLog
.
prototype
;
let
common_user_fee_setting
=
commonUserFeeSetting
.
prototype
;
/**
* 根据id获取币币手续费设置纪录。
* @param id
* @returns {Promise<Model>}
*/
export
const
spotFeeStatusCheck
=
async
function
(
id
)
{
return
await
fee_rate_spot_log
.
findOne
({
attributes
:
[
'id'
,
'is_check'
],
where
:
{
id
:
id
,
},
raw
:
true
,
});
};
/**
* 根据id获取合约手续费设置纪录。
* @param id
* @returns {Promise<Model>}
*/
export
const
contractFeeStatusCheck
=
async
function
(
id
)
{
return
await
fee_rate_contract_log
.
findOne
({
attributes
:
[
'id'
,
'is_check'
],
where
:
{
id
:
id
,
},
raw
:
true
,
});
};
export
const
baseCoinContractFeeStatusCheck
=
async
function
(
id
)
{
return
await
fee_rate_base_coin_contract_log
.
findOne
({
attributes
:
[
'id'
,
'is_check'
],
where
:
{
id
:
id
,
},
raw
:
true
,
});
};
/****************************************** 普通用户费率设置状态更新相关操作。 **********************************************/
/**
* 获取已提交且到开始时间的的记录。
*
* @returns {Promise<Model>}
*/
export
const
findUserFeeDataNeed2Active
=
async
function
()
{
return
await
common_user_fee_setting
.
findAll
({
where
:
{
begin_time
:
{
[
OP
.
lte
]:
new
Date
()
},
status
:
FEE_STATUS
.
STATUS_FEE_SETTING_SUBMIT
,
},
raw
:
true
,
});
};
/**
* 获取已生效且到过期时间的。
*
* @returns {Promise<Model>}
*/
export
const
findUserFeeDataNeed2Expire
=
async
function
()
{
return
await
common_user_fee_setting
.
findAll
({
where
:
{
expire_time
:
{
[
OP
.
lt
]:
new
Date
()
},
status
:
FEE_STATUS
.
STATUS_FEE_SETTING_EFFECTED
,
},
raw
:
true
,
});
};
/**
* 更新手续费设置纪录的状态。
* @returns {Promise<void>}
*/
export
const
userFeeSettingStatusUpdate
=
async
function
(
id
,
status
)
{
try
{
let
toUpdate
=
{
status
:
status
,
update_time
:
new
Date
()
};
let
condition
=
{
id
:
id
,
};
await
common_user_fee_setting
.
update
(
toUpdate
,
{
where
:
condition
});
logger
.
warn
(
"task.fee.setting.status.update.model.userFeeSettingStatusUpdate data update success."
);
}
catch
(
e
)
{
logger
.
error
(
"task.fee.setting.status.update.model.userFeeSettingStatusUpdate data update fail! "
+
"id: %s, status: %s"
,
id
,
status
);
//TODO:发lark
}
};
cron/service/marketMakerMgr.service.ts
0 → 100644
View file @
37363b2d
/*
//
// 做市商 信息管理
//
import {
ormDB,
userInfoSon,
feeRateContractLog,
feeRateSpotLog,
commonUserFeeSetting,
contractPairs,
userInfo
} from "@madex/ex-ts-dao";
const Op = ormDB.Op;
let { resUtils, logger, datetimeUtils }= require('@madex/ex-js-public');
const user_info = userInfo.prototype;
const market_maker = marketMaker.prototype;
const user_daily_trade = DAO.userDailyTrade.prototype;
const contract_daily_fee = DAO.contractDailyFee.prototype;
const ex_trade_detail_spot = DAO.exTradeDetailSpot.prototype;
const ex_kline = DAO.exKlineSpot.prototype;
const pairType = DAO.exPair.PAIR_TYPE;
const user_info_son = userInfoSon.prototype;
const SonStatus = userInfoSon.STATUS;
let feeRateSpotSer = require('./feeRateSpotLog.service');
let redis = require('../../redis/redis-client');
let redisUtilsCommon = require('../../redis/redis.utils');
let ticker = require('../../utils/ticker.utils.js')
const pairMgr = require('../../utils/expair.mgr');
const DAY = 24 * 3600 * 1000;
const FEE_MODEL = {
"fixedingain": "fixedingain"
}
const BTC_AMOUNT = {
"BTC30": 30,
"BTC5": 5,
"BTC0": 0,
},
FEE_RATE = {
"Wan1": 0.0001,
"Wan2": 0.0002,
"Default": 0.001,
"maker_default":0.0008,
"Free": 0,
},
Market_Maker_FEE = {
init_taker: 0.0002,
init_maker: 0,
}
;
//对btc价格,缓存 {coinSymbol: priceInfo}
var price2BTC = {};
//价格缓存时间 2分钟
const CACHE_TIMEOUT = 2 * 60 * 1000;
/!**
* 与btc价格折算
*!/
let marketMakerService = {};
module.exports = marketMakerService;
const marketTypes = Object.values(marketMaker.MAKER_TYPE);
async function delayPromise(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
marketMakerService.add = async function (body) {
let _func_name = "marketMakerService.add";
let { user_id, maker_type, maker_name, maker_mgr } = body;
try {
let maker = await market_maker.findOne({
where: {
user_id: user_id,
maker_type: maker_type,
},
raw: true,
});
if (maker) {
return maker; // 存在该做市商 直接返回
}
let user = await user_info.findOne({
attributes: ['user_id'],
where: {
user_id: user_id
},
raw: true,
})
if (!user) throw '13215';
if (!marketTypes.includes(Number(maker_type))) {
throw '3000'
}
if (maker_name && maker_name.length > 250 || maker_mgr && maker_mgr.length > 250) {
throw '3000'
}
let res = await market_maker.create({
user_id: user_id,
maker_type: Number(maker_type),
maker_name,
maker_mgr
});
return res;
// resUtils.
} catch (error) {
logger.warn(_func_name, error)
throw error;
}
};
marketMakerService.update = async function (body) {
let _func_name = "marketMakerService.update";
let { user_id, maker_type, maker_name, maker_mgr } = body;
try {
if (!marketTypes.includes(maker_type)) {
throw '3000'
}
if (maker_name && maker_name.length > 250 || maker_mgr && maker_mgr.length > 250) {
throw '3000'
}
let maker = await market_maker.findOne({
where: {
user_id: user_id,
},
raw: true,
});
if (maker) {
await market_maker.update({
maker_type: maker_type,
maker_name,
maker_mgr
}, {
where: {
user_id: user_id
}
});
return "ok"
} else {
throw "1002"
}
} catch (error) {
logger.warn(_func_name, error)
throw error;
}
};
// 修改项目方做市交易对
marketMakerService.addProjectMakerPair = async function (body) {
let _func_name = "marketMakerService.updateProjectMaker";
let { user_id, pairArr, amount_require_btc, amount_require_usdt, statis_period } = body;
try {
if (!user_id || !Array.isArray(pairArr)) {
throw '3000'
}
amount_require_btc = parseFloat(amount_require_btc);
amount_require_usdt = parseFloat(amount_require_usdt);
statis_period = parseInt(statis_period);
if (isNaN(amount_require_btc) || amount_require_btc <= 0 || isNaN(amount_require_usdt) || amount_require_usdt <= 0 || isNaN(statis_period) || statis_period <= 0 || statis_period > 30) {
throw '3000';
}
let maker = await market_maker.findOne({
where: {
user_id: user_id,
},
raw: true,
});
let makerPairs = await marketMakerPair.prototype.findAll({
attributes: ['user_id', 'pair'],
where: {
user_id: user_id,
},
raw: true,
});
let hasPairs = [];
if (makerPairs.length > 0) {
for (let i = 0; i < makerPairs.length; i++) {
hasPairs.push(makerPairs[i].pair);
}
}
if (maker) {
if (maker.maker_type != marketMaker.MAKER_TYPE.PROJECT_MAKER) {
throw '3000'
}
let items = [], feeSetItems = [];
for (let i = 0; i < pairArr.length; i++) {
let pairObj = await pairMgr.getPair(pairArr[i]);
let { pair, pair_type } = pairObj;
if (pair_type != pairType.MAIN && pair_type != pairType.NEW) {
throw "3016"
}
if (hasPairs.includes(pair)) continue; //跳过已经添加对交易对;
let [coin_symbol, currency_symbol] = pair.split('_');
items.push({
user_id,
pair: pair,
coin_symbol: coin_symbol,
currency_symbol: currency_symbol,
status: 1,
amount_require_btc,
amount_require_usdt,
statis_period,
});
feeSetItems.push({
user_id, pair,
fee_model: "fixedingain",
maker_fee: 0,
taker_fee: 0,
beginAt: new Date(),
expireAt: new Date(Date.now() + statis_period * DAY),
is_check: 0,
comment: '项目上线项目方做市商费率设置',
}, {
user_id, pair,
fee_model: "fixedingain",
maker_fee: Market_Maker_FEE.init_maker,
taker_fee: Market_Maker_FEE.init_taker, //
beginAt: new Date(Date.now() + statis_period * DAY),
expireAt: new Date(Date.now() + 365 * DAY),
is_check: 0,
comment: '项目上线项目方做市商费率设置_到期配置',
});
}
if (items.length > 0) {
let mkps = await await marketMakerPair.prototype.bulkCreate(items);
await feeRateSpotLog.prototype.bulkCreate(feeSetItems);
return mkps;
} else {
throw '3000'
}
} else {
throw "1002"
}
} catch (error) {
logger.warn(_func_name, error)
throw error;
}
};
// 修改项目方做市交易对
marketMakerService.updateProjectMakePairStatus = async function (body) {
let _func_name = "marketMakerService.updateProjectMakePairStatus";
let { user_id, pair, status } = body;
try {
if (!user_id || !pair) {
throw '3000'
}
status = Number(status);
if(![0, 1].includes(status)){ //
throw '3000'
}
let makerPairs = await marketMakerPair.prototype.findOne({
attributes: ['id','user_id', 'pair'],
where: {
user_id: user_id,
pair: pair
},
raw: true,
});
if(!makerPairs) {
throw '1002';
}
await marketMakerPair.prototype.update({
status: status,
},{
where: {
id: makerPairs.id,
user_id: user_id,
pair: pair
}
});
return 'OK';
} catch (error) {
logger.warn(_func_name, error)
throw error;
}
};
// 删除 交易对
marketMakerService.removeMakerPair = async function (body) {
let {id, user_id, pair } = body;
if(!id || !user_id || !pair) {
throw '3000';
}
let condition = {
id: id,
user_id,
pair,
};
let one = await marketMakerPair.prototype.findOne({
attributes: ['user_id'],
where: condition,
raw: true,
})
if(one) {
return marketMakerPair.prototype.destroy({ where: condition });
} else {
throw '1002';
}
}
marketMakerService.findMarker = async function (user_id) {
let _func_name = "marketMakerService.add";
try {
let res = await market_maker.findOne({
where: {
user_id: user_id,
},
raw: true,
});
if (res) {
res.spotDiscount = [];
res.contractDiscount = [];
res.contractMakerDiscount = 0;
res.contractTakerDiscount = 0;
res.contractExpireAt = 0;
let [spotDiscount, contractDiscount] = await Promise.all([getSpotFeeRate(user_id), getContractFeeRate(user_id)]);
if (spotDiscount) {
res.spotDiscount = spotDiscount;
} if (contractDiscount) {
res.contractDiscount = contractDiscount;
// res.contractMakerDiscount = contractDiscount.maker_fee || 0;
// res.contractTakerDiscount = contractDiscount.taker_fee || 0;
// res.contractExpireAt = contractDiscount.expireAt;
}
} else {
throw '1002';
}
return res;
} catch (error) {
logger.warn(_func_name, error)
throw error;
}
};
marketMakerService.findMarkerList = async function (user_id, maker_type, page, size, callBack) {
let _func_name_ = "marketMakerService.findMarkerList";
let queryObj = {};
if(user_id) {
queryObj['user_id'] = user_id;
}
if(maker_type && marketTypes.includes(maker_type)) {
queryObj['maker_type'] = maker_type;
}
marketMaker.queryPage(queryObj, page, size, [["createdAt", "DESC"]], callBack, err => {
resUtils.dbFail1(err, _func_name_, 'findMarkerList', 'findMarkerList', callBack);
});
};
// 所有做市商成交量排行榜, 先按日期
marketMakerService.findMarkerDeals = async function (begin_time, end_time, makerType) {
let _func_name_ = 'marketMakerService.findMarkerDeals';
let redisKey = [];
if (!datetimeUtils.valid(end_time)) {
end_time = Date.now();
begin_time = end_time - DAY * 7;
}
begin_time = new Date(begin_time).getTime();
end_time = new Date(end_time).getTime();
if (end_time - begin_time >= DAY * 7) {
// throw '2083'; // 超过7天
begin_time = end_time - DAY * 7
}
let begin = begin_time - begin_time % DAY;//获取当天开始时间
let end = end_time - end_time % DAY;//获取当天开始时间
redisKey.push(begin, end);
let userIds = [];
if(Object.values(marketMaker.MAKER_TYPE).includes(makerType)) {
userIds = await getMakerUserID([makerType]);
} else {
userIds = await getMakerUserID();
}
redisKey = 'deal_' + redisKey.join('_');
let resultCache = await redisUtilsCommon.getSync(redisKey);
if (resultCache) {
return resultCache
}
return await Promise.race([delayPromise(5000), getMakerDeals(userIds, begin, end)]).then(dt => {
if (dt && dt.length > 0) {
redisUtilsCommon.writeSync(redisKey, JSON.stringify(dt), 60 * 60 * 4);
return dt;
} else {
throw '2116';
}
}).catch(err => {
logger.error('%s 错误 %s', _func_name_, err);
throw err;
});
};
// 获取指定做市商成交量排行榜, 先按日期
marketMakerService.findOneMarkerDeals = async function (user_id, begin_time, end_time) {
let _func_name_ = 'marketMakerService.findMarkerDeals';
let redisKey = [];
if (!datetimeUtils.valid(end_time)) {
end_time = Date.now();
begin_time = end_time - DAY * 7;
}
begin_time = new Date(begin_time).getTime();
end_time = new Date(end_time).getTime();
if (end_time - begin_time >= DAY * 31) {
// throw '2083'; // 超过7天
begin_time = end_time - DAY * 31
}
let begin = begin_time - begin_time % DAY;//获取当天开始时间
let end = end_time - end_time % DAY;//获取当天开始时间
let res = await market_maker.findOne({
where: {
user_id: user_id,
},
raw: true,
});
if (!res) {
throw "12200";
}
redisKey.push(user_id, begin, end);
redisKey = 'deal_one_' + redisKey.join('_');
let resultCache = await redisUtilsCommon.getSync(redisKey);
if (resultCache) {
return resultCache
}
return await Promise.race([delayPromise(5000), getMakerDeals([user_id], begin, end)]).then(dt => {
if (dt && dt.length > 0) {
let total = calcTotal(dt);
redisUtilsCommon.writeSync(redisKey, JSON.stringify(total), 60 * 60 * 12);
return total;
} else {
throw '2116';
}
}).catch(err => {
logger.error('%s 错误 %s', _func_name_, err);
throw err;
});
};
// 移除不活跃交易对, 将下线币种相关交易对删除
marketMakerService.removeOffLinePair = async function () {
let coin = new Set();
let allCoins = await marketMakerPair.prototype.findAll({
attributes: ['coin_symbol'],
raw: true,
group: ['coin_symbol'],
});
if(allCoins.length === 0) return 0;
for(let i = 0; i < allCoins.length; i++) {
coin.add(allCoins[i] && allCoins[i].coin_symbol);
}
if(coin.size < 1) return 0;
let activeCoin = await coinType.prototype.findAll({
attributes: ['is_active', 'symbol'],
where: {
symbol: {
[Op.in]: [...coin]
},
is_active: 1,
},
raw: true,
});
for(let i = 0; i < activeCoin.length; i++) {
let { symbol }= activeCoin[i];
if(coin.has(symbol)) {
coin.delete(symbol);
}
}
if(coin.size) {
return await marketMakerPair.prototype.destroy({ where: {
coin_symbol: {
[Op.in]: [...coin],
}
}});
} else {
return 0;
}
}
/!**
* 如果用户设置前7日>30BTC并且享受免费, 则一直为免费
* @param {*} user_id
* @param {*} pair
* @param {*} time
*!/
async function getProjectSpotFeeRate(user_id, pair, time) {
let maker = FEE_RATE.maker_default, taker = FEE_RATE.Default;
try {
let res = await feeRateSpotLog.prototype.findOne({
attributes: ['maker_fee', 'taker_fee'],
where: {
user_id: user_id,
pair: pair,
is_check: 1,
beginAt: {[Op.lt]: new Date(time),},
expireAt: {[Op.gte]: new Date(time),}
},
raw: true,
});
if(res && Number(res.maker_fee) >= 0 && Number(res.taker_fee) >= 0 ) {
maker = Number(res.maker_fee);
taker = Number(res.taker_fee);
}
} catch (error) {
logger.warn(' marketMarkerMgr.service ', error);
}
return {
taker,
maker,
}
}
// 每日定时统计项目方 指定交易对做市信息, 并根据成交量信息进行费率分档优惠;
export const statisProjectMakerDeals = async function (now = Date.now()) {
try {
let users = await projectMaker();
let startTime = now - now % DAY - DAY;// 当前统计昨天的成交数据
let btc2usdt = await getDealOneDayInUSDT(startTime, startTime + DAY);
let fatherFeeObj = {}; // { fatherid_pair: {maker, taker}}
for (let i = 0; i < users.length; i++) {
let { user_id, pair, status, statis_period, amount_require_usdt} = users[i]; //status 1 激活时才统计
if (user_id && pair) {
let redisKey = user_id +"_" + pair + "_projectMaker_FeeRate";
await delayPromise(100);
let [statis, statisUsdt] = await statisUserPairSpot(user_id, pair, startTime, btc2usdt);
let feeObjBtc = getUserFeeRateFromStatis(statis); // old
let feeObjUsdt = getUserFeeRateFromUsdtStatis(statisUsdt, statis_period, amount_require_usdt)
await adjustMakerFeeRate(now, user_id, pair, status, feeObjBtc, feeObjUsdt, fatherFeeObj);
redisUtilsCommon.write(redisKey, JSON.stringify(Object.assign({}, feeObjUsdt, feeObjBtc)), 0, () => { });
}
}
now = Date.now();
let expired = now + DAY - 30000;
for(let key in fatherFeeObj) {
let [user_id, pair] = key.split('@');
let faterFee = fatherFeeObj[key];
if(faterFee) {
let { maker_fee, taker_fee } = faterFee;
await setExpiredFeeSettingActiveOver(user_id, pair);
await feeRateSpotSer.add(user_id, pair, FEE_MODEL.fixedingain, maker_fee, taker_fee, now, expired, Market_Maker_FEE.init_maker, Market_Maker_FEE.init_taker, "项目方做市商策略根据子账户交易量设置父账户费率");
}
}
} catch (error) {
logger.warn(' statisProjectMakerDeals error ', error);
}
}
// 获取项目方做市商成交信息
marketMakerService.findProjectMakerInfo = async function (user_id) {
let res = [];
try {
let projectMakers = await marketMakerPair.prototype.findAll({
where: {
user_id: user_id,
},
raw: true,
});
let redisPro = []
for (let i = 0; i < projectMakers.length; i++) {
let maker = projectMakers[i];
if (maker) {
let { user_id, pair } = maker;
if (user_id && pair) {
let redisKey = user_id + "_" + pair + "_projectMaker_FeeRate";
let redisDt = await redisUtilsCommon.getSync(redisKey);
res.push(Object.assign({}, redisDt || {}, maker));
}
}
}
} catch (error) {
logger.warn(' findProjectMakerInfo error', error);
}
return res;
}
// 调整做市商费率最佳
async function adjustMakerFeeRate(now, user_id, pair, enableAjustFee, feeObjBtc = {}, feeObjUsdt = {}, fatherFeeObj = {}) {
// let now = Date.now();
let expired = new Date(now).getTime() + DAY - 30000; // 有效期提前30s,早于新费率开始时间
console.error(' 执行项目做市商 uid %s , %s 费率调整 ', user_id, pair);
let maker_fee = Market_Maker_FEE.init_maker, taker_fee = Market_Maker_FEE.init_taker;
let {maker, taker} = await getProjectSpotFeeRate(user_id, pair, now - 3600000);// 查询费率变更前的费率 0 则继续免费
if(enableAjustFee) {
if(feeObjUsdt && feeObjUsdt.canAjustFeeRateUsdt) { // 新版usdt计量策略优先
console.error(' 新做市策略 ', JSON.stringify(feeObjUsdt));
if(taker_fee > feeObjUsdt.taker_rate ) { // taker_rate, maker_rate,
taker_fee = feeObjUsdt.taker_rate;
}
if(maker_fee > feeObjUsdt.maker_rate) {
maker_fee = feeObjUsdt.maker_rate;
}
await storeFatherFeeSet(user_id, pair, maker_fee, taker_fee, fatherFeeObj);
await setExpiredFeeSettingActiveOver(user_id, pair);
return await feeRateSpotSer.add(user_id, pair, FEE_MODEL.fixedingain, maker_fee, taker_fee, now, expired, Market_Maker_FEE.init_maker, Market_Maker_FEE.init_taker, "项目方做市商根据usdt成交量自动调整");
} else if(feeObjBtc && feeObjBtc.canAjustFeeRateBTC) { // 执行老版 btc 计量策略
console.error(' 早期做市策略 ', JSON.stringify(feeObjBtc));
if(maker==FEE_RATE.Free && taker == FEE_RATE.Free && feeObjBtc.feeRate == FEE_RATE.Wan1) {//手动设置,默认免手续费;若项目单个交易对连续7天日均交易量达到30BTC以上,该交易对手续费保持免费;(运营加需求)
await storeFatherFeeSet(user_id, pair, FEE_RATE.Free, FEE_RATE.Free, fatherFeeObj);
await setExpiredFeeSettingActiveOver(user_id, pair);
return await feeRateSpotSer.add(user_id, pair, FEE_MODEL.fixedingain, FEE_RATE.Free, FEE_RATE.Free, now, expired, Market_Maker_FEE.init_maker, Market_Maker_FEE.init_taker, "项目方做市商根据btc成交量自动调整");
}
else {
console.error(' 早期做市策略 ', JSON.stringify(feeObjBtc));
// maker_fee = feeObjBtc.feeRate, taker_fee = feeObjBtc.feeRate;
maker_fee = Math.min(maker_fee, feeObjBtc.feeRate), taker_fee = Math.min(taker_fee, feeObjBtc.feeRate);
await storeFatherFeeSet(user_id, pair, maker_fee, taker_fee, fatherFeeObj);
await setExpiredFeeSettingActiveOver(user_id, pair);
return await feeRateSpotSer.add(user_id, pair, FEE_MODEL.fixedingain, maker_fee, taker_fee, now, expired, Market_Maker_FEE.init_maker, Market_Maker_FEE.init_taker, "项目方做市商策略根据btc成交量自动调整");
}
}
}
}
async function storeFatherFeeSet(user_id, pair, maker_fee, taker_fee, fatherFeeObj = {}) {
let faterObj = await getFaterUID(user_id);
if(faterObj && faterObj.father_id) {
let key = faterObj.father_id +"@"+ pair;
if(!fatherFeeObj[key]) {
fatherFeeObj[key] = {
pair,
maker_fee,
taker_fee
}
} else {
fatherFeeObj[key] = {
pair,
maker_fee: Math.min(maker_fee, fatherFeeObj[key].maker_fee),
taker_fee: Math.min(taker_fee, fatherFeeObj[key].taker_fee),
}
}
}
logger.info(' father fee setting ', JSON.stringify(fatherFeeObj));
}
// 将即过期默认为生效的置为生效完成, 防止覆盖新的费率
async function setExpiredFeeSettingActiveOver(user_id, pair ) {
try {
let now = new Date();
// console.log(' 更新做市商即将到期生效的费率', user_id, pair);
let res = await feeRateSpotLog.prototype.update({
is_check: feeRateSpotLog.IS_CHECK.ActiveOver,
},{
where: {
user_id: user_id,
pair: pair,
is_check: feeRateSpotLog.IS_CHECK.Uncheck,
beginAt: {
[Op.gte]: now,
[Op.lt]: new Date(now.getTime() + 3600*1000)
},
}
});
// console.error(' 使当前未生效过期 res ', JSON.stringify(res));
} catch (error) {
logger.error(' make expried fee setting active_over: error ', error);
}
}
async function getSpotFeeRate(user_id) {
let order = [['beginAt', 'desc']];
let res = await feeRateSpotLog.prototype.findAll({
where: {
user_id: user_id,
is_check: 1,//已经生效
},
order,
raw: true,
});
return res;
}
// 获取合约费率
async function getContractFeeRate(user_id) {
let order = [['beginAt', 'desc']];
let res = await feeRateContractLog.prototype.findAll({
where: {
user_id: user_id,
is_check: 1,//已经生效
},
order,
raw: true,
});
return res;
}
// 获取某个子账户的父账户
async function getFaterUID(user_id) {
return user_info_son.findOne({
attributes: ['father_id'],
where: {
user_id,
status: SonStatus.NORMAL,
},
raw: true,
});
}
async function getMakerDeals(userIds, start, end) {
let res = [];
try {
if (userIds.length === 0) return [];
let [spot, contract] = await Promise.all([getSpotDeals(userIds, start, end), getUserContractDeals(userIds, start, end)]);
for (let tm = end; tm >= start; tm -= DAY) { // 按时间倒叙排列
for (let id = 0; id < userIds.length; id++) {
let tkey = tm + "_" + userIds[id] + "_taker";
let mkey = tm + "_" + userIds[id] + "_maker";
let obj = {
time: tm,
user_id: userIds[id],
spotTaker: (Number(spot[tkey]) || 0).toFixed(4), // usdt 计价
spotMaker: (Number(spot[mkey]) || 0).toFixed(4), // usdt 计价
contractTaker: (Number(contract[tkey]) || 0).toFixed(4), // btc 计价
contractMaker: (Number(contract[mkey]) || 0).toFixed(4), // btc计价
}
res.push(obj);
}
}
} catch (error) {
logger.warn('getMakerDeals error', error);
}
return res;
}
function calcTotal(dt) {
try {
let spot_taker = 0, spot_maker = 0, contract_taker = 0, contract_maker = 0;
for (let i = 0; i < dt.length; i++) {
let { spotTaker, spotMaker, contractTaker, contractMaker } = dt[i];
spot_taker += Number(spotTaker),
spot_maker += Number(spotMaker),
contract_taker += Number(contractTaker),
contract_maker += Number(contractMaker);
}
return {
items: dt,
spot_taker,
spot_maker,
contract_taker,
contract_maker
}
} catch (error) {
logger.warn('calcTotal error', error);
}
}
async function getMakerUserID(makerTypes = [marketMaker.MAKER_TYPE.NORMAL, marketMaker.MAKER_TYPE.PLATFORM_MAKER, marketMaker.MAKER_TYPE.PROJECT_MAKER]) {
let userId = [];
try {
let user = await market_maker.findAll({
attributes: ['user_id'],
where: {
maker_type: { [Op.in]: makerTypes} //平台做市商与项目方做市商
},
raw: true,
});
for (let i = 0; i < user.length; i++) {
if (user[i] && user[i].user_id) {
userId.push(user[i].user_id)
}
}
} catch (error) {
logger.warn("getMakerUserID 获取做市商用户ID异常", error)
}
return userId;
};
//
async function getSpotDeals(userids, startTime, endTime) {
let resObj = {};
try {
let spotdels = await user_daily_trade.findAll({
attributes: ['equal_usdt', 'equal_btc_maker', 'equal_btc_taker', 'trade_date', 'user_id'],
where: {
user_id: {
[Op.in]: userids
},
trade_date: {
[Op.gte]: startTime,
[Op.lt]: endTime,
}
},
order: [['trade_date', 'desc'], ['equal_usdt', 'desc']]
});
for (let i = 0; i < spotdels.length; i++) {
let { equal_btc_maker, equal_btc_taker, user_id, trade_date, equal_usdt } = spotdels[i];
if (equal_usdt > 0) {
let Key = new Date(trade_date).getTime() + "_" + user_id;
// let maker_usdt = equal_usdt * equal_btc_maker / equal_btc;
// spotdels[i]['maker_usdt'] = maker_usdt;
// spotdels[i]['taker_usdt'] = equal_usdt - maker_usdt;
// resObj[Key] = spotdels[i];
resObj[Key + "_maker"] = equal_btc_maker;
resObj[Key + "_taker"] = equal_btc_taker;
}
}
} catch (error) {
logger.warn("getSpotDeals error", error);
}
return resObj;
}
/!**
* 用户成交记录详情 maker taker 量
* @param {*} userids
*!/
async function getUserContractDeals(userids, startTime, endTime) {
// 获取用户
let objAll = {};
try {
let order_detail = await contract_daily_fee.findAll({
attributes: [
'user_id',
'createdAt',
[ormDBCon.literal('sum(equal_btc_amount_maker)'), 'equal_btc_amount_maker'],
[ormDBCon.literal('sum(equal_btc_amount_taker)'), 'equal_btc_amount_taker'],
],
where: {
user_id: {
[Op.in]: userids
},
createdAt: {
[Op.gte]: startTime,
[Op.lt]: endTime,
},
},
group: ['createdAt', 'user_id'],
raw: true,
});
for (let i = 0; i < order_detail.length; i++) {
let order = order_detail[i];
let { user_id, createdAt, equal_btc_amount_maker, equal_btc_amount_taker } = order;
let key = new Date(createdAt).getTime() + "_" + user_id;
objAll[key + "_maker"] = equal_btc_amount_maker;
objAll[key + "_taker"] = equal_btc_amount_taker;
}
}
catch (error) {
logger.warn('getUserContractDeals error', error);
}
return objAll;
}
// 统计 项目方 7日, 15日 指定币种对 做市
async function projectMaker() {
let res = [];
try {
res = await marketMakerPair.prototype.findAll({
// where: { // 统计全部交易对, status = 1时才设置费率
// status: 1, // 激活
// },
order: [['id','asc']],
raw: true,
});
} catch (error) {
logger.warn(' 获取项目方做市商 projectMaker error', error);
}
return res;
}
// 获取昨天一天的的统计交易量
// 该交易对对所有交易量都归该做市帐号
async function getDealOneDay(pair, startTime, endTime) {
let resCountInBTC = 0;
try {
let tradeDetail = await ex_trade_detail_spot.find({
attributes: ['currency_symbol', [ormDBSpot.literal('SUM(deal_money)'), 'deal_money']],
where: {
pair: pair,
createdAt: {
[Op.gte]: startTime,
[Op.lt]: endTime,
}
},
group: ['currency_symbol'],
raw: true,
});
if (tradeDetail && tradeDetail.deal_money > 0.00000001) {
let currencySymbol = tradeDetail.currency_symbol;
let currencyAmount = tradeDetail.deal_money;
let price = await coinPriceInBTC(currencySymbol, startTime, endTime);
let equalBTC = currencyAmount * price;
// let equalBTC = currencyAmount * 0.001;
if (equalBTC >= 0.00000001) {
resCountInBTC = equalBTC;
}
}
} catch (error) {
logger.error(" 查询用户每天做市量出错 ", error);
}
return resCountInBTC;
}
async function coinPriceInBTC(coinSymbol, startTime, endTime) {
let time = Date.now();
if(!coinSymbol) {
logger.error(' coinSymbol illegal, coinSymbol is: ',coinSymbol);
}
let priceInfo = price2BTC[coinSymbol];
if (coinSymbol === 'BTC') {
//BTC无转换
return 1;
} else if (priceInfo && (time - priceInfo.updatedTime) <= CACHE_TIMEOUT) {
return priceInfo.price;
} else {
//拉取24小时平均价格
let tickerPair, lastPrice = 0;
if (coinSymbol === 'USDT' || coinSymbol === 'DAI' || coinSymbol === 'GUSD') {
tickerPair = 'BTC_' + coinSymbol;
} else {
tickerPair = coinSymbol + '_BTC';
}
try {
let priceRes = await ex_kline.find({
attributes: [[ormDBSpot.literal('AVG(close)'), 'closePrice']],
where: {
pair: tickerPair,
period: '1hour',
createdAt: {
[Op.gte]: startTime,
[Op.lt]: endTime,
}
},
raw: true,
});
if (priceRes && priceRes.closePrice > 0) {
if (coinSymbol === 'USDT' || coinSymbol === 'DAI' || coinSymbol === 'GUSD') {
lastPrice = 1 / priceRes.closePrice;
} else {
lastPrice = priceRes.closePrice;
}
price2BTC[coinSymbol] = { updatedTime: Date.now(), price: lastPrice };
} else {
logger.warn(` 未查询到交易对${tickerPair} 24hour均值`, priceRes);
}
return lastPrice;
} catch (error) {
logger.warn(` 查询到交易对${tickerPair} 24hour均值出错 `, error);
price2BTC[coinSymbol] = { updatedTime: Date.now(), price: 0 };
return 0;
}
}
}
marketMakerService.getDealOneDayInUSDT = getDealOneDayInUSDT;
// 获取交易对USDT交易量
async function getDealOneDayInUSDT(startTime, endTime) {
let price = await ticker.rateCoin2USDT('BTC');
let priceRes = await ex_kline.find({
attributes: [[ormDBSpot.literal('AVG(close)'), 'closePrice']],
where: {
pair: "BTC_USDT",
period: '1hour',
createdAt: {
[Op.gte]: new Date(startTime),
[Op.lt]: new Date(endTime),
}
},
raw: true,
});
if(priceRes && Number(priceRes.closePrice) > 0) {
price = Number(priceRes.closePrice).toFixed(4);
}
return Number(price);
}
// 统计币币成交量信息
async function statisUserPairSpot(user_id, pair, timestamp, btc2usdt) {
let redisKey = user_id + "_" + pair + '_projectMaker_spot';
let redisKeyUsdt = user_id + "_" + pair + '_projectMaker_spot_usdt';
let resultCache = {}, resultCacheInUsdt = {} ;
try {
[resultCache, resultCacheInUsdt] = await Promise.all([redisUtilsCommon.getSync(redisKey), redisUtilsCommon.getSync(redisKeyUsdt)]) ;
let userDeals = await getDealOneDay(pair, new Date(timestamp), timestamp + DAY);
resultCache = updateCache(resultCache, timestamp, userDeals);
let usdtAmount = Number(userDeals) * btc2usdt
resultCacheInUsdt = updateCache(resultCacheInUsdt, timestamp, usdtAmount);
redisUtilsCommon.write(redisKey, JSON.stringify(resultCache), 0, () => { });
redisUtilsCommon.write(redisKeyUsdt, JSON.stringify(resultCacheInUsdt), 0, () => { });
} catch (error) {
logger.warn(' 统计项目做市上成交总和 error ', error);
}
return [resultCache, resultCacheInUsdt];
}
function updateCache(resultCache, timestamp, userDeals) {
if (resultCache) {
let timesArr = Object.keys(resultCache);
if (!timesArr.includes(String(timestamp)) && userDeals > 0) {//是否存在今天的数据
resultCache[timestamp] = userDeals;
}
if (timesArr.length > 31) {
for (let i = 0, len = timesArr.length - 31; i < len; i++) {
if (timestamp - Number(timesArr[i]) > 31 * DAY) { // 删除超过30天的缓存数据
delete resultCache[timesArr[i]];
}
}
}
} else { // 无缓存数据
if (userDeals > 0) {
resultCache = {
[timestamp]: userDeals
}
}
}
return Object.assign({}, resultCache);
}
// 从统计结果中获取用户费率, 旧btc交易量统计会逐渐改为usdt统计
function getUserFeeRateFromStatis(dealAmountCache) {
let feeRate = FEE_RATE.Default, avg7 = 0, avg15 = 0, canAjustFeeRateBTC = false;
try {
const day7 = 7, day15 = 15;
let timeArr = Object.keys(dealAmountCache), len = timeArr.length, sum;
let feeRate7 = FEE_RATE.Default, feeRate15 = FEE_RATE.Default;
if(len > 0 && len < day7) {// 低于 7 天
sum = 0;
for (let i = 0; i < len; i++) {
let ts = timeArr[i];
sum += Number(dealAmountCache[ts]) || 0;
}
avg7 = sum / len;
}
if (len >= day7) {
canAjustFeeRateBTC = true;
sum = 0;
for (let i = len - 1, stopIndex = len - day7; i >= stopIndex; i--) {
let ts = timeArr[i];
sum += Number(dealAmountCache[ts]) || 0;
}
avg7 = sum / day7;
if (avg7 >= BTC_AMOUNT.BTC30) {
feeRate7 = FEE_RATE.Wan1;
} else if (avg7 >= BTC_AMOUNT.BTC5) {
feeRate7 = FEE_RATE.Wan2;
} else if (avg7 > BTC_AMOUNT.BTC0) {
feeRate7 = FEE_RATE.Default;
}
}
if (len >= day15) {
sum = 0;
for (let i = len - 1, stopIndex = len - day15; i >= stopIndex; i--) {
let ts = timeArr[i];
sum += Number(dealAmountCache[ts]) || 0;
}
avg15 = sum / day15;
if (avg15 >= BTC_AMOUNT.BTC30) {
feeRate15 = FEE_RATE.Free;
} else if (avg15 >= BTC_AMOUNT.BTC5) {
feeRate15 = FEE_RATE.Wan2;
} else if (avg15 > BTC_AMOUNT.BTC0) {
feeRate15 = FEE_RATE.Default;
}
}
feeRate = Math.min(feeRate7, feeRate15);
} catch (error) {
logger.warn(' getUserFeeRateFromStatis error', error);
}
return { feeRate, avg7, avg15, canAjustFeeRateBTC};
}
// 增加usdt统计需求,
function getUserFeeRateFromUsdtStatis(dealAmount, statis_period, requireAmount = 100000) {
let timeArr = Object.keys(dealAmount), len = timeArr.length, canAjustFeeRateUsdt = false, sum = 0, avg = 0;
let taker_rate = 0.0002, maker_rate = 0; // 新项目做市商需求,如果<100K, taker 0.02%, maker = 0;
if(len > 0 && len < statis_period) {
for(let i = 0; i < len; i++) {
let ts = timeArr[i];
sum += Number(dealAmount[ts]) || 0;
}
avg = sum / len;
} else if(len >= statis_period) {
canAjustFeeRateUsdt = true;
sum = 0;
for (let i = len - 1, stopIndex = len - statis_period; i >= stopIndex; i--) {
let ts = timeArr[i];
sum += Number(dealAmount[ts]) || 0;
}
avg = sum / statis_period;
if(avg >= requireAmount) {
taker_rate = 0;
}
}
return { taker_rate, maker_rate, avg_usdt: avg, canAjustFeeRateUsdt};
}
*/
cron/service/task.fee.setting.status.update.service.ts
0 → 100644
View file @
37363b2d
import
{
FEE_STATUS
,
FEE_TYPE
}
from
"../../src/constant/marketMakerConst"
;
let
{
logger
}
=
require
(
'@madex/ex-js-public'
);
let
{
spotFeeStatusCheck
,
contractFeeStatusCheck
,
baseCoinContractFeeStatusCheck
,
findUserFeeDataNeed2Active
,
findUserFeeDataNeed2Expire
,
userFeeSettingStatusUpdate
}
=
require
(
'../model/task.fee.setting.status.update.model'
);
/**
* 币币、合约费率设置记录状态。
*/
import
{
FEE_RATE_LOG_STATUS
}
from
"../../src/constant/feeRateLogConst"
;
/****************************************** 普通用户费率设置状态更新相关操作。 **********************************************/
/**
* 市商、普通用户、KOL 费率状态更新。
* @returns {Promise<void>}
*/
export
const
commonUserFeeSettingStatusUpdateService
=
async
function
(
ctime
=
new
Date
())
{
try
{
await
commonUserStatusUpdate
();
}
catch
(
error
)
{
logger
.
error
(
' commonUserFeeSettingStatusUpdate error '
,
error
);
}
logger
.
warn
(
' commonUserFeeSettingStatusUpdate '
,
ctime
,
' stat over '
);
};
/**
* 状态扫描和更新。
* @returns {Promise<void>}
*/
async
function
commonUserStatusUpdate
()
{
let
[
data2Submit
,
data2Expire
]
=
await
Promise
.
all
([
findUserFeeDataNeed2Active
(),
findUserFeeDataNeed2Expire
()]);
await
userDataCheckAndUpdate
(
data2Submit
);
await
userDataCheckAndUpdate
(
data2Expire
);
}
/**
* 检查数据情况并更新状态。
* @param data
* @returns {Promise<void>}
*/
async
function
userDataCheckAndUpdate
(
data
)
{
if
(
data
===
null
||
data
.
length
===
0
)
{
return
;
}
for
(
let
i
=
0
,
len
=
data
.
length
;
i
<
len
;
i
++
)
{
let
item
=
data
[
i
];
let
id
=
item
.
id
;
let
logIds
=
item
.
fee_log_ids
;
let
idArr
=
logIds
.
split
(
","
);
if
(
idArr
===
null
||
idArr
.
length
===
0
)
{
logger
.
error
(
"commonUserFeeSettingStatusUpdate.userDataCheckAndUpdate log id parse fail! id: %s"
,
id
);
continue
;
}
// 根据记录id确定该设置项的状态。
let
logId
=
idArr
[
0
];
let
feeStatusData
;
if
(
Number
(
item
.
type
)
===
FEE_TYPE
.
FEE_TYPE_SPOT
)
{
feeStatusData
=
await
spotFeeStatusCheck
(
logId
);
}
else
if
(
Number
(
item
.
type
)
===
FEE_TYPE
.
FEE_TYPE_CONTRACT
)
{
feeStatusData
=
await
contractFeeStatusCheck
(
logId
);
}
else
if
(
Number
(
item
.
type
)
===
FEE_TYPE
.
FEE_TYPE_BASE_COIN_CONTRACT
)
{
feeStatusData
=
await
baseCoinContractFeeStatusCheck
(
logId
);
}
if
(
feeStatusData
===
null
)
{
logger
.
error
(
"commonUserFeeSettingStatusUpdate.userDataCheckAndUpdate fee setting record miss! "
+
"id: %s, logId: %s"
,
id
,
logId
);
continue
;
}
let
status
=
item
.
status
;
let
statusNew
=
status
;
let
feeStatus
=
Number
(
feeStatusData
.
is_check
);
switch
(
feeStatus
)
{
case
FEE_RATE_LOG_STATUS
.
CHECK_STATUS_ACTIVE
:
statusNew
=
FEE_STATUS
.
STATUS_FEE_SETTING_EFFECTED
;
break
;
case
FEE_RATE_LOG_STATUS
.
CHECK_STATUS_ACTIVE_OVER
:
statusNew
=
FEE_STATUS
.
STATUS_FEE_SETTING_EXPIRE
;
break
;
case
FEE_RATE_LOG_STATUS
.
CHECK_STATUS_DELETED
:
statusNew
=
FEE_STATUS
.
STATUS_FEE_SETTING_DELETED
;
break
;
default
:
continue
;
}
if
(
statusNew
!==
status
)
{
await
userFeeSettingStatusUpdate
(
id
,
statusNew
);
logger
.
info
(
"commonUserFeeSettingStatusUpdate.userDataCheckAndUpdate log(%s) status updated. %s -> %s"
,
id
,
status
,
statusNew
);
}
}
}
\ No newline at end of file
cron/coinAndPairSetting.ts
→
cron/
task/
coinAndPairSetting.ts
View file @
37363b2d
...
@@ -5,7 +5,7 @@ const schedule = require('node-schedule');
...
@@ -5,7 +5,7 @@ const schedule = require('node-schedule');
let
{
logger
,
datetimeUtils
}
=
require
(
'@madex/ex-js-public'
);
let
{
logger
,
datetimeUtils
}
=
require
(
'@madex/ex-js-public'
);
import
{
spotPairs
,
ormDB
,
coinType
}
from
"@madex/ex-ts-dao"
;
import
{
spotPairs
,
ormDB
,
coinType
}
from
"@madex/ex-ts-dao"
;
import
{
getPairFromCore
,
getCoinFromCore
}
from
'../src/utils/coreSystemUtils'
import
{
getPairFromCore
,
getCoinFromCore
}
from
'../
../
src/utils/coreSystemUtils'
let
running
=
false
;
let
running
=
false
;
...
...
cron/task/task_fee_rate_base_coin_contract_log.ts
0 → 100644
View file @
37363b2d
import
{
ormDB
,
userInfoSon
,
feeRateBaseCoinContractLog
,
contractPairs
}
from
"@madex/ex-ts-dao"
;
import
{
FEE_RATE_LOG_STATUS
}
from
"../../src/constant/feeRateLogConst"
;
import
{
changeUserContractFee
,
isWhiteListUser
}
from
"../model/task.fee.rate.log.model"
;
const
schedule
=
require
(
'node-schedule'
);
const
{
logger
,
daoType
}
=
require
(
'@madex/ex-js-public'
);
let
fee_rate_base_coin_contract_log
=
feeRateBaseCoinContractLog
.
prototype
;
let
feeRateCheckStatus
=
FEE_RATE_LOG_STATUS
;
let
user_info_son
=
userInfoSon
.
prototype
;
let
Op
=
ormDB
.
Op
;
const
oneHour
=
1000
*
60
*
60
;
const
oneDay
=
oneHour
*
24
;
const
oneMonth
=
oneDay
*
30
;
let
inJob
=
false
;
let
limit
=
3000
;
/**
* 注意:
* fee_rate_spot_log
* fee_rate_contract_log
* fee_rate_base_coin_contract_log
* 相关表中不支持 all 或 ALL 交易对
* 管理后台配置用户费率的 all 交易对也是分多个交易对来处理的
* 即(common_user_fee_setting 中的 all 分多个交易对 设置到 fee_rate_log 表中)
*/
let
setFeeRateJob
=
schedule
.
scheduleJob
(
'*/30 * * * * *'
,
function
()
{
if
(
inJob
)
{
return
;
}
inJob
=
true
;
doJob
().
catch
(
err
=>
{
logger
.
warn
(
'setFeeRateJob'
,
err
);
}).
then
(()
=>
{
inJob
=
false
;
});
});
let
setDefaultRun
=
false
;
let
setExpiredDefaultJob
=
schedule
.
scheduleJob
(
'*/5 * * * *'
,
function
()
{
logger
.
info
(
' base coin contract setExpiredDefaultJob run '
,
new
Date
().
toISOString
());
if
(
setDefaultRun
)
{
return
;
}
setDefaultRun
=
true
;
setExpiredDefault
().
then
(
res
=>
{
setDefaultRun
=
false
;
}).
catch
(
err
=>
{
setDefaultRun
=
false
;
logger
.
warn
(
'base coin contract setFeeRateJob'
,
err
);
})
});
let
doJob
=
async
function
()
{
let
ctm
=
new
Date
();
let
dblogs
=
await
fee_rate_base_coin_contract_log
.
findAll
({
where
:
{
is_check
:
0
,
beginAt
:
{
[
Op
.
lte
]:
ctm
},
expireAt
:
{
[
Op
.
gte
]:
ctm
},
taker_fee
:
{
[
Op
.
gte
]:
0.0002
},
},
limit
:
limit
,
raw
:
true
,
});
for
(
let
i
=
0
;
i
<
dblogs
.
length
;
i
++
)
{
if
(
await
isWhiteListUser
(
dblogs
[
i
].
user_id
)
&&
dblogs
[
i
].
comment
&&
dblogs
[
i
].
comment
.
indexOf
(
'到期'
)
!=
-
1
)
{
continue
;
}
if
(
Number
(
dblogs
[
i
].
maker_fee
)
<
0
&&
(
Math
.
abs
(
Number
(
dblogs
[
i
].
maker_fee
))
>
Math
.
abs
(
Number
(
dblogs
[
i
].
taker_fee
))))
{
continue
;
}
await
changeOneFee
(
dblogs
[
i
]);
}
await
removeOldLog
();
};
let
changeOneFee
=
async
function
(
dblog
)
{
let
transaction
;
return
changeUserContractFee
(
dblog
.
user_id
,
dblog
.
pair
,
dblog
.
fee_model
,
dblog
.
maker_fee
,
dblog
.
taker_fee
,
dblog
.
id
).
then
(
async
res
=>
{
if
(
!
res
)
{
throw
'changeUserFee fail'
;
}
let
dbsons
=
await
user_info_son
.
findAll
({
attributes
:
[
'user_id'
,
'type'
],
where
:
{
father_id
:
dblog
.
user_id
,
// status: userInfoSon.STATUS.NORMAL, // 量化交易内部创建的账号需要变更手续费;
},
raw
:
true
,
});
let
son_fee_rate
:
any
=
[];
for
(
let
i
=
0
;
i
<
dbsons
.
length
;
i
++
)
{
let
son
=
dbsons
[
i
];
son_fee_rate
.
push
({
user_id
:
son
.
user_id
,
pair
:
dblog
.
pair
,
fee_model
:
dblog
.
fee_model
,
maker_fee
:
dblog
.
maker_fee
,
taker_fee
:
dblog
.
taker_fee
,
beginAt
:
new
Date
(),
expireAt
:
dblog
.
expireAt
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
comment
:
'继承父账户费率'
,
});
}
transaction
=
await
ormDB
.
transaction
();
await
fee_rate_base_coin_contract_log
.
update
({
// 将当前生效中的值置为过期
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
},
{
where
:
{
user_id
:
dblog
.
user_id
,
pair
:
dblog
.
pair
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
},
transaction
:
transaction
,
});
await
fee_rate_base_coin_contract_log
.
update
({
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
},
{
where
:
{
id
:
dblog
.
id
,
user_id
:
dblog
.
user_id
,
pair
:
dblog
.
pair
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
},
transaction
:
transaction
,
});
if
(
son_fee_rate
.
length
>
0
)
{
await
fee_rate_base_coin_contract_log
.
bulkCreate
(
son_fee_rate
,
{
transaction
:
transaction
,
});
}
await
transaction
.
commit
();
transaction
=
null
;
}).
catch
(
async
err
=>
{
if
(
transaction
)
{
await
transaction
.
rollback
();
transaction
=
null
;
}
logger
.
warn
(
'base.coin.setFeeRateJob.changeOneFee'
,
dblog
,
err
);
});
};
let
removeOldLog
=
async
function
()
{
let
ctm
=
Date
.
now
();
let
etm
=
new
Date
(
ctm
-
1000
*
60
*
60
*
24
*
31
);
await
fee_rate_base_coin_contract_log
.
destroy
({
where
:
{
is_check
:
{
[
Op
.
in
]:
[
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
feeRateCheckStatus
.
CHECK_STATUS_DELETED
,
]
},
updatedAt
:
{
[
Op
.
lt
]:
etm
},
}
});
};
// 过期费率处理
async
function
setExpiredDefault
()
{
let
comment
=
'费率到期系统自动调整为基础费率'
;
let
ctm
=
new
Date
(
Date
.
now
()
-
oneDay
);
// 已经过期;
let
expirdFees
=
await
fee_rate_base_coin_contract_log
.
findAll
({
attributes
:
[
'user_id'
,
'pair'
,
'fee_model'
,
'maker_fee'
,
'taker_fee'
],
where
:
{
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
// 正在生效中的
expireAt
:
{
[
Op
.
lte
]:
ctm
},
},
limit
:
500
,
// 后边处理插入时可以单次插入
raw
:
true
,
});
if
(
expirdFees
.
length
==
0
)
return
;
let
expiredUsers
:
any
=
[];
for
(
let
i
=
0
;
i
<
expirdFees
.
length
;
i
++
)
{
expiredUsers
.
push
(
expirdFees
[
i
].
user_id
);
}
let
uncheckCounts
=
await
fee_rate_base_coin_contract_log
.
findAll
({
attributes
:
[[
ormDB
.
literal
(
'count(1)'
),
'amount'
],
'user_id'
],
where
:
{
user_id
:
expiredUsers
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
beginAt
:
{
[
Op
.
lte
]:
new
Date
()
},
comment
,
},
raw
:
true
,
group
:
[
'user_id'
],
});
let
unCheckCountObj
=
{};
for
(
let
i
=
0
;
i
<
uncheckCounts
.
length
;
i
++
)
{
let
{
user_id
,
amount
}
=
uncheckCounts
[
i
];
unCheckCountObj
[
user_id
]
=
amount
;
}
let
defaultPairFee
=
await
contractPairs
.
prototype
.
findAll
({
attributes
:
[
'taker_fee'
,
'maker_fee'
,
'symbol'
],
where
:
{
status
:
2
},
raw
:
true
,
});
let
defaultFeeObj
=
{},
max_maker_rate
=
0.0004
,
max_taker_rate
=
0.0006
;
// 2020.5.9
for
(
let
i
=
0
;
i
<
defaultPairFee
.
length
;
i
++
)
{
let
{
symbol
,
maker_fee
,
taker_fee
}
=
defaultPairFee
[
i
];
defaultFeeObj
[
symbol
]
=
defaultPairFee
[
i
];
if
(
max_maker_rate
<
maker_fee
)
{
max_maker_rate
=
maker_fee
;
}
if
(
max_taker_rate
<
taker_fee
)
{
max_taker_rate
=
taker_fee
;
}
}
let
newFeeArr
:
any
=
[];
let
beginAt
=
new
Date
();
for
(
let
i
=
0
;
i
<
expirdFees
.
length
;
i
++
)
{
let
{
pair
,
fee_model
,
user_id
,
maker_fee
:
before_maker_fee
,
taker_fee
:
before_taker_fee
}
=
expirdFees
[
i
];
if
(
await
isWhiteListUser
(
user_id
))
{
continue
;
}
let
new_maker_fee
=
max_maker_rate
,
new_taker_fee
=
max_taker_rate
;
if
(
unCheckCountObj
[
user_id
]
>
0
)
{
// 已经存在
continue
;
}
if
(
defaultFeeObj
[
pair
])
{
let
{
maker_fee
,
taker_fee
}
=
defaultFeeObj
[
pair
];
new_maker_fee
=
maker_fee
;
new_taker_fee
=
taker_fee
;
if
(
new_maker_fee
===
before_maker_fee
&&
new_taker_fee
===
before_taker_fee
)
{
continue
}
}
newFeeArr
.
push
({
user_id
,
pair
:
pair
,
fee_model
,
maker_fee
:
new_maker_fee
,
taker_fee
:
new_taker_fee
,
beginAt
:
beginAt
,
expireAt
:
new
Date
(
beginAt
.
getTime
()
+
oneMonth
),
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
comment
,
});
}
// 如果有活动,采用活动的费率
if
(
newFeeArr
.
length
>
0
)
{
let
trans
:
any
;
try
{
trans
=
await
ormDB
.
transaction
();
await
fee_rate_base_coin_contract_log
.
update
({
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
},
{
where
:
{
user_id
:
expiredUsers
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
// 正在生效中的
expireAt
:
{
[
Op
.
lte
]:
ctm
},
},
transaction
:
trans
,
});
await
fee_rate_base_coin_contract_log
.
bulkCreate
(
newFeeArr
,
{
transaction
:
trans
,
});
await
trans
.
commit
();
trans
=
null
;
}
catch
(
error
)
{
if
(
trans
)
{
trans
.
rollback
();
}
}
}
}
cron/task/task_fee_rate_contract_log.ts
0 → 100644
View file @
37363b2d
import
{
ormDB
,
userInfoSon
,
feeRateContractLog
,
contractPairs
}
from
"@madex/ex-ts-dao"
;
import
{
FEE_RATE_LOG_STATUS
}
from
"../../src/constant/feeRateLogConst"
;
import
{
changeUserContractFee
,
isWhiteListUser
}
from
"../model/task.fee.rate.log.model"
;
const
schedule
=
require
(
'node-schedule'
);
const
{
logger
,
daoType
}
=
require
(
'@madex/ex-js-public'
);
let
fee_rate_contract_log
=
feeRateContractLog
.
prototype
;
let
feeRateCheckStatus
=
FEE_RATE_LOG_STATUS
;
let
user_info_son
=
userInfoSon
.
prototype
;
let
Op
=
ormDB
.
Op
;
const
oneHour
=
1000
*
60
*
60
;
const
oneDay
=
oneHour
*
24
;
const
oneMonth
=
oneDay
*
30
;
let
inJob
=
false
;
let
limit
=
3000
;
/**
* 注意:
* fee_rate_spot_log
* fee_rate_contract_log
* fee_rate_base_coin_contract_log
* 相关表中不支持 all 或 ALL 交易对
* 管理后台配置用户费率的 all 交易对也是分多个交易对来处理的
* 即(common_user_fee_setting 中的 all 分多个交易对 设置到 fee_rate_log 表中)
*/
let
setFeeRateJob
=
schedule
.
scheduleJob
(
'*/30 * * * * *'
,
function
()
{
if
(
inJob
)
{
return
;
}
inJob
=
true
;
doJob
().
catch
(
err
=>
{
logger
.
warn
(
'setFeeRateJob'
,
err
);
}).
then
(()
=>
{
inJob
=
false
;
});
});
let
setDefaultRun
=
false
;
let
setExpiredDefaultJob
=
schedule
.
scheduleJob
(
'*/5 * * * *'
,
function
()
{
logger
.
info
(
' contract setExpiredDefaultJob run '
,
new
Date
().
toISOString
());
if
(
setDefaultRun
)
{
return
;
}
setDefaultRun
=
true
;
setExpiredDefault
().
then
(
res
=>
{
setDefaultRun
=
false
;
}).
catch
(
err
=>
{
setDefaultRun
=
false
;
logger
.
warn
(
'contract setFeeRateJob'
,
err
);
})
});
let
doJob
=
async
function
()
{
let
ctm
=
new
Date
();
let
dblogs
=
await
fee_rate_contract_log
.
findAll
({
where
:
{
is_check
:
0
,
beginAt
:
{
[
Op
.
lte
]:
ctm
},
expireAt
:
{
[
Op
.
gte
]:
ctm
},
},
limit
:
limit
,
raw
:
true
,
});
for
(
let
i
=
0
;
i
<
dblogs
.
length
;
i
++
)
{
if
(
await
isWhiteListUser
(
dblogs
[
i
].
user_id
)
&&
dblogs
[
i
].
comment
&&
dblogs
[
i
].
comment
.
indexOf
(
'到期'
)
!=
-
1
)
{
continue
;
}
if
(
Number
(
dblogs
[
i
].
maker_fee
)
<
0
&&
(
Math
.
abs
(
Number
(
dblogs
[
i
].
maker_fee
))
>
Math
.
abs
(
Number
(
dblogs
[
i
].
taker_fee
))))
{
continue
;
}
await
changeOneFee
(
dblogs
[
i
]);
}
await
removeOldLog
();
};
let
changeOneFee
=
async
function
(
dblog
)
{
let
transaction
;
return
changeUserContractFee
(
dblog
.
user_id
,
dblog
.
pair
,
dblog
.
fee_model
,
dblog
.
maker_fee
,
dblog
.
taker_fee
,
dblog
.
id
).
then
(
async
res
=>
{
if
(
!
res
)
{
throw
'changeUserFee fail'
;
}
let
dbsons
=
await
user_info_son
.
findAll
({
attributes
:
[
'user_id'
,
'type'
],
where
:
{
father_id
:
dblog
.
user_id
,
// status: userInfoSon.STATUS.NORMAL, // 量化交易内部创建的账号需要变更手续费;
},
raw
:
true
,
});
let
son_fee_rate
:
any
=
[];
for
(
let
i
=
0
;
i
<
dbsons
.
length
;
i
++
)
{
let
son
=
dbsons
[
i
];
son_fee_rate
.
push
({
user_id
:
son
.
user_id
,
pair
:
dblog
.
pair
,
fee_model
:
dblog
.
fee_model
,
maker_fee
:
dblog
.
maker_fee
,
taker_fee
:
dblog
.
taker_fee
,
beginAt
:
new
Date
(),
expireAt
:
dblog
.
expireAt
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
comment
:
'继承父账户费率'
,
});
}
transaction
=
await
ormDB
.
transaction
();
await
fee_rate_contract_log
.
update
({
// 将当前生效中的值置为过期
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
},
{
where
:
{
user_id
:
dblog
.
user_id
,
pair
:
dblog
.
pair
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
},
transaction
:
transaction
,
});
await
fee_rate_contract_log
.
update
({
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
},
{
where
:
{
id
:
dblog
.
id
,
user_id
:
dblog
.
user_id
,
pair
:
dblog
.
pair
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
},
transaction
:
transaction
,
});
if
(
son_fee_rate
.
length
>
0
)
{
await
fee_rate_contract_log
.
bulkCreate
(
son_fee_rate
,
{
transaction
:
transaction
,
});
}
await
transaction
.
commit
();
transaction
=
null
;
}).
catch
(
async
err
=>
{
if
(
transaction
)
{
await
transaction
.
rollback
();
transaction
=
null
;
}
logger
.
warn
(
'setFeeRateJob.changeOneFee'
,
dblog
,
err
);
});
};
let
removeOldLog
=
async
function
()
{
let
ctm
=
Date
.
now
();
let
etm
=
new
Date
(
ctm
-
1000
*
60
*
60
*
24
*
31
);
await
fee_rate_contract_log
.
destroy
({
where
:
{
is_check
:
{
[
Op
.
in
]:
[
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
feeRateCheckStatus
.
CHECK_STATUS_DELETED
,
]
},
updatedAt
:
{
[
Op
.
lt
]:
etm
},
}
});
};
// 过期费率处理
async
function
setExpiredDefault
()
{
let
comment
=
'费率到期系统自动调整为基础费率'
;
let
ctm
=
new
Date
(
Date
.
now
()
-
oneDay
);
// 已经过期;
let
expirdFees
=
await
fee_rate_contract_log
.
findAll
({
attributes
:
[
'user_id'
,
'pair'
,
'fee_model'
,
'maker_fee'
,
'taker_fee'
],
where
:
{
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
// 正在生效中的
expireAt
:
{
[
Op
.
lte
]:
ctm
},
},
limit
:
500
,
// 后边处理插入时可以单次插入
raw
:
true
,
});
if
(
expirdFees
.
length
==
0
)
return
;
let
expiredUsers
:
any
=
[];
for
(
let
i
=
0
;
i
<
expirdFees
.
length
;
i
++
)
{
expiredUsers
.
push
(
expirdFees
[
i
].
user_id
);
}
let
uncheckCounts
=
await
fee_rate_contract_log
.
findAll
({
attributes
:
[[
ormDB
.
literal
(
'count(1)'
),
'amount'
],
'user_id'
],
where
:
{
user_id
:
expiredUsers
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
beginAt
:
{
[
Op
.
lte
]:
new
Date
()
},
comment
,
},
raw
:
true
,
group
:
[
'user_id'
],
});
let
unCheckCountObj
=
{};
for
(
let
i
=
0
;
i
<
uncheckCounts
.
length
;
i
++
)
{
let
{
user_id
,
amount
}
=
uncheckCounts
[
i
];
unCheckCountObj
[
user_id
]
=
amount
;
}
let
defaultPairFee
=
await
contractPairs
.
prototype
.
findAll
({
attributes
:
[
'taker_fee'
,
'maker_fee'
,
'symbol'
],
where
:
{
status
:
2
},
raw
:
true
,
});
let
defaultFeeObj
=
{},
max_maker_rate
=
0.0004
,
max_taker_rate
=
0.0006
;
// 2020.5.9
for
(
let
i
=
0
;
i
<
defaultPairFee
.
length
;
i
++
)
{
let
{
symbol
,
maker_fee
,
taker_fee
}
=
defaultPairFee
[
i
];
defaultFeeObj
[
symbol
]
=
defaultPairFee
[
i
];
if
(
max_maker_rate
<
maker_fee
)
{
max_maker_rate
=
maker_fee
;
}
if
(
max_taker_rate
<
taker_fee
)
{
max_taker_rate
=
taker_fee
;
}
}
let
newFeeArr
:
any
=
[];
let
beginAt
=
new
Date
();
for
(
let
i
=
0
;
i
<
expirdFees
.
length
;
i
++
)
{
let
{
pair
,
fee_model
,
user_id
,
maker_fee
:
before_maker_fee
,
taker_fee
:
before_taker_fee
}
=
expirdFees
[
i
];
let
new_maker_fee
=
max_maker_rate
,
new_taker_fee
=
max_taker_rate
;
if
(
await
isWhiteListUser
(
user_id
))
{
continue
;
}
if
(
unCheckCountObj
[
user_id
]
>
0
)
{
// 已经存在
continue
;
}
if
(
defaultFeeObj
[
pair
])
{
let
{
maker_fee
,
taker_fee
}
=
defaultFeeObj
[
pair
];
new_maker_fee
=
maker_fee
;
new_taker_fee
=
taker_fee
;
if
(
new_maker_fee
===
before_maker_fee
&&
new_taker_fee
===
before_taker_fee
)
{
continue
}
}
newFeeArr
.
push
({
user_id
,
pair
:
pair
,
fee_model
,
maker_fee
:
new_maker_fee
,
taker_fee
:
new_taker_fee
,
beginAt
:
beginAt
,
expireAt
:
new
Date
(
beginAt
.
getTime
()
+
oneMonth
),
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
comment
,
});
}
// 如果有活动,采用活动的费率
if
(
newFeeArr
.
length
>
0
)
{
let
trans
:
any
;
try
{
trans
=
await
ormDB
.
transaction
();
await
fee_rate_contract_log
.
update
({
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
},
{
where
:
{
user_id
:
expiredUsers
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
// 正在生效中的
expireAt
:
{
[
Op
.
lte
]:
ctm
},
},
transaction
:
trans
,
});
await
fee_rate_contract_log
.
bulkCreate
(
newFeeArr
,
{
transaction
:
trans
,
});
await
trans
.
commit
();
trans
=
null
;
}
catch
(
error
)
{
if
(
trans
)
{
trans
.
rollback
();
}
}
}
}
cron/task/task_fee_rate_spot_log.ts
0 → 100644
View file @
37363b2d
/**
* 原文件:b024 - task_fee_rate_spot_log.js
*/
import
{
ormDB
,
userInfoSon
,
feeRateSpotLog
,
spotPairs
}
from
"@madex/ex-ts-dao"
;
import
{
FEE_RATE_LOG_STATUS
}
from
"../../src/constant/feeRateLogConst"
;
import
{
changeUserSpotFee
,
isWhiteListUser
}
from
"../model/task.fee.rate.log.model"
;
let
{
redisUtilsCommon
:
RedisClient
,
}
=
require
(
'@madex/ex-js-common'
);
const
schedule
=
require
(
'node-schedule'
);
const
logger
=
require
(
'@madex/ex-js-public'
).
logger
;
let
user_info_son
=
userInfoSon
.
prototype
;
let
fee_rate_spot_log
=
feeRateSpotLog
.
prototype
;
let
feeRateCheckStatus
=
FEE_RATE_LOG_STATUS
;
let
Op
=
ormDB
.
Op
;
const
oneHour
=
1000
*
60
*
60
;
const
oneDay
=
oneHour
*
24
;
const
oneMonth
=
oneDay
*
30
;
let
inJob
=
false
;
let
limit
=
3000
;
/**
* 注意:
* fee_rate_spot_log
* fee_rate_contract_log
* fee_rate_base_coin_contract_log
* 相关表中不支持all 或 ALL 交易对
* 管理后台配置用户费率的 all 交易对也是分多个交易对来处理的
* 即(common_user_fee_setting 中的 all 分多个交易对 设置到 fee_rate_log 表中)
*/
let
setFeeRateJob
=
schedule
.
scheduleJob
(
'*/30 * * * * *'
,
function
()
{
if
(
inJob
)
{
return
;
}
inJob
=
true
;
doJob
().
catch
(
err
=>
{
logger
.
warn
(
'setFeeRateJob'
,
err
);
}).
then
(()
=>
{
inJob
=
false
;
});
});
let
setDefaultRun
=
false
;
let
setExpiredDefaultJob
=
schedule
.
scheduleJob
(
'*/5 * * * *'
,
function
()
{
logger
.
info
(
' spot setExpiredDefaultJob run '
,
new
Date
().
toISOString
());
if
(
setDefaultRun
)
{
return
;
}
setDefaultRun
=
true
;
setExpiredDefault
().
then
(
res
=>
{
setDefaultRun
=
false
;
}).
catch
(
err
=>
{
setDefaultRun
=
false
;
logger
.
warn
(
'spot setFeeRateJob'
,
err
);
})
});
let
doJob
=
async
function
()
{
let
ctm
=
new
Date
();
let
dblogs
=
await
fee_rate_spot_log
.
findAll
({
where
:
{
is_check
:
0
,
beginAt
:
{
[
Op
.
lte
]:
ctm
},
expireAt
:
{
[
Op
.
gte
]:
ctm
},
taker_fee
:
{
[
Op
.
gte
]:
0
},
},
limit
:
limit
,
raw
:
true
,
});
for
(
let
i
=
0
;
i
<
dblogs
.
length
;
i
++
)
{
if
(
Number
(
dblogs
[
i
].
maker_fee
)
<
0
&&
(
Math
.
abs
(
Number
(
dblogs
[
i
].
maker_fee
))
>
Math
.
abs
(
Number
(
dblogs
[
i
].
taker_fee
))))
{
continue
;
}
await
changeOneFee
(
dblogs
[
i
]);
}
await
removeOldLog
();
};
let
changeOneFee
=
async
function
(
dblog
)
{
let
transaction
;
return
changeUserSpotFee
(
dblog
.
user_id
,
dblog
.
pair
,
dblog
.
fee_model
,
dblog
.
maker_fee
,
dblog
.
taker_fee
,
dblog
.
id
).
then
(
async
res
=>
{
if
(
!
res
)
{
throw
'changeUserFee fail'
;
}
let
dbsons
=
await
user_info_son
.
findAll
({
attributes
:
[
'user_id'
],
where
:
{
father_id
:
dblog
.
user_id
,
},
raw
:
true
,
});
let
son_fee_rate
:
any
=
[];
for
(
let
i
=
0
;
i
<
dbsons
.
length
;
i
++
)
{
let
son
=
dbsons
[
i
];
son_fee_rate
.
push
({
user_id
:
son
.
user_id
,
pair
:
dblog
.
pair
,
fee_model
:
dblog
.
fee_model
,
maker_fee
:
dblog
.
maker_fee
,
taker_fee
:
dblog
.
taker_fee
,
beginAt
:
new
Date
(),
expireAt
:
dblog
.
expireAt
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
comment
:
'继承父账户费率'
,
});
}
await
storeUserSpotFeeRedis
(
dblog
.
user_id
,
dblog
.
pair
,
dblog
.
taker_fee
,
dblog
.
maker_fee
);
transaction
=
await
ormDB
.
transaction
();
await
fee_rate_spot_log
.
update
({
// 将当前生效中的值置为过期
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
},
{
where
:
{
user_id
:
dblog
.
user_id
,
pair
:
dblog
.
pair
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
},
transaction
:
transaction
,
});
await
fee_rate_spot_log
.
update
({
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
},
{
where
:
{
id
:
dblog
.
id
,
user_id
:
dblog
.
user_id
,
pair
:
dblog
.
pair
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
},
transaction
:
transaction
,
});
if
(
son_fee_rate
.
length
>
0
)
{
await
fee_rate_spot_log
.
bulkCreate
(
son_fee_rate
,
{
transaction
:
transaction
,
});
}
await
transaction
.
commit
();
transaction
=
null
;
}).
catch
(
async
err
=>
{
if
(
transaction
)
{
await
transaction
.
rollback
();
transaction
=
null
;
}
if
(
err
==
3000
)
{
await
fee_rate_spot_log
.
update
({
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
},
{
where
:
{
id
:
dblog
.
id
,
user_id
:
dblog
.
user_id
,
pair
:
dblog
.
pair
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
},
});
}
logger
.
warn
(
'setFeeRateJob.changeOneFee'
,
dblog
,
err
);
});
};
let
removeOldLog
=
async
function
()
{
let
ctm
=
Date
.
now
();
let
etm
=
new
Date
(
ctm
-
1000
*
60
*
60
*
24
*
31
);
await
fee_rate_spot_log
.
destroy
({
where
:
{
is_check
:
{
[
Op
.
in
]:
[
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
feeRateCheckStatus
.
CHECK_STATUS_DELETED
,
]
},
updatedAt
:
{
[
Op
.
lt
]:
etm
},
}
});
};
async
function
storeUserSpotFeeRedis
(
user_id
,
pair
,
taker_fee
,
maker_fee
)
{
let
redisKey
=
'user_spot_fee_rate_'
+
user_id
;
let
res
=
await
RedisClient
.
getSync
(
redisKey
);
if
(
!
res
)
{
res
=
{};
}
res
[
pair
]
=
{
taker
:
taker_fee
,
maker
:
maker_fee
}
await
RedisClient
.
writeSync
(
redisKey
,
JSON
.
stringify
(
res
));
}
// 过期费率处理
async
function
setExpiredDefault
()
{
let
comment
=
'费率到期系统自动调整为基础费率'
;
let
ctm
=
new
Date
(
Date
.
now
()
-
oneDay
);
// 已经过期一段时间;
let
expirdFees
=
await
fee_rate_spot_log
.
findAll
({
attributes
:
[
'user_id'
,
'pair'
,
'fee_model'
,
'maker_fee'
,
'taker_fee'
],
where
:
{
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
// 正在生效中的
expireAt
:
{
[
Op
.
lte
]:
ctm
},
},
limit
:
500
,
// 后边处理插入时可以单次插入
raw
:
true
,
});
if
(
expirdFees
.
length
==
0
)
return
;
let
expiredUsers
:
any
=
[];
for
(
let
i
=
0
;
i
<
expirdFees
.
length
;
i
++
)
{
expiredUsers
.
push
(
expirdFees
[
i
].
user_id
);
}
let
uncheckCounts
=
await
fee_rate_spot_log
.
findAll
({
attributes
:
[[
ormDB
.
literal
(
'count(1)'
),
'amount'
],
'user_id'
],
where
:
{
user_id
:
expiredUsers
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
beginAt
:
{
[
Op
.
lte
]:
new
Date
()
},
comment
,
},
raw
:
true
,
group
:
[
'user_id'
],
});
let
unCheckCountObj
=
{};
for
(
let
i
=
0
;
i
<
uncheckCounts
.
length
;
i
++
)
{
let
{
user_id
,
amount
}
=
uncheckCounts
[
i
];
unCheckCountObj
[
user_id
]
=
amount
;
}
let
defaultPairFee
=
await
spotPairs
.
prototype
.
findAll
({
attributes
:
[
'maker_rate'
,
'taker_rate'
,
'symbol'
],
where
:
{
status
:
2
},
raw
:
true
,
});
let
defaultFeeObj
=
{},
max_maker_rate
=
0.001
,
max_taker_rate
=
0.002
;
// 2020.5.9
let
activePairs
:
any
=
[];
for
(
let
i
=
0
;
i
<
defaultPairFee
.
length
;
i
++
)
{
let
{
symbol
,
maker_fee
,
taker_fee
}
=
defaultPairFee
[
i
];
activePairs
.
push
(
symbol
);
defaultFeeObj
[
symbol
]
=
defaultPairFee
[
i
];
if
(
max_maker_rate
<
maker_fee
)
{
max_maker_rate
=
maker_fee
;
}
if
(
max_taker_rate
<
taker_fee
)
{
max_taker_rate
=
taker_fee
;
}
}
let
newFeeArr
:
any
=
[];
let
beginAt
=
new
Date
();
let
expiredPairs
:
any
=
[];
for
(
let
i
=
0
;
i
<
expirdFees
.
length
;
i
++
)
{
let
{
pair
,
fee_model
,
user_id
,
maker_fee
:
before_maker_fee
,
taker_fee
:
before_taker_fee
}
=
expirdFees
[
i
];
if
(
await
isWhiteListUser
(
user_id
))
{
continue
;
}
if
(
!
activePairs
.
includes
(
pair
))
{
expiredPairs
.
push
(
pair
);
continue
;
}
if
(
unCheckCountObj
[
user_id
]
>
0
)
{
// 已经存在
continue
;
}
let
new_maker_fee
=
max_maker_rate
,
new_taker_fee
=
max_taker_rate
;
if
(
defaultFeeObj
[
pair
])
{
let
{
maker_rate
,
taker_rate
}
=
defaultFeeObj
[
pair
];
new_maker_fee
=
maker_rate
;
new_taker_fee
=
taker_rate
;
if
(
new_maker_fee
===
before_maker_fee
&&
new_taker_fee
===
before_taker_fee
)
{
continue
}
}
newFeeArr
.
push
({
user_id
,
pair
:
pair
,
fee_model
,
maker_fee
:
new_maker_fee
,
taker_fee
:
new_taker_fee
,
beginAt
:
beginAt
,
expireAt
:
new
Date
(
beginAt
.
getTime
()
+
oneMonth
),
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_UNCHECK
,
comment
:
comment
,
});
}
if
(
expiredPairs
.
length
>
0
)
{
// 下线交易对处理
await
fee_rate_spot_log
.
update
({
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
},
{
where
:
{
pair
:
expiredPairs
,
}
})
}
if
(
newFeeArr
.
length
>
0
)
{
let
trans
:
any
;
try
{
trans
=
await
ormDB
.
transaction
();
await
fee_rate_spot_log
.
update
({
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE_OVER
,
},
{
where
:
{
user_id
:
expiredUsers
,
is_check
:
feeRateCheckStatus
.
CHECK_STATUS_ACTIVE
,
// 正在生效中的
expireAt
:
{
[
Op
.
lte
]:
ctm
},
},
transaction
:
trans
,
});
await
fee_rate_spot_log
.
bulkCreate
(
newFeeArr
,
{
transaction
:
trans
,
});
await
trans
.
commit
();
trans
=
null
;
}
catch
(
error
)
{
if
(
trans
)
{
trans
.
rollback
();
}
}
}
}
cron/task/task_fee_setting_status_update.ts
0 → 100644
View file @
37363b2d
/* ======================================================================
* 市商、普通用户、KOL费率设置纪录状态更新。
* ====================================================================== */
import
{
commonUserFeeSettingStatusUpdateService
}
from
"../service/task.fee.setting.status.update.service"
;
let
schedule
=
require
(
'node-schedule'
);
let
{
logger
}
=
require
(
'@madex/ex-js-public'
);
let
userSettingUpdateRunning
=
false
;
/**
* 市商、普通用户、KOL 费率设置纪录状态更新。
* 每10分钟更新一次。
*/
let
userSettingStatusUpdate
=
schedule
.
scheduleJob
(
'0 */10 * * * *'
,
async
function
()
{
try
{
logger
.
info
(
'task_fee_setting_status_update userSettingStatusUpdate start'
);
if
(
!
userSettingUpdateRunning
)
{
userSettingUpdateRunning
=
true
;
await
commonUserFeeSettingStatusUpdateService
();
userSettingUpdateRunning
=
false
;
}
}
catch
(
error
)
{
userSettingUpdateRunning
=
false
;
logger
.
warn
(
'task_fee_setting_status_update userSettingStatusUpdate error'
,
error
);
}
});
\ No newline at end of file
cron/task/task_market_maker_statis.ts
0 → 100644
View file @
37363b2d
/*
import { statisProjectMakerDeals } from "../service/marketMakerMgr.service";
const schedule = require('node-schedule');
const logger = require('@madex/ex-js-public').logger;
let subModel = {};
module.exports = subModel;
// 统计项目方做市商成交量信息,并设置费率,
let inJob = false;
let setFeeRateJob = schedule.scheduleJob('0 10 0 * * *', async function () {
if (inJob) {
return;
}
inJob = true;
try {
await statisProjectMakerDeals();
inJob = false;
} catch (error) {
inJob = false;
logger.warn(' 统计项目方做市商成交量 error', error);
}
});*/
src/functional/mvc/service/commonUserFeeSetting.service.ts
View file @
37363b2d
...
@@ -153,31 +153,32 @@ export async function add(commonUserFeeVO: CommonUserFeeVO, currentUserId: any,
...
@@ -153,31 +153,32 @@ export async function add(commonUserFeeVO: CommonUserFeeVO, currentUserId: any,
let
pair
=
dbInfo
.
pair
;
let
pair
=
dbInfo
.
pair
;
let
type
=
dbInfo
.
type
;
let
type
=
dbInfo
.
type
;
let
now
=
new
Date
();
let
now
=
new
Date
();
let
insertDb
One
:
any
=
[];
let
insertDb
List
:
any
=
[];
let
rateLog
=
buildSubmitItem
(
pair
,
dbInfo
,
now
,
dbInfo
.
user_channel
);
let
rateLogs
=
await
buildSubmitItems
(
pair
,
dbInfo
,
now
,
dbInfo
.
user_channel
,
type
);
//提交到log表
//提交到log表
if
(
type
==
FEE_TYPE
.
FEE_TYPE_SPOT
)
{
if
(
type
==
FEE_TYPE
.
FEE_TYPE_SPOT
)
{
insertDb
One
=
await
feeRateSpotLog
.
prototype
.
create
(
rateLog
,
{
insertDb
List
=
await
feeRateSpotLog
.
prototype
.
bulkCreate
(
rateLogs
,
{
transaction
:
tx
transaction
:
tx
});
});
}
}
else
if
(
type
==
FEE_TYPE
.
FEE_TYPE_BASE_COIN_CONTRACT
)
{
//币本位
else
if
(
type
==
FEE_TYPE
.
FEE_TYPE_BASE_COIN_CONTRACT
)
{
//币本位
insertDb
One
=
await
feeRateBaseCoinContractLog
.
prototype
.
create
(
rateLog
,
{
insertDb
List
=
await
feeRateBaseCoinContractLog
.
prototype
.
bulkCreate
(
rateLogs
,
{
transaction
:
tx
transaction
:
tx
});
});
}
}
else
{
//U本位
else
{
//U本位
insertDb
One
=
await
feeRateContractLog
.
prototype
.
create
(
rateLog
,
{
insertDb
List
=
await
feeRateContractLog
.
prototype
.
bulkCreate
(
rateLogs
,
{
transaction
:
tx
transaction
:
tx
});
});
}
}
let
feeLogId
=
insertDbOne
.
id
;
let
ids
=
insertDbList
.
map
(
item
=>
item
.
id
)
;
await
commonUserFeeSetting
.
prototype
.
update
({
await
commonUserFeeSetting
.
prototype
.
update
({
fee_log_ids
:
feeLogId
,
fee_log_ids
:
ids
.
toString
()
,
update_time
:
new
Date
()
update_time
:
new
Date
()
},
{
},
{
where
:
{
where
:
{
...
@@ -224,34 +225,34 @@ export async function update(commonUserFeeVO: CommonUserFeeVO, currentUserId: an
...
@@ -224,34 +225,34 @@ export async function update(commonUserFeeVO: CommonUserFeeVO, currentUserId: an
let
tx
;
let
tx
;
try
{
try
{
tx
=
await
ormDB
.
transaction
();
tx
=
await
ormDB
.
transaction
();
let
feeLogId
:
any
;
let
feeLogId
s
:
any
;
//这四项修改需要 重新写入 rate_log
//这四项修改需要 重新写入 rate_log
if
(
commonUserFeeVO
.
maker_fee
!=
dbInfo
.
maker_fee
||
commonUserFeeVO
.
taker_fee
!=
dbInfo
.
taker_fee
if
(
commonUserFeeVO
.
maker_fee
!=
dbInfo
.
maker_fee
||
commonUserFeeVO
.
taker_fee
!=
dbInfo
.
taker_fee
||
commonUserFeeVO
.
begin_time
!=
dbInfo
.
begin_time
||
commonUserFeeVO
.
expire_time
!=
dbInfo
.
expire_time
)
{
||
commonUserFeeVO
.
begin_time
!=
dbInfo
.
begin_time
||
commonUserFeeVO
.
expire_time
!=
dbInfo
.
expire_time
)
{
let
insertDb
One
:
any
;
let
insertDb
List
:
any
;
let
rateLog
=
buildSubmitItem
(
pair
,
commonUserFeeVO
,
new
Date
(),
Number
(
commonUserFeeVO
.
user_channel
)
);
let
rateLog
s
=
await
buildSubmitItems
(
pair
,
commonUserFeeVO
,
new
Date
(),
Number
(
commonUserFeeVO
.
user_channel
),
type
);
//提交到log表
//提交到log表
if
(
type
==
FEE_TYPE
.
FEE_TYPE_SPOT
)
{
if
(
type
==
FEE_TYPE
.
FEE_TYPE_SPOT
)
{
insertDb
One
=
await
feeRateSpotLog
.
prototype
.
create
(
rateLog
,
{
insertDb
List
=
await
feeRateSpotLog
.
prototype
.
bulkCreate
(
rateLogs
,
{
transaction
:
tx
transaction
:
tx
});
});
}
}
else
if
(
type
==
FEE_TYPE
.
FEE_TYPE_BASE_COIN_CONTRACT
)
{
//币本位
else
if
(
type
==
FEE_TYPE
.
FEE_TYPE_BASE_COIN_CONTRACT
)
{
//币本位
insertDb
One
=
await
feeRateBaseCoinContractLog
.
prototype
.
create
(
rateLog
,
{
insertDb
List
=
await
feeRateBaseCoinContractLog
.
prototype
.
bulkCreate
(
rateLogs
,
{
transaction
:
tx
transaction
:
tx
});
});
}
}
else
{
//U本位
else
{
//U本位
insertDb
One
=
await
feeRateContractLog
.
prototype
.
create
(
rateLog
,
{
insertDb
List
=
await
feeRateContractLog
.
prototype
.
bulkCreate
(
rateLogs
,
{
transaction
:
tx
transaction
:
tx
});
});
}
}
feeLogId
=
insertDbOne
.
id
;
feeLogIds
=
insertDbList
.
map
(
item
=>
item
.
id
);
}
}
let
dbFeeLogIdsArr
=
dbInfo
.
fee_log_ids
.
split
(
","
);
dbFeeLogIdsArr
.
push
(
String
(
feeLogId
));
await
commonUserFeeSetting
.
prototype
.
update
({
await
commonUserFeeSetting
.
prototype
.
update
({
maker_fee
:
Number
(
commonUserFeeVO
.
maker_fee
),
maker_fee
:
Number
(
commonUserFeeVO
.
maker_fee
),
taker_fee
:
Number
(
commonUserFeeVO
.
taker_fee
),
taker_fee
:
Number
(
commonUserFeeVO
.
taker_fee
),
...
@@ -263,7 +264,7 @@ export async function update(commonUserFeeVO: CommonUserFeeVO, currentUserId: an
...
@@ -263,7 +264,7 @@ export async function update(commonUserFeeVO: CommonUserFeeVO, currentUserId: an
amount_require_usdt
:
commonUserFeeVO
.
amount_require_usdt
,
amount_require_usdt
:
commonUserFeeVO
.
amount_require_usdt
,
applicant
:
commonUserFeeVO
.
applicant
,
applicant
:
commonUserFeeVO
.
applicant
,
update_time
:
new
Date
(),
update_time
:
new
Date
(),
fee_log_ids
:
feeLogId
?
dbFeeLogIdsArr
.
toString
()
:
dbInfo
.
fee_log_ids
,
fee_log_ids
:
feeLogId
s
?
feeLogIds
.
toString
()
:
dbInfo
.
fee_log_ids
,
},
{
},
{
where
:
{
where
:
{
id
:
Number
(
commonUserFeeVO
.
id
)
id
:
Number
(
commonUserFeeVO
.
id
)
...
@@ -460,10 +461,25 @@ async function getDbFeeSetting(user_id: number | any, type: number | any, user_c
...
@@ -460,10 +461,25 @@ async function getDbFeeSetting(user_id: number | any, type: number | any, user_c
return
dbInfo
;
return
dbInfo
;
}
}
function
buildSubmitItem
(
pair
:
string
,
dbInfo
:
any
,
now
:
Date
,
user_channel
:
number
)
{
async
function
buildSubmitItems
(
pair
:
string
,
dbInfo
:
any
,
now
:
Date
,
user_channel
:
number
,
type
:
number
)
{
let
pairList
:
any
;
if
(
pair
==
'all'
)
{
if
(
type
==
FEE_TYPE
.
FEE_TYPE_SPOT
)
{
pairList
=
await
getAllSpotPairs
();
}
else
{
pairList
=
await
getAllContractPairs
();
}
}
else
{
pairList
=
[
pair
]
}
let
itemList
:
any
=
[];
for
(
let
onePair
of
pairList
)
{
let
item
=
{
let
item
=
{
user_id
:
dbInfo
.
user_id
,
user_id
:
dbInfo
.
user_id
,
pair
:
p
air
,
pair
:
oneP
air
,
fee_model
:
FEE_MODEL_SPOT_DEFAULT
,
fee_model
:
FEE_MODEL_SPOT_DEFAULT
,
maker_fee
:
dbInfo
.
maker_fee
,
maker_fee
:
dbInfo
.
maker_fee
,
taker_fee
:
dbInfo
.
taker_fee
,
taker_fee
:
dbInfo
.
taker_fee
,
...
@@ -484,8 +500,11 @@ function buildSubmitItem(pair: string, dbInfo: any, now: Date, user_channel: num
...
@@ -484,8 +500,11 @@ function buildSubmitItem(pair: string, dbInfo: any, now: Date, user_channel: num
else
{
else
{
item
.
comment
=
COMMENT_USER_FEE_SUBMIT
item
.
comment
=
COMMENT_USER_FEE_SUBMIT
}
}
itemList
.
push
(
item
);
}
return
item
;
return
itemList
;
}
}
async
function
checkSpotPair
(
pair
:
string
)
{
async
function
checkSpotPair
(
pair
:
string
)
{
...
@@ -537,3 +556,34 @@ async function getProjectMakerTradeStat(user_id: number, pair: string) {
...
@@ -537,3 +556,34 @@ async function getProjectMakerTradeStat(user_id: number, pair: string) {
return
res
;
return
res
;
}
}
async
function
getAllSpotPairs
()
{
let
dbPairs
=
await
spotPairs
.
prototype
.
findAll
(
{
attributes
:
[
'symbol'
],
where
:
{
status
:
2
},
raw
:
true
}
);
return
dbPairs
.
map
(
item
=>
item
.
symbol
);
}
async
function
getAllContractPairs
()
{
let
dbPairs
=
await
contractPairs
.
prototype
.
findAll
(
{
attributes
:
[
'symbol'
],
where
:
{
status
:
2
},
raw
:
true
}
);
return
dbPairs
.
map
(
item
=>
item
.
symbol
);
}
src/functional/mvc/service/notice.service.ts
View file @
37363b2d
...
@@ -41,10 +41,11 @@ export interface NoticePageVO extends NoticeVO {
...
@@ -41,10 +41,11 @@ export interface NoticePageVO extends NoticeVO {
export
async
function
list
(
noticePageVO
:
NoticePageVO
)
{
export
async
function
list
(
noticePageVO
:
NoticePageVO
)
{
let
where
=
Object
.
create
(
null
);
let
where
=
Object
.
create
(
null
);
where
.
del_sign
=
0
;
if
(
noticePageVO
.
publish_flag
)
{
if
(
noticePageVO
.
publish_flag
)
{
where
.
publish_flag
=
noticePageVO
.
publish_flag
;
where
.
publish_flag
=
noticePageVO
.
publish_flag
;
}
}
if
(
Number
(
noticePageVO
.
user_id
)
>=
0
)
{
if
(
noticePageVO
.
user_id
&&
Number
(
noticePageVO
.
user_id
)
>=
0
)
{
where
.
user_id
=
noticePageVO
.
user_id
;
where
.
user_id
=
noticePageVO
.
user_id
;
}
}
if
(
noticePageVO
.
notice_type
)
{
if
(
noticePageVO
.
notice_type
)
{
...
@@ -57,9 +58,6 @@ export async function list(noticePageVO: NoticePageVO) {
...
@@ -57,9 +58,6 @@ export async function list(noticePageVO: NoticePageVO) {
let
date
=
datetimeUtils
.
trim
(
noticePageVO
.
push_time
,
's'
);
let
date
=
datetimeUtils
.
trim
(
noticePageVO
.
push_time
,
's'
);
where
.
push_time
=
{
[
ormDB
.
Op
.
gte
]:
date
};
where
.
push_time
=
{
[
ormDB
.
Op
.
gte
]:
date
};
}
}
if
(
noticePageVO
.
del_sign
||
noticePageVO
.
del_sign
===
0
)
{
where
.
del_sign
=
noticePageVO
.
del_sign
;
}
if
(
noticePageVO
.
status
)
{
if
(
noticePageVO
.
status
)
{
where
.
status
=
noticePageVO
.
status
;
where
.
status
=
noticePageVO
.
status
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment