| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836 | 
							- const logger = require('./logger')
 
- var remote_config_db = require("./db/remote_config_db");
 
- var collect_coins_db = require("./db/collect_coins_db");
 
- var withdraw_db = require("./db/withdraw_db");
 
- var moralis = require("./moralis_sdk");
 
- var utils = require("./utils");
 
- const axios = require('axios');
 
- var { account_config } = require('../config/config.js');
 
- const { max } = require('moment');
 
- const redis = require('./db/redis_db');
 
- // 拿到飞书写入的 token
 
- const feishu_write_table_token_url = 'https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal'
 
- const feishu_write_table_data_url = 'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg/values_batch_update'
 
- const feishu_insert_table_url = 'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg/insert_dimension_range'
 
- const feishu_delete_table_url = 'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg/dimension_range'
 
- const feishu_get_table_metadata_url = 'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg/metainfo'
 
- const feishu_create_table_url = 'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg/dimension_range'
 
- const mTokenPriceCache = new Map()
 
- const mDecimalsCache = new Map()
 
- //########################################### 出入金数据统计 ########################################
 
- const http_request_get = async (data) => {
 
-     var host = account_config.STATISTICS_URL
 
-     // host = 'https://api.denetme.net/denet/wallet/stat/getMoneyStat?date='
 
-     var path = data
 
-     var url = host + path
 
-     logger.log('http_request_get', url)
 
-     return new Promise(response => {
 
-         axios.get(url)
 
-             .then(res => {
 
-                 logger.log('res=>', res.status, res.data);
 
-                 if (res.data.code == 0) {
 
-                     response(res.data)
 
-                 } else {
 
-                     response({
 
-                         code: 0,
 
-                         msg: err.toString(),
 
-                         data: {
 
-                             canNotWithdrawUSD: '0',
 
-                             canWithdrawUSD: '0',
 
-                             incomeUSDTotal: '0',
 
-                             incomeUSDFee: '0'
 
-                         }
 
-                     })
 
-                 }
 
-             }).catch(err => {
 
-                 logger.error('http_request_get', err.toString(), url.toString());
 
-                 response({
 
-                     code: -1,
 
-                     msg: err.toString(),
 
-                     data: {
 
-                         canNotWithdrawUSD: '0',
 
-                         canWithdrawUSD: '0',
 
-                         incomeUSDTotal: '0',
 
-                         incomeUSDFee: '0'
 
-                     }
 
-                 })
 
-             });
 
-     })
 
- }
 
- function getBscEnv() {
 
-     var bsc_env
 
-     switch (process.env.NODE_ENV) {
 
-         case 'dev':
 
-         case 'test':
 
-             bsc_env = 'bsc_testnet'
 
-             bsc_env = 'bsc_mainnet'
 
-             break
 
-         case 'prd':
 
-             bsc_env = 'bsc_mainnet'
 
-             break
 
-         default:
 
-             bsc_env = 'bsc_mainnet'
 
-             break
 
-     }
 
-     return bsc_env;
 
- }
 
