'use strict'; 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 User = require('../user/user.model'); const USDT2VIC_RATE = 100; const FundSchema = new mongoose.Schema({ userId: { type: String }, tokenAddress: { type: {}, default: { 'usdtBTC': '', 'usdtETH': '', 'usdtTRX': '' } }, // fundList 为充值的矿晶的一系列数值,用于计算收益 // fund = 矿晶,单位KG fundList: { type: [], default: [] }, // fundSum, 用户充值的总usdt数 // fundSum 目前被用来记录邀请人奖励!!! fundSum: { type: Number, default: 0 }, // asset表示用户的收益,包括VIC和团队奖励的USDT // vic是挖矿得到的奖励 // usdt是社群奖励,后面加上了糖果,也代表糖果数量 asset: { type: {}, default: { 'vic': 0, 'usdt': 50 //默认100糖果 } }, // 团队总充值资产 groupFundSum: { type: Number, default: 0 }, lastMine: { type: String }, lastDeposit: { type: String }, lastWithdraw: { type: {}, default: { usdt: '', vic: '' } }, option: { type: {} }, }, { timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' } }); const FundModel = mongoose.model('Fund', FundSchema); FundModel.prototype.hasNewDeposit = async function () { if (this.tokenAddress.usdtETH) { const usdtTx = await getUSDTTxList(this.tokenAddress.usdtETH.address); const fundList = this.fundList; const newDepositList = getNewDepositTx(usdtTx, fundList); if (newDepositList && newDepositList.length > 0) return { hasNew: true, list: newDepositList }; } return { hasNew: false }; }; /** [addFund] : 向用户添加矿晶,在用户充值USDT时调用!!!! * 当一个用户充值, • 4% 给上面第一个 金 或 银 或 铜 会员 • 3% • 如果直接上家是金,就全给他; • 如果直接上家不是金,就平分 3% 给上线所有银会员 • 2% 给上线所有金会员平分 */ FundModel.prototype.addFund = async (txlist = [], option) => { let newSum = 0; const actionPromiseList = []; const newFundList = txlist.map(txObj => { const depositAmount = +txObj.amount * USDT2VIC_RATE; newSum += depositAmount; const action = createAction(0, { userId: this.userId, amount: +txObj.amount, // 充值记录的数值仍然是区块链的数值 tokenType: 'vic', // 目前设定只能挖出矿晶vic remain: this.asset }); actionPromiseList.push(action.save()); txObj.amount = depositAmount; // 之后返回fundList里的数值需要把区块链的数值乘以比率 !!!! return createNewFund(txObj); }); // 1.注入资金 const res = await FundModel.findByIdAndUpdate(this.id, { $push: { fundList: newFundList }, $inc: { fundSum: newSum }, $set: { lastDeposit: new Date().toISOString() } // eslint-disable-next-line no-unused-vars }, { ...option, returnOriginal: false }).exec().catch(err => null); // 2.记录action Promise.all(actionPromiseList).catch(err => { mylog.error('充值行为记录失败', err.errmsg); }); // 3.增加上家团队总额 FundModel.findOneAndUpdate({ userId: option.inviter }, { $inc: { groupFundSum: newSum } }).exec(); // 3.对于自己的邀请者进行奖励,按照自己充值金额的十分之一,累加到邀请人的fundList里,类型为1 const myId = this.userId; User.findById(myId).then(async user => { if (!user && !user.inviter) return 0; const inviteFund = createNewFund({ amount: +newSum * 0.1, blockNumber: 'followerReward', hash: myId }); User.findByIdAndUpdate(user.inviter, { $push: inviteFund }); }); return res; }; FundModel.prototype.increase = async (assetName, amount, option = {}) => { if (!assetName || !amount || amount <= 0 || !Number.isFinite(amount) || !ASSETTYPES.includes(assetName)) return null; const asset = 'asset.' + assetName; const res = await FundModel.findByIdAndUpdate(this.id, { $inc: { [asset]: amount } // eslint-disable-next-line no-unused-vars }, { ...option, returnOriginal: false }).exec().catch(err => null); if (!res || !res.asset) throw new Error('用户资产修改[increase]失败!'); if (res.asset[assetName] < 0) throw new Error('Insufficient funds'); return res; }; FundModel.prototype.decrease = async (assetName, amount, option) => { // 传入的amount应该是大于0的正数 if (!assetName || !amount || amount <= 0 || !Number.isFinite(amount) || !ASSETTYPES.includes(assetName)) return null; amount = 0 - amount; const asset = 'asset.' + assetName; const res = await FundModel.findByIdAndUpdate(this.id, { $inc: { [asset]: amount } // eslint-disable-next-line no-unused-vars }, { ...option, returnOriginal: false }).exec().catch(err => null); if (!res || !res.asset) throw new Error('用户资产修改[decrease]失败!'); if (res.asset[assetName] < 0) throw new Error('Insufficient funds'); return res; }; module.exports = FundModel;