进销存系统会员积分与促销方案设计
会员积分体系概述
会员积分是进销存系统中提升客户粘性的重要手段。一个完善的积分体系需要考虑积分获取规则、积分扣减机制、积分有效期、积分兑换礼品等多个维度。
积分规则配置表设计
| 规则类型 | 规则名称 | 积分倍数 | 说明 |
|---|---|---|---|
| 消费获得 | 消费积分 | 1元=1积分 | 默认积分规则 |
| 消费获得 | 会员日双倍 | 1元=2积分 | 每月会员日 |
| 消费获得 | 新品尝鲜 | 1元=3积分 | 指定新品 |
| 行为获得 | 签到奖励 | +5积分/天 | 每日签到 |
| 行为获得 | 完善资料 | +50积分 | 首次完善 |
积分核心代码实现
// 积分服务类
class PointsService {
constructor(ctx) {
this.ctx = ctx;
}
// 计算订单可获得积分
async calculateOrderPoints(orderId) {
const order = await this.ctx.model.Order.findById(orderId);
const rules = await this.ctx.model.PointsRule.find({
enabled: true,
$or: [
{ ruleType: 'consume', startTime: { $lte: order.createTime }, endTime: { $gte: order.createTime } },
{ ruleType: 'consume', startTime: { $exists: false }, endTime: { $exists: false } }
]
});
let totalPoints = 0;
const orderItems = order.items;
for (const item of orderItems) {
// 查找商品对应的积分规则
const rule = rules.find(r => r.productIds && r.productIds.includes(item.productId)) || rules[0];
const pointRate = rule ? rule.pointRate : 1;
totalPoints += Math.floor(item.quantity * item.price * pointRate);
}
return totalPoints;
}
// 积分发放
async grantPoints(memberId, points, source, refId) {
const member = await this.ctx.model.Member.findById(memberId);
const transaction = await this.ctx.model.transaction();
try {
// 记录积分流水
await this.ctx.model.PointsRecord.create([{
memberId,
points,
type: 'income',
source,
refId,
balance: member.totalPoints + points,
createTime: new Date()
}], { session: transaction });
// 更新会员总积分
await this.ctx.model.Member.updateOne(
{ _id: memberId },
{ $inc: { totalPoints: points, availablePoints: points } },
{ session: transaction }
);
await transaction.commit();
return true;
} catch (err) {
await transaction.abort();
throw err;
}
}
// 积分扣减(兑换/抵扣)
async deductPoints(memberId, points, source, refId) {
const member = await this.ctx.model.Member.findById(memberId);
if (member.availablePoints < points) {
throw new Error('积分不足');
}
const transaction = await this.ctx.model.transaction();
try {
await this.ctx.model.PointsRecord.create([{
memberId,
points: -points,
type: 'expense',
source,
refId,
balance: member.availablePoints - points,
createTime: new Date()
}], { session: transaction });
await this.ctx.model.Member.updateOne(
{ _id: memberId },
{ $inc: { availablePoints: -points } },
{ session: transaction }
);
await transaction.commit();
return true;
} catch (err) {
await transaction.abort();
throw err;
}
}
}
促销方案设计
1. 促销活动类型
| 促销类型 | 说明 | 示例 |
|---|---|---|
| 折扣促销 | 按折扣比例优惠 | 新品8折 |
| 满减促销 | 满足条件减金额 | 满200减20 |
| 买赠促销 | 买指定商品送赠品 | 买一送一 |
| 积分抵扣 | 积分抵现金 | 100积分抵10元 |
| 组合促销 | 套装组合优惠 | A+B套餐8折 |
2. 促销规则引擎
// 促销计算服务
class PromotionService {
constructor(ctx) {
this.ctx = ctx;
}
// 计算订单优惠
async calculatePromotions(order) {
const promotions = await this.ctx.model.Promotion.find({
status: 'active',
startTime: { $lte: order.createTime },
endTime: { $gte: order.createTime }
});
let totalDiscount = 0;
let discountDetails = [];
for (const promo of promotions) {
const discount = await this.calculatePromotionDiscount(order, promo);
if (discount > 0) {
totalDiscount += discount;
discountDetails.push({
promotionId: promo._id,
promotionName: promo.name,
discount: discount
});
}
}
return {
originalAmount: order.totalAmount,
discountAmount: totalDiscount,
finalAmount: order.totalAmount - totalDiscount,
discountDetails
};
}
// 计算单条促销优惠
async calculatePromotionDiscount(order, promotion) {
let discount = 0;
switch (promotion.promoType) {
case 'discount':
// 折扣促销
const eligibleAmount = this.getEligibleAmount(order, promotion);
discount = eligibleAmount * (1 - promotion.discountRate);
break;
case 'reduce':
// 满减促销
const totalAmount = this.getEligibleAmount(order, promotion);
if (totalAmount >= promotion.thresholdAmount) {
discount = promotion.reduceAmount;
}
break;
case 'gift':
// 买赠促销
const giftResult = this.calculateGiftPromotion(order, promotion);
discount = giftResult.discount;
// 记录赠品信息
order.gifts = giftResult.gifts;
break;
case 'points_deduct':
// 积分抵扣
const memberPoints = await this.getMemberPoints(order.memberId);
const maxDeduct = Math.floor(memberPoints / promotion.pointsRate);
discount = Math.min(maxDed, promotion.maxDeductAmount);
break;
}
return discount;
}
}
促销与积分的结合
在实际业务中,促销活动和会员积分通常需要配合使用:
- 促销活动可以获得额外积分
- 积分可以抵扣订单金额
- 会员等级影响积分倍率
- 促销期间积分可能翻倍
总结
会员积分和促销系统是进销存系统中的重要营销模块,需要根据实际业务需求进行灵活配置。一个好的设计应该支持多种促销方式的组合,同时保证性能能够支撑高并发的促销场景。