互联网运营是指通过内容、活动、用户、数据等手段,提升产品的用户量、活跃度、留存率等指标,实现产品商业目标的工作。运营需要与技术、产品、设计等部门协作,共同推动产品发展。
- 更好的需求理解:理解运营需求背后的业务目标,做出更合适的技术方案
- 数据驱动开发:了解关键指标,在开发中埋点、监控、优化
- 跨部门协作:与运营、产品沟通更顺畅,减少理解偏差
- 职业发展:具备产品思维,向技术管理或产品技术复合型人才发展
- 技术选型:根据运营需求选择合适的技术方案(如推荐算法、AB测试等)
| 指标 | 英文 | 说明 | 程序员关注点 |
|---|
| DAU | Daily Active Users | 日活跃用户数 | 需要统计每日登录/使用的用户数 |
| MAU | Monthly Active Users | 月活跃用户数 | 统计每月活跃用户,用于计算留存率 |
| WAU | Weekly Active Users | 周活跃用户数 | 周活跃用户统计 |
| 新增用户 | New Users | 首次注册/使用的用户 | 需要区分新老用户,设置用户标识 |
| 留存率 | Retention Rate | 用户回访比例 | 计算次日/7日/30日留存,需要记录用户首次使用时间 |
| 流失率 | Churn Rate | 用户流失比例 | 监控用户流失,需要定义流失标准(如30天未登录) |
| 用户生命周期 | User Lifetime | 用户从注册到流失的时间 | 需要记录用户注册时间和最后活跃时间 |
| 指标 | 英文 | 说明 | 程序员关注点 |
|---|
| PV | Page View | 页面浏览量 | 统计页面访问次数,需要埋点 |
| UV | Unique Visitor | 独立访客数 | 统计独立用户数,需要去重 |
| 访问深度 | Visit Depth | 用户单次访问的页面数 | 统计会话中的页面访问数 |
| 停留时长 | Session Duration | 用户在页面的停留时间 | 记录页面进入和离开时间 |
| 跳出率 | Bounce Rate | 只访问一个页面就离开的比例 | 统计单页面会话比例 |
| 转化率 | Conversion Rate | 完成目标行为的用户比例 | 统计关键行为完成率(如注册、下单) |
| 复购率 | Repurchase Rate | 用户重复购买的比例 | 统计用户多次购买行为 |
| 指标 | 英文 | 说明 | 程序员关注点 |
|---|
| GMV | Gross Merchandise Volume | 成交总额 | 统计订单总金额,需要准确计算 |
| ARPU | Average Revenue Per User | 每用户平均收入 | 总收入/用户数,需要统计收入数据 |
| ARPPU | Average Revenue Per Paying User | 每付费用户平均收入 | 总收入/付费用户数 |
| 客单价 | Average Order Value | 平均订单金额 | 订单总金额/订单数 |
| 付费率 | Paying Rate | 付费用户占比 | 付费用户数/总用户数 |
| LTV | Lifetime Value | 用户生命周期价值 | 用户在整个生命周期内的总价值 |
| CAC | Customer Acquisition Cost | 获客成本 | 营销费用/新增用户数 |
| 黑话 | 全称/含义 | 说明 |
|---|
| 拉新 | 获取新用户 | 通过各种渠道吸引新用户注册 |
| 促活 | 促进活跃 | 提升用户活跃度,增加使用频次 |
| 留存 | 用户留存 | 让用户持续使用产品 |
| 召回 | 用户召回 | 通过推送、短信等方式唤醒流失用户 |
| 促活 | 促进活跃 | 提升用户活跃度 |
| 裂变 | 病毒式传播 | 通过分享、邀请等方式实现用户自增长 |
| 私域流量 | Private Domain Traffic | 企业自主运营的用户流量(如微信群、公众号) |
| 公域流量 | Public Domain Traffic | 平台提供的流量(如淘宝、抖音) |
| 流量池 | Traffic Pool | 积累的用户流量资源 |
| 获客 | Customer Acquisition | 获取新客户 |
| 激活 | Activation | 让新用户完成关键行为(如首次下单) |
| 黑话 | 全称/含义 | 说明 |
|---|
| UGC | User Generated Content | 用户生成内容(如评论、帖子) |
| PGC | Professional Generated Content | 专业生成内容(如官方文章) |
| OGC | Organization Generated Content | 机构生成内容 |
| 内容池 | Content Pool | 积累的内容资源库 |
| 内容分发 | Content Distribution | 将内容推送给目标用户 |
| 内容标签 | Content Tag | 对内容进行分类标记 |
| 内容审核 | Content Moderation | 审核用户生成的内容 |
| SEO | Search Engine Optimization | 搜索引擎优化 |
| SEM | Search Engine Marketing | 搜索引擎营销(付费推广) |
| 黑话 | 全称/含义 | 说明 |
|---|
| 活动页 | Campaign Page | 专门为活动设计的页面 |
| 活动配置 | Campaign Configuration | 配置活动规则、奖品等 |
| 活动埋点 | Campaign Tracking | 统计活动相关数据 |
| 限时活动 | Limited Time Campaign | 有时间限制的活动 |
| 秒杀 | Flash Sale | 限时限量的抢购活动 |
| 拼团 | Group Buying | 多人组团购买享受优惠 |
| 砍价 | Price Cutting | 邀请好友帮忙砍价 |
| 满减 | Full Reduction | 满一定金额减价 |
| 优惠券 | Coupon | 折扣券、代金券等 |
| 积分 | Points | 用户积分系统 |
| 会员体系 | Membership System | 会员等级、权益体系 |
| 黑话 | 全称/含义 | 说明 |
|---|
| 埋点 | Event Tracking | 在代码中插入统计代码,记录用户行为 |
| 漏斗分析 | Funnel Analysis | 分析用户转化流程,找出流失环节 |
| 路径分析 | Path Analysis | 分析用户行为路径 |
| 热力图 | Heatmap | 可视化用户点击、浏览热点 |
| AB测试 | A/B Testing | 对比测试不同方案的效果 |
| 灰度发布 | Canary Release | 先让部分用户使用新功能 |
| 数据看板 | Dashboard | 数据可视化展示平台 |
| 实时数据 | Real-time Data | 实时统计的数据 |
| 离线数据 | Offline Data | 需要计算的数据(如T+1报表) |
| 数据埋点 | Data Tracking | 在关键位置埋点统计 |
| 数据清洗 | Data Cleaning | 清理异常、重复数据 |
| 黑话 | 全称/含义 | 说明 |
|---|
| 用户画像 | User Profile | 用户特征标签集合 |
| 用户分群 | User Segmentation | 将用户分成不同群体 |
| 精准推送 | Targeted Push | 根据用户特征推送内容 |
| 个性化推荐 | Personalized Recommendation | 基于用户行为推荐内容 |
| 用户标签 | User Tag | 给用户打标签(如VIP、活跃用户) |
| 沉默用户 | Silent Users | 长期不活跃的用户 |
| 高价值用户 | High Value Users | 付费高、活跃度高的用户 |
| 流失预警 | Churn Warning | 预测用户可能流失 |
| 用户召回 | User Recall | 唤醒流失用户 |
| 黑话 | 全称/含义 | 说明 |
|---|
| MVP | Minimum Viable Product | 最小可行产品 |
| 迭代 | Iteration | 产品版本更新 |
| 功能上线 | Feature Launch | 新功能发布 |
| 需求评审 | Requirement Review | 评审产品需求 |
| PRD | Product Requirements Document | 产品需求文档 |
| 原型 | Prototype | 产品原型图 |
| 交互设计 | Interaction Design | 用户交互流程设计 |
| 用户体验 | User Experience (UX) | 用户使用产品的感受 |
| 用户反馈 | User Feedback | 用户对产品的意见 |
| Bug修复 | Bug Fix | 修复产品缺陷 |
// 埋点示例:记录用户行为
@Service
public class EventTrackingService {
/**
* 记录页面浏览
*/
public void trackPageView(String userId, String pageName) {
Event event = Event.builder()
.eventType("page_view")
.userId(userId)
.pageName(pageName)
.timestamp(System.currentTimeMillis())
.build();
// 发送到数据统计系统
eventQueue.send(event);
}
/**
* 记录用户行为
*/
public void trackEvent(String userId, String eventName, Map<String, Object> properties) {
Event event = Event.builder()
.eventType(eventName)
.userId(userId)
.properties(properties)
.timestamp(System.currentTimeMillis())
.build();
eventQueue.send(event);
}
}
// 使用示例
@RestController
public class OrderController {
@Autowired
private EventTrackingService eventTrackingService;
@PostMapping("/orders")
public Result createOrder(@RequestBody OrderDTO orderDTO) {
// 业务逻辑
Order order = orderService.createOrder(orderDTO);
// 埋点:记录下单事件
Map<String, Object> properties = new HashMap<>();
properties.put("order_id", order.getId());
properties.put("amount", order.getAmount());
properties.put("product_count", order.getItems().size());
eventTrackingService.trackEvent(
orderDTO.getUserId(),
"order_created",
properties
);
return Result.success(order);
}
}
// AB测试服务
@Service
public class ABTestService {
/**
* 获取用户分组(A组或B组)
*/
public String getUserGroup(String userId, String experimentId) {
// 使用用户ID的哈希值确保分组稳定
int hash = (userId + experimentId).hashCode();
return hash % 2 == 0 ? "A" : "B";
}
/**
* 判断用户是否在实验组
*/
public boolean isInExperimentGroup(String userId, String experimentId) {
String group = getUserGroup(userId, experimentId);
return "B".equals(group); // B组为实验组
}
}
// 使用示例:新功能灰度发布
@RestController
public class FeatureController {
@Autowired
private ABTestService abTestService;
@GetMapping("/new-feature")
public Result getNewFeature(@RequestParam String userId) {
// AB测试:50%用户看到新功能
if (abTestService.isInExperimentGroup(userId, "new_feature_v2")) {
return Result.success(newFeatureV2Service.getData());
} else {
return Result.success(oldFeatureService.getData());
}
}
}
// 用户标签服务
@Service
public class UserTagService {
/**
* 给用户打标签
*/
public void addTag(String userId, String tag) {
userTagRepository.addTag(userId, tag);
// 记录标签变更事件
eventTrackingService.trackEvent(userId, "tag_added",
Map.of("tag", tag));
}
/**
* 判断用户是否有标签
*/
public boolean hasTag(String userId, String tag) {
return userTagRepository.hasTag(userId, tag);
}
/**
* 根据标签筛选用户
*/
public List<String> getUsersByTag(String tag) {
return userTagRepository.getUsersByTag(tag);
}
}
// 使用示例:VIP用户特殊处理
@Service
public class OrderService {
@Autowired
private UserTagService userTagService;
public Order createOrder(OrderDTO orderDTO) {
// VIP用户享受特殊优惠
if (userTagService.hasTag(orderDTO.getUserId(), "VIP")) {
orderDTO.setDiscount(0.9); // 9折
}
return orderRepository.save(orderDTO);
}
}
// 推送服务
@Service
public class PushService {
/**
* 精准推送:根据用户标签推送
*/
public void pushToTaggedUsers(String tag, String title, String content) {
List<String> userIds = userTagService.getUsersByTag(tag);
for (String userId : userIds) {
pushToUser(userId, title, content);
}
}
/**
* 推送给单个用户
*/
public void pushToUser(String userId, String title, String content) {
PushMessage message = PushMessage.builder()
.userId(userId)
.title(title)
.content(content)
.timestamp(System.currentTimeMillis())
.build();
// 发送推送
pushQueue.send(message);
}
}
// 活动配置实体
@Entity
public class Campaign {
private Long id;
private String name;
private LocalDateTime startTime;
private LocalDateTime endTime;
private String rules; // JSON格式的活动规则
private String status; // DRAFT, ACTIVE, ENDED
}
// 活动服务
@Service
public class CampaignService {
/**
* 检查活动是否有效
*/
public boolean isCampaignActive(Long campaignId) {
Campaign campaign = campaignRepository.findById(campaignId);
LocalDateTime now = LocalDateTime.now();
return campaign.getStatus().equals("ACTIVE")
&& now.isAfter(campaign.getStartTime())
&& now.isBefore(campaign.getEndTime());
}
/**
* 应用活动优惠
*/
public BigDecimal applyCampaignDiscount(Long campaignId, BigDecimal amount) {
Campaign campaign = campaignRepository.findById(campaignId);
CampaignRules rules = JSON.parseObject(campaign.getRules(), CampaignRules.class);
// 满减规则
if (rules.getFullReduction() != null) {
if (amount.compareTo(rules.getFullReduction().getFullAmount()) >= 0) {
return amount.subtract(rules.getFullReduction().getReductionAmount());
}
}
// 折扣规则
if (rules.getDiscount() != null) {
return amount.multiply(rules.getDiscount());
}
return amount;
}
}
// 优惠券实体
@Entity
public class Coupon {
private Long id;
private String code;
private String type; // DISCOUNT, CASH, FREE_SHIPPING
private BigDecimal value;
private LocalDateTime expireTime;
private Integer totalCount; // 总数量
private Integer usedCount; // 已使用数量
}
// 优惠券服务
@Service
public class CouponService {
/**
* 领取优惠券(防刷)
*/
@Transactional
public Coupon claimCoupon(String userId, Long couponId) {
Coupon coupon = couponRepository.findById(couponId);
// 检查是否已领取
if (userCouponRepository.existsByUserIdAndCouponId(userId, couponId)) {
throw new BusinessException("已领取过该优惠券");
}
// 检查库存(使用乐观锁)
if (coupon.getUsedCount() >= coupon.getTotalCount()) {
throw new BusinessException("优惠券已领完");
}
// 原子性更新库存
int updated = couponRepository.incrementUsedCount(couponId);
if (updated == 0) {
throw new BusinessException("优惠券已领完");
}
// 发放优惠券
UserCoupon userCoupon = UserCoupon.builder()
.userId(userId)
.couponId(couponId)
.status("UNUSED")
.createTime(LocalDateTime.now())
.build();
return userCouponRepository.save(userCoupon);
}
}
// 数据统计服务
@Service
public class StatisticsService {
/**
* 统计DAU(日活跃用户)
*/
public Long getDAU(LocalDate date) {
return userActivityRepository.countDistinctUsersByDate(date);
}
/**
* 计算留存率
*/
public BigDecimal getRetentionRate(LocalDate date, int days) {
// 获取基准日的新增用户
Long newUsers = userRepository.countNewUsersByDate(date);
// 获取N日后的回访用户
LocalDate targetDate = date.plusDays(days);
Long retainedUsers = userActivityRepository.countRetainedUsers(date, targetDate);
if (newUsers == 0) {
return BigDecimal.ZERO;
}
return BigDecimal.valueOf(retainedUsers)
.divide(BigDecimal.valueOf(newUsers), 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
}
/**
* 漏斗分析
*/
public FunnelResult analyzeFunnel(String funnelId, LocalDate startDate, LocalDate endDate) {
// 定义漏斗步骤
List<String> steps = Arrays.asList("view", "add_cart", "checkout", "pay");
List<Long> stepCounts = new ArrayList<>();
for (String step : steps) {
Long count = eventRepository.countEvents(funnelId, step, startDate, endDate);
stepCounts.add(count);
}
// 计算转化率
List<BigDecimal> conversionRates = new ArrayList<>();
for (int i = 1; i < stepCounts.size(); i++) {
if (stepCounts.get(i-1) > 0) {
BigDecimal rate = BigDecimal.valueOf(stepCounts.get(i))
.divide(BigDecimal.valueOf(stepCounts.get(i-1)), 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
conversionRates.add(rate);
}
}
return FunnelResult.builder()
.steps(steps)
.stepCounts(stepCounts)
.conversionRates(conversionRates)
.build();
}
}
- 理解业务目标:了解运营需求背后的业务目标
- 技术可行性评估:评估技术实现的难度和成本
- 数据需求明确:明确需要统计哪些数据,如何埋点
- 埋点规范:建立统一的埋点规范,便于数据分析
- 实时数据:提供实时数据接口,支持运营决策
- 数据准确性:确保数据统计的准确性,避免误导决策
- 配置化:活动、优惠券等尽量配置化,减少开发成本
- 可扩展性:考虑未来扩展需求,预留扩展点
- 性能优化:高并发场景(如秒杀)需要性能优化
- 关键指标监控:监控DAU、GMV等关键指标
- 异常告警:数据异常时及时告警
- 性能监控:监控系统性能,避免影响用户体验
| 指标 | 英文 | 说明 | 程序员关注点 |
|---|
| 发卡量 | Card Issuance | 累计发行的信用卡数量 | 统计发卡记录,需要记录发卡时间、卡类型 |
| 有效卡量 | Active Cards | 激活且未注销的卡数量 | 需要区分激活状态、注销状态 |
| 活卡率 | Active Card Rate | 活跃卡占有效卡的比例 | 统计活跃卡数(有交易记录的卡) |
| 动卡率 | Card Usage Rate | 有交易的卡占有效卡的比例 | 统计有交易记录的卡数 |
| 户均卡数 | Cards Per Customer | 平均每个客户持有的卡数 | 客户数/总卡数 |
| 卡均交易额 | Transaction Per Card | 平均每张卡的交易金额 | 总交易额/有效卡数 |
| 卡均余额 | Average Balance Per Card | 平均每张卡的欠款余额 | 总余额/有效卡数 |
| 循环余额 | Revolving Balance | 未全额还款产生的循环信用余额 | 统计未全额还款的账户余额 |
| 分期余额 | Installment Balance | 分期付款的未还本金 | 统计分期产品的未还本金 |
| 逾期率 | Delinquency Rate | 逾期账户占比 | 逾期账户数/总账户数 |
| 不良率 | NPL Rate | 不良贷款率(通常逾期90天以上) | 不良账户数/总账户数 |
| 损失率 | Loss Rate | 最终无法收回的损失占比 | 核销金额/总贷款余额 |
| 黑话 | 全称/含义 | 说明 |
|---|
| 信用卡产品 | Credit Card Product | 不同类型的信用卡(如普卡、金卡、白金卡) |
| 卡等级 | Card Tier | 卡的级别(普卡、金卡、白金卡、钻石卡) |
| 信用额度 | Credit Limit | 银行授予的可用信用额度 |
| 可用额度 | Available Credit | 当前可使用的额度 |
| 已用额度 | Used Credit | 已使用的额度 |
| 临时额度 | Temporary Credit | 临时提升的额度 |
| 固定额度 | Permanent Credit | 永久性的信用额度 |
| 提额 | Credit Increase | 提升信用额度 |
| 降额 | Credit Decrease | 降低信用额度 |
| 封卡 | Card Closure | 冻结或注销信用卡 |
| 解封 | Card Unfreeze | 解除卡片冻结状态 |
| 黑话 | 全称/含义 | 说明 |
|---|
| 消费 | Purchase | 信用卡刷卡消费 |
| 取现 | Cash Advance | 从信用卡提取现金 |
| 还款 | Payment | 偿还信用卡欠款 |
| 全额还款 | Full Payment | 还清所有欠款 |
| 最低还款 | Minimum Payment | 只还最低还款额 |
| 分期 | Installment | 将消费金额分期还款 |
| 账单分期 | Statement Installment | 对账单金额进行分期 |
| 消费分期 | Purchase Installment | 单笔消费分期 |
| 现金分期 | Cash Installment | 提取现金后分期还款 |
| 提前还款 | Early Payment | 在分期到期前提前还款 |
| 违约金 | Penalty | 未按时还款产生的违约金 |
| 利息 | Interest | 循环信用产生的利息 |
| 手续费 | Service Fee | 分期、取现等产生的手续费 |
| 黑话 | 全称/含义 | 说明 |
|---|
| 授信 | Credit Granting | 授予信用额度 |
| 征信 | Credit Investigation | 查询个人信用记录 |
| 征信报告 | Credit Report | 个人信用记录报告 |
| 信用评分 | Credit Score | 信用评分(如FICO分) |
| 风险等级 | Risk Level | 客户风险等级(低、中、高) |
| 黑名单 | Blacklist | 高风险客户名单 |
| 白名单 | Whitelist | 优质客户名单 |
| 灰名单 | Greylist | 需要关注的客户名单 |
| 反欺诈 | Anti-Fraud | 识别和防范欺诈交易 |
| 交易监控 | Transaction Monitoring | 实时监控异常交易 |
| 风险预警 | Risk Warning | 识别潜在风险并预警 |
| 贷后管理 | Post-Loan Management | 放款后的风险管理 |
| 黑话 | 全称/含义 | 说明 |
|---|
| M0/M1/M2/M3 | 逾期阶段 | M0正常,M1逾期1-30天,M2逾期31-60天,M3逾期61-90天 |
| M4+ | 严重逾期 | 逾期90天以上 |
| 催收 | Collection | 对逾期账户进行催收 |
| 内催 | Internal Collection | 银行内部催收 |
| 外催 | External Collection | 委托第三方机构催收 |
| 法催 | Legal Collection | 通过法律途径催收 |
| 核销 | Write-off | 将无法收回的坏账核销 |
| 呆账 | Bad Debt | 无法收回的坏账 |
| 催收率 | Collection Rate | 成功催收的金额占比 |
| 回收率 | Recovery Rate | 回收的金额占逾期金额的比例 |
| 黑话 | 全称/含义 | 说明 |
|---|
| 新户 | New Customer | 新注册的客户 |
| 老户 | Existing Customer | 已有客户 |
| 新户礼 | New Customer Gift | 新客户注册奖励 |
| 首刷礼 | First Purchase Gift | 首次消费奖励 |
| 开卡礼 | Card Activation Gift | 激活卡片奖励 |
| 积分 | Points | 消费获得的积分 |
| 积分兑换 | Points Redemption | 用积分兑换礼品 |
| 积分有效期 | Points Expiry | 积分的有效期 |
| 里程 | Miles | 航空里程积分 |
| 返现 | Cashback | 消费返现金 |
| 免息期 | Interest-Free Period | 免收利息的期限 |
| 年费 | Annual Fee | 信用卡年费 |
| 免年费 | Annual Fee Waiver | 免除年费 |
| 权益 | Benefits | 信用卡提供的权益(如机场贵宾厅) |
// 额度管理服务
@Service
public class CreditLimitService {
/**
* 计算可用额度
*/
public BigDecimal getAvailableCredit(Long cardId) {
Card card = cardRepository.findById(cardId);
// 已用额度 = 消费金额 + 取现金额 + 分期余额
BigDecimal usedCredit = getUsedCredit(cardId);
// 可用额度 = 信用额度 - 已用额度
return card.getCreditLimit().subtract(usedCredit);
}
/**
* 检查额度是否充足
*/
public boolean checkCreditLimit(Long cardId, BigDecimal amount) {
BigDecimal availableCredit = getAvailableCredit(cardId);
return availableCredit.compareTo(amount) >= 0;
}
/**
* 申请提额
*/
@Transactional
public void applyCreditIncrease(Long cardId, BigDecimal newLimit) {
Card card = cardRepository.findById(cardId);
// 风控审核
if (!riskService.approveCreditIncrease(card.getUserId(), newLimit)) {
throw new BusinessException("提额申请未通过审核");
}
// 更新额度
card.setCreditLimit(newLimit);
cardRepository.save(card);
// 记录额度变更历史
creditLimitHistoryRepository.save(
CreditLimitHistory.builder()
.cardId(cardId)
.oldLimit(card.getCreditLimit())
.newLimit(newLimit)
.changeType("INCREASE")
.createTime(LocalDateTime.now())
.build()
);
// 发送通知
notificationService.sendCreditLimitChangeNotification(card.getUserId(), newLimit);
}
}
// 分期服务
@Service
public class InstallmentService {
/**
* 申请分期
*/
@Transactional
public Installment createInstallment(InstallmentRequest request) {
Card card = cardRepository.findById(request.getCardId());
// 检查分期金额
if (request.getAmount().compareTo(card.getCreditLimit()) > 0) {
throw new BusinessException("分期金额超过信用额度");
}
// 计算分期手续费和每期还款额
InstallmentPlan plan = calculateInstallmentPlan(
request.getAmount(),
request.getPeriods(),
request.getType()
);
// 创建分期记录
Installment installment = Installment.builder()
.cardId(request.getCardId())
.amount(request.getAmount())
.periods(request.getPeriods())
.type(request.getType())
.serviceFee(plan.getTotalServiceFee())
.monthlyPayment(plan.getMonthlyPayment())
.status("ACTIVE")
.createTime(LocalDateTime.now())
.build();
installmentRepository.save(installment);
// 更新卡余额
card.setInstallmentBalance(
card.getInstallmentBalance().add(request.getAmount())
);
cardRepository.save(card);
return installment;
}
/**
* 计算分期计划
*/
private InstallmentPlan calculateInstallmentPlan(
BigDecimal amount,
Integer periods,
String type) {
// 根据分期类型和期数计算手续费率
BigDecimal serviceFeeRate = getServiceFeeRate(type, periods);
// 总手续费
BigDecimal totalServiceFee = amount.multiply(serviceFeeRate);
// 每期还款额 = (本金 + 总手续费) / 期数
BigDecimal monthlyPayment = amount.add(totalServiceFee)
.divide(BigDecimal.valueOf(periods), 2, RoundingMode.HALF_UP);
return InstallmentPlan.builder()
.totalServiceFee(totalServiceFee)
.monthlyPayment(monthlyPayment)
.build();
}
}
// 逾期管理服务
@Service
public class DelinquencyService {
/**
* 计算逾期天数
*/
public int calculateOverdueDays(Long cardId) {
Card card = cardRepository.findById(cardId);
Bill latestBill = billRepository.findLatestBill(cardId);
if (latestBill == null || latestBill.getStatus().equals("PAID")) {
return 0;
}
LocalDate dueDate = latestBill.getDueDate();
LocalDate now = LocalDate.now();
if (now.isAfter(dueDate)) {
return (int) ChronoUnit.DAYS.between(dueDate, now);
}
return 0;
}
/**
* 判断逾期阶段
*/
public String getDelinquencyStage(int overdueDays) {
if (overdueDays <= 0) {
return "M0";
} else if (overdueDays <= 30) {
return "M1";
} else if (overdueDays <= 60) {
return "M2";
} else if (overdueDays <= 90) {
return "M3";
} else {
return "M4+";
}
}
/**
* 执行催收流程
*/
public void executeCollection(Long cardId) {
int overdueDays = calculateOverdueDays(cardId);
String stage = getDelinquencyStage(overdueDays);
Card card = cardRepository.findById(cardId);
Bill bill = billRepository.findLatestBill(cardId);
switch (stage) {
case "M1":
// 短信提醒
smsService.sendOverdueReminder(card.getUserId(), bill.getAmount());
break;
case "M2":
// 电话催收
callCenterService.callCustomer(card.getUserId());
// 发送催收函
letterService.sendCollectionLetter(card.getUserId(), bill);
break;
case "M3":
// 委托第三方催收
thirdPartyCollectionService.delegate(cardId);
break;
case "M4+":
// 进入法律程序
legalService.initiateLegalAction(cardId);
break;
}
// 更新逾期状态
card.setDelinquencyStage(stage);
card.setOverdueDays(overdueDays);
cardRepository.save(card);
}
}
// 积分服务
@Service
public class PointsService {
/**
* 计算消费积分
*/
public Integer calculatePoints(Transaction transaction) {
Card card = cardRepository.findById(transaction.getCardId());
// 根据卡等级获取积分倍数
BigDecimal pointsRate = getPointsRate(card.getCardTier());
// 根据商户类型获取积分倍数
BigDecimal merchantRate = getMerchantPointsRate(transaction.getMerchantType());
// 积分 = 消费金额 * 卡等级倍数 * 商户类型倍数
BigDecimal points = transaction.getAmount()
.multiply(pointsRate)
.multiply(merchantRate);
return points.intValue();
}
/**
* 发放积分
*/
@Transactional
public void grantPoints(Long cardId, Integer points, String source) {
Card card = cardRepository.findById(cardId);
// 更新积分余额
card.setPointsBalance(card.getPointsBalance() + points);
cardRepository.save(card);
// 记录积分流水
PointsRecord record = PointsRecord.builder()
.cardId(cardId)
.points(points)
.type("EARNED")
.source(source)
.balance(card.getPointsBalance())
.createTime(LocalDateTime.now())
.build();
pointsRecordRepository.save(record);
}
/**
* 积分兑换
*/
@Transactional
public void redeemPoints(Long cardId, Integer points, String rewardId) {
Card card = cardRepository.findById(cardId);
// 检查积分是否充足
if (card.getPointsBalance() < points) {
throw new BusinessException("积分不足");
}
// 扣除积分
card.setPointsBalance(card.getPointsBalance() - points);
cardRepository.save(card);
// 记录积分流水
PointsRecord record = PointsRecord.builder()
.cardId(cardId)
.points(points)
.type("REDEEMED")
.source(rewardId)
.balance(card.getPointsBalance())
.createTime(LocalDateTime.now())
.build();
pointsRecordRepository.save(record);
// 发放奖励
rewardService.grantReward(card.getUserId(), rewardId);
}
}
// 风控服务
@Service
public class RiskControlService {
/**
* 交易风控检查
*/
public RiskResult checkTransactionRisk(Transaction transaction) {
Card card = cardRepository.findById(transaction.getCardId());
User user = userRepository.findById(card.getUserId());
RiskResult result = new RiskResult();
// 1. 额度检查
if (!creditLimitService.checkCreditLimit(
transaction.getCardId(),
transaction.getAmount())) {
result.setRiskLevel("HIGH");
result.setReason("额度不足");
return result;
}
// 2. 黑名单检查
if (blacklistService.isBlacklisted(user.getId())) {
result.setRiskLevel("HIGH");
result.setReason("客户在黑名单中");
return result;
}
// 3. 异常交易检测
if (isAbnormalTransaction(transaction, card)) {
result.setRiskLevel("MEDIUM");
result.setReason("交易异常");
return result;
}
// 4. 反欺诈检查
FraudResult fraudResult = fraudDetectionService.detect(transaction);
if (fraudResult.isFraud()) {
result.setRiskLevel("HIGH");
result.setReason("疑似欺诈交易");
return result;
}
result.setRiskLevel("LOW");
return result;
}
/**
* 检测异常交易
*/
private boolean isAbnormalTransaction(Transaction transaction, Card card) {
// 检查交易金额是否异常(超过平时消费习惯)
BigDecimal avgAmount = transactionRepository.getAverageAmount(
transaction.getCardId(),
LocalDate.now().minusDays(30)
);
if (avgAmount != null &&
transaction.getAmount().compareTo(avgAmount.multiply(new BigDecimal("3"))) > 0) {
return true;
}
// 检查交易时间是否异常(非正常消费时间)
LocalTime transactionTime = transaction.getCreateTime().toLocalTime();
if (transactionTime.isBefore(LocalTime.of(6, 0)) ||
transactionTime.isAfter(LocalTime.of(23, 0))) {
return true;
}
// 检查交易地点是否异常(短时间内跨地区交易)
List<Transaction> recentTransactions = transactionRepository.findRecentTransactions(
transaction.getCardId(),
LocalDateTime.now().minusHours(1)
);
for (Transaction recent : recentTransactions) {
if (!recent.getMerchantLocation().equals(transaction.getMerchantLocation())) {
// 计算距离
double distance = calculateDistance(
recent.getMerchantLocation(),
transaction.getMerchantLocation()
);
if (distance > 1000) { // 1小时内移动超过1000公里
return true;
}
}
}
return false;
}
}
// 信用卡业务统计服务
@Service
public class CreditCardStatisticsService {
/**
* 统计活卡率
*/
public BigDecimal getActiveCardRate(LocalDate date) {
// 有效卡数
Long activeCards = cardRepository.countActiveCards(date);
// 总有效卡数
Long totalCards = cardRepository.countTotalCards(date);
if (totalCards == 0) {
return BigDecimal.ZERO;
}
return BigDecimal.valueOf(activeCards)
.divide(BigDecimal.valueOf(totalCards), 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
}
/**
* 统计逾期率
*/
public BigDecimal getDelinquencyRate(LocalDate date) {
// 逾期账户数
Long overdueAccounts = cardRepository.countOverdueAccounts(date);
// 总账户数
Long totalAccounts = cardRepository.countTotalAccounts(date);
if (totalAccounts == 0) {
return BigDecimal.ZERO;
}
return BigDecimal.valueOf(overdueAccounts)
.divide(BigDecimal.valueOf(totalAccounts), 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
}
/**
* 统计卡均交易额
*/
public BigDecimal getAverageTransactionPerCard(LocalDate startDate, LocalDate endDate) {
// 总交易额
BigDecimal totalAmount = transactionRepository.sumAmountByDateRange(
startDate,
endDate
);
// 有效卡数
Long activeCards = cardRepository.countActiveCards(endDate);
if (activeCards == 0) {
return BigDecimal.ZERO;
}
return totalAmount.divide(
BigDecimal.valueOf(activeCards),
2,
RoundingMode.HALF_UP
);
}
/**
* 统计分期渗透率(使用分期的客户占比)
*/
public BigDecimal getInstallmentPenetrationRate(LocalDate date) {
// 有分期的客户数
Long customersWithInstallment = cardRepository.countCustomersWithInstallment(date);
// 总客户数
Long totalCustomers = cardRepository.countTotalCustomers(date);
if (totalCustomers == 0) {
return BigDecimal.ZERO;
}
return BigDecimal.valueOf(customersWithInstallment)
.divide(BigDecimal.valueOf(totalCustomers), 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
}
}
// 新户营销服务
@Service
public class NewCustomerMarketingService {
/**
* 新户注册奖励
*/
@Transactional
public void grantNewCustomerReward(Long userId) {
// 发放开卡礼
rewardService.grantReward(userId, "NEW_CUSTOMER_GIFT");
// 发放积分
pointsService.grantPoints(userId, 1000, "NEW_CUSTOMER_BONUS");
// 设置首刷礼标记
userTagService.addTag(userId, "FIRST_PURCHASE_REWARD");
}
/**
* 首刷奖励
*/
@Transactional
public void grantFirstPurchaseReward(Long cardId, Transaction transaction) {
User user = userRepository.findByCardId(cardId);
// 检查是否首次消费
if (!userTagService.hasTag(user.getId(), "FIRST_PURCHASE_REWARD")) {
return;
}
// 发放首刷礼
rewardService.grantReward(user.getId(), "FIRST_PURCHASE_GIFT");
// 额外积分奖励
pointsService.grantPoints(cardId, 500, "FIRST_PURCHASE_BONUS");
// 移除标记
userTagService.removeTag(user.getId(), "FIRST_PURCHASE_REWARD");
}
}
// 分期营销服务
@Service
public class InstallmentMarketingService {
/**
* 推送分期优惠
*/
public void pushInstallmentPromotion(Long cardId) {
Card card = cardRepository.findById(cardId);
Bill bill = billRepository.findLatestBill(cardId);
// 检查是否满足推送条件
if (bill == null || bill.getStatus().equals("PAID")) {
return;
}
// 账单金额大于1000元,推送分期优惠
if (bill.getAmount().compareTo(new BigDecimal("1000")) > 0) {
// 计算分期优惠(如免手续费)
InstallmentPromotion promotion = InstallmentPromotion.builder()
.cardId(cardId)
.billId(bill.getId())
.discountRate(new BigDecimal("0.5")) // 手续费5折
.expireTime(LocalDateTime.now().plusDays(7))
.build();
// 保存优惠
installmentPromotionRepository.save(promotion);
// 推送消息
pushService.pushToUser(
card.getUserId(),
"分期优惠",
"您的账单可享受分期手续费5折优惠,立即办理!"
);
}
}
}
- 《增长黑客》:了解用户增长策略
- 《数据化运营》:学习数据驱动的运营方法
- 《运营之光》:了解互联网运营的实践
- 《信用卡业务》:了解信用卡业务知识
- 36氪:了解互联网行业动态
- 人人都是产品经理:学习产品和运营知识
- GrowingIO:数据分析和增长相关文章
- 银联数据:了解信用卡行业动态
- Google Analytics:网站数据分析
- 神策数据:用户行为分析平台
- GrowingIO:用户增长分析平台
- 风控系统:信用卡风控相关工具
作为程序员,了解运营知识可以帮助你:
- 更好地理解需求:理解业务目标,做出更合适的技术方案
- 数据驱动开发:在开发中考虑数据统计和分析需求
- 提升协作效率:与运营、产品沟通更顺畅
- 拓展职业发展:向技术管理或产品技术复合型人才发展
关键是要理解运营的核心指标、常用术语,以及在技术实现中如何支持运营需求(如埋点、AB测试、用户标签等)。
在信用卡行业,作为程序员需要特别注意:
- 风控优先:信用卡业务风险高,风控系统是核心,需要实时监控异常交易
- 合规要求:金融行业监管严格,需要遵守相关法规(如数据安全、隐私保护)
- 资金安全:涉及资金流转,需要保证交易的安全性和准确性
- 数据准确性:业务指标(如逾期率、不良率)直接影响业务决策,数据必须准确
- 实时性要求:交易风控、额度检查等需要实时响应,不能有延迟
- 复杂业务规则:分期、利息、手续费等计算规则复杂,需要仔细实现
- 催收流程:逾期管理涉及多个阶段,需要自动化催收流程
- 积分系统:积分计算、兑换、过期等逻辑需要精确实现
- 额度管理:准确计算可用额度,支持提额、降额等操作
- 分期管理:支持多种分期类型,准确计算手续费和还款计划
- 逾期管理:准确计算逾期天数,自动执行催收流程
- 风控系统:实时检测异常交易,防范欺诈风险
- 积分系统:准确计算积分,支持积分兑换和过期处理
- 数据统计:准确统计业务指标(活卡率、逾期率、卡均交易额等)
掌握这些知识,可以帮助你在信用卡行业更好地理解业务需求,设计更合适的技术方案,与业务团队高效协作。