- async function findCurBalance(type, address) {
 
-     var balances
 
-     var price
 
-     var tokenItems = []
 
-     switch (type) {
 
-         case 'bsc':
 
-             balances = await moralis.getAccountAllCoins({
 
-                 chain: getBscEnv(),
 
-                 address: address
 
-             })
 
-             // price = await moralis.getAllTotkenPrice({ chain: getBscEnv() })
 
-             price = await getPrice(getBscEnv())
 
-             break
 
-         case 'czz':
 
-             balances = await moralis.getAccountAllCoins({
 
-                 chain: 'czz',
 
-                 address: address
 
-             })
 
-             price = await getPrice('czz')
 
-             // price = await moralis.getAllTotkenPrice({ chain: 'czz' })
 
-             break
 
-     }
 
-     logger.info('findCurBalance', type, address, balances, price)
 
-     if (typeof price === 'string') {
 
-         price = JSON.parse(price)
 
-     }
 
-     if (!balances || !price) return null
 
-     priceItem = moralis.findTokenPriceItem('0x0000000000000000000000000000000000000000', price)
 
-     if (!balances.native.balance) {
 
-         balances.native.balance = '0'
 
-     }
 
-     if (balances.native) {
 
-         balances.native.usdPrice = parseFloat(balances.native.balance) / parseFloat(10 ** 18) * priceItem.usdPrice
 
-         logger.info('findTokenPriceItem 0x0000000000000000000000000000000000000000 ', balances, priceItem, type)
 
-         var bo = {
 
-             address: address,
 
-             token_address: '0x0000000000000000000000000000000000000000',
 
-             chain: type,
 
-             amount: balances.native.balance,
 
-             decimals: 18,
 
-             price: priceItem.usdPrice,
 
-             usd: balances.native.usdPrice
 
-         }
 
-         tokenItems.push(bo)
 
-     }
 
-     if (balances.other && Array.isArray(balances.other)) {
 
-         for (let index = 0; index < balances.other.length; index++) {
 
-             const element = balances.other[index];
 
-             priceItem = moralis.findTokenPriceItem(element.token_address, price)
 
-             logger.info('findTokenPriceItem element ', priceItem, element.token_address)
 
-             if (priceItem) {
 
-                 if (!element.decimals || element.decimals == 0)
 
-                     element.decimals = 18
 
-                 element.usdPrice = parseFloat(element.balance) / parseFloat(10 ** element.decimals) * priceItem.usdPrice
 
-                 var bo = {
 
-                     address: address,
 
-                     token_address: element.token_address,
 
-                     chain: type,
 
-                     amount: element.balance,
 
-                     decimals: element.decimals,
 
-                     price: priceItem.usdPrice,
 
-                     usd: element.usdPrice
 
-                 }
 
-                 tokenItems.push(bo)
 
-             }
 
-         }
 
-     }
 
-     logger.debug('tokenUsds', tokenItems, type)
 
-     return {
 
-         nativeUsd: balances.native.usdPrice,
 
-         tokenUsds: tokenItems,
 
-         totalUsd: addUsds(tokenItems, 'token_balance')
 
-     }
 
- }
 
- async function getAllBalanceV2() {
 
-     var company = await moralis.queryCompanyInfoFromId(0)
 
-     logger.info('getAllBalance company', company)
 
-     var bsc_balances = await findCurBalance('bsc', company.user_address)
 
-     var czz_balances = await findCurBalance('czz', company.user_address)
 
-     logger.info('findCurBalance bsc_balances', bsc_balances)
 
-     logger.info('findCurBalance czz_balances', czz_balances)
 
-     let lists = bsc_balances.tokenUsds.concat(czz_balances.tokenUsds);
 
-     return {
 
-         bsc: bsc_balances,
 
-         czz: czz_balances,
 
-         infos: lists,
 
-         totalUsd: bsc_balances.totalUsd + czz_balances.totalUsd,
 
-         totalNativeBalanceUsd: bsc_balances.nativeUsd + czz_balances.nativeUsd
 
-     }
 
- }
 
- function parseGas(response, index, price) {
 
-     try {
 
-         logger.info('parseGas in', response, index)
 
-         if (response && Array.isArray(response) && response.length > 0) {
 
-             var obj
 
-             if (response[index] && typeof response[index] === 'string')
 
-                 try {
 
-                     obj = JSON.parse(response[index])
 
-                 } catch (error) {
 
-                     logger.error('JSON.parse(response[index])', error.toString)
 
-                 }
 
-             return parseFloat(obj.gasPrice.number) * parseFloat(obj.gasLimit.number) / parseFloat(10 ** 18) * parseFloat(price)
 
-         }
 
-         else return 0
 
-     } catch (error) {
 
-         logger.error('parseGas', error.toString(), JSON.stringify(response))
 
-         return 0
 
-     }
 
- }
 
- async function getPrice(key) {
 
-     if (mTokenPriceCache.has(key)) {
 
-         price = mTokenPriceCache.get(key)
 
-     } else {
 
-         var price = await moralis.getAllTotkenPrice({
 
-             chain: key
 
-         })
 
-         if (typeof price === 'string') {
 
-             price = JSON.parse(price)
 
-         }
 
-         mTokenPriceCache.set(key, price)
 
-     }
 
-     return price
 
- }
 
- async function getPriceFromCache(key, address) {
 
-     console.info('getPriceFromCache>', key, address)
 
-     var price = await getPrice(key)
 
-     // var price = await moralis.getAllTotkenPrice({
 
-     //     chain: key
 
-     // })
 
-     // if (typeof price === 'string') {
 
-     //     price = JSON.parse(price)
 
-     // }
 
-     var priceItem = moralis.findTokenPriceItem(address, price)
 
-     if (priceItem && priceItem.usdPrice) {
 
-         return priceItem.usdPrice
 
-     } else {
 
-         return '0'
 
-     }
 
- }
 
