本篇主要明确配捐系统的概念和具体实现,包括数据结构设计、逻辑关系分析等。前端
什么是配捐?
配捐的概念诞生于1954年,由美国通用基金会创造。截止2016年,通用的总计配捐总额达到3800万美圆。最初只是赞助员工母校的贫困学生,以后逐渐延伸到其余公益领域,也带动了其余企业加入配捐大潮。json
网上释义: 本身找吧;数据结构
个人释义: 配捐是一种公益活动,参与用户的某种公益行为在知足活动合约中设定的捐款条件后,会触发活动的参与企业以用户的名义为项目捐款。简单来讲就是"你出力,我出钱"。异步
常见的配捐有如下几种形式:ui
从业务本质上来讲,配捐实际上属于一种活动,因此在作系统设计时应看成活动来设计。设计
一般「活动」是在后台配置,包括:发布、修改、下线、上线活动。那咱们先大概肯定下「活动」的相关数据结构。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”,"…"}
后台界面上根据活动类型加载活动明细表。
活动期间和活动结束后均不得修改活动内容,若是要修改只能够在活动以前修改。
在具体实现时咱们还须要考虑配捐与用户、活动、分享、订单等系统之间的逻辑关系。既然讲到实现,那咱们就要明确到底要实现什么。
先拿「分享配捐」来讲吧。从产品需求中得知有如下几点:
实现过程当中的问题和解决方案:
其实「2」和「3」的解决方案是同一个。让咱们进一步分析下:
用户参与,参与什么呢?参与活动,什么活动呢?分享捐款活动,在活动中作了什么事呢?分享!
企业参与,参与什么呢?参与和用户一样的活动,什么活动呢?分享捐款活动,在活动中作了什么事呢?捐款,生成捐款订单!
如今,咱们把用户参与活动的事件及流程,抽象在一张“活动事件表”里。
活动事件表「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」 的问题。 这样设计的优势就是从数据结构层作到系统解耦,既不须要修改订单表、分享表和活动表又能够灵活扩展。