我正在尝试做一个我发现有点困难的计算。对于那些数学爱好者,请帮忙。
背景
我正在构建一个移动应用程序,用户可以在其中订阅指定时间段(即 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);
});
测试数据
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
所以关键算法是:
- 按购买日期排序
- 累计购买日期在重叠累计期内的天数
如果您的数据结构像 [{ 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/