如何处理复杂的用户状态?

时间:2015-12-31 02:16:01

标签: php mysql database oop conceptual

我的应用程序处理用户付款。在该公司中,该用户具有以下状态:

  • 合规(用户到目前为止支付所有债务)
  • 逾期/违约(用户注册最少3个月且至少没有支付1笔债务)
  • 不活跃(用户注册时间少于3个月且未支付任何债务)

在应用程序内的多个位置(和规则)中处理这些规则的最佳方法是什么?

我是否需要像status_id和cron这样的字段每小时更新一次?

status_id字段并在每个需要显示状态的查询中编写SQL规则?

加载User模型并调用具有该规则的->status()方法?在这种情况下,我如何显示"总计",如:我们有3000个逾期用户,15000个非活动用户等...

这让我头疼了几个月,我真的需要帮助哈哈。我们目前有一个解决方案,但处理它太复杂了。由于它似乎是处理付款的应用程序中的常见问题,因此必须采用更简单的方法:P

谢谢!

备注

  • 应用程序目前有90.000个用户
  • 我们需要实时提供此信息。
  • 此信息用于报告中以生成字符。
  • 此信息显示在用户个人资料中。
  • 此信息显示在列表中。
  • 当用户在这些状态之间切换时会通知用户(例如,"您有债务"当用户输入"逾期")。
  • 此信息不是由应用程序用户管理。
  • 需要跟踪状态。

3 个答案:

答案 0 :(得分:3)

如果您在多个地方使用此字段,则应将状态存储在一个位置并根据需要进行更新(我还会保留状态的历史记录,但这是另一回事。)

如果状态因某些用户操作(例如正在处理付款)而发生更改,则您可以对操作使用触发器。但是,您的状态更改似乎是基于事件发生后的时间。在这种情况下,您应该运行定期计划的作业(作为cron作业或数据库事件)。

我对你为什么每小时都这样做感到有点困惑。似乎每天一次是最合适的。如果"债务"在任意时间支付,然后支付过程应更新状态。对于降级状态,每天一次工作就足够了。

答案 1 :(得分:1)

有趣的问题,但也没有一个单一的答案。

我认为这里的复杂性可能来自周围的代码,而不是核心业务逻辑和需求。我这样说是因为三种状态类型都是坏的,所有这些类型都来自你的内部应用程序。

一种可能的解决方案,我假设某种程度的MVC或类似。

鉴于你的模型use Illuminate\Database\Eloquent\Model; use App\DebtCollector; public class User extends Model { // Assuming model has the following fields // id, status, registration_date, and a one to many // relationship with debts protected $fillable = [ 'raw_status', 'registration_date', ]; public function debts() { return $this->hasMany(Debt::class); } public function refreshStatus() { $dc = new DebtCollector(); // Business logic inside the "DebtCollector" class $this->raw_status = $dc->resolveStatus($this->debts, $this->registration_date); // Save value to the underlying datebase $this->save(); } // If you fetch a status directly, it will refresh first, // then return the value // public function getStatusAttribute() { $this->refreshStatus(); return $this->raw_status; } } // Schedule task somewhere - ran nightly, or whenever // // This way you can refresh the status only on certain groups // of data - for example, if the business flow means that once // they become compliant, they can't go back, there is no need // to refresh their status anymore // User::where('raw_status', '<>', 'compliant')->refreshStatus(); // Alternatively, the schedule could chunk results and do an update // only to those not updated in the last 24 hours // $date = new DateTime; $date->modify('-24 hours'); $formatted_date = $date->format('Y-m-d H:i:s'); User::where('last_updated', '>', $formatted_data)->refreshStatus(); ,并扩展一个像Eloquent这样的ORM(我会从Laravel中说服我,因为我最熟悉它,但任何ORM都可以工作):

<div class="row small-up-1 medium-up-2 large-up-4">
  <div class="column">
    <img src="//placehold.it/300x300" class="thumbnail" alt="">
  </div>
  <div class="column">
    <img src="//placehold.it/300x300" class="thumbnail" alt="">
  </div>
  <div class="column">
    <img src="//placehold.it/300x300" class="thumbnail" alt="">
  </div>
  <div class="column">
    <img src="//placehold.it/300x300" class="thumbnail" alt="">
  </div>
  <div class="column">
    <img src="//placehold.it/300x300" class="thumbnail" alt="">
  </div>
  <div class="column">
    <img src="//placehold.it/300x300" class="thumbnail" alt="">
  </div>
</div>

答案 2 :(得分:1)

我想说这个问题有多种解决方案。

我建议没有任何明确的状态。从我所看到的,你可以随时&#34;弄清楚&#34;基于其他一些数据的当前状态。 例如&#34;用户迄今已支付所有债务&#34;。通过分析给定时期的所有变化,您只需知道这一点。您可以汇总数据以找出您需要知道的所有内容。那么你根本不需要保存状态。它只是源自客户在特定时期内发生的所有变更。

同样是总计。您可以在数据库级别上轻松完成此操作,甚至可以使用某些基于文档的DB或ElasticSearch。

当然,这假设您跟踪更改的历史记录。如果你这样做 - 问题解决了。如果您不这样做 - 您必须将状态保存到数据库中,并且无法获取历史数据。