You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ramda.js中按条件构建促销及积分相关复杂字符串?

需求与问题描述

给定以下变量示例:

var availableDeals = 20;
var activatedDeals = 5;
var maximumGems = 100;
var earnedGems = 70;

需要根据不同条件生成三种促销活动与积分推广消息:

  • 已激活20个活动中的5个,已赚取100个gems中的70个,消费更多赚取更多gems。
  • 还有15个活动待激活,仅需30个更多gems即可解锁活动(当所需gems≤50时使用'仅需')。
  • 还有1个活动待激活,仅需1个更多gems即可解锁活动(当剩余活动/gems数量为1时使用该表述)。

本人尝试编写了如下Ramda.js代码,但无法正确处理所有条件:

const getTitle = (activatedDeals, totalDeals, currentGems, maxGems, requiredGems) => {
 return R.cond([
   [R.equals(0), R.always('No deals to activate')], 
   [R.equals(activatedDeals), R.always('All deals activated')],
   [R.lt(activatedDeals), R.always(`${totalDeals - activatedDeals} deals to activate`)],
   [R.T, R.always('- deals to activate')], // Error scenario
 ])(
   totalDeals,
 ) +`, ${currentGems} of ${maxGems} gems, ${requiredGems} more gems to unlock a deal`;
}

请问如何针对活动与gems的多种条件完成字符串的正确拼接?


解决方案

你可以把活动状态和宝石需求的逻辑拆成独立的处理单元,再组合出最终消息,这样既符合Ramda的函数式风格,也能清晰覆盖所有条件:

1. 生成活动状态描述

先写一个函数处理活动相关的文本:

const getDealStatusText = (activated, total) => {
  return R.cond([
    [R.equals(0), R.always('无活动可激活')],
    [R.equals(activated), R.always('所有活动已激活')],
    [R.pipe(R.subtract(R.__, activated), R.equals(1)), 
     R.always('还有1个活动待激活')],
    [R.T, R.pipe(R.subtract(R.__, activated), num => `还有${num}个活动待激活`)]
  ])(total);
};

2. 生成宝石需求描述

再写一个函数处理宝石相关的文本:

const getGemRequirementText = (current, max, required) => {
  const earnedText = `已赚取${max}个gems中的${current}个`;
  
  const requiredText = R.cond([
    [R.equals(current), R.always('已赚满所有gems')],
    [R.equals(1), R.always('仅需1个更多gems即可解锁活动')],
    [R.lte(R.__, 50), num => `仅需${num}个更多gems即可解锁活动`],
    [R.T, num => `还需${num}个更多gems即可解锁活动`]
  ])(required);

  return current < max ? `${earnedText},${requiredText}` : earnedText;
};

3. 组合完整推广消息

最后把两个函数整合,处理特殊场景:

const getPromoMessage = (activatedDeals, availableDeals, earnedGems, maximumGems, requiredGems) => {
  const dealText = getDealStatusText(activatedDeals, availableDeals);
  
  if (dealText === '所有活动已激活' || dealText === '无活动可激活') {
    return dealText;
  }

  const gemText = getGemRequirementText(earnedGems, maximumGems, requiredGems);
  
  // 触发场景1:已激活部分活动,且所需宝石超过50,提示消费赚更多
  const shouldPromptSpend = activatedDeals > 0 && activatedDeals < availableDeals 
    && earnedGems < maximumGems && requiredGems > 50;
  
  if (shouldPromptSpend) {
    return `已激活${availableDeals}个活动中的${activatedDeals}个,${gemText.split(',')[0]},消费更多赚取更多gems。`;
  }

  return `${dealText},${gemText}`;
};

测试不同场景

// 场景1:已激活5/20,赚70/100,需60宝石(>50触发消费提示)
console.log(getPromoMessage(5, 20, 70, 100, 60)); 
// 输出:已激活20个活动中的5个,已赚取100个gems中的70个,消费更多赚取更多gems。

// 场景2:剩余15个活动,需30宝石(≤50用"仅需")
console.log(getPromoMessage(5, 20, 70, 100, 30)); 
// 输出:还有15个活动待激活,已赚取100个gems中的70个,仅需30个更多gems即可解锁活动

// 场景3:剩余1个活动,需1个宝石
console.log(getPromoMessage(19, 20, 99, 100, 1)); 
// 输出:还有1个活动待激活,已赚取100个gems中的99个,仅需1个更多gems即可解锁活动

这种拆分方式让每个函数只负责单一逻辑,后续要调整规则也更容易修改。

内容的提问来源于stack exchange,提问作者Aravind Shankar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:15:26