diff --git a/src/main/java/com/geekq/miaosha/SnowflakeIdWorker.java b/src/main/java/com/geekq/miaosha/common/SnowflakeIdWorker.java similarity index 94% rename from src/main/java/com/geekq/miaosha/SnowflakeIdWorker.java rename to src/main/java/com/geekq/miaosha/common/SnowflakeIdWorker.java index 779032c..4b46294 100644 --- a/src/main/java/com/geekq/miaosha/SnowflakeIdWorker.java +++ b/src/main/java/com/geekq/miaosha/common/SnowflakeIdWorker.java @@ -1,4 +1,4 @@ -package com.geekq.miaosha; +package com.geekq.miaosha.common; /** * Twitter_Snowflake
* SnowFlake的结构如下(每部分用-分开):
@@ -73,6 +73,17 @@ public class SnowflakeIdWorker { this.datacenterId = datacenterId; } + /** + * 生成订单唯一ID + * @param workerId + * @param datacenterId + * @return + */ + public static long getOrderId(long workerId, long datacenterId){ + SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0); + return idWorker.nextId(); + } + // ==============================Methods========================================== /** * 获得下一个ID (该方法是线程安全的) diff --git a/src/main/java/com/geekq/miaosha/service/rpchander/RpcCompensateService.java b/src/main/java/com/geekq/miaosha/service/rpchander/RpcCompensateService.java new file mode 100644 index 0000000..43fd0ff --- /dev/null +++ b/src/main/java/com/geekq/miaosha/service/rpchander/RpcCompensateService.java @@ -0,0 +1,106 @@ +package com.geekq.miaosha.service.rpchander; + +import com.geekq.miaosha.common.SnowflakeIdWorker; +import com.geekq.miaosha.common.resultbean.ResultGeekQ; +import com.geekq.miaosha.service.rpchander.enums.PlanStepStatus; +import com.geekq.miaosha.service.rpchander.enums.PlanStepType; +import com.geekq.miaosha.service.rpchander.vo.HandlerParam; +import com.geekq.miaosha.service.rpchander.vo.PlanOrder; +import com.geekq.miaosha.service.rpchander.vo.PlanStep; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Service +public class RpcCompensateService { + + + public ResultGeekQ recharge(){ + ResultGeekQ result = ResultGeekQ.build(); + /** + * 各种校验check + */ + + + /** + * 需要可加redis分布式锁 + */ + + /** + * 拦截 + * 校验状态 -- init 或 ROLLING_BACK则 返回 + * + * 成功则返回已处理状态 + */ + + /** + * 生成订单和处理步骤 + */ + + /** + * 获取订单 + */ + long orderId = SnowflakeIdWorker.getOrderId(1,1); + + /** + * 创建订单步骤 可定义一个VO + * 一个planorder 对应多个planstep + * 创建 PlanOrder 创建 planStep + * createOrderStep(vo); + */ + + +// PlanOrder planOrder = new PlanOrder(); +// planOrder.setCreateTime(new Date()); +// planOrder.setVersion(0); +// planOrder.setUserId(inputVo.getUserId()); +// planOrder.setOrderNo(inputVo.getOrderNo()); +// planOrder.setType(PlanOrderType.X_RECHARGE.name()); +// planOrder.setParams(params); +// planOrder.setStatus(PlanOrderStatus.INIT.name()); +// planOrderDao.insertSelective(planOrder); +// +// List steps = new ArrayList<>(); +// //第一步请求民生 +// steps.add(planStepLogic.buildStep(planOrder.getId(), PlanStepType.X_RECHARGE_CMBC, PlanStepStatus.INIT)); +// if (inputVo.getCouponId() != null) { +// //第二步使用优惠券 +// steps.add(planStepLogic.buildStep(planOrder.getId(), PlanStepType.X_RECHARGE_USE_COUPON, PlanStepStatus.INIT)); +// } +// //第三步减扣主账户 +// steps.add(planStepLogic.buildStep(planOrder.getId(), PlanStepType.X_RECHARGE_POINT, PlanStepStatus.INIT)); +// //第四部减扣子账户 +// steps.add(planStepLogic.buildStep(planOrder.getId(), PlanStepType.X_RECHARGE_SUB_POINT, PlanStepStatus.INIT)); +// //第五步发送通知 +// steps.add(planStepLogic.buildStep(planOrder.getId(), PlanStepType.X_RECHARGE_NOTIFY, PlanStepStatus.INIT)); +// +// planStepDao.batchInsert(steps); + + /** + * + * 调用Rpc接口 第几步错误则回滚前几步 + * 并更新step状态 + * + * 然后定时任务去处理 状态为INIT与ROLLBACK的 状态订单 + * + * + */ +// HandlerParam handlerParam = new HandlerParam(); +// handlerParam.setPlanOrder(planOrder); +// AutoInvestPlanRechargeOrderInputVo inputVo = JsonUtil.jsonToBean(planOrder.getParams(), AutoInvestPlanRechargeOrderInputVo.class); +// handlerParam.setInputVo(inputVo); +// for (int i = 0; i < planStepList.size(); i++) { +// PlanStep planStep = planStepList.get(i); +// PlanStepType stepType = PlanStepType.valueOf(planStep.getType()); +// xxx handler = (xxx) xxxx.getApplicationContext().getBean(stepType.getHandler()); +// boolean handlerResult = handler.handle(handlerParam); +// if (!handlerResult) { +// break; +// } +// } + return result; + } + +} \ No newline at end of file diff --git a/src/main/java/com/geekq/miaosha/service/rpchander/RpcHandler.java b/src/main/java/com/geekq/miaosha/service/rpchander/RpcHandler.java new file mode 100644 index 0000000..9c94d31 --- /dev/null +++ b/src/main/java/com/geekq/miaosha/service/rpchander/RpcHandler.java @@ -0,0 +1,10 @@ +package com.geekq.miaosha.service.rpchander; + +public interface RpcHandler { + + int RETRY_COUNT = 5 ; + + boolean handele(); + + boolean rollBack(); +} diff --git a/src/main/java/com/geekq/miaosha/service/rpchander/enums/PlanStepStatus.java b/src/main/java/com/geekq/miaosha/service/rpchander/enums/PlanStepStatus.java new file mode 100644 index 0000000..7c5686e --- /dev/null +++ b/src/main/java/com/geekq/miaosha/service/rpchander/enums/PlanStepStatus.java @@ -0,0 +1,11 @@ +package com.geekq.miaosha.service.rpchander.enums; + +public enum PlanStepStatus { + + INIT, //未处理 + PROCESSING,//处理中 + SUCCESS, //成功 + FAIL, //失败 + ROLLED_BACK, //已回滚 + +} diff --git a/src/main/java/com/geekq/miaosha/service/rpchander/enums/PlanStepType.java b/src/main/java/com/geekq/miaosha/service/rpchander/enums/PlanStepType.java new file mode 100644 index 0000000..0a2c1a2 --- /dev/null +++ b/src/main/java/com/geekq/miaosha/service/rpchander/enums/PlanStepType.java @@ -0,0 +1,43 @@ +package com.geekq.miaosha.service.rpchander.enums; + +public enum PlanStepType { + + U_CMBC(10, "protocolHandler"), + U_UPDATE_REDIS_AMOUNT(20, "redisAmountHandler"), + U_USE_COUPON(30, "couponHandler"), + U_USE_SCORE(40, "scoreHandler"), + U_USE_UCODE(50, "uCodeHandler"), + U_POINT(60, "pointHandler"), + U_SUB_POINT(70, "subPointHandler"), + U_NOTIFY(80, "notifyHandler"), + + X_RECHARGE_CMBC(10, "rechargeCmbcHandler"), + X_RECHARGE_USE_COUPON(20, "rechargeCouponHandler"), + X_RECHARGE_POINT(30, "rechargePointHandler"), + X_RECHARGE_SUB_POINT(40, "rechargeSubPointHandler"), + X_RECHARGE_NOTIFY(50, "rechargeNotifyHandler"); + + private int priority; + private String handler; + + public String getHandler() { + return handler; + } + + public void setHandler(String handler) { + this.handler = handler; + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } + + PlanStepType(int priority, String handler) { + this.priority = priority; + this.handler = handler; + } +} diff --git a/src/main/java/com/geekq/miaosha/service/rpchander/vo/HandlerParam.java b/src/main/java/com/geekq/miaosha/service/rpchander/vo/HandlerParam.java new file mode 100644 index 0000000..ea802c0 --- /dev/null +++ b/src/main/java/com/geekq/miaosha/service/rpchander/vo/HandlerParam.java @@ -0,0 +1,9 @@ +package com.geekq.miaosha.service.rpchander.vo; + +public class HandlerParam { + + private int realCount; + private PlanOrder planOrder; + private PlanStep planStep; + +} diff --git a/src/main/java/com/geekq/miaosha/service/rpchander/vo/PlanOrder.java b/src/main/java/com/geekq/miaosha/service/rpchander/vo/PlanOrder.java new file mode 100644 index 0000000..be77fab --- /dev/null +++ b/src/main/java/com/geekq/miaosha/service/rpchander/vo/PlanOrder.java @@ -0,0 +1,125 @@ +package com.geekq.miaosha.service.rpchander.vo; + +import java.util.Date; + +public class PlanOrder { + private Long id; + + private Date createTime; + + private Date updateTime; + + private Integer version; + + private Integer userId; + + private String orderNo; + + private Integer orderId; + + private Integer accountId; + + private String type; + + private String cmbcStatus; + + private String params; + + private String status; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public String getOrderNo() { + return orderNo; + } + + public void setOrderNo(String orderNo) { + this.orderNo = orderNo; + } + + public Integer getOrderId() { + return orderId; + } + + public void setOrderId(Integer orderId) { + this.orderId = orderId; + } + + public Integer getAccountId() { + return accountId; + } + + public void setAccountId(Integer accountId) { + this.accountId = accountId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCmbcStatus() { + return cmbcStatus; + } + + public void setCmbcStatus(String cmbcStatus) { + this.cmbcStatus = cmbcStatus; + } + + public String getParams() { + return params; + } + + public void setParams(String params) { + this.params = params; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} \ No newline at end of file diff --git a/src/main/java/com/geekq/miaosha/service/rpchander/vo/PlanStep.java b/src/main/java/com/geekq/miaosha/service/rpchander/vo/PlanStep.java new file mode 100644 index 0000000..80d2cba --- /dev/null +++ b/src/main/java/com/geekq/miaosha/service/rpchander/vo/PlanStep.java @@ -0,0 +1,105 @@ +package com.geekq.miaosha.service.rpchander.vo; + +import java.util.Date; + +public class PlanStep { + private Long id; + + private Date createTime; + + private Date updateTime; + + private Integer version; + + private Long orderId; + + private String status; + + private String type; + + private Integer priority; + + private Integer retryCount; + + private String remark; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public Long getOrderId() { + return orderId; + } + + public void setOrderId(Long orderId) { + this.orderId = orderId; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status == null ? null : status.trim(); + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type == null ? null : type.trim(); + } + + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + + public Integer getRetryCount() { + return retryCount; + } + + public void setRetryCount(Integer retryCount) { + this.retryCount = retryCount; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark == null ? null : remark.trim(); + } +} \ No newline at end of file