## 预定
预定是平台为用户提供的一种低成本专利资源短期占有服务。
*****
### 预定方式
1. 买家自己预定
2. 销售帮用户 **预定 / 续订**
#### 1. 买家自己预定
1. 买家点击预定按钮,选择 天数 , 单价(元/天) ,单价由用户的会员等级确定
2. 选择天数后,确认支付金额,点击提交,此专利商品被**预锁定**,状态变为不可售,在卖家中心显示为 **抢订中(未支付)**
3. 支付成功后,即预定成功(预定有效期限计时 从收到付款回调,预定/续订成功后开始)
4. 预定成功后,此专利商品被**正式锁定**,状态为不可售,在卖家中心显示为 **已被预定**
5. 用户在 用户中心 - 预定管理 可以看到此预定记录
6. 预锁定时间为5分钟,超时未支付,预定被系统自动取消释放
7. 普通用户每天最多只能创建5个“预锁定”预定,以此来限制用户恶意抢订
#### 2. 销售帮用户预定
1. 销售点击预定,选择天数,输入用户手机号码(若手机号码存在则自动关联用户,不存在则提示,不存在也可帮其预定)
2. 选择天数后,确认支付金额,点击提交,此专利商品被**预锁定**,状态变为不可售,在卖家中心显示为 **抢订中(未支付)**
3. 支付成功后,即预定成功(预定有效期限计时 从收到付款回调,预定/续订成功后开始)
4. 预定成功后,此专利商品被**正式锁定**,状态为不可售,在卖家中心显示为 **已被预定**
5. 销售在 销售中心 - 预定管理 可以看到此预定记录
6. 预锁定时间为5分钟,超时未支付,预定被系统自动取消释放
7. 销售每天最多只能创建10个“预锁定”预定,以此来限制用户恶意抢订
> 对于预锁定的预定,可以在页面某个位置给用户以倒计时提示,告诉用户别人还未支付,你还有机会预定!营造一种紧迫感,按时用户机会稍纵即逝!
*****
### 预定状态变更及说明
| 状态 | 状态变更及说明 |
| --- | --- |
| 预锁定 | 用户提交预定,还未支付时,专利商品被锁定,不能被预定、购买了,此时卖家也不能更新这件专利商品的信息,在卖家中心 状态显示为 **抢订中(未支付)** |
| 被释放 | 预锁定的预定记录,超时未支付,会被系统自动释放,专利商品自动解锁,恢复正常,此预定生命周期结束,此预定记录关闭,用户还可以再次进行预定 |
| 预定成功 | 专利商品被锁定,不能被预定、购买了,此时卖家也不能更新这件专利商品的信息,在卖家中心 状态显示为 **已被预定** |
| 预定到期 | 预定按天数计算,到期后,专利商品自动解锁,恢复正常,此预定生命周期结束,此预定记录关闭,用户还可以再次进行预定 |
| 续订 | 在预定未到期的情况下(预定有效期内)可以对其进行续订,续订直接顺延到期时长,操作和首次预定时基本相同 |
| 取消预定 | 用户主动取消预定,专利商品立即自动解锁,恢复正常,用户还可以再次进行预定 |
| 已创建订单 | 此预定已创建订单(预定有效期内创建订单),和订单进行关联(记录扣减金额) |
| 已完成订单 | 关联订单已完成,此预定生命周期结束 |
*****
#### 预定功能其他说明
**预定规则:** 同一件专利商品,每位用户最多只能预定三次(包含续订),每次预定/续订不超过三天,即用户最多可以预定一件专利9天,**销售帮其预定/续订也算在内**。
**什么是有效预定金额:**
在预定的有效期内下单,可以扣减此预定的支付金额,因未续订而导致过期,则判定预定失效,预定过的金额也无效了,不会计入扣减。也就是说,如果用户未在预定有效期内下单,就会损失之前支付过的全部预定金额。还有一种情况,比如今天预定过期了,第二天又再次预定了,那么有效金额从这次预定开始算,之前的就算全部作废了。
**下单时抵扣:**
预定费可用于下单时抵扣,但是具体的抵扣规则呢,如果销售和用户共同参与预定/续订了呢?
分两种情况:
1. 全程用户自己参与预定和续订,都是自己交预定费用的。这种情况,用户下单时抵扣自己有效预定的金额。
2. 用户和销售都参与预定和续订了,这种情况下单时只抵扣用户自己支付过的有效预定的那部分金额。
**如果帮其预定的用户还不存在怎么办?**
首先如果存在的话,直接关联用户。不存在的话,根据预定时填写的用户手机号写一条记录,待用户他日登陆/注册之时,自动同步回之前的预定信息即可。
*****
### 重要概念
**一个用户只能对同一件专利商品预定一次,其他操作为续订,预定到期和主动取消预定除外,预定到期和用户主动取消预定后还可以再次进行预定。**
**一个销售对一件专利商品,只能同时为一个用户预定,不能同时为多个用户预定同一件专利。只有当为某个用户预定的专利到期或取消后,再才可以为其他用户预定此件专利商品。**
**对于销售帮用户创建的预定,销售和用户都可以对其进行续订,由用户自己创建的预定,销售不能参与续订,但在销售中心看得到用户的预定记录。**
**销售预定/续订所支付的费用不计入下单扣减部分,只有用户自己支付的部分才计入扣减部分。**
**预定/续订价格如果是销售进行操作的话,哪怕是帮用户操作,价格也都是统一的(10元一次)。如果是用户自己进行的操作,则根据用户的会员体系计算。**
*****
#### 用户中心(买家) - 预定管理
- 预定列表
- 续订
- 取消预定
- 预定详情
- 预定记录
- 预定支付记录
*****
#### 销售中心 - 预定管理
- 预定列表
- 续订
- 取消预定
- 预定详情
- 预定记录
- 预定支付记录
- 用户信息
*****
#### 数据字典
```sql
# 订单表增加 预定ID 和 预定抵扣金额 字段
ALTER TABLE `ecshop2016`.ecs_order_info add (
`reservation_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '预定ID, s_patent_reservation table id (如果预定有效期内购买了这件专利商品,则订单记录关联其预定ID)',
`reservation_deduction_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '预定抵扣金额'
);
# 专利预定 表
DROP TABLE IF EXISTS `s_patent_reservation`;
CREATE TABLE `s_patent_reservation` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`goods_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '专利商品ID, ecs_goods table goods_id',
`order_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '订单ID, ecs_order_info table order_id (如果预定有效期内创建了订单则关联创建的订单ID)',
`user_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建预定的用户ID, ecs_users table user_id, 销售或用户',
`target_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '目标用户id, ecs_users table user_id,如果是销售帮其预定的,那么这个字段就是用户ID,否则为0',
`mobile` char(15) NULL DEFAULT '' COMMENT '手机号码,销售帮其预定时, 如果用户不存在,则记录这个手机号码为约定凭证,待用户他日登陆之时再同步过去(在这条记录 的 target_id 上更新上 user_id 即可)',
`user_total_pay` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '用户累计已支付金额(用户为这笔预定总共成功支付了的金额,也是 达成订单时的有效抵扣金额)',
`sale_total_pay` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '销售累计已支付金额(不参与下单抵扣)',
`reservation_count` tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT '预定/续订次数(已成功预定/续订次数)',
`expires_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '预定到期时间',
`start_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '预定到期时间的起(有效期限计 从首次预定收到付款回调,预定成功后开始)',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '更新时间',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态:0-创建预定,待支付,1-预定生效中,2-预定已到期,3-已取消预定,4-已创建订单,5-已完成订单',
primary key (`id`)
) engine=innodb AUTO_INCREMENT=1 default charset=utf8 COMMENT='专利预定 表';
# 专利预定订单/记录 表
DROP TABLE IF EXISTS `s_patent_reservation_order`;
CREATE TABLE `s_patent_reservation_order` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`reservation_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '所属预定ID, s_patent_reservation table id',
`goods_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '所属预定的专利商品ID, ecs_goods table goods_id',
`user_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '生成预定订单的用户ID, ecs_users table user_id, 销售或用户',
`user_role` tinyint(4) unsigned NOT NULL DEFAULT 1 COMMENT '生成预定订单的用户角色:1-普通用户,2-销售',
`order_sn` char(50) NULL DEFAULT NULL COMMENT '预定订单编号',
`amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '支付金额',
`data_json` text NULL COMMENT '订单数据json,如单价,级别价格等信息',
`buy_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '购买时长(秒)',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '更新时间',
`pay_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '支付时间,支付成功即预定成功,所以也是预定时间',
`type` tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT '类型:0-“首次”预定,1-续订',
`pay_status` tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT '支付状态:0-未支付,1-已支付',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态:0-生成预定订单,待支付,1-已完成(收到付款回调,时长更新到 已预定表中),2-已取消',
primary key (`id`),
UNIQUE KEY `order_sn` (`order_sn`) USING BTREE
) engine=innodb AUTO_INCREMENT=1 default charset=utf8 COMMENT='专利预定订单/记录 表';
-- 每次点击预定都会生成一条订单,用于支付,但是对用户默认只显示完成支付的记录行(支付订单表,类似于支付流水表)
-- 如有退款的话,订单不会不会(再次)更新状态
# 专利预定订单支付 记录/日志 表
DROP TABLE IF EXISTS `s_patent_reservation_order_pay_record`;
CREATE TABLE `s_patent_reservation_order_pay_record` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`order_sn` char(50) NULL DEFAULT NULL COMMENT '预定订单编号, s_patent_reservation_order table order_sn',
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '记录标题:正常/重复支付-需退款/多方重复支付-需退款/...',
`pay_platform` char(20) NULL DEFAULT '' COMMENT '支付平台标识:alipay/wxpay...',
`return_json` text NULL COMMENT '第三方支付平台支付回调回执所返回数据,json格式保存',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`refund_status` tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT '退款处理状态:0-无,1-申请退款(处理中),2-退款失败,3-完成退款',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态:0-正常,1-重复支付(需向用户退款),2-已完成',
primary key (`id`)
) engine=innodb AUTO_INCREMENT=1 default charset=utf8 COMMENT='专利预定订单支付 记录/日志 表';
-- 这个支付日志记录表是关联 预定订单表的,如果需要和12306一样,每次点击订单支付【都用不同的数据(订单编号)】去请求支付接口返回支付信息(第三方的支付连接或二维码)的话,
-- 还需要在中间增加一张与订单表对应的表,因为第三方是根据你传入的订单编号来生成支付信息,如果你传入上次的订单编号,第三方也会返回和上次相同的支付信息
-- 不过我们不考虑12306那种情况,因为12306需要快速支付出票,不能出现好友认领支付二维码后,没有支付,又再不能生成新的支付二维码,导致也不能使用自己的支付宝扫码付款而只能重新下单,我们暂不考虑这样的情况
-- 不同第三方平台策略可能不同,我们实现一个通用的,考虑所有情况,能满足全部使用环境,而不能只为特定平台考虑,任何依赖于外部环境的系统都是不安全不健壮的。
# 预定订单退款记录表
DROP TABLE IF EXISTS `s_patent_reservation_order_refund`;
CREATE TABLE `s_patent_reservation_order_refund` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`pay_record_id` char(50) NULL DEFAULT NULL COMMENT '对应的专利预定订单支付记录ID, s_patent_reservation_order_pay_record table id',
`order_sn` char(50) NULL DEFAULT NULL COMMENT '预定订单编号, s_patent_reservation_order table order_sn',
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '退款标题:多方重复支付退款/重复支付退款/预定失败退款/续订失败退款...',
`content` text NULL COMMENT '退款说明',
`amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '退款金额',
`pay_platform` char(20) NULL DEFAULT '' COMMENT '如使用在线支付渠道退款时,支付平台标识:alipay/wxpay...',
`return_json` text NULL COMMENT '如使用在线支付渠道退款时,第三方支付平台支付回调回执所返回数据,json格式保存',
`type` tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT '退款方式:0-无,1-线下渠道退款,2-在线支付渠道退款(原支付通道返回),3-其他',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '退款处理状态:0-创建退款,1-退款处理中,2-退款失败,3-完成退款',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
primary key (`id`)
) engine=innodb AUTO_INCREMENT=1 default charset=utf8 COMMENT='专利预定订单退款 记录/日志 表';
# 专利预定记录/日志 表
DROP TABLE IF EXISTS `s_patent_reservation_record`;
CREATE TABLE `s_patent_reservation_record` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`reservation_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '所属预定ID, s_patent_reservation table id',
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '日志标题:创建预定-待支付/支付成功/预定成功/预定过期/续订成功/...',
`content` text NULL COMMENT '日志内容',
`payload` text NULL COMMENT '载荷/参数,可携带业务方数据,如 操作类型,涉及金额等等,在日志模板中会用到',
`type` tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT '日志类型:见日志类',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
primary key (`id`)
) engine=innodb AUTO_INCREMENT=1 default charset=utf8 COMMENT='专利预定记录/日志 表';
-- 记录预定的操作日志,让每次操作和变更都有日志记录(需要注意的是:对于业务来说日志并不重要,任何的业务逻辑都不能依赖于日志,日志只是方便用户查看信息,有一个历史记录的作用)
```