- function convertChain(chain) {
 
-     return chain
 
- }
 
- function balance2USDPrice(amount, decimals, price) {
 
-     return parseFloat(amount) / parseFloat(10 ** decimals) * parseFloat(price)
 
- }
 
- async function getDecimalsFromRedis(chain, address) {
 
-     var decimals = 18
 
-     try {
 
-         var newKey = redis.formatRedisKey('REDIS_ERC20_CONTRACT_DECIMALS', chain, address.toLowerCase())
 
-         if (mDecimalsCache.has(newKey)) {
 
-             decimals = mDecimalsCache.get(newKey)
 
-         } else {
 
-             decimals = await redis.readAppendRedis('REDIS_ERC20_CONTRACT_DECIMALS', chain, address.toLowerCase())
 
-             mDecimalsCache.set(newKey, decimals)
 
-         }
 
-         if (!decimals) decimals = '18'
 
-     } catch (error) {
 
-         logger.error('getDecimalsFromRedis', chain, address, error.toString())
 
-         decimals = 18
 
-     }
 
-     return decimals
 
- }
 
- function addUsds(infos, type) {
 
-     var total = 0
 
-     if (infos && Array.isArray(infos) && infos.length > 0) {
 
-         for (let index = 0; index < infos.length; index++) {
 
-             const element = infos[index];
 
-             switch (type) {
 
-                 case 'gas':
 
-                     // logger.info('addUsds total ', type, element.gasUsd, element, total)
 
-                     total += element.gasUsd
 
-                     break
 
-                 case 'withdraw':
 
-                     total += element.withdrawUsd
 
-                     break
 
-                 case 'collect_coins':
 
-                     total += element.withdrawUsd
 
-                     break
 
-                 case 'slGas':
 
-                     total += element.slGasUsd
 
-                     break
 
-                 case 'token_balance':
 
-                     total += element.usd
 
-                     break
 
-                 case 'native_in_coins':
 
-                     if (element.token_address && element.token_address == '0x0000000000000000000000000000000000000000')
 
-                         total += element.inUsd
 
-                     break
 
-                 case 'native_token_in_coins':
 
-                     total += element.inUsd
 
-                     break
 
-             }
 
-         }
 
-     }
 
-     return total
 
- }
 
- async function getWithdrawOutInfoV2(startTime, endTime) {
 
-     if (startTime && endTime) {
 
-         startTime = new Date(startTime).getTime()
 
-         endTime = new Date(endTime).getTime()
 
-     }
 
-     if (!startTime && endTime) {
 
-         startTime = 0
 
-         endTime = new Date(endTime).getTime()
 
-     }
 
-     var withdraw_ret = await withdraw_db.getWidthdrawTotalFee(startTime, endTime)
 
-     var withDrawInfos = []
 
-     for (let index = 0; index < withdraw_ret.length; index++) {
 
-         const trs = withdraw_ret[index];
 
-         // console.log('getWithdrawOutInfoV2 element ', trs)
 
-         var token_address = trs.contract_address
 
-         if (!trs.contract_address)
 
-             token_address = '0x0000000000000000000000000000000000000000'
 
-         try {
 
-             var input = {
 
-                 dt: utils.chinaTimeMs(trs.update_time),
 
-                 user_address: trs.to_address,
 
-                 token_address: token_address,
 
-                 chain: convertChain(trs.chain_id + ""),
 
-                 amount: trs.amount,
 
-                 decimals: await getDecimalsFromRedis(convertChain(trs.chain_id + ""), token_address),
 
-                 price: await getPriceFromCache(convertChain(trs.chain_id + ""), token_address),
 
-                 gasUsd: parseFloat(trs.gas_price) * parseFloat(trs.gas_limit) / parseFloat(10 ** 18) * await getPriceFromCache(convertChain(trs.chain_id + ""), '0x0000000000000000000000000000000000000000')
 
-             }
 
-             if (!input.gasUsd) {
 
-                 logger.info('withdraw_ret input ', trs, input)
 
-                 input.gasUsd = 0
 
-             }
 
-             //换算成美元
 
-             input.withdrawUsd = balance2USDPrice(input.amount, input.decimals, input.price)
 
-             console.log('getWithdrawOutInfoV2 input ', input)
 
-             withDrawInfos.push(input)
 
-         } catch (error) {
 
-             logger.error('getWithdrawOutInfoV2 trs', error.toString())
 
-         }
 
-     }
 
-     // logger.log('getWithdrawOutInfoV2 totalOutGasFeeUsd addUsds', addUsds(withDrawInfos, 'gas'), withDrawInfos[0], withDrawInfos[1])
 
-     return {
 
-         infos: withDrawInfos,
 
-         totalOutGasFeeUsd: addUsds(withDrawInfos, 'gas'),
 
-         totalWithdrawUsd: addUsds(withDrawInfos, 'withdraw'),
 
-     }
 
- }
 
