设计模式 - 跟踪用户代币/硬币的策略



我正在开发一个网络应用程序,用户可以每月购买代币/硬币,这意味着代币将在月底到期(例如,3美元将在一个月内获得5个代币)。当涉及到存储和跟踪每个用户令牌时,我有点困惑该采取什么策略。

在一个由两部分组成的问题中:

1) 由于用户通常可以在一个月的任何阶段购买代币,因此月份是定义为"30"天,还是映射到日历月的日期?(例如:如果代币在3月份购买,它们会持续31天吗?但如果在5月份购买,它会持续30天吗?)

2) 问题的第二部分是如何跟踪这些代币?如果用户支付了一年的订阅费(12个月内每月5个代币),但也被允许在一年中购买更多代币(6月份用户想要10个代币)。我如何才能真正跟踪每个月购买了多少代币?

我心中有一些实现想法,但似乎没有一个是"正确的"。我希望有人能解决类似的问题,或者能给我介绍任何相关的文献。

提前谢谢。

由于用户通常可以在一个月的任何阶段购买代币,月份是定义为"30"天,还是映射到日历月?(例如:如果代币在3月份购买它们可以使用31天,但如果在5月份购买,它们可以使用30天?)

总是整整一个月

为什么?因为你对用户很好;)

我会选择一个完整的月份,因为日期方法很简单。并且更容易为成员跟踪。对于喜欢在2月底购买最多代币的人来说,31天是一个更好的选择。例如,1月31日的购买将在3月3日到期,而不是2月28日。

当然,你可以自己决定,但这是最合理的选择,也可以确保你减少与客户的麻烦。

问题的第二部分是如何跟踪这些代币?如果用户支付一年的订阅费(每月5个代币,12个月),但也被允许在今年(六月用户想要10个代币),我该如何实际保留跟踪每个月购买了多少代币?

为每次代币购买创建一个表,其中包含购买的时间和日期以及代币数量

TokenPurchaseNumber | UserId | TokenCount | PurchaseDateTime| ExpireDateTime
---------------------------------------------------------------------
10001               | 1      | 200        | Jan 20          | Feb 20
10002               | 1      | 100        | Jan 24          | Feb 24
10002               | 2      | 300        | Jan 24          | Feb 24
10003               | 1      | 20         | Jan 25          | Feb 25
10004               | 1      | 40         | Jan 29          | Feb 29

这样,您就可以使用唯一的采购编号对所有采购进行良好的存档,并可以为用户生成采购历史记录。

您可以考虑不使用ExpireDateTime列,因为您只需将购买代币的日期+31天与今天进行比较。

现在,如何计算用户拥有的代币总数似乎是下一个问题

有两种选择,第一种将有更好的购买历史和档案。

选项1:

这相当容易,每次用户购买代币时,您都会在上表中创建一行,但也会将其添加到他自己的用户表列tokens中保存的总金额中。

每次用户登录(或您想要的任何其他选择的时间),您都可以检查他们的总令牌,例如165。

现在是2月21日,所以你可以查看他在1月21日之后的所有代币购买情况。我们把这些加起来,我们看到用户只能拥有100+20+40=160的可能数量的有效代币。因此,我们删除了他的5个代币,并向他发送消息,他在1月20日购买的#1001的5个代币已过期。

第二个选项:

当用户使用代币时,只需从最旧的购买中删除代币即可。到期日期到期后,删除整个购买行,有效地删除该购买的剩余代币。

1)这在某种程度上取决于您。我认为代币持续30天和1个月没有太大区别,但在我看来,持续30天更好——我宁愿知道,无论我什么时候购买,我的5美元都是一样的。无论你做什么决定,都要确保清楚地向用户说明。

2) 由于每组令牌可以有不同的"到期"日期,因此必须将这些令牌分别存储在后端数据库中。当用户使用令牌时,递减剩余令牌的数量,直到达到零。

TokenGroupId | UserId | TotalTokens | RemainingTokens | Active | Expires
------------------------------------------------------------------------
6789         | 1234   | 5           | 2               | Mar 1  | Mar 31
6790         | 1235   | 5           | 5               | Mar 13 | Apr 12

我曾经实现过这样一个系统。我用下面的想法解决了问题。

实际上,您不想将用户的代币总数存储在数据库中,而是将每个购买操作与购买的代币数量一起存储。

数据库结构如下所示:

- purchase_id
- user_id
- dollar_amount
- purchase_date
- expiration_date
- purchased_tokens
- remaining_tokens

这里重要的一点是,如果某些代币可能有更重要的持续时间,比如促销操作,那么您可以存储所购买代币的到期日期。

存储的还有已购买代币的总数以及剩余代币的数量。由于我们不存储用户拥有的代币总数,因此我们需要跟踪实际花费了哪些代币,因此我们可以通过对未过期的remaining_tokens求和来计算总数。

要选择消费哪些代币,基本上是始终消费购买的最旧代币,并在获得0个剩余代币后从下一次购买中取出。

最新更新