server_data_statistics.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. const logger = require('../model/logger')
  2. var remote_config_db = require("../model/db/remote_config_db");
  3. var collect_coins_db = require("../model/db/collect_coins_db");
  4. var withdraw_db = require("../model/db/withdraw_db");
  5. var moralis = require("../model/moralis_sdk");
  6. var utils = require("../model/utils");
  7. const axios = require('axios');
  8. var { account_config } = require('../config/config.js');
  9. const { max } = require('moment');
  10. // 拿到飞书写入的 token
  11. const feishu_write_table_token_url = 'https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal'
  12. const feishu_write_table_data_url = 'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg/values_batch_update'
  13. const feishu_insert_table_url = 'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg/insert_dimension_range'
  14. const reportTime = '02:00:00'
  15. //########################################### 出入金数据统计 ########################################
  16. const http_request_get = async (data) => {
  17. var host = account_config.STATISTICS_URL
  18. // host = 'https://api.denetme.net/denet/wallet/stat/getMoneyStat?date='
  19. var path = data
  20. var url = host + path
  21. logger.log('http_request_get', url)
  22. return new Promise(response => {
  23. axios.get(url)
  24. .then(res => {
  25. logger.log('res=>', res.status, res.data);
  26. if (res.data.code == 0) {
  27. response(res.data)
  28. } else {
  29. response({
  30. code: 0,
  31. msg: err.toString(),
  32. data: {
  33. canNotWithdrawUSD: '0',
  34. canWithdrawUSD: '0',
  35. incomeUSDTotal: '0',
  36. incomeUSDFee: '0'
  37. }
  38. })
  39. }
  40. }).catch(err => {
  41. logger.error('http_request_get', err.toString(), url.toString());
  42. response({
  43. code: -1,
  44. msg: err.toString(),
  45. data: {
  46. canNotWithdrawUSD: '0',
  47. canWithdrawUSD: '0',
  48. incomeUSDTotal: '0',
  49. incomeUSDFee: '0'
  50. }
  51. })
  52. });
  53. })
  54. }
  55. async function computeAddressPrice(total_in_coins) {
  56. //计算总的价格
  57. for (key of total_in_coins.keys()) {
  58. var item = total_in_coins.get(key)
  59. var amount = item.amount
  60. var usdPrice = item.usdPrice
  61. if (key == '0x0000000000000000000000000000000000000000') {
  62. item.totalUsdPrice = parseFloat(amount) / parseFloat(10 ** 18) * parseFloat(usdPrice)
  63. } else {
  64. var decimals = 18
  65. try {
  66. decimals = await redis.readAppendRedis('REDIS_ERC20_CONTRACT_DECIMALS', item.chain, key.toLowerCase())
  67. logger.info('REDIS_ERC20_CONTRACT_DECIMALS', key.toLowerCase(), decimals)
  68. } catch (error) {
  69. decimals = 18
  70. }
  71. item.totalUsdPrice = parseFloat(amount) / parseFloat(10 ** decimals) * parseFloat(usdPrice)
  72. }
  73. }
  74. }
  75. function getBscEnv() {
  76. var bsc_env
  77. switch (process.env.NODE_ENV) {
  78. case 'dev':
  79. case 'test':
  80. // bsc_env = 'bsc_testnet'
  81. bsc_env = 'bsc_mainnet'
  82. break
  83. case 'prd':
  84. bsc_env = 'bsc_mainnet'
  85. break
  86. default:
  87. bsc_env = 'bsc_mainnet'
  88. break
  89. }
  90. return bsc_env;
  91. }
  92. async function filterCollectCoinsLists(collect_ret, filterTypt) {
  93. const total_in_coins = new Map();
  94. var total_gas_fee = 0
  95. for (let index = 0; index < collect_ret.results.length; index++) {
  96. const element = collect_ret.results[index];
  97. if (element.chain == null || element.chain == filterTypt) {
  98. var before_gas_fee = element.before_gas_fee ? BigInt(element.before_gas_fee) : element.chain == 'czz' ? BigInt(21000 * 2000000000) : BigInt(21000 * 5000000000)
  99. total_gas_fee = BigInt(element.total_gas_fee) + BigInt(before_gas_fee) + BigInt(total_gas_fee)
  100. if (element.transfers) {
  101. var opts = JSON.parse(element.transfers)
  102. for (let index = 0; index < opts.length; index++) {
  103. const transfers = opts[index];
  104. if (transfers.chain == filterTypt) {
  105. var address = transfers.contractAddress ? transfers.contractAddress : '0x0000000000000000000000000000000000000000'
  106. if (total_in_coins.get(address) != null) {
  107. var ins = total_in_coins.get(address)
  108. ins.amount = BigInt(ins.amount) + BigInt(transfers.amount)
  109. total_in_coins.set(address, ins)
  110. } else {
  111. total_in_coins.set(address, {
  112. amount: BigInt(transfers.amount), //总入金
  113. usdPrice: transfers.usdPrice,
  114. chain: transfers.chain,
  115. })
  116. }
  117. }
  118. }
  119. }
  120. }
  121. }
  122. //计算总的价格
  123. await computeAddressPrice(total_in_coins)
  124. var bsc_env = getBscEnv()
  125. //获取 total gas
  126. try {
  127. if (total_in_coins.size > 0) {
  128. switch (filterTypt) {
  129. case 'bsc_testnet':
  130. case 'bsc_mainnet':
  131. var price = await moralis.getAllTotkenPrice({ chain: bsc_env })
  132. if (typeof price === 'string') {
  133. price = JSON.parse(price)
  134. }
  135. var bnbPriceItem = moralis.findTokenPriceItem('0x0000000000000000000000000000000000000000', price)
  136. total_gas_fee = parseFloat(total_gas_fee) / parseFloat(10 ** 18) * parseFloat(bnbPriceItem.usdPrice)
  137. logger.info('new-total_gas_fee ', total_gas_fee, bnbPriceItem)
  138. break
  139. case 'czz':
  140. var price = await moralis.getAllTotkenPrice({ chain: 'czz' })
  141. if (typeof price === 'string') {
  142. price = JSON.parse(price)
  143. }
  144. var czzPriceItem = moralis.findTokenPriceItem('0x0000000000000000000000000000000000000000', price)
  145. total_gas_fee = parseFloat(total_gas_fee) / parseFloat(10 ** 18) * parseFloat(czzPriceItem.usdPrice)
  146. logger.info('new-total_gas_fee czz', total_gas_fee, czzPriceItem)
  147. break
  148. }
  149. }
  150. } catch (error) {
  151. logger.error('total_gas_fee', error)
  152. }
  153. if (!total_in_coins.get('0x0000000000000000000000000000000000000000')) {
  154. total_in_coins.set('0x0000000000000000000000000000000000000000', {
  155. amount: 0,
  156. usdPrice: 0,
  157. chain: filterTypt,
  158. totalUsdPrice: 0
  159. })
  160. }
  161. return {
  162. map: total_in_coins,
  163. totalGasFee: total_gas_fee //总入金所消耗的 gas fee
  164. }
  165. }
  166. function sumBalance(map) {
  167. var balances = 0;
  168. for (key of map.keys()) {
  169. balances += map.get(key).totalUsdPrice
  170. }
  171. return balances
  172. }
  173. async function getSLGas() {
  174. var maps = new Map()
  175. var collect_ret = await collect_coins_db.query_collect_total_fee(null, null);
  176. for (let index = 0; index < collect_ret.results.length; index++) {
  177. var element = collect_ret.results[index]
  178. try {
  179. if (element.prestore_gas_fee && typeof element.prestore_gas_fee === 'string') {
  180. var pre_gas_obj = JSON.parse(element.prestore_gas_fee)
  181. var bgf = element.before_gas_fee
  182. if (!bgf && pre_gas_obj.amount) {
  183. bgf = pre_gas_obj.amount
  184. }
  185. // logger.info('getSLGas item', bgf, pre_gas_obj, element)
  186. if (maps.get(pre_gas_obj.chain)) {
  187. maps.get(pre_gas_obj.chain).sl_gas_fee = BigInt(maps.get(pre_gas_obj.chain).sl_gas_fee) + (BigInt(pre_gas_obj.amount) - BigInt(bgf))
  188. } else {
  189. maps.set(pre_gas_obj.chain, {
  190. sl_gas_fee: BigInt(pre_gas_obj.amount) - BigInt(bgf)
  191. })
  192. }
  193. }
  194. } catch (error) {
  195. logger.error('getSLGas error', error.toString())
  196. }
  197. }
  198. var bsc_env = getBscEnv()
  199. logger.info('getSLGas', maps)
  200. var bsc_sl
  201. var czz_sl
  202. for (key of maps.keys()) {
  203. var item = maps.get(key)
  204. switch (key) {
  205. case "bsc_mainnet":
  206. case "bsc_testnet":
  207. var price = await moralis.getAllTotkenPrice({ chain: bsc_env })
  208. if (typeof price === 'string') {
  209. price = JSON.parse(price)
  210. }
  211. var bnbPriceItem = moralis.findTokenPriceItem('0x0000000000000000000000000000000000000000', price)
  212. bsc_sl = parseFloat(item.sl_gas_fee) / parseFloat(10 ** 18) * parseFloat(bnbPriceItem.usdPrice)
  213. break
  214. case "czz":
  215. var price = await moralis.getAllTotkenPrice({ chain: 'czz' })
  216. if (typeof price === 'string') {
  217. price = JSON.parse(price)
  218. }
  219. var czzPriceItem = moralis.findTokenPriceItem('0x0000000000000000000000000000000000000000', price)
  220. czz_sl = parseFloat(item.sl_gas_fee) / parseFloat(10 ** 18) * parseFloat(czzPriceItem.usdPrice)
  221. break
  222. }
  223. }
  224. return {
  225. bsc: bsc_sl,
  226. czz: czz_sl,
  227. total: bsc_sl + czz_sl
  228. }
  229. }
  230. async function getCollectCoinsOutInfo(startTime, endTime) {
  231. var collect_ret = await collect_coins_db.query_collect_total_fee(startTime, endTime);
  232. logger.info('getCollectCoinsOutInfo query_collect_total_fee', startTime, endTime)
  233. var bsc_env = getBscEnv()
  234. var bsc_envnet = await filterCollectCoinsLists(collect_ret, bsc_env)
  235. logger.info('getCollectCoinsOutInfo bsc_env', bsc_env, bsc_envnet)
  236. var czz = await filterCollectCoinsLists(collect_ret, 'czz')
  237. logger.info('getCollectCoinsOutInfo czz', czz)
  238. logger.info('getCollectCoinsOutInfo total ', bsc_envnet.totalGasFee, czz.totalGasFee)
  239. return {
  240. bsc: bsc_envnet.map,
  241. czz: czz.map,
  242. totalGasFee: parseFloat(bsc_envnet.totalGasFee) + parseFloat(czz.totalGasFee), //总归集消耗的 gas fee
  243. totalInFee: sumBalance(bsc_envnet.map) + sumBalance(czz.map),//总入金美元
  244. }
  245. }
  246. async function filterWithdrawTotalOutFee(chain_id, filterItem) {
  247. const withdraw_out_map = new Map();
  248. var price = await moralis.getAllTotkenPrice({ chain: chain_id + "" })
  249. if (typeof price === 'string') {
  250. price = JSON.parse(price)
  251. }
  252. for (let index = 0; index < filterItem.length; index++) {
  253. const element = filterItem[index];
  254. if (element.chain_id == chain_id) {
  255. var address = element.type == 'native' ? '0x0000000000000000000000000000000000000000' : element.contract_address
  256. if (withdraw_out_map.get(address) != null) {
  257. var item = withdraw_out_map.get(address)
  258. item.totalAmount = BigInt(element.amount) + BigInt(item.totalAmount)
  259. } else {
  260. var priceItem = moralis.findTokenPriceItem(address, price)
  261. var decimals = 18
  262. if (key == '0x0000000000000000000000000000000000000000') {
  263. item.totalUsdPrice = parseFloat(amount) / parseFloat(10 ** 18) * parseFloat(usdPrice)
  264. } else {
  265. try {
  266. decimals = await redis.readAppendRedis('REDIS_ERC20_CONTRACT_DECIMALS', chain_id + "", address.toLowerCase())
  267. logger.info('REDIS_ERC20_CONTRACT_DECIMALS', key.toLowerCase(), decimals)
  268. } catch (error) {
  269. decimals = 18
  270. }
  271. }
  272. withdraw_out_map.set(address, {
  273. totalAmount: BigInt(element.amount), //出金数量
  274. usdPrice: priceItem.usdPrice,
  275. chain: element.chain_id,
  276. decimals: decimals,
  277. })
  278. }
  279. }
  280. }
  281. logger.info('filterWithdrawTotalOutFee', withdraw_out_map, chain_id)
  282. return withdraw_out_map
  283. }
  284. async function getWithdrawOutInfo(startTime, endTime) {
  285. if (startTime && endTime) {
  286. startTime = new Date(startTime).getTime()
  287. endTime = new Date(endTime).getTime()
  288. }
  289. var withdraw_ret = await withdraw_db.getWidthdrawTotalFee(startTime, endTime)
  290. const withdraw_gas_map = new Map();
  291. for (let index = 0; index < withdraw_ret.length; index++) {
  292. const element = withdraw_ret[index];
  293. if (element.gas_price && element.gas_limit)
  294. var total_gas_fee2 = (BigInt(element.gas_price) * BigInt(element.gas_limit))
  295. if (withdraw_gas_map.get(element.chain_id) != null) {
  296. withdraw_gas_map.get(element.chain_id).total_gas_fee = BigInt(withdraw_gas_map.get(element.chain_id).total_gas_fee) + BigInt(total_gas_fee2)
  297. } else {
  298. withdraw_gas_map.set(element.chain_id,
  299. {
  300. total_gas_fee: BigInt(total_gas_fee2),
  301. total_withdraw: null
  302. }
  303. )
  304. }
  305. }
  306. var bsc_env = getBscEnv()
  307. //计算总消耗的 gas
  308. var keys = withdraw_gas_map.keys();
  309. var total_gas_fee = 0
  310. for (key of keys) {
  311. // console.log(key, withdraw_gas_map.get(key)); // map.get(key)可得value值。
  312. var value = withdraw_gas_map.get(key).total_gas_fee
  313. //获取币价
  314. try {
  315. if (key == 2019) {
  316. var price = await moralis.getAllTotkenPrice({ chain: 'czz' })
  317. if (typeof price === 'string') {
  318. price = JSON.parse(price)
  319. }
  320. var czzPriceItem = moralis.findTokenPriceItem('0x0000000000000000000000000000000000000000', price)
  321. total_gas_fee += parseFloat(value) / parseFloat(10 ** 18) * parseFloat(czzPriceItem.usdPrice)
  322. logger.info('new-total_gas_fee czz', total_gas_fee, czzPriceItem)
  323. } else {
  324. var price = await moralis.getAllTotkenPrice({ chain: bsc_env })
  325. if (typeof price === 'string') {
  326. price = JSON.parse(price)
  327. }
  328. var bnbPriceItem = moralis.findTokenPriceItem('0x0000000000000000000000000000000000000000', price)
  329. total_gas_fee += parseFloat(value) / parseFloat(10 ** 18) * parseFloat(bnbPriceItem.usdPrice)
  330. logger.info('new-total_gas_fee bsc', total_gas_fee, bnbPriceItem)
  331. }
  332. } catch (error) {
  333. logger.error('total_gas_fee', error)
  334. }
  335. }
  336. var withdrawout = 0
  337. if (!startTime && !endTime) {
  338. for (key of withdraw_gas_map.keys()) {
  339. try {
  340. var outs = await filterWithdrawTotalOutFee(key, withdraw_ret)
  341. withdraw_gas_map.get(key).total_withdraw = outs
  342. // logger.error('withdraw_gas_map.get(key).total_withdraw outs', outs)
  343. if (outs) {
  344. for (ckey of outs.keys()) {
  345. var item = outs.get(ckey);
  346. withdrawout = parseFloat(withdrawout) + (parseFloat(item.totalAmount) / parseFloat(10 ** item.decimals) * parseFloat(item.usdPrice))
  347. }
  348. }
  349. } catch (error) {
  350. logger.error('filterWithdrawTotalOutFee error', error.toString())
  351. }
  352. }
  353. }
  354. return {
  355. outmap: withdraw_gas_map,
  356. totalGasFee: total_gas_fee,
  357. totalWithdraw: withdrawout
  358. };
  359. }
  360. async function updateBalance(obj, type) {
  361. var price
  362. if (type == 'bsc') {
  363. var bsc_env = getBscEnv()
  364. price = await moralis.getAllTotkenPrice({ chain: bsc_env })
  365. } else if (type == 'czz') {
  366. price = await moralis.getAllTotkenPrice({ chain: 'czz' })
  367. }
  368. if (typeof price === 'string') {
  369. price = JSON.parse(price)
  370. }
  371. var priceItem = moralis.findTokenPriceItem('0x0000000000000000000000000000000000000000', price, price)
  372. if (!obj.native.balance) {
  373. obj.native.balance = '0'
  374. }
  375. if (obj.native) {
  376. obj.native.usdPrice = parseFloat(obj.native.balance) / parseFloat(10 ** 18) * priceItem.usdPrice
  377. logger.info('findTokenPriceItem 0x0000000000000000000000000000000000000000 ', obj, priceItem, type)
  378. }
  379. var tokenTotal = 0
  380. if (obj.other && Array.isArray(obj.other)) {
  381. for (let index = 0; index < obj.other.length; index++) {
  382. const element = obj.other[index];
  383. priceItem = moralis.findTokenPriceItem(element.token_address, price)
  384. logger.info('findTokenPriceItem element ', priceItem, element.token_address)
  385. if (priceItem) {
  386. if (!element.decimals || element.decimals == 0)
  387. element.decimals = 18
  388. element.usdPrice = parseFloat(element.balance) / parseFloat(10 ** element.decimals) * priceItem.usdPrice
  389. tokenTotal += element.usdPrice
  390. }
  391. }
  392. }
  393. return {
  394. nativeTotal: obj.native.usdPrice,
  395. tokenTotal: tokenTotal,
  396. total: parseFloat(obj.native.usdPrice) + parseFloat(tokenTotal)
  397. }
  398. }
  399. async function getAllBalance() {
  400. var bsc_env = getBscEnv()
  401. var company = await moralis.queryCompanyInfoFromId(0)
  402. logger.info('getAllBalance company', company)
  403. var bsc_balance = await moralis.getAccountAllCoins({
  404. chain: bsc_env,
  405. address: company.user_address
  406. })
  407. logger.info('getAccountAllCoins bsc_balance', bsc_balance)
  408. var bscb = await updateBalance(bsc_balance, 'bsc')
  409. logger.info('getAccountAllCoins updateBalance bscb', bscb)
  410. var czz_balance = await moralis.getAccountAllCoins({
  411. chain: 'czz',
  412. address: company.user_address
  413. })
  414. logger.info('getAccountAllCoins czz_balance', czz_balance)
  415. var czzb = await updateBalance(czz_balance, 'czz')
  416. logger.info('getAccountAllCoins updateBalance czzb', czzb)
  417. return {
  418. bsc: bscb,
  419. czz: czzb,
  420. totalBalance: bscb.total + czzb.total
  421. }
  422. }
  423. /**
  424. * 获取时间段总支出的 gas fee
  425. * @param {*} startTime
  426. * @param {*} endTime
  427. */
  428. async function getStatisticsInfo() {
  429. // //今日
  430. var startTime = utils.getLastDay('YYYY-MM-DD') + " 00:00:00"
  431. var endTime = utils.getLastDay('YYYY-MM-DD') + " 23:59:59"
  432. logger.info('getTotalOutGasFee', startTime, endTime)
  433. //归集
  434. var collectCoinsOut = await getCollectCoinsOutInfo(startTime, endTime)
  435. logger.info('getCollectCoinsOutInfo collectCoinsOut', collectCoinsOut)
  436. //提币
  437. var withdrawOut = await getWithdrawOutInfo(startTime, endTime)
  438. logger.info('getWithdrawOutInfo withdrawOut ', withdrawOut)
  439. var data = await http_request_get(utils.getLastDay('YYYYMMDD'))
  440. //历史,总的
  441. //归集
  442. var totalCollectCoinsOut = await getCollectCoinsOutInfo(null, null)
  443. logger.info('totalCollectCoinsOut ', totalCollectCoinsOut)
  444. //提币
  445. var totalWithdrawOut = await getWithdrawOutInfo(null, null)
  446. logger.info('totalWithdrawOut ', totalWithdrawOut)
  447. //获取当前账户总余额
  448. var curBalances = await getAllBalance()
  449. logger.info('getAllBalance ', curBalances)
  450. //获取散落 gas
  451. var totalSLGas = await getSLGas()
  452. logger.info('getSLGas ret', totalSLGas)
  453. return {
  454. updateTime: utils.getLastDay('YYYY-MM-DD'),
  455. todayTotalProfit: parseFloat(data.data.incomeUSDTotal) - parseFloat(collectCoinsOut.totalGasFee + withdrawOut.totalGasFee),
  456. todayTotalOutGasFee: collectCoinsOut.totalGasFee + withdrawOut.totalGasFee, //今日总支出的 gas fee
  457. canNotWithdrawUSD: parseFloat(data.data.canNotWithdrawUSD), //不可提现余额
  458. canWithdrawUSD: parseFloat(data.data.canWithdrawUSD), //可提现余额
  459. todayIncomeUSDTotal: parseFloat(data.data.incomeUSDTotal), //今日总收入
  460. todayIncomeUSDFee: parseFloat(data.data.incomeUSDFee), //今日固定收入
  461. totalOutGasFee: totalCollectCoinsOut.totalGasFee + totalWithdrawOut.totalGasFee, //总支出 gas fee
  462. totalWithdrawGasFee: totalWithdrawOut.totalGasFee, //总提币 gas fee
  463. totalCollectCoinsGasFee: totalCollectCoinsOut.totalGasFee, //总归集 gas fee
  464. totalInFee: totalCollectCoinsOut.totalInFee, //总入金
  465. totalNativeInFee: {
  466. bsc: totalCollectCoinsOut.bsc.get('0x0000000000000000000000000000000000000000').totalUsdPrice,
  467. czz: totalCollectCoinsOut.czz.get('0x0000000000000000000000000000000000000000').totalUsdPrice
  468. }, //总 native 入金
  469. totalOutFee: totalWithdrawOut.totalWithdraw, //总出金
  470. totalBalances: curBalances.totalBalance, //总余额
  471. ylGasBalance: { //预留 gas 费余额 native 总余额 - 总入金
  472. bsc: curBalances.bsc.nativeTotal - totalCollectCoinsOut.bsc.get('0x0000000000000000000000000000000000000000').totalUsdPrice,
  473. czz: curBalances.czz.nativeTotal - totalCollectCoinsOut.czz.get('0x0000000000000000000000000000000000000000').totalUsdPrice,
  474. total: (curBalances.bsc.nativeTotal - totalCollectCoinsOut.bsc.get('0x0000000000000000000000000000000000000000').totalUsdPrice) + (curBalances.czz.nativeTotal - totalCollectCoinsOut.czz.get('0x0000000000000000000000000000000000000000').totalUsdPrice)
  475. },
  476. slGasBalance: totalSLGas, //散落 gas 费余额 充值 0.5 gas - 使用 0.3 gas= 散落 0.2gas
  477. }
  478. }
  479. function timeoutFunc(config, func) {
  480. config.runNow && func()
  481. let nowTime = new Date(utils.getCurrentDate()).getTime()
  482. // nowTime = new Date().getTime()
  483. let timePoints = config.time.split(':').map(i => parseInt(i))
  484. let recent = new Date(utils.getCurrentDate()).setHours(...timePoints)
  485. recent >= nowTime || (recent += 24 * 3600000)
  486. console.log('timeoutFunc-------------------', nowTime, timePoints, recent)
  487. setTimeout(() => {
  488. func()
  489. setInterval(func, config.interval * 3600000)
  490. }, recent - nowTime)
  491. }
  492. const getFeishuToken = async (params) => {
  493. return new Promise(resolve => {
  494. axios.post(feishu_write_table_token_url,
  495. {
  496. app_id: "cli_a223f015abbad00e",
  497. app_secret: "DMCF6tBwIpeOQPnWrFUMYd6tmjb53C4n"
  498. },
  499. {
  500. timeout: 1 * 60 * 1000,
  501. headers: {
  502. 'Content-Type': "application/json; charset=utf-8"
  503. }
  504. })
  505. .then(res => {
  506. logger.log('getFeishuToken res=>', res.status, res.data);
  507. resolve(res.data)
  508. }).catch(err => {
  509. logger.error('getFeishuToken error ', JSON.stringify(err));
  510. resolve(JSON.stringify(err))
  511. });
  512. })
  513. }
  514. function writeTable(app_token, data) {
  515. logger.info('writeTable', data)
  516. var body = {
  517. 'valueRanges': [
  518. {
  519. 'range': '0pRQpu!A2:C2',
  520. 'values': [
  521. [data.totalCollectCoinsGasFee, //归集总 gas
  522. data.totalWithdrawGasFee, //提币总 gas
  523. data.totalOutGasFee], //总支出 gas
  524. ]
  525. },
  526. {
  527. 'range': '1ygrMB!A2:B2',
  528. 'values': [
  529. [
  530. data.totalInFee, //总入金
  531. data.totalOutFee,//总出金
  532. ],
  533. ]
  534. },
  535. {
  536. 'range': 'BMjMDr!A3:J3',
  537. 'values': [
  538. [
  539. data.updateTime, //更新时间
  540. data.todayTotalProfit,//今日总利润
  541. data.todayIncomeUSDTotal,//今日总收入
  542. data.todayIncomeUSDFee,//今日固定手续费收入
  543. data.todayTotalOutGasFee,//今日总 gas 支出
  544. data.totalBalances, //总余额
  545. data.canNotWithdrawUSD, //不可提现余额
  546. data.canWithdrawUSD,//可提现余额
  547. data.ylGasBalance.total,//预留 gas
  548. data.slGasBalance.total,//散落 gas
  549. ],
  550. ]
  551. }
  552. ]
  553. }
  554. return new Promise(resolve => {
  555. axios.post(feishu_write_table_data_url,
  556. body,
  557. {
  558. timeout: 1 * 60 * 1000,
  559. headers: {
  560. 'Content-Type': "application/json; charset=utf-8",
  561. 'Authorization': 'Bearer ' + app_token
  562. }
  563. })
  564. .then(res => {
  565. logger.log('writeTable res=>', res.status, res.data);
  566. resolve(res.data)
  567. }).catch(err => {
  568. logger.error('writeTable error ', JSON.stringify(err));
  569. resolve(JSON.stringify(err))
  570. });
  571. })
  572. }
  573. async function insertTableRows(app_token) {
  574. var body = {
  575. dimension: {
  576. sheetId: 'BMjMDr',
  577. majorDimension: 'ROWS',
  578. startIndex: 2,
  579. endIndex: 3,
  580. },
  581. inheritStyle: 'AFTER'
  582. }
  583. return new Promise(resolve => {
  584. axios.post(feishu_insert_table_url,
  585. JSON.stringify(body),
  586. {
  587. timeout: 1 * 60 * 1000,
  588. headers: {
  589. 'Content-Type': "application/json; charset=utf-8",
  590. 'Authorization': 'Bearer ' + app_token
  591. }
  592. })
  593. .then(res => {
  594. console.log('res=>', res.status, res.data);
  595. resolve(res.data)
  596. }).catch(err => {
  597. logger.error('error ', JSON.stringify(err));
  598. resolve(JSON.stringify(err))
  599. });
  600. })
  601. }
  602. async function exec(data) {
  603. var app = await getFeishuToken()
  604. await insertTableRows(app.app_access_token)
  605. await writeTable(app.app_access_token, data)
  606. }
  607. async function report2FeishuTable() {
  608. try {
  609. logger.error('数据统计 start')
  610. logger.info('report2FeishuTable')
  611. var data = await getStatisticsInfo();
  612. logger.info('getStatisticsInfo', data)
  613. var ret = await exec(data)
  614. logger.error('数据统计 end','https://st94nif1cq.feishu.cn/sheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg?sheet=BMjMDr',JSON.stringify(data),JSON.stringify(ret))
  615. } catch (error) {
  616. logger.error('report2FeishuTable', error.toString())
  617. }
  618. }
  619. timeoutFunc({
  620. interval: 1, //间隔天数,间隔为整数
  621. runNow: false, //是否立即运行
  622. time: reportTime //执行的时间点 时在0~23之间
  623. }, func => {
  624. if (process.env.NODE_ENV == 'prd') {
  625. report2FeishuTable()
  626. }
  627. })
  628. // logger.info('getAllBalance ', getAllBalance())
  629. module.exports = {
  630. getStatisticsInfo
  631. }