Files
2026-04-21 22:34:39 +08:00

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