- async function getCollectCoinsOutInfoV2(startTime, endTime) {
 
-     var collect_ret = await collect_coins_db.query_collect_total_fee(startTime, endTime);
 
-     // console.log('getCollectCoinsOutInfoV2 collect_ret', collect_ret.results.length)
 
-     //每笔入金的详细信息
 
-     var infos = []
 
-     //入金充值的 gas 和实际消费的 gas
 
-     var inGasFeeInfo = []
 
-     if (collect_ret && collect_ret.results && Array.isArray(collect_ret.results) && collect_ret.results.length > 0) {
 
-         for (let index = 0; index < collect_ret.results.length; index++) {
 
-             var element = collect_ret.results[index]
 
-             if (!element.chain)
 
-                 element.chain = 'bsc_mainnet'
 
-             var update_tm = element.update_time
 
-             var user_address = element.user_address
 
-             // console.log('getCollectCoinsOutInfoV2 element', element.before_gas_fee, element.resposes, typeof element.resposes, JSON.parse(element.resposes))
 
-             var resposes;
 
-             if (element.resposes && typeof element.resposes === 'string') {
 
-                 try {
 
-                     resposes = JSON.parse(element.resposes)
 
-                 } catch (error) {
 
-                     logger.error('element.response parse', error.toString())
 
-                 }
 
-             }
 
-             if (element.prestore_gas_fee && typeof element.prestore_gas_fee === 'string') {
 
-                 try {
 
-                     var gasObj = JSON.parse(element.prestore_gas_fee)
 
-                     var before_gas_fee = element.before_gas_fee ? element.before_gas_fee : '0'
 
-                     if (gasObj) {
 
-                         // logger.log('element.prestore_gas_fee parse', before_gas_fee, gasObj, gasObj.chain)
 
-                         var newGasObj = {
 
-                             chain: convertChain(gasObj.chain),
 
-                             amount: gasObj.amount,
 
-                             useGas: before_gas_fee,
 
-                             price: await getPriceFromCache(convertChain(gasObj.chain), '0x0000000000000000000000000000000000000000'),
 
-                         }
 
-                         //实际充值手续费用到的 usd
 
-                         newGasObj.gasUsd = balance2USDPrice(newGasObj.useGas, 18, newGasObj.price)
 
-                         //散落 gas
 
-                         newGasObj.slGasUsd = balance2USDPrice(parseFloat(newGasObj.amount) - parseFloat(newGasObj.useGas), 18, newGasObj.price)
 
-                         inGasFeeInfo.push(newGasObj)
 
-                     }
 
-                 } catch (error) {
 
-                     logger.error('element.prestore_gas_fee parse', error.toString())
 
-                 }
 
-             }
 
-             if (element.transfers && typeof element.transfers === 'string') {
 
-                 try {
 
-                     var trss = JSON.parse(element.transfers)
 
-                     // console.log('trss.transfers', trss.chain)
 
-                     for (let index = 0; index < trss.length; index++) {
 
-                         const trs = trss[index];
 
-                         var address = trs.contractAddress == null ? '0x0000000000000000000000000000000000000000' : trs.contractAddress
 
-                         console.log('trss.transfers', address, trs)
 
-                         var input = {
 
-                             dt: update_tm,
 
-                             user_address: user_address,
 
-                             token_address: address,
 
-                             chain: convertChain(trs.chain),
 
-                             amount: trs.amount,
 
-                             decimals: trs.contractAddress == null ? 18 : await getDecimalsFromRedis(convertChain(trs.chain), trs.contractAddress),
 
-                             price: await getPriceFromCache(convertChain(trs.chain), address),
 
-                             gasUsd: parseGas(resposes, index, await getPriceFromCache(convertChain(trs.chain), '0x0000000000000000000000000000000000000000')) //入金 gas 手续费
 
-                         }
 
-                         //换算成美元
 
-                         input.inUsd = balance2USDPrice(input.amount, input.decimals, input.price)
 
-                         infos.push(input)
 
-                     }
 
-                 } catch (error) {
 
-                     logger.error('transfers handle error', error.toString())
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     return {
 
-         infos: infos,
 
-         totalNativeInFee: addUsds(infos, 'native_in_coins'), //总 native 入金
 
-         totalInFee: addUsds(infos, 'native_token_in_coins'), //总入金
 
-         totalInGasFeeUsd: addUsds(infos, 'gas') + addUsds(inGasFeeInfo, 'gas'),//总入金消耗的 gas 包含打 gas fee
 
-         slTotalGasFeeUsd: addUsds(inGasFeeInfo, 'slGas') //散落 gas
 
-     }
 
- }
 
- async function getServerData(startTime, endTime) {
 
-     //拿到所有归集 list
 
-     var collectCoinsInfos = await getCollectCoinsOutInfoV2(startTime, endTime)
 
-     // console.log('getCollectCoinsOutInfoV2 collectCoinsInfos ', collectCoinsInfos)
 
-     //拿到所有出金
 
-     var withdrawInfos = await getWithdrawOutInfoV2(startTime, endTime)
 
-     // console.log('getWithdrawOutInfoV2 withdrawInfos ', withdrawInfos)
 
-     return {
 
-         collectCoinsInfos: collectCoinsInfos,
 
-         withdrawInfos: withdrawInfos
 
-     }
 
- }
 
- function sortList(lists) {
 
-     lists.sort((a, b) => {
 
-         let t1 = new Date(a.dt)
 
-         let t2 = new Date(b.dt)
 
-         return t2.getTime() - t1.getTime()
 
-     })
 
-     return lists
 
- }
 
- function formatTableData(type, datas) {
 
-     var arrs = []
 
-     for (let index = 0; index < datas.length; index++) {
 
-         const element = datas[index];
 
-         switch (type) {
 
-             case 'incoins':
 
-                 arrs.push([element.dt,
 
-                 element.user_address,
 
-                 element.token_address,
 
-                 element.chain,
 
-                 element.amount,
 
-                 element.decimals,
 
-                 element.price,
 
-                 element.gasUsd,
 
-                 element.inUsd
 
-                 ])
 
-                 break;
 
-             case 'outcoins':
 
-                 arrs.push([element.dt,
 
-                 element.user_address,
 
-                 element.token_address,
 
-                 element.chain,
 
-                 element.amount,
 
-                 element.decimals,
 
-                 element.price,
 
-                 element.gasUsd,
 
-                 element.withdrawUsd
 
-                 ])
 
-                 break
 
-             case 'balances':
 
-                 arrs.push([element.address,
 
-                 element.token_address,
 
-                 element.chain,
 
-                 element.amount,
 
-                 element.decimals,
 
-                 element.price,
 
-                 element.usd
 
-                 ])
 
-                 break
 
-             default:
 
-                 break;
 
-         }
 
-     }
 
-     logger.info('formatTableData', arrs)
 
-     return arrs
 
- }
 
- async function getStatisticsInfoV2(day) {
 
-     // //今日
 
-     var startTime = utils.getLastDay(day, 'YYYY-MM-DD') + " 00:00:00"
 
-     var endTime = utils.getLastDay(day, 'YYYY-MM-DD') + " 23:59:59"
 
-     logger.info('getTotalOutGasFee', startTime, endTime)
 
-     var rangeData = await getServerData(startTime, endTime)
 
-     logger.info('getServerData rangeData', rangeData)
 
-     var allData = await getServerData(null, endTime)
 
-     // var allData = rangeData
 
-     logger.info('getServerData allData', allData)
 
-     var data = await http_request_get(utils.getLastDay(day, 'YYYYMMDD'))
 
-     logger.info('http_request_get data', data)
 
-     //获取当前账户总余额
 
-     var curBalances = await getAllBalanceV2()
 
-     logger.info('getAllBalanceV2 curBalances', curBalances)
 
-     return {
 
-         updateTime: utils.getLastDay(day, 'YYYY-MM-DD'),
 
-         todayTotalProfit: parseFloat(data.data.incomeUSDTotal) - parseFloat(rangeData.collectCoinsInfos.totalInGasFeeUsd + rangeData.withdrawInfos.totalOutGasFeeUsd),//今日收入
 
-         todayTotalOutGasFee: rangeData.collectCoinsInfos.totalInGasFeeUsd + rangeData.withdrawInfos.totalOutGasFeeUsd,//今日总支出的 gas fee
 
-         canNotWithdrawUSD: parseFloat(data.data.canNotWithdrawUSD),                                    //不可提现余额
 
-         canWithdrawUSD: parseFloat(data.data.canWithdrawUSD),                                          //可提现余额
 
-         todayIncomeUSDTotal: parseFloat(data.data.incomeUSDTotal),                                     //今日总收入
 
-         todayIncomeUSDFee: parseFloat(data.data.incomeUSDFee),                                         //今日固定收入
 
-         totalOutGasFee: allData.collectCoinsInfos.totalInGasFeeUsd + allData.withdrawInfos.totalOutGasFeeUsd, //总支出 gas fee
 
-         totalWithdrawGasFee: allData.withdrawInfos.totalOutGasFeeUsd,                        //总提币 gas fee
 
-         totalCollectCoinsGasFee: allData.collectCoinsInfos.totalInGasFeeUsd,                            //总归集 gas fee
 
-         totalInFee: allData.collectCoinsInfos.totalInFee,                                               //总入金
 
-         totalNativeInFee: allData.collectCoinsInfos.totalNativeInFee,                                   //总 native 入金
 
-         totalOutFee: allData.withdrawInfos.totalWithdrawUsd,                                            //总出金
 
-         totalBalances: curBalances.totalUsd,                                                            //总余额
 
-         ylGasBalance: curBalances.totalNativeBalanceUsd - allData.collectCoinsInfos.totalNativeInFee,   //预留 gas 费余额  native 总余额 - 总入金
 
-         slGasBalance: allData.collectCoinsInfos.slTotalGasFeeUsd,   //散落 gas 费余额  充值 0.5 gas - 使用 0.3 gas= 散落 0.2gas
 
-         todayInUsdLists: sortList(rangeData.collectCoinsInfos.infos),//入金列表
 
-         todayOutUsdLists: sortList(rangeData.withdrawInfos.infos),//出金列表
 
-         totalInUsdLists: sortList(allData.collectCoinsInfos.infos),//总入金列表
 
-         totalOutUsdLists: sortList(allData.withdrawInfos.infos),//总出金列表
 
-         totalBalanceLists: curBalances.infos //总余额
 
-     }
 
- }
 
- const getFeishuToken = async (params) => {
 
-     return new Promise(resolve => {
 
-         axios.post(feishu_write_table_token_url,
 
-             {
 
-                 app_id: "cli_a223f015abbad00e",
 
-                 app_secret: "DMCF6tBwIpeOQPnWrFUMYd6tmjb53C4n"
 
-             },
 
-             {
 
-                 timeout: 1 * 60 * 1000,
 
-                 headers: {
 
-                     'Content-Type': "application/json; charset=utf-8"
 
-                 }
 
-             })
 
-             .then(res => {
 
-                 logger.log('getFeishuToken res=>', res.status, res.data);
 
-                 resolve(res.data)
 
-             }).catch(err => {
 
-                 logger.error('getFeishuToken error ', JSON.stringify(err));
 
-                 resolve(JSON.stringify(err))
 
-             });
 
-     })
 
- }
 
- function formatTableRangle(id, size) {
 
-     var newId = id + size
 
-     logger.info('formatTableRangle', id, size, newId)
 
-     return newId
 
- }
 
- async function writeTable(app_token, data) {
 
-     logger.info('writeTable', data)
 
-     var valueRanges = []
 
-     if (data.todayInUsdLists.length > 0) {
 
-         await insertTableRows(app_token, 'Ji1hLG', 1, data.todayInUsdLists.length + 1)
 
-         valueRanges.push({//入金汇总
 
-             'range': formatTableRangle('Ji1hLG!A2:I', data.todayInUsdLists.length + 1),
 
-             'values': formatTableData('incoins', data.todayInUsdLists)
 
-         })
 
-     }
 
-     if (data.todayOutUsdLists.length > 0) {
 
-         await insertTableRows(app_token, 'aFCrrP', 1, data.todayOutUsdLists.length + 1)
 
-         valueRanges.push({//出金汇总
 
-             'range': formatTableRangle('aFCrrP!A2:I', data.todayOutUsdLists.length + 1),
 
-             'values': formatTableData('outcoins', data.todayOutUsdLists)
 
-         })
 
-     }
 
-     if (data.totalBalanceLists.length > 0) {
 
-         var rows = await getTableRows(app_token, 2)
 
-         if (rows > 1) {
 
-             logger.info('getTableRows', rows)
 
-             await delTableRows(app_token, '2hNaot', 2, rows)
 
-             await addTableRows(app_token, '2hNaot', rows)
 
-         }
 
-         valueRanges.push({ //总余额汇总
 
-             'range': formatTableRangle('2hNaot!A2:I', data.totalBalanceLists.length + 1),
 
-             'values': formatTableData('balances', data.totalBalanceLists)
 
-         })
 
-     }
 
-     valueRanges.push({//归集汇总
 
-         'range': formatTableRangle('0pRQpu!A2:C', 2),
 
-         'values': [
 
-             [data.totalCollectCoinsGasFee, //归集总 gas
 
-             data.totalWithdrawGasFee, //提币总 gas
 
-             data.totalOutGasFee], //总支出 gas
 
-         ]
 
-     })
 
-     valueRanges.push({//总入账
 
-         'range': formatTableRangle('1ygrMB!A2:B', 2),
 
-         'values': [
 
-             [
 
-                 data.totalInFee, //总入金
 
-                 data.totalOutFee,//总出金
 
-             ]
 
-         ]
 
-     })
 
-     valueRanges.push({//利润表单
 
-         'range': formatTableRangle('BMjMDr!A3:J', 3),
 
-         'values': [
 
-             [
 
-                 data.updateTime,      //更新时间
 
-                 data.todayTotalProfit,//今日总利润
 
-                 data.todayIncomeUSDTotal,//今日总收入
 
-                 data.todayIncomeUSDFee,//今日固定手续费收入
 
-                 data.todayTotalOutGasFee,//今日总 gas 支出
 
-                 data.totalBalances, //总余额
 
-                 data.canNotWithdrawUSD, //不可提现余额
 
-                 data.canWithdrawUSD,//可提现余额
 
-                 data.ylGasBalance,//预留 gas
 
-                 data.slGasBalance,//散落 gas
 
-             ],
 
-         ]
 
-     })
 
-     var body = {
 
-         'valueRanges': valueRanges
 
-     }
 
-     return new Promise(resolve => {
 
-         axios.post(feishu_write_table_data_url,
 
-             body,
 
-             {
 
-                 timeout: 1 * 60 * 1000,
 
-                 headers: {
 
-                     'Content-Type': "application/json; charset=utf-8",
 
-                     'Authorization': 'Bearer ' + app_token
 
-                 }
 
-             })
 
-             .then(res => {
 
-                 logger.log('writeTable res=>', res.status, res.data);
 
-                 resolve(res.data)
 
-             }).catch(err => {
 
-                 logger.error('writeTable error ', JSON.stringify(err));
 
-                 resolve(JSON.stringify(err))
 
-             });
 
-     })
 
- }
 
- async function getTableRows(app_token, index) {
 
-     return new Promise(resolve => {
 
-         axios.get(feishu_get_table_metadata_url,
 
-             {
 
-                 timeout: 1 * 60 * 1000,
 
-                 headers: {
 
-                     'Content-Type': "application/json; charset=utf-8",
 
-                     'Authorization': 'Bearer ' + app_token
 
-                 }
 
-             })
 
-             .then(res => {
 
-                 console.log('res=>', res.status, res.data, res.data.data.sheets);
 
-                 resolve(res.data.data.sheets[index].rowCount)
 
-             }).catch(err => {
 
-                 logger.error('error ', JSON.stringify(err));
 
-                 resolve(0)
 
-             });
 
-     })
 
- }
 
- async function delTableRows(app_token, sheetId, startIndex, endIndex) {
 
-     var body = {
 
-         dimension: {
 
-             sheetId: sheetId,
 
-             majorDimension: 'ROWS',
 
-             startIndex: startIndex,
 
-             endIndex: endIndex,
 
-         },
 
-     }
 
-     return new Promise(resolve => {
 
-         axios.delete(feishu_delete_table_url,
 
-             {
 
-                 data: body,
 
-                 timeout: 1 * 60 * 1000,
 
-                 headers: {
 
-                     'Content-Type': "application/json; charset=utf-8",
 
-                     'Authorization': 'Bearer ' + app_token
 
-                 }
 
-             })
 
-             .then(res => {
 
-                 console.log('delTableRows res=>', res.status, res.data);
 
-                 resolve(res.data)
 
-             }).catch(err => {
 
-                 logger.error('delTableRows error ', JSON.stringify(err));
 
-                 resolve(JSON.stringify(err))
 
-             });
 
-     })
 
- }
 
- async function insertTableRows(app_token, sheetId, startIndex, endIndex) {
 
-     logger.info('insertTableRows', app_token, sheetId, startIndex, endIndex)
 
-     var body = {
 
-         dimension: {
 
-             sheetId: sheetId,
 
-             majorDimension: 'ROWS',
 
-             startIndex: startIndex,
 
-             endIndex: endIndex,
 
-         },
 
-         inheritStyle: 'AFTER'
 
-     }
 
-     return new Promise(resolve => {
 
-         axios.post(feishu_insert_table_url,
 
-             JSON.stringify(body),
 
-             {
 
-                 timeout: 1 * 60 * 1000,
 
-                 headers: {
 
-                     'Content-Type': "application/json; charset=utf-8",
 
-                     'Authorization': 'Bearer ' + app_token
 
-                 }
 
-             })
 
-             .then(res => {
 
-                 console.log('res=>', res.status, res.data);
 
-                 resolve(res.data)
 
-             }).catch(err => {
 
-                 logger.error('error ', JSON.stringify(err));
 
-                 resolve(JSON.stringify(err))
 
-             });
 
-     })
 
- }
 
- async function addTableRows(app_token, sheetId, endIndex) {
 
-     var body = {
 
-         dimension: {
 
-             sheetId: sheetId,
 
-             majorDimension: 'ROWS',
 
-             length: endIndex,
 
-         },
 
-     }
 
-     return new Promise(resolve => {
 
-         axios.post(feishu_create_table_url,
 
-             JSON.stringify(body),
 
-             {
 
-                 timeout: 1 * 60 * 1000,
 
-                 headers: {
 
-                     'Content-Type': "application/json; charset=utf-8",
 
-                     'Authorization': 'Bearer ' + app_token
 
-                 }
 
-             })
 
-             .then(res => {
 
-                 console.log('res=>', res.status, res.data);
 
-                 resolve(res.data)
 
-             }).catch(err => {
 
-                 logger.error('error ', JSON.stringify(err));
 
-                 resolve(JSON.stringify(err))
 
-             });
 
-     })
 
- }
 
- async function exec(data) {
 
-     var app = await getFeishuToken()
 
-     await insertTableRows(app.app_access_token, 'BMjMDr', 2, 3)
 
-     return await writeTable(app.app_access_token, data)
 
- }
 
- async function report2FeishuTable(day) {
 
-     try {
 
-         logger.error('数据统计 start')
 
-         logger.info('report2FeishuTable')
 
-         var data = await getStatisticsInfoV2(day);
 
-         // data = ''
 
-         logger.info('getStatisticsInfo', data)
 
-         var ret = await exec(data)
 
-         logger.error('数据统计完成:', 'https://st94nif1cq.feishu.cn/sheets/shtcnp6zbrsep1Sz3Cvk7NXRpDg?sheet=BMjMDr')
 
-         mTokenPriceCache.clear()
 
-     } catch (error) {
 
-         logger.error('report2FeishuTable', error.toString())
 
-     }
 
- }
 
- async function test() {
 
-     // var ret = await getStatisticsInfoV2(2)
 
-     // logger.debug('getStatisticsInfoV2', await getStatisticsInfoV2(2), mTokenPriceCache.size)
 
-     // for (let index = 40; index >=0; index--) {
 
-     await report2FeishuTable(1)
 
-     // }
 
- }
 
- // test()
 
- // exec()
 
- module.exports = {
 
-     getStatisticsInfoV2
 
- }
 
 
  |