169 lines
5.2 KiB
JavaScript
169 lines
5.2 KiB
JavaScript
'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 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: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
// asset表示用户的收益,包括VIC和团队奖励的USDT
|
||
// vic是挖矿得到的奖励
|
||
// usdt是社群奖励,后面加上了糖果,也代表糖果数量
|
||
asset: {
|
||
type: {},
|
||
default: {
|
||
'vic': 0,
|
||
'usdt': 100 //默认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 function (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 => {
|
||
throw new Error('充值行为记录失败', err.errmsg);
|
||
});
|
||
|
||
// 3.增加上家团队总额
|
||
FundModel.findOneAndUpdate({ userId: option.inviter }, {
|
||
$inc: {
|
||
groupFundSum: newSum
|
||
}
|
||
});
|
||
// 4.奖励团队
|
||
// todo
|
||
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;
|
||
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 function (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; |