用于恢复购买的 Javascript 算法

标签 javascript algorithm math

我正在尝试做一个我发现有点困难的计算。对于那些数学爱好者,请帮忙。

背景

我正在构建一个移动应用程序,用户可以在其中订阅指定时间段(即 3 天、10 天、30 天、731 天)的服务。

例如,现在,如果他们订阅了 3 天,并且在 2 天后,他们又订阅了 10 天,那么他们的订阅将从现在起 11 天后到期。

例如

=== 3 ===>
       === 10 ===>  | expires 13 days from the purchase date

问题

我需要能够在任何给定时间点恢复一个人的订阅。

例如,如果用户使用新设备登录,我需要能够将他们的订阅恢复到当前状态。

解决方案

我可以使用现有的 restore 函数来做到这一点。

此函数返回用户曾经购买过的所有产品的列表。每次购买包含:

  • productId - 与产品匹配(即 3 天、10 天、30 天,731 天)

  • date - 购买的时间戳

我需要编写一个函数来计算给定时间点的用户当前订阅状态。如果他们的历史购买已过期,他们将被忽略,但如果购买仍然有效,则必须累积到订阅总数。

例如

=== 3 ===>
        === 10 ===>     | expired
                             === 3 ===>
                                     === 3 ===>  | expires

(我正在使用 following api )

我的尝试

  public PRODUCT_IDS: string[] = ['3days', '10days', '30days', '2years'];
  public PRODUCT_DAYS: number[] = [3, 10, 30, 731];

  private restore(): void {
    this.iap.restorePurchases().then((purchases: any[]) => {
      var currentDateMilliseconds = (new Date).getTime();
      let subDate: number = 0;
      for (let i: number = 0; i < purchases.length; i++) {
        let productid: string = purchases[i];
        let purchaseDate: number = purchases[i].date;
        if (productid && purchaseDate) {
          for (let j: number = 0; j < this.PRODUCT_IDS.length; j++) {
            if (productid === this.PRODUCT_IDS[j]) {
              let prodMilis = this.PRODUCT_DAYS[j] * 1000 * 60 * 60 * 24;
              let tempDate: number = purchaseDate + prodMilis;
              if (tempDate - currentDateMilliseconds > 0) {
                subDate += tempDate - currentDateMilliseconds;
              }
            }
          }
        }
      }

      this.personModel.contactable = subDate;
    });
  }

如您所见,这是不完整的。

我正在尝试用总的累计订阅到期日期填充变量 subDate

问题

如果有人能协助我完成这个功能,我将不胜感激。

更多信息

  .restorePurchases()
  .then(function (data) {
    console.log(data);
    /*
      [{
        transactionId: ...
        productId: ...
        state: ...
        date: ...
      }]
    */
  })
  .catch(function (err) {
    console.log(err);
  });

ref

测试数据

  private restorePurchases(): Promise<any[]> {
    return new Promise<any[]>((resolve) => {
      let data: any[] =
        [
          {
            productId: '3days',
            date: 1499841497305
          },
          {
            productId: '10days',
            date: 1499841498305
          },
          {
            productId: '3days',
            date: 14998414979305
          }
        ];

      resolve(data);
    });
  }

最佳答案

给定(按购买日期排序)

Date  Purchase
1000  3
1002  10
2000  3
2001  3

预计结束日期为 2006.0

迭代,累积重叠的天数:

Date  Days CumulEnd  OverlapId  
1000  3    1003      0
1002  10   1013      0
2000  3    2003      1
2001  3    2006      1

所以关键算法是:

  1. 按购买日期排序
  2. 累计购买日期在重叠累计期内的天数

如果您的数据结构像 [{ date: 1000, days: 3 }, { date: 1002, days: 10 }],那么累加器可能会像这样工作:

function collectOverlaps(accumulator, currentElem, currentIndex, array) {
   var currDate = currentElem.date;
   // if no previous overlaps or does not overlap last, create new
   if(accumulator.length == 0 || 
     currDate > accumulator[accumulator.length - 1].end) {
      accumulator.push({ start: currDate, end: currDate + currentElem.days });
   } else { // extend overlap
      accumulator[accumulator.length - 1].end += currentElem.days;
   }
   return accumulator;
}

然后我们可以这样累积重叠:

// overlaps will contain { start: x, end: y }
var overlaps = purchases.reduce(collectOverlaps, []);

例子:

var purchases = [{date: 1000, days:3}, {date: 1002, days:10}, {date:2000, days:3}, {date:2001, days:3}];
var overlaps = purchases.reduce(collectOverlaps, []);
console.log(collectOverlaps);

产生:

[[object Object] {
  end: 1013,
  start: 1000
}, [object Object] {
  end: 2006,
  start: 2000
}]

您可以通过丢弃不再有效的重叠来使这更简单,但这样至少您可以获得一组完整的连续许可期限。

关于用于恢复购买的 Javascript 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45059535/

相关文章:

javascript - ReactJs - 如何在一个组件内传递数据

php - 欧拉计划 #23 : Non-abundant sums

algorithm - 识别并集多边形的原始边

algorithm - 用EM算法填充多个缺失数据

php - 如何获取十进制数左右两边的位数

c++ - 检测 2 个长方体是否碰撞给出边界的算法

javascript - 单击函数获取旧数据属性值 - JQuery

javascript - 如何将生产网站的Javascript替换为本地Javascript?

php - 选择一个以前没有被选中的随机行?

javascript - 如何像 Accordion 一样使用 polymer 核心坍塌?