m
This commit is contained in:
+400
@@ -0,0 +1,400 @@
|
||||
"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
|
||||
Reference in New Issue
Block a user