diff --git a/clean.js b/clean.js new file mode 100644 index 0000000..534ab48 --- /dev/null +++ b/clean.js @@ -0,0 +1,89 @@ +'use strict'; +const mongoose = require('mongoose'); +const Fund = require('./src/modules/fund/fund.model'); +const Action = require('./src/modules/action/action.model'); +const PrettyStream = require('bunyan-pretty-colors'); +const bunyan = require('bunyan'); +const path = require('path'); +const fs = require('fs'); + +const prettyStdOut = new PrettyStream(); + +if (!fs.existsSync('clean')) { + fs.mkdirSync('clean'); +} +const logger = function (option) { + option = option || {}; + return bunyan.createLogger({ + name: "log", + src: false, + streams: [ + { + level: 'info', + stream: prettyStdOut + }, + { + level: 'info', + type: 'rotating-file', + path: path.join(option.root, option.file || 'info.log'), + period: '1d', // daily rotation + count: 365 // keep 30 days + } + ] + }); +}; +const filename = 'clean' + new Date().getFullYear() + new Date().getMonth() + new Date().getDate(); +const mylog = logger(({ root: 'clean', file: filename })); + +const probe = { + currentIndex: 0 +}; +async function clean () { + let allFund = await Fund.find({ fundSum: { $gt: 0 } }); + // 批量更新,每次十个 + for (let currentIndex = 0; currentIndex < allFund.length; currentIndex++) { + const userFund = allFund[currentIndex]; + const fundList = userFund.fundList; + const boughtAmountSum = fundList.reduce((sum, fund) => sum + +fund.amount, 0); + const releasedAmout = (await Action.find({ type: '1', userId: userFund.userId })).reduce((sum, action) => sum + +action.amount, 0); + const rest = boughtAmountSum - releasedAmout; + mylog.info('No. ', currentIndex, '用户' + userFund.userId, '剩余 ', rest); + const vic = userFund.asset.vic || 0; + const newFund = vic + rest; + await Fund.findByIdAndUpdate(userFund.id, { vicFundSum: newFund, 'asset.vic': 0, 'asset.usdt': 0, fundList: [], snapshot: { asset: userFund.asset, fundList } }); + probe.currentIndex = currentIndex; + } +} + +const start = async (job, done) => { + const SysConfig = require('./configSec'); + mongoose.set('useCreateIndex', true); + const { DB_USER_NAME, DB_PASSWD, DB_HOST, DB_PORT, DB_NAME } = SysConfig; + const db = mongoose.connection; + db.on('error', mylog.error); + db.once('open', function() { + mylog.info('数据库连接成功...'); + }); + mylog.info('开始连接数据库...'); + await mongoose.connect(`mongodb://${DB_USER_NAME}:${DB_PASSWD}@${DB_HOST}:${DB_PORT}/${DB_NAME}`, { + useNewUrlParser: true, + bufferMaxEntries: 0, + autoReconnect: true, + useFindAndModify: false, + useUnifiedTopology: true + }); + const beforeExit = async (msg) => { + mylog.info('意外退出', msg); + mylog.info('进行到第'+ probe.currentIndex + '个用户'); + process.exit(0); + }; + process.on('SIGINT', beforeExit); + process.on('uncaughtException', beforeExit); + process.on('unhandledRejection', beforeExit); + typeof process.send === 'function' && process.send('子进程开始执行mine'); + clean(job, done); + typeof process.send === 'function' && process.send('子进程mine执行完毕'); + process.exit(); +}; + +start(); diff --git a/src/common/constant.js b/src/common/constant.js index 6c73706..4ee3b89 100644 --- a/src/common/constant.js +++ b/src/common/constant.js @@ -2,5 +2,8 @@ module.exports = { USDTAddr: '0xdac17f958d2ee523a2206206994597c13d831ec7', - startBlock: 8510200 + VICAddr: '0xA5D1Eb8bBB42b7f2EBBebF174B3966510243F30c', + startBlock: 8510200, + VIC_DECIMAL: 1e18, + USDT_DECIMAL: 1e6, }; \ No newline at end of file diff --git a/src/common/deposit.js b/src/common/deposit.js index 534c7c7..514687c 100644 --- a/src/common/deposit.js +++ b/src/common/deposit.js @@ -1,6 +1,6 @@ 'use strict'; const { ERC20 } = require('../utils/erc20'); -const { USDTAddr, startBlock } = require('./constant'); +const { USDTAddr, VICAddr, startBlock, VIC_DECIMAL, USDT_DECIMAL } = require('./constant'); const getUSDTTxList = async address => { if (!address) return null; @@ -9,23 +9,43 @@ const getUSDTTxList = async address => { }); return res.filter(tx => tx.tokenName === 'Tether USD' && tx.tokenSymbol === 'USDT' && tx.to === address && tx.from !== address); //只取转入到本地址的 }; +const getVICTxList = async address => { + if (!address) return null; + const res = await ERC20.getActions(address, VICAddr, startBlock).catch(err => { + if (err) return []; + }); + return res.filter(tx => tx.tokenName === 'Value of Individual' && tx.tokenSymbol === 'VIC' && tx.to === address && tx.from !== address); //只取转入到本地址的 +}; -const parseUsdtTx = txList => { +const parseETHTx = txList => { if (!txList || !Array.isArray(txList)) return []; return txList.map(tx => { - tx.amount = (+tx.value) / 1e6; + tx.amount = (+tx.value) / VIC_DECIMAL; return tx; }); }; - -const getNewDepositTx = (usdtTx = [], fundList = []) => { +// usdt +const getNewUSDTDepositTx = (usdtTx = [], fundList = []) => { if (fundList.length > usdtTx.length) return null; // fundList的顺序应该与usdtTx的顺序一致,所以只要截取新的 const newUsdtTxList = usdtTx.slice(fundList.length); - return parseUsdtTx(newUsdtTxList); + return parseETHTx(newUsdtTxList); +}; +// vic +const getNewDepositTx = (vicTx = [], fundList = []) => { + if (fundList.length >= vicTx.length) return null; + const newList = []; + const existedFund = fundList.map(fund => fund.txHash).filter(f => f !== null); + for (let i = 0, len = vicTx.length; i < len; ++i) { + if (!existedFund.includes(vicTx[i].hash)) { + newList.push(vicTx[i]); + } + } + return parseETHTx(newList); }; module.exports = { + getVICTxList, getUSDTTxList, getNewDepositTx }; \ No newline at end of file diff --git a/src/jobs/jobs.js b/src/jobs/jobs.js index 08cd5c1..5341a28 100644 --- a/src/jobs/jobs.js +++ b/src/jobs/jobs.js @@ -39,7 +39,7 @@ watcher.on('startMine', () => { mylog.info('挖矿程序执行完毕'); }); rl.on('message', function (msg) { - mylog.info('MineInfo', msg) + mylog.info('MineInfo', msg); }); rl.on('exit', function () { mylog.info('挖矿程序执行完毕'); diff --git a/src/jobs/mine.js b/src/jobs/mine.js index 1a0a4c5..0d17f0f 100644 --- a/src/jobs/mine.js +++ b/src/jobs/mine.js @@ -37,82 +37,81 @@ const User = require('../modules/user/user.model'); const Fund = require('../modules/fund/fund.model'); const system = require('../modules/system/system.model'); const { createAction } = require('../modules/action/action.handler'); +const revenueLadderSheet = [ + {amount: 10000, rate: 0.001}, + {amount: 40000, rate: 0.003}, + {amount: 50000, rate: 0.006}, + {amount: 100000, rate: 0.01}, + {amount: 300000, rate: 0.015}, + {amount: 500000, rate: 0.018}, + {amount: NaN, rate: 0.02} +]; -const tokenReleaseRate = 0.02; -const inviteReward = 2.5; +const probe = { + currentIndex: 0 +}; -async function awardMine(user, fund) { - if (!user || !fund || fund.fundList.length === 0) return 0; - let sum = 0; - for (let i = 0, len = fund.fundList.length; i < len; ++i) { - const released = fund.releasedAmout || 0; - if (released === fund.releasedAmout) { - mylog.info('矿晶失效,开始标记'); - await Fund.findByIdAndUpdate(fund.id, { - $set: { - [`fundList.${i}.status`]: 2 //标记失效 - } - }); - return 0; +function awardMine(fund) { + if (!fund || fund.vicFundSum === 0) return 0; + let rest = +fund.vicFundSum; + let revenue = 0; + for (let level of revenueLadderSheet) { + if (rest - level.amount > 0) { + revenue += level.amount * level.rate; + rest -= level.amount; + } else { + revenue += rest * level.rate; + break; } - const profit = +fund.fundList[i].amount * tokenReleaseRate; - await Fund.findByIdAndUpdate(fund.id, { - $inc: { - [`fundList.${i}.mineCount`]: 1, - [`fundList.${i}.releasedAmout`]: profit, - }, - }); - sum += profit; } - return sum.toFixed(2); -} -function awardInvite(user, fund) { - const follerNum = user.group.length || 0; - const hasAwardFoller = fund.option && fund.option.usedGroupReward / 10 || 0; // 求增量: 总额 - 已领取总额(fundSum) - const newFoller = follerNum - hasAwardFoller; - if (newFoller < 0) return 0; - // 挖矿奖励 = 充值金额奖励 + 社区奖励 - return (newFoller * inviteReward).toFixed(2); + return revenue; } // fund.option.usedGroupReward : 已领取的社群奖励总额 const doReward = async (user, fund) => { - // 1.对于充值的fundList的每一项,按照2%进行发放,累加到asset.vic,添加action,类型为1 - // 2.对于社团成员进行人头数目,按照10vic/人进行奖励,累加到asset.vic,添加action,类型为2 if (!user || !fund) return 0; - const rewardMine = await awardMine(user, fund); - // const rewardInvite = awardInvite(user, fund); - const rewardInvite = 0; - const reward = +rewardMine + rewardInvite; + const rewardMine = awardMine(fund); + if (rewardMine === 0) return 0; mylog.info('挖矿奖励: ', rewardMine); - mylog.info('社群奖励: ', rewardInvite); - reward && await Fund.findByIdAndUpdate(fund.id, { + rewardMine && await Fund.findByIdAndUpdate(fund.id, { $inc: { - 'asset.vic': reward, - 'asset.usdt': rewardInvite, // 用来记录所有社群奖励总额 + vicFundSum: rewardMine, }, $set: { - 'option.newFoller': rewardInvite / 5, - 'option.usedGroupReward': rewardInvite, // 本次的奖励值累加到已领取团队奖励总和内 - 'lastMine': new Date().toISOString() + lastMine: new Date().toISOString() } - }).then(() => { + }).then(async () => { rewardMine > 0 && createAction(1, { userId: user.id, - tokenType: 'vic', + tokenType: 'vic2vic', // 新模式标记 amount: rewardMine, remain: fund.asset }).save(); - rewardInvite > 0 && createAction(2, { - userId: user.id, - tokenType: 'vic', - amount: rewardInvite, - remain: fund.asset - }).save(); + if (user.inviter) { + const inviter = await Fund.findOne({ userId: user.inviter }); + if (inviter && +inviter.vicFundSum >= 10000) { + const rewardInviter = rewardMine * 0.1; + Promise.all([ + Fund.findOneAndUpdate({ userId: user.inviter }, { + $inc: { + vicFundSum: rewardInviter + } + }), + createAction(4, { + userId: user.inviter, + tokenType: 'vic2vic', // 新模式标记 + amount: rewardInviter, + remain: fund.asset, + detail: { level: 1, info: '1级奖励' } + }).save() + ]).catch((err) => mylog.error(err.errmsg)); + } + } }); }; + const mock = { - touch: () => {mylog.info('-----------------\n');}, - done: () => {mylog.info('done');}, + touch: () => { mylog.info('-----------------\n'); }, + done: () => { mylog.info('done'); }, }; async function mine (job = mock, done = mock) { @@ -137,7 +136,7 @@ async function mine (job = mock, done = mock) { }); // 批量更新,每次十个 for (; currentIndex < allFundNum;) { - const userFundList = await Fund.find().sort('_id').limit(10).skip(currentIndex); + const userFundList = await Fund.find({ vicFundSum: { $gt: 0 } }).sort('_id').limit(10).skip(currentIndex); typeof job.touch === 'function' && job.touch(); if (!userFundList || !Array.isArray(userFundList)) return 0; for (let i = 0, len = userFundList.length; i < len; ++i) { @@ -185,9 +184,7 @@ async function mine (job = mock, done = mock) { typeof done === 'function' && done('收益计算分配完成'); process.exit(); } -const probe = { - currentIndex: 0 -}; + const start = async (job, done) => { const SysConfig = require('../../configSec'); mongoose.set('useCreateIndex', true); diff --git a/src/modules/fund/fund.controller.js b/src/modules/fund/fund.controller.js index 9b580fa..6ec8da7 100644 --- a/src/modules/fund/fund.controller.js +++ b/src/modules/fund/fund.controller.js @@ -11,12 +11,11 @@ const { calRevenueLastday, getActiveFund } = require('./fund.handler'); const { getDate } = require('../../utils/date'); const Crypto = require('../../utils/crypto'); const actionFilter = 'id type amount detail op createdAt tokenType'; -const { USDT2VIC_RATE } = require('./constant'); const depositCoinsList = [{ id: 'usdtETH', - label: 'usdt', - rate: USDT2VIC_RATE + label: 'vic', + rate: 1 }]; const withdrawCoinsList = [{ id: 'vic', @@ -33,11 +32,11 @@ const withdrawCoinsList = [{ module.exports = { async getFundDetail (req, res) { const { userId } = res.locals.user; - return Fund.findOne({ userId }, 'asset').then(fund => { + return Fund.findOne({ userId }, 'vicFundSum').then(fund => { return res.json({ code: 0, msg: 'success', - data: fund && fund.asset + data: { vic: fund.vicFundSum || 0, usdt: 0 } }); }).catch(err => { mylog.error("[getFundDetail]", err); @@ -123,9 +122,9 @@ module.exports = { }); const [user, fund] = await Promise.all([User.findById(userId), Fund.findOne({ userId })]); if ( - (coinId === 'vic' && +amount < 30) + +amount < 1000 || - +fund.fundSum < 500 + +fund.vicFundSum < 1000 || +user.verifyLevel < 1 ) { @@ -135,6 +134,12 @@ module.exports = { error: '不满足提现条件', }); } + const cost = +amount * 1.005; + if (fund.asset && +fund.asset[coinId] < cost) return res.json({ + code: 2, + msg: '资金不足', + error: 'insufficient fund' + }); let hashpwd = password; if (hashpwd.length < 30) { hashpwd = Crypto.hash(password, {hasher: 'md5'}); @@ -144,16 +149,10 @@ module.exports = { msg: '资金密码错误', error: '资金密码错误', }); - const cost = +amount * 1.005; - if (fund.asset && +fund.asset[coinId] < cost) return res.json({ - code: 2, - msg: '资金不足', - error: 'insufficient fund' - }); const action = createAction(3, { userId, amount, remain: fund.asset, op: 0, detail: { targetAddress, coinId } }); const ticket = createTicket('withdraw', { userId, amount: +amount, action, targetAddress, coinId }); try { - await fund.decrease(coinId, cost); + await fund.decFund(cost); } catch (error) { mylog.error('[Fund提现] ', error); action.detail = { error }; @@ -217,12 +216,6 @@ module.exports = { }; }), async getWithdrawCoinsList (req, res) { - // const { userId } = res.locals.user; - // const userFund = await Fund.findOne({userId}).exec(); - // const asset = userFund.asset; - // const list = []; - // (asset['vic'] >= 1000) && list.push(withdrawCoinsList[0]); - // (asset['usdt'] > 0 && (!userFund.lastWithdraw.usdt || (new Date() - new Date(userFund.lastWithdraw.usdt)) / (1000 * 3600 * 24 * 7) >= 1)) && list.push(withdrawCoinsList[1]); return res.json({ code: 0, data: withdrawCoinsList @@ -249,7 +242,8 @@ module.exports = { // 计算昨日收益 let revenueLastday = calRevenueLastday(actions); // 筛选有效矿晶 - let activeFund = getActiveFund(fund.fundList); + // let activeFund = getActiveFund(fund.fundList); + let activeFund = fund.vicFundSum; let revenueAll = Array.isArray(allAction) && allAction.reduce((pre, cur) => pre + (+cur.amount || 0), 0) || 0; revenueAll = revenueAll.toFixed(4); return res.json({ @@ -272,7 +266,8 @@ module.exports = { // 计算昨日收益 let revenueLastday = calRevenueLastday(actions); // 筛选有效矿晶 - let activeFund = getActiveFund(fund.fundList); + // let activeFund = getActiveFund(fund.fundList); + let activeFund = fund.vicFundSum; if (!newFund || !newFund.fundList) newFund = fund; let revenueAll = Array.isArray(allAction) && allAction.reduce((pre, cur) => pre + (+cur.amount || 0), 0) || 0; revenueAll = revenueAll.toFixed(4); @@ -291,7 +286,7 @@ module.exports = { }, async getFundList (req, res) { const { userId } = res.locals.user; - return Fund.findOne({userId}, 'fundList').then(fund => { + return Fund.findOne({ userId }, 'fundList').then(fund => { return res.json({ code: 0, data: fund.fundList @@ -310,7 +305,8 @@ module.exports = { const [ start, end ] = getDate(1); let now = new Date(); // 筛选有效矿晶 - let activeFund = getActiveFund(fund.fundList); + // let activeFund = getActiveFund(fund.fundList); + let activeFund = fund.vicFundSum; const actions = await Action.find({ userId, type: 1, createdAt: { $gt: start, $lt: now } }).exec(); const allAction = await Action.find({ userId, type: 1 }).exec(); // 计算昨日收益 diff --git a/src/modules/fund/fund.handler.js b/src/modules/fund/fund.handler.js index ec593f7..546088c 100644 --- a/src/modules/fund/fund.handler.js +++ b/src/modules/fund/fund.handler.js @@ -8,13 +8,13 @@ const DayLong = 24 * 60 * 60 * 1000; */ class Fund { constructor (data = {}) { - const { amount, blockNumber, hash = '', blockHash = '', from = '', to = '', timeStamp = '', usdtValue = 0, type = 'deposit' } = data; + const { amount, blockNumber, hash = '', blockHash = '', from = '', to = '', timeStamp = '', rawAmount = 0, type = 'deposit' } = data; this.status = 0; this.type = type; this.amount = +amount; this.from = from; this.to = to; - this.usdtValue = usdtValue; + this.rawAmount = rawAmount; this.timeStamp = timeStamp; this.blockNumber = blockNumber; this.blockHash = blockHash; diff --git a/src/modules/fund/fund.model.js b/src/modules/fund/fund.model.js index 8287af4..f9d2cd0 100644 --- a/src/modules/fund/fund.model.js +++ b/src/modules/fund/fund.model.js @@ -4,10 +4,9 @@ const mongoose = require('mongoose'); const ASSETTYPES = ['gin', 'vic', 'usdtBTC', 'usdtETH', 'usdtTRX']; const { createAction } = require('../action/action.handler'); const { createNewFund } = require('./fund.handler'); -const { getNewDepositTx, getUSDTTxList } = require('../../common/deposit'); +const { getNewDepositTx, getVICTxList } = require('../../common/deposit'); const User = require('../user/user.model'); - -const { USDT2VIC_RATE } = require('./constant'); +const System = require('../system/system.model'); const FundSchema = new mongoose.Schema({ userId: { @@ -16,6 +15,7 @@ const FundSchema = new mongoose.Schema({ tokenAddress: { type: {}, default: { + 'vic': '', 'usdtBTC': '', 'usdtETH': '', 'usdtTRX': '' @@ -33,6 +33,11 @@ const FundSchema = new mongoose.Schema({ type: Number, default: 0 }, + // vic兑换的基金 + vicFundSum: { + type: Number, + default: 0 + }, // asset表示用户的收益,包括VIC和团队奖励的USDT // vic是挖矿得到的奖励 // usdt是社群奖励,后面加上了糖果,也代表糖果数量 @@ -44,6 +49,10 @@ const FundSchema = new mongoose.Schema({ } }, // 团队总充值资产 + groupVicFundSum: { + type: Number, + default: 0 + }, groupFundSum: { type: Number, default: 0 @@ -77,10 +86,10 @@ const FundModel = mongoose.model('Fund', FundSchema); FundModel.prototype.hasNewDeposit = async function () { if (this.tokenAddress.usdtETH) { - const usdtTx = await getUSDTTxList(this.tokenAddress.usdtETH.address); - if (usdtTx && usdtTx.length > 0) { + const vicTx = await getVICTxList(this.tokenAddress.usdtETH.address); + if (vicTx && vicTx.length > 0) { const fundList = this.fundList; - const newDepositList = getNewDepositTx(usdtTx, fundList); + const newDepositList = getNewDepositTx(vicTx, fundList); if (newDepositList && newDepositList.length > 0) { mylog.info(`用户${this.userId} 有新的充值记录`); return { hasNew: true, list: newDepositList }; @@ -89,16 +98,17 @@ FundModel.prototype.hasNewDeposit = async function () { } return { hasNew: false }; }; - -/** -[addFund] : 向用户添加矿晶,在用户充值USDT时调用!!!! -、 */ +const DEFAULT_RATE = 1; FundModel.prototype.addFund = async function (txlist = [], option) { let newSum = 0; + const VIC_RATE = (await System.findOne({ key: 'VIC_RATE' }).exec().catch(() => { + mylog.error('没有获取到vic兑换比例'); + return DEFAULT_RATE; + })) || DEFAULT_RATE; const actionPromiseList = []; const newFundList = txlist.map(txObj => { - txObj.usdtValue = txObj.amount; - const depositAmount = +txObj.amount * USDT2VIC_RATE; + txObj.rawAmount = txObj.amount; // tx.amout是区块链交易的数值,已经除了精度 + const depositAmount = +txObj.amount * (Number.isSafeInteger(VIC_RATE) ? VIC_RATE : DEFAULT_RATE); newSum += depositAmount; const action = createAction(0, { userId: this.userId, @@ -108,6 +118,7 @@ FundModel.prototype.addFund = async function (txlist = [], option) { }); typeof action.save === 'function' && actionPromiseList.push(action.save()); txObj.amount = depositAmount; // 之后返回fundList里的数值需要把区块链的数值乘以比率 !!!! + txObj.type = 'vic2fund'; return createNewFund({...txObj}); }); // 1.注入资金 @@ -116,13 +127,12 @@ FundModel.prototype.addFund = async function (txlist = [], option) { fundList: newFundList }, $inc: { - fundSum: newSum + vicFundSum: newSum }, $set: { lastDeposit: new Date().toISOString() } - // eslint-disable-next-line no-unused-vars - }, { ...option, returnOriginal: false }).exec().catch(err => null); + }, { ...option, returnOriginal: false }).exec().catch(err => mylog.error(err.errmsg)); // 2.记录action Promise.all(actionPromiseList).catch(err => { @@ -131,41 +141,12 @@ FundModel.prototype.addFund = async function (txlist = [], option) { // 3.增加上家团队总额 option.inviter && FundModel.findOneAndUpdate({ userId: option.inviter }, { $inc: { - groupFundSum: newSum + groupVicFundSum: newSum } }).exec(); - // 3.对于自己的邀请者进行奖励,按照自己充值金额的十分之一,累加到邀请人的fundList里,类型为1 - const myId = this.userId; - User.findById(myId).then(async user => { - if (!user && !user.inviter) return 0; - const award = +newSum * 0.1; - const inviteFund = createNewFund({ - type: 'inviteAward', - amount: award, - blockNumber: 'followerReward', - hash: myId - }); - User.findByIdAndUpdate(user.inviter, { - $push: { - fundList: inviteFund - } - }); - createAction(4, { - userId: user.inviter, - amount: award, // 充值记录的数值仍然是区块链的数值 - tokenType: 'vic', // 目前设定只能挖出矿晶vic - remain: this.asset, - detail: { - desc: `${user.id}充值${newSum} 奖励其推荐人${user.inviter}: ${award}矿晶`, - from: myId, - to: user.inviter - } - }).save(); - }).catch(err => { - mylog.error(`${myId}充值奖励其推荐人时出错 `, JSON.stringify(err)); - }); return res; }; + FundModel.prototype.increase = async function (assetName, amount, option = {}) { if (!assetName || !amount || amount <= 0 || !Number.isFinite(amount) || !ASSETTYPES.includes(assetName)) return null; const asset = 'asset.' + assetName; @@ -179,6 +160,7 @@ FundModel.prototype.increase = async function (assetName, amount, option = {}) { if (res.asset[assetName] < 0) throw new Error('Insufficient funds'); return res; }; + FundModel.prototype.decrease = async function (assetName, amount, option) { // 传入的amount应该是大于0的正数 if (!assetName || !amount || amount <= 0 || !Number.isFinite(amount) || !ASSETTYPES.includes(assetName)) return null; @@ -195,4 +177,30 @@ FundModel.prototype.decrease = async function (assetName, amount, option) { return res; }; +FundModel.prototype.incFund = async function (amount, option = {}) { + if (!amount || amount <= 0 || !Number.isFinite(amount)) return null; + const asset = 'vicFundSum'; + const res = await FundModel.findByIdAndUpdate(this.id, { + $inc: { + [asset]: amount + } + }, { ...option, returnOriginal: false }).exec().catch(err => mylog.error(err)); + if (!res || !res.asset) throw new Error('用户资产修改[increase]失败!'); + return res; +}; + +FundModel.prototype.decFund = async function (amount, option) { + // 传入的amount应该是大于0的正数 + if (!amount || amount <= 0 || !Number.isFinite(amount)) return null; + amount = 0 - amount; + const asset = 'vicFundSum'; + const res = await FundModel.findByIdAndUpdate(this.id, { + $inc: { + [asset]: amount + } + }, { ...option, returnOriginal: false }).exec().catch(err => mylog.error(err)); + if (!res || !res.asset) throw new Error('用户资产修改[decrease]失败!'); + return res; +}; + module.exports = FundModel; \ No newline at end of file diff --git a/src/modules/user/user.controller.js b/src/modules/user/user.controller.js index c1d8347..68ec6f1 100644 --- a/src/modules/user/user.controller.js +++ b/src/modules/user/user.controller.js @@ -1,5 +1,5 @@ const User = require('./user.model'); -const Fund = require('../fund/fund.model'); +const Action = require('../action/action.model'); const VReq = require('../vreq/vreq.model'); const MsgCode = require('../msgCode/msgCode.controller'); const changePwd = require('../sign/sign.controller').changePasswd; @@ -124,13 +124,13 @@ module.exports = { }, async getGroupBasicInfo (req, res) { const { userId } = res.locals.user; - const [user, fund] = await Promise.all([User.findById(userId), Fund.findOne({userId})]); + const [user, action] = await Promise.all([User.findById(userId), Action.findOne({userId, type: '4'})]); if (!user) return res.json({ code: 1, msg: '未知用户' }); const follower = user.group && user.group.length || 0; - const reward = fund.asset && fund.asset.usdt || 0; + const reward = Array.isArray(action) && action.reduce((acc, obj) => acc + +obj.amount, 0) || 0; // const list = await User.find({ inviter: { $in: user.group } }).exec(); const list = await User.find({ inviter: userId }).exec(); const sum = list.reduce((acc, u) => {