400 lines
18 KiB
JavaScript
400 lines
18 KiB
JavaScript
"use strict";
|
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
};
|
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.UserImService = void 0;
|
|
const common_1 = require("@nestjs/common");
|
|
const typeorm_1 = require("@nestjs/typeorm");
|
|
const typeorm_2 = require("typeorm");
|
|
const cache_manager_1 = require("@nestjs/cache-manager");
|
|
const user_model_1 = require("../../../model/user.model");
|
|
const api_1 = require("../../common/api");
|
|
const app_env_1 = require("../../../app.env");
|
|
const user_im_vo_1 = require("../vo/user_im.vo");
|
|
const red_packet_model_1 = require("../../../model/red_packet.model");
|
|
const red_packet_record_model_1 = require("../../../model/red_packet_record.model");
|
|
const repository_help_1 = require("../../common/util/repository_help");
|
|
const user_id_context_1 = require("../../common/context/user_id.context");
|
|
const data_source_context_1 = require("../../common/context/data_source.context");
|
|
const help_1 = require("../../common/util/help");
|
|
const decimal_help_1 = require("../../common/util/decimal_help");
|
|
const im_help_1 = require("../../common/util/im_help");
|
|
const user_verify_model_1 = require("../../../model/user_verify.model");
|
|
let UserImService = class UserImService {
|
|
userRepos;
|
|
redPacketRepos;
|
|
redPacketRecordRepos;
|
|
userVerifyModel;
|
|
cacheManager;
|
|
constructor(userRepos, redPacketRepos, redPacketRecordRepos, userVerifyModel, cacheManager) {
|
|
this.userRepos = userRepos;
|
|
this.redPacketRepos = redPacketRepos;
|
|
this.redPacketRecordRepos = redPacketRecordRepos;
|
|
this.userVerifyModel = userVerifyModel;
|
|
this.cacheManager = cacheManager;
|
|
}
|
|
async like(dto) {
|
|
const users = await this.userRepos.find({
|
|
where: [
|
|
{
|
|
phone: dto.keyword,
|
|
},
|
|
],
|
|
});
|
|
return api_1.Api.pagination(users.map((it) => {
|
|
const vo = new user_im_vo_1.UserLikeVo();
|
|
vo.uid = app_env_1.AppEnv.IM_USER_ID_PREFIX + it.id;
|
|
vo.user = it;
|
|
return vo;
|
|
}), 0);
|
|
}
|
|
async info(dto) {
|
|
const user = await this.userRepos.findOneBy({ id: dto.id });
|
|
return api_1.Api.success(user);
|
|
}
|
|
async redPackeDetail(dto) {
|
|
const data = await this.redPacketRepos.findOne({
|
|
where: {
|
|
id: dto.id,
|
|
},
|
|
relations: ['user'],
|
|
});
|
|
return api_1.Api.success(data);
|
|
}
|
|
async redPackeRecords(dto, page) {
|
|
const list = await repository_help_1.RepositoryHelp.finePaginatedData(this.redPacketRecordRepos, page, {
|
|
where: {
|
|
redPacketId: dto.id,
|
|
},
|
|
order: {
|
|
id: 'desc',
|
|
},
|
|
relations: ['user'],
|
|
});
|
|
return api_1.Api.pagination(list, 0);
|
|
}
|
|
async createRedPacket(dto) {
|
|
const uid = (0, user_id_context_1.getUserIdContext)();
|
|
const user = await this.userRepos.findOneByOrFail({
|
|
id: uid,
|
|
});
|
|
const userVerify = await this.userVerifyModel.findOneBy({
|
|
userId: uid,
|
|
});
|
|
const redEnvelope = user.redEnvelope;
|
|
const redEnvelopeMaxAmount = user.redEnvelopeMaxAmount;
|
|
const amount = Number(dto.amount);
|
|
if (userVerify?.status != user_verify_model_1.VerifyAuditStatus.Approved) {
|
|
return api_1.Api.error('您还未实名,无法发送红包');
|
|
}
|
|
if (!user.isRedEnvelope) {
|
|
return api_1.Api.error('您发送红包资格被管理员取下,请联系客服');
|
|
}
|
|
if (amount <= 0) {
|
|
return api_1.Api.error('金额必须大于0');
|
|
}
|
|
if (help_1.Help.phpmymd5(dto.password) != '123456') {
|
|
return api_1.Api.error('支付密码错误');
|
|
}
|
|
if (dto.type == red_packet_model_1.RedPacketType.Luck) {
|
|
if (!dto.count) {
|
|
return api_1.Api.error('红包个数必须大于0');
|
|
}
|
|
}
|
|
if (!redEnvelope || Number(redEnvelope) < amount) {
|
|
return api_1.Api.error('红包资产余额不足');
|
|
}
|
|
if (redEnvelopeMaxAmount && Number(redEnvelopeMaxAmount) < amount) {
|
|
return api_1.Api.error(`最大可发送红包金额(${redEnvelopeMaxAmount})`);
|
|
}
|
|
return data_source_context_1.DataSourceContext.startTransaction(async (trx) => {
|
|
const userRepos = trx.getRepository(user_model_1.UserModel);
|
|
const redPacketRepos = trx.getRepository(red_packet_model_1.RedPacketModel);
|
|
const totalAmount = Math.round(amount * 100);
|
|
const totalCount = dto.type == red_packet_model_1.RedPacketType.Luck ? dto.count : 1;
|
|
const now = help_1.Help.getSecondTimestamp();
|
|
const affected = await repository_help_1.RepositoryHelp.update(userRepos, {
|
|
id: uid,
|
|
redEnvelope: (0, typeorm_2.MoreThanOrEqual)(`${amount}`),
|
|
}, {
|
|
redEnvelope: () => `redEnvelope - ${amount}`,
|
|
});
|
|
if (!affected) {
|
|
await trx.rollback();
|
|
return api_1.Api.error('红包资产余额不足01');
|
|
}
|
|
const claimedUserId = dto.claimedUserId?.replace(app_env_1.AppEnv.IM_USER_ID_PREFIX, '') || '';
|
|
const redPacket = redPacketRepos.create({
|
|
totalAmount,
|
|
totalCount,
|
|
remainingAmount: totalAmount,
|
|
remainingCount: totalCount,
|
|
userId: uid,
|
|
groupId: dto.groupId,
|
|
claimedUserId: dto.type == red_packet_model_1.RedPacketType.Ordinary ? Number(claimedUserId) : 0,
|
|
status: red_packet_model_1.RedPacketStatus.Unclaimed,
|
|
type: dto.type,
|
|
createdAt: now,
|
|
expireTime: now + 60 * 60 * 24,
|
|
});
|
|
await redPacketRepos.insert(redPacket);
|
|
await this.autoClaimedRedPacket(trx, redPacket);
|
|
return api_1.Api.success(redPacket);
|
|
});
|
|
}
|
|
async autoClaimedRedPacket(trx, redPacket) {
|
|
const sendUserIds = app_env_1.AppEnv.IM_AUTO_CLAIMED_RED_PACKET_SEND_UIDS.split(',').map((it) => Number(it));
|
|
const sendGroupIds = app_env_1.AppEnv.IM_AUTO_CLAIMED_RED_PACKET_SEND_GROUPIDS.split(',').map((it) => {
|
|
return decodeURIComponent(it);
|
|
});
|
|
if (redPacket.type != red_packet_model_1.RedPacketType.Luck) {
|
|
return;
|
|
}
|
|
if (!sendUserIds.includes(redPacket.userId)) {
|
|
return;
|
|
}
|
|
if (!sendGroupIds.includes(redPacket.groupId)) {
|
|
return;
|
|
}
|
|
const remainingAmount = redPacket.remainingAmount;
|
|
const remainingCount = redPacket.remainingCount;
|
|
const rate = help_1.Help.getRandomInt(70, 75) / 100;
|
|
let maxAmount = remainingAmount * rate;
|
|
const maxCount = Math.floor(remainingCount * rate);
|
|
const userRepos = trx.getRepository(user_model_1.UserModel);
|
|
const redPacketRepos = trx.getRepository(red_packet_model_1.RedPacketModel);
|
|
const redPacketRecordRepos = trx.getRepository(red_packet_record_model_1.RedPacketRecordModel);
|
|
const users = await userRepos
|
|
.createQueryBuilder('u')
|
|
.where('user_type = 2 and autoRedEnvelope = 1 and avatar is not null')
|
|
.orderBy('RAND()')
|
|
.limit(maxCount)
|
|
.getMany();
|
|
for (let i = 0, len = users.length; i < len; i++) {
|
|
const user = users[i];
|
|
const uid = user.id;
|
|
const now = help_1.Help.getSecondTimestamp() + 1;
|
|
const amount = this.calculateRandomAmount(maxAmount, len - i);
|
|
maxAmount -= amount;
|
|
redPacket.remainingAmount -= amount;
|
|
redPacket.remainingCount -= 1;
|
|
const record = redPacketRecordRepos.create({
|
|
amount: decimal_help_1.DecimalHelp.div(amount, 100),
|
|
redPacketId: redPacket.id,
|
|
userId: uid,
|
|
createdAt: now,
|
|
});
|
|
await redPacketRecordRepos.insert(record);
|
|
await userRepos.update({
|
|
id: uid,
|
|
}, {
|
|
redEnvelope: () => `redEnvelope + ${record.amount}`,
|
|
});
|
|
}
|
|
await redPacketRepos.save(redPacket);
|
|
}
|
|
async claimedPrepare(dto) {
|
|
const uid = (0, user_id_context_1.getUserIdContext)();
|
|
const userVerify = await this.userVerifyModel.findOneBy({
|
|
userId: uid,
|
|
});
|
|
if (userVerify?.status != user_verify_model_1.VerifyAuditStatus.Approved) {
|
|
return api_1.Api.error('您还未实名,无法领取红包');
|
|
}
|
|
const redPacket = await this.redPacketRepos.findOne({
|
|
where: {
|
|
id: dto.id,
|
|
},
|
|
relations: ['user'],
|
|
});
|
|
if (!redPacket) {
|
|
return api_1.Api.error(`红包不存在`);
|
|
}
|
|
if (redPacket.status == red_packet_model_1.RedPacketStatus.Expire) {
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Expired, redPacket));
|
|
}
|
|
const existingRecord = await this.redPacketRecordRepos.findOneBy({
|
|
redPacketId: redPacket.id,
|
|
userId: uid,
|
|
});
|
|
if (existingRecord) {
|
|
const vo = new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Success, redPacket, existingRecord);
|
|
return api_1.Api.success(vo);
|
|
}
|
|
if (redPacket.status == red_packet_model_1.RedPacketStatus.Claimed) {
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Finished, redPacket));
|
|
}
|
|
const now = help_1.Help.getSecondTimestamp();
|
|
if (redPacket.expireTime < now) {
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Expired, redPacket));
|
|
}
|
|
if (redPacket.type == red_packet_model_1.RedPacketType.Ordinary) {
|
|
if (redPacket.userId == uid) {
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Own, redPacket));
|
|
}
|
|
if (redPacket.type == red_packet_model_1.RedPacketType.Ordinary) {
|
|
if (redPacket.claimedUserId != uid) {
|
|
return api_1.Api.error(`这个红包不是发给你的`);
|
|
}
|
|
}
|
|
}
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Unclaimed, redPacket));
|
|
}
|
|
async claimed(dto) {
|
|
const uid = (0, user_id_context_1.getUserIdContext)();
|
|
const userVerify = await this.userVerifyModel.findOneBy({
|
|
userId: uid,
|
|
});
|
|
if (userVerify?.status != user_verify_model_1.VerifyAuditStatus.Approved) {
|
|
return api_1.Api.error('您还未实名,无法领取红包');
|
|
}
|
|
return data_source_context_1.DataSourceContext.startTransaction(async (trx) => {
|
|
const userRepos = trx.getRepository(user_model_1.UserModel);
|
|
const redPacketRepos = trx.getRepository(red_packet_model_1.RedPacketModel);
|
|
const redPacketRecordRepos = trx.getRepository(red_packet_record_model_1.RedPacketRecordModel);
|
|
const redPacket = await redPacketRepos.findOne({
|
|
where: {
|
|
id: dto.id,
|
|
},
|
|
relations: ['user'],
|
|
});
|
|
if (!redPacket) {
|
|
await trx.rollback();
|
|
return api_1.Api.error(`红包不存在`);
|
|
}
|
|
if (redPacket.status == red_packet_model_1.RedPacketStatus.Expire) {
|
|
await trx.rollback();
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Expired, redPacket));
|
|
}
|
|
if (redPacket.status == red_packet_model_1.RedPacketStatus.Claimed ||
|
|
redPacket.remainingCount <= 0) {
|
|
await trx.rollback();
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Finished, redPacket));
|
|
}
|
|
const now = help_1.Help.getSecondTimestamp();
|
|
if (redPacket.expireTime < now) {
|
|
await trx.rollback();
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Expired, redPacket));
|
|
}
|
|
const existingRecord = await this.redPacketRecordRepos.findOneBy({
|
|
redPacketId: redPacket.id,
|
|
userId: uid,
|
|
});
|
|
if (existingRecord) {
|
|
await trx.rollback();
|
|
const vo = new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Success, redPacket, existingRecord);
|
|
return api_1.Api.success(vo);
|
|
}
|
|
if (redPacket.type == red_packet_model_1.RedPacketType.Ordinary) {
|
|
if (redPacket.userId == uid) {
|
|
await trx.rollback();
|
|
return api_1.Api.success(new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Own, redPacket));
|
|
}
|
|
if (redPacket.claimedUserId != uid) {
|
|
await trx.rollback();
|
|
return api_1.Api.error(`这个红包不是发给你的`);
|
|
}
|
|
await redPacketRepos.update({
|
|
id: redPacket.id,
|
|
}, {
|
|
status: red_packet_model_1.RedPacketStatus.Claimed,
|
|
remainingAmount: 0,
|
|
remainingCount: 0,
|
|
});
|
|
const record = redPacketRecordRepos.create({
|
|
amount: decimal_help_1.DecimalHelp.div(redPacket.totalAmount, 100),
|
|
redPacketId: redPacket.id,
|
|
userId: uid,
|
|
createdAt: now,
|
|
});
|
|
await redPacketRecordRepos.insert(record);
|
|
await userRepos.update({
|
|
id: uid,
|
|
}, {
|
|
redEnvelope: () => `redEnvelope + ${record.amount}`,
|
|
});
|
|
await trx.commit();
|
|
const vo = new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Success, redPacket, record);
|
|
return api_1.Api.success(vo);
|
|
}
|
|
else {
|
|
const amount = this.calculateRandomAmount(redPacket.remainingAmount, redPacket.remainingCount);
|
|
const affected = await repository_help_1.RepositoryHelp.update(redPacketRepos, {
|
|
id: redPacket.id,
|
|
remainingAmount: (0, typeorm_2.MoreThanOrEqual)(amount),
|
|
remainingCount: (0, typeorm_2.MoreThanOrEqual)(1),
|
|
}, {
|
|
remainingAmount: () => `remainingAmount - ${amount}`,
|
|
remainingCount: () => `remainingCount - 1`,
|
|
status: redPacket.remainingCount <= 1
|
|
? red_packet_model_1.RedPacketStatus.Claimed
|
|
: red_packet_model_1.RedPacketStatus.Claiming,
|
|
});
|
|
if (!affected) {
|
|
return api_1.Api.error('网络错误,请稍后重试');
|
|
}
|
|
const record = redPacketRecordRepos.create({
|
|
amount: decimal_help_1.DecimalHelp.div(amount, 100),
|
|
redPacketId: redPacket.id,
|
|
userId: uid,
|
|
createdAt: now,
|
|
});
|
|
await redPacketRecordRepos.insert(record);
|
|
await userRepos.update({
|
|
id: uid,
|
|
}, {
|
|
redEnvelope: () => `redEnvelope + ${record.amount}`,
|
|
});
|
|
await trx.commit();
|
|
const vo = new user_im_vo_1.UserClaimedVo(user_im_vo_1.UserClaimedStats.Success, redPacket, record);
|
|
return api_1.Api.success(vo);
|
|
}
|
|
});
|
|
}
|
|
calculateRandomAmount(remainingAmount, remainingCount) {
|
|
if (remainingCount === 1) {
|
|
return remainingAmount;
|
|
}
|
|
const max = Math.floor((remainingAmount / remainingCount) * 2);
|
|
const amount = Math.floor(Math.random() * max) + 1;
|
|
return Math.min(amount, remainingAmount);
|
|
}
|
|
async updateUserProfile(dto) {
|
|
const uid = (0, user_id_context_1.getUserIdContext)();
|
|
const imUid = app_env_1.AppEnv.IM_USER_ID_PREFIX + uid;
|
|
const res = await im_help_1.IMHelp.updateUserProfile(imUid, dto.nick, dto.avatar);
|
|
if (res.ErrorCode == 0) {
|
|
return api_1.Api.success();
|
|
}
|
|
else {
|
|
return api_1.Api.error(res.ErrorInfo);
|
|
}
|
|
}
|
|
getUserGradeByImUid() {
|
|
return api_1.Api.pagination([], 0);
|
|
}
|
|
};
|
|
exports.UserImService = UserImService;
|
|
exports.UserImService = UserImService = __decorate([
|
|
(0, common_1.Injectable)(),
|
|
__param(0, (0, typeorm_1.InjectRepository)(user_model_1.UserModel)),
|
|
__param(1, (0, typeorm_1.InjectRepository)(red_packet_model_1.RedPacketModel)),
|
|
__param(2, (0, typeorm_1.InjectRepository)(red_packet_record_model_1.RedPacketRecordModel)),
|
|
__param(3, (0, typeorm_1.InjectRepository)(user_verify_model_1.UserVerifyModel)),
|
|
__param(4, (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER)),
|
|
__metadata("design:paramtypes", [typeorm_2.Repository,
|
|
typeorm_2.Repository,
|
|
typeorm_2.Repository,
|
|
typeorm_2.Repository, Object])
|
|
], UserImService);
|
|
//# sourceMappingURL=user_im.service.js.map
|