团购活动:定时退费

This commit is contained in:
luying
2022-10-08 20:24:30 +08:00
parent e9170e61e1
commit 1f196a5d36
5 changed files with 74 additions and 6 deletions

View File

@@ -1,11 +1,14 @@
import { ACTIVITY_TYPE, GROUP_SHOP_PRICE_STATUS, PUSH_ROUTE } from "../../consts"; import { ACTIVITY_TYPE, GROUP_SHOP_PRICE_STATUS, MAIL_TYPE, PUSH_ROUTE } from "../../consts";
import { ActivityModel, ActivityModelType } from "../../db/Activity"; import { ActivityModel, ActivityModelType } from "../../db/Activity";
import { ActivityGroupShopRecModel } from "../../db/ActivityGroupShopRec"; import { ActivityGroupShopRecModel } from "../../db/ActivityGroupShopRec";
import { ActivityGroupShopRefundModel, RefundRec } from "../../db/ActivityGroupShopRefund";
import { ActivityGroupShopUserRecModel } from "../../db/ActivityGroupShopUserRec"; import { ActivityGroupShopUserRecModel } from "../../db/ActivityGroupShopUserRec";
import { GroupShopData } from "../../domain/activityField/groupShopField"; import { GroupShopData } from "../../domain/activityField/groupShopField";
import { RewardInter } from "../../pubUtils/interface"; import { RewardInter } from "../../pubUtils/interface";
import { sendMailByContent } from "../mailService";
import { sendMessageToGroupShopWithSuc } from "../pushService"; import { sendMessageToGroupShopWithSuc } from "../pushService";
import { getRoleCreateTime, getServerCreateTime } from "../redisService"; import { getRoleCreateTime, getServerCreateTime } from "../redisService";
import { getGoldObject } from "../role/rewardService";
import { getActivityById } from "./activityService"; import { getActivityById } from "./activityService";
/** /**
@@ -76,13 +79,33 @@ export async function setGroupShopToSetSum(arr: { activityId: number, itemId: nu
export async function refundGroupShop() { export async function refundGroupShop() {
let activities = await ActivityModel.findActivityByType(ACTIVITY_TYPE.GROUP_SHOP); let activities = await ActivityModel.findActivityByType(ACTIVITY_TYPE.GROUP_SHOP);
let recs = new Map<string, { activityId: number, itemId: number, reward: RewardInter[] }[]>();
for(let activityData of activities) { for(let activityData of activities) {
let hasRefund = await ActivityGroupShopRefundModel.check(activityData.activityId);
if(!hasRefund) continue;
let recs = new Map<string, { itemId: number, diff: number }[]>();
let playerData = await getGroupShopServerData(activityData); let playerData = await getGroupShopServerData(activityData);
if(playerData.endTime >= Date.now()) continue;
let items = playerData.items||[]; let items = playerData.items||[];
for(let item of items) { for(let item of items) {
let playerRecords = await ActivityGroupShopUserRecModel.findByPrice(activityData.activityId, item.id, item.getCurDiscount().price); let playerRecords = await ActivityGroupShopUserRecModel.findByPrice(activityData.activityId, item.id, item.getCurDiscount().price);
for(let { roleId, records } of playerRecords) {
for(let { price, buyCnt } of records) {
if(price <= item.getCurDiscount().price) continue;
let diff = (price - item.getCurDiscount().price) * buyCnt;
if(!recs.has(roleId)) recs.set(roleId, []);
recs.get(roleId).push({ itemId: item.id, diff });
}
}
} }
let refundRecs: RefundRec[] = [];
for(let [ roleId, arr ] of recs) {
let reward = arr.map(({ diff }) => getGoldObject(diff));
await sendMailByContent(MAIL_TYPE.GROUP_SHOP_REFUND, roleId, { goods: reward });
refundRecs.push(...arr.map(cur => ({ roleId, ...cur })));
}
await ActivityGroupShopRefundModel.refund(activityData.activityId, refundRecs);
} }
} }

View File

@@ -60,6 +60,7 @@ export enum MAIL_TYPE {
LADDER = 30, // 名将擂台 LADDER = 30, // 名将擂台
GUILD_MAIL = 31, // 军团邮件 GUILD_MAIL = 31, // 军团邮件
REBATE = 32, // 返利邮件 REBATE = 32, // 返利邮件
GROUP_SHOP_REFUND = 33, // 退费
}; };
export const SEND_NAME = '系统'; export const SEND_NAME = '系统';

View File

@@ -0,0 +1,41 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
export class RefundRec {
@prop({ required: true })
roleId: string;
@prop({ required: true })
itemId: number;
@prop({ required: true })
diff: number;
}
/**
* 活动系统 - 团购玩家记录
*/
@index({ activityId: 1 })
export default class Activity_Group_Shop_Refund extends BaseModel {
@prop({ required: true })
activityId: number; // 活动Id
@prop({ required: true, type: RefundRec, _id: false })
refundRec: RefundRec[]; // 是否退好费了
public static async check(activityId: number) {
return await ActivityGroupShopRefundModel.exists({ activityId });
}
public static async refund(activityId: number, refundRec: RefundRec[]) {
let result: ActivityGroupShopRefundRecType = await ActivityGroupShopRefundModel.findOneAndUpdate({ activityId }, { $set: { refundRec } }, { upsert: true, new: true }).lean();
return result;
}
}
export const ActivityGroupShopRefundModel = getModelForClass(Activity_Group_Shop_Refund);
export interface ActivityGroupShopRefundRecType extends Pick<DocumentType<Activity_Group_Shop_Refund>, keyof Activity_Group_Shop_Refund> { }
export type ActivityGroupShopRefundRecTypeParam = Partial<ActivityGroupShopRefundRecType>; // 将所有字段变成可选项

View File

@@ -30,9 +30,6 @@ export class GroupShopBuyRecord {
@prop({ required: true }) @prop({ required: true })
buyCnt: number; // 购买次数 buyCnt: number; // 购买次数
@prop({ required: true })
refundPrice: number; // 退费价格
constructor(curDiscount: GroupShopDiscount, buyCnt: number) { constructor(curDiscount: GroupShopDiscount, buyCnt: number) {
this.time = nowSeconds(); this.time = nowSeconds();
if(curDiscount) { if(curDiscount) {
@@ -42,7 +39,6 @@ export class GroupShopBuyRecord {
this.price = curDiscount.price; this.price = curDiscount.price;
} }
this.buyCnt = buyCnt; this.buyCnt = buyCnt;
this.refundPrice = 0;
} }
} }

View File

@@ -229,5 +229,12 @@
"sendName": "您忠诚的小跟班", "sendName": "您忠诚的小跟班",
"content": "亲爱的主公,欢迎回来!感谢您在封测期间的支持,您在测试期间共充值%d元现将获得%d元宝返还。请查收", "content": "亲爱的主公,欢迎回来!感谢您在封测期间的支持,您在测试期间共充值%d元现将获得%d元宝返还。请查收",
"time": 720 "time": 720
},
{
"id": 33,
"title": "&",
"sendName": "您忠诚的小跟班",
"content": "退费",
"time": 720
} }
] ]