There's two popular ways you can approach this.
(您可以通过两种流行的方法来解决这个问题。)
While you provide a number of metrics (orders, ratings, duration, earnings) let's simplify the example to 'points'. (当您提供许多指标(订单,等级,持续时间,收入)时,让我们将示例简化为“点”。)
The first scenario is a formulaic level system, where your concept of points constitutes a threshold and can be calculated on the fly.
(第一种情况是公式级别的系统,您的积分概念构成了一个阈值,可以即时进行计算。)
For example, >10 points is always 'silver'. (例如,> 10分始终是“银色”。)
If you have the ability to lose points in your system then you can duck below silver in this model. (如果您有能力在系统中失去积分,则可以在此模型中躲在白银之下。)
The second is a more event-centric model, where changing over a threshold can change your level, but reverting doesn't reduce your level.
(第二个是更以事件为中心的模型,在该模型中更改阈值可以更改您的级别,但是还原并不会降低您的级别。)
This is much more like a 'season best' score for your points. (对于您的得分,这更像是“赛季最佳”得分。)
My initial thought is that the complexity in your code comes from the calculation of the level, not the storage (so its not necessarily in your model).
(我最初的想法是代码中的复杂性来自于级别的计算,而不是存储(因此在模型中不一定如此)。)
How you model this is heavily dependant on the things that depend on your levels or points.
(如何进行建模在很大程度上取决于取决于您的级别或分数的事物。)
A few probing questions would be: (一些探索性的问题是:)
- Does a level affect things like billing?
(等级会影响帐单吗?)
What about access to services or features? (如何访问服务或功能?)
Knowing this will influence how you hook into Laravel's authorisation code (validators, route access etc). (知道这一点将影响您如何挂接到Laravel的授权代码(验证器,路由访问等)。)
- Does your level formulas fit into the first or second scenario (can people revert backwards a level).
(您的关卡公式是否适合第一种或第二种情况(人们可以向后还原一个关卡)吗?)
This helps you determine if you want to store the level or always calculate it (and maybe cache it...). (这可以帮助您确定是要存储级别还是始终计算级别(并可能对其进行缓存...)。)
- Does your level system decay?
(您的水平系统会衰减吗?)
For your example with user warnings, do those warnings 'decay' over eg a month and are not factored in if they're too old? (对于您的带有用户警告的示例,这些警告是否会在一个月内“衰减”,并且如果它们太旧了,就不会考虑在内?)
This helps you decide on any appropriate caching or filtering for input data to your scoring algorithm. (这可以帮助您决定对计分算法的输入数据进行任何适当的缓存或筛选。)
My initial instinct is to map a 'status' field to your primary entity or model.
(我的本能是将“状态”字段映射到您的主要实体或模型。)
For example your User model might have a level
field. (例如,您的用户模型可能具有一个level
字段。)
Transitions in your level field can then be handled by a state machine (do some further googling) that factors in all your calculations and scoring algorithms. (然后可以由状态机(进行一些进一步的搜索)来处理您级别字段中的转换,该状态机会影响您所有的计算和评分算法。)
Alternatively you could have it as a custom accessor on a model and calculate it on the fly. (或者,您可以将其作为模型上的自定义访问器,并即时进行计算。)
Given my initial instinct, I'd simple have a field that is guarded:
(鉴于我的本能,我将简单地保护一个字段:)
class User {
//...
protected $guarded = ['level'];
// ...
}
A good example of a state transition between 'levels' (as an API) would be to look at Stripe's Billing/Invoices workflows.
(在“级别”(作为API)之间进行状态转换的一个很好的例子是查看Stripe的计费/发票工作流程。)
While it's a very different business domain, it is however a simple API with aa lot of intricacies in the transitions between workflow statuses. (尽管它是一个非常不同的业务领域,但是它是一个简单的API,在工作流状态之间的转换中有很多复杂性。)
You can look to those business rules as examples for inspiration of how you can structure your own code and data structures. (您可以将这些业务规则作为示例,以启发您如何构造自己的代码和数据结构。)
Last up, you probably want to hook into Laravel's event system to trigger 'levelling' events, and ensure that the transition between those levels is only handled by a single set of code (try to avoid calculating levels on the fly across a bunch of controllers - bring it all together in your service).
(最后,您可能想挂入Laravel的事件系统以触发“水平”事件,并确保仅通过一组代码来处理这些水平之间的过渡(尽量避免在多个控制器之间实时计算水平) -将它们整合在一起为您服务)。)
Oh and while you're thinking of schema... do you need to store someone's level history and reasons for 'transitioning' through the levels?
(哦,而您在考虑架构时...您是否需要存储某人的关卡历史记录以及通过这些关卡“过渡”的原因?)
Food for thought =D (思考的食物= D)