配捐系统模型设计

本篇主要明确配捐系统的概念和具体实现,包括数据结构设计、逻辑关系分析等。前端

什么是配捐?
配捐的概念诞生于1954年,由美国通用基金会创造。截止2016年,通用的总计配捐总额达到3800万美圆。最初只是赞助员工母校的贫困学生,以后逐渐延伸到其余公益领域,也带动了其余企业加入配捐大潮。json

网上释义: 本身找吧;数据结构

个人释义: 配捐是一种公益活动,参与用户的某种公益行为在知足活动合约中设定的捐款条件后,会触发活动的参与企业以用户的名义为项目捐款。简单来讲就是"你出力,我出钱"。异步

常见的配捐有如下几种形式:ui

  1. 分享配捐:用户分享成功一次,公益企业捐出必定数量的$。
  2. 捐款配捐:用户捐款多少,公益企业就按必定比例捐出多少。

从业务本质上来讲,配捐实际上属于一种活动,因此在作系统设计时应看成活动来设计。设计

数据模型设计

一般「活动」是在后台配置,包括:发布、修改、下线、上线活动。那咱们先大概肯定下「活动」的相关数据结构。code

配捐活动的主要结构以下:对象

活动类型表「activity_type」事件

id: {type: 'integer', primaryKey: true, autoIncrement:true} //活动类型ID
activityType: {type: 'string', required: true} //活动类型:分享配捐|捐款配捐|…
createdAt:{type: 'timestamp', required: true}
活动类型不可删除;

活动表「activity」图片

id: {type: 'integer', primaryKey: true, autoIncrement:true} //活动ID
activityTypeID: {type: ‘integer', required: true} //活动类型ID:
activityName: {type: ‘integer', required: ture} //活动名称, 如:分享配捐第一期
activityImages: {type: ‘text', required: false} //活动图片/封面
startTime: {type: ‘timestamp', required: ture} //活动起始时间
endTime: {type: ‘timestamp', required: ture} //活动结束时间
createdAt: {type: 'timestamp', required: true} //活动建立时间
updatedAt: {type: 'timestamp', required: true} //活动修改时间
remark: {type: ‘text', required: false} //活动规则备注
state: {type: ‘integer', required: true} //活动状态

配捐活动明细表「Activity_matching_gift」

id: {type: 'integer', primaryKey: true, autoIncrement:false} //活动ID
donationAmount: {type: 'decimal(11,2)', required: true} //配捐金额
donationProportion: {type: 'string', required: true} //配捐比例
Donors: {type: 'string', required: true} //配捐参与企业, json字符串 {“charity1”,”charity2”,”charity3”,"…"}
后台界面上根据活动类型加载活动明细表。
活动期间和活动结束后均不得修改活动内容,若是要修改只能够在活动以前修改。

在具体实现时咱们还须要考虑配捐与用户、活动、分享、订单等系统之间的逻辑关系。既然讲到实现,那咱们就要明确到底要实现什么。

先拿「分享配捐」来讲吧。从产品需求中得知有如下几点:

  • 用户登陆&分享成功后,触发企业捐款;可是在捐款列表中显示的是分享用户的相关信息。因为参与的第三方企业不能作到实时捐款,因此会在捐款列表中标记XX机构将会配捐多少。
  • 一个用户一天以内能够分享屡次,可是企业一天只配捐一次,无论该用户分享了多少次。

实现过程当中的问题和解决方案:

  1. 捐款列表是已支付的订单。用户分享后要在捐款列表中马上显示分享用户的信息,而用户只是分享并无实际捐款,如何解决这个问题?
    解决方案是为该用户建立一个订单金额为0的订单,即空订单。
  2. 第三方企业不能作到实时捐款,那么就要求订单和待配捐的任务必需要有一个关联,以便系统能够异步定时处理这些配捐任务。那么用户-活动-分享-订单之间到底如何创建关系合适呢?是否能够根据分享订单查询企业是否真实捐款了呢?
  3. 前端捐款列表页面如何作到对于不一样的捐款活动展现不一样的样式风格呢?

其实「2」和「3」的解决方案是同一个。让咱们进一步分析下:

  • [x] 用户-参与-活动-分享

用户参与,参与什么呢?参与活动,什么活动呢?分享捐款活动,在活动中作了什么事呢?分享!

  • [x] 企业-参与-活动-捐款-订单

企业参与,参与什么呢?参与和用户一样的活动,什么活动呢?分享捐款活动,在活动中作了什么事呢?捐款,生成捐款订单!

如今,咱们把用户参与活动的事件及流程,抽象在一张“活动事件表”里。

活动事件表「Activity_event」

id: {type: 'integer', primaryKey: true, autoIncrement:true} 
userID: {type: 'string', required: true} //用户ID
activityID: {type: 'integer', required: true} //活动ID
activityTypeID: {type: 'integer', required: true} //活动类型ID
userEventID: {type: 'integer', required: true} //用户事件ID,这个事件多是分享也多是别的,因活动类型而定;用户分享ID|... 
remark: {type: 'string', required: false} //备注
createdAt:{type: 'timestamp', required: true}
state: {type: 'integer', required: true} //活动事件状态,未完成|已完成
「活动事件表」里即记录了活动关系,也记录了待处理的异步任务。

后期与配捐的企业结算也须要这张表。

活动事件订单表「Activity_event_order」

id: {type: 'integer', primaryKey: true, autoIncrement:true} 
eventID: {type: 'integer', primaryKey: true, autoIncrement:true} //活动事件表ID
orderID: {type: 'string', required: true} // 订单ID,若是是分享事件,那么这里多是用户分享后生成的空订单ID,也多是企业配捐的订单ID
remark: {type: 'string', required: false} //备注,好比能够标注订单的性质,share|matchingGift
createdAt:{type: 'timestamp', required: true}
为何须要「活动事件订单表」呢?由于不一样类型活动的事件,或同一种事件,今天多是对订单有影响,明天多是对积分有影响。因此必须把具体被影响的对象抽象出来。

「活动事件订单表」表示这个“事件”是对订单有影响,记录的是事件和订单的关系。

若是一个分享订单对应有两个企业配捐,那么这个表一个产生3条记录。一个用户分享的空订单ID,两个企业捐款的订单ID,三个都对应同一个事件ID。

最后 「订单表」 关联 「活动事件订单表」 和 「活动事件表」 就能够解决上面 「2」和「3」 的问题。 这样设计的优势就是从数据结构层作到系统解耦,既不须要修改订单表、分享表和活动表又能够灵活扩展。
相关文章
相关标签/搜索