chengpeng 5 سال پیش
والد
کامیت
c0b5562df2

+ 10 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysUserCashAccountDao.java

@@ -2,8 +2,17 @@ package com.ym.mec.biz.dal.dao;
 
 import com.ym.mec.biz.dal.entity.SysUserCashAccount;
 import com.ym.mec.common.dal.BaseDAO;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
 
 public interface SysUserCashAccountDao extends BaseDAO<Integer, SysUserCashAccount> {
 
-	
+    /**
+     * 账户余额加
+     * @param userId
+     * @param amount
+     * @return
+     */
+    int incrAccount(@Param("userId") Integer userId, @Param("amount") BigDecimal amount);
 }

+ 52 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/RechargeDto.java

@@ -0,0 +1,52 @@
+package com.ym.mec.biz.dal.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+
+public class RechargeDto {
+
+    @ApiModelProperty(value = "充值金额",required = false)
+    private BigDecimal rechargeAmount;
+
+    @ApiModelProperty(value = "用户id",required = false)
+    private Integer userId;
+
+    @ApiModelProperty(value = "银行卡",required = false)
+    private String  bankNo;
+
+    @ApiModelProperty(value = "银行名",required = false)
+    private String bankName;
+
+    public BigDecimal getRechargeAmount() {
+        return rechargeAmount;
+    }
+
+    public void setRechargeAmount(BigDecimal rechargeAmount) {
+        this.rechargeAmount = rechargeAmount;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getBankNo() {
+        return bankNo;
+    }
+
+    public void setBankNo(String bankNo) {
+        this.bankNo = bankNo;
+    }
+
+    public String getBankName() {
+        return bankName;
+    }
+
+    public void setBankName(String bankName) {
+        this.bankName = bankName;
+    }
+}

+ 6 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/StudentRechargeService.java

@@ -1,8 +1,14 @@
 package com.ym.mec.biz.service;
 
+import com.ym.mec.biz.dal.dto.RechargeDto;
 import com.ym.mec.biz.dal.entity.StudentRecharge;
 import com.ym.mec.common.service.BaseService;
 
 public interface StudentRechargeService extends BaseService<String, StudentRecharge> {
 
+    /**
+     * 账户充值
+     * @param rechargeDto
+     */
+    Boolean recharge(RechargeDto rechargeDto);
 }

+ 43 - 6
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentRechargeServiceImpl.java

@@ -1,23 +1,60 @@
 package com.ym.mec.biz.service.impl;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 import com.ym.mec.biz.dal.dao.StudentRechargeDao;
+import com.ym.mec.biz.dal.dao.SysUserCashAccountDao;
+import com.ym.mec.biz.dal.dao.SysUserCashAccountDetailDao;
+import com.ym.mec.biz.dal.dto.RechargeDto;
 import com.ym.mec.biz.dal.entity.StudentRecharge;
+import com.ym.mec.biz.dal.entity.SysUserCashAccountDetail;
+import com.ym.mec.biz.dal.enums.PlatformCashAccountDetailTypeEnum;
 import com.ym.mec.biz.service.StudentRechargeService;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
 
 @Service
 public class StudentRechargeServiceImpl extends BaseServiceImpl<String, StudentRecharge>  implements StudentRechargeService {
 	
-	@Autowired
+	@Resource
 	private StudentRechargeDao studentRechargeDao;
 
+	@Resource
+	private SysUserCashAccountDao sysUserCashAccountDao;
+
+	@Resource
+	private SysUserCashAccountDetailDao sysUserCashAccountDetailDao;
 	@Override
 	public BaseDAO<String, StudentRecharge> getDAO() {
 		return studentRechargeDao;
 	}
-	
+
+	@Override
+	public Boolean recharge(RechargeDto rechargeDto) {
+
+		//TODO 调用第三方充值接口
+		Date now  = new Date();
+
+		//生成充值记录
+        StudentRecharge studentRecharge = new StudentRecharge();
+        studentRecharge.setAmount(rechargeDto.getRechargeAmount());
+		studentRecharge.setCreateTime(now);
+		studentRecharge.setUserId(rechargeDto.getUserId().longValue());
+		studentRecharge.setTransNo(null);
+		studentRechargeDao.insert(studentRecharge);
+		//账户金额
+		SysUserCashAccountDetail cashAccount = new SysUserCashAccountDetail();
+		cashAccount.setAmount(rechargeDto.getRechargeAmount());
+		cashAccount.setBalance(null);
+		cashAccount.setTransNo(null);
+		cashAccount.setType(PlatformCashAccountDetailTypeEnum.RECHARGE);
+		cashAccount.setUserId(rechargeDto.getUserId());
+		cashAccount.setCreateTime(now);
+		sysUserCashAccountDetailDao.insert(cashAccount);
+		//更新账户余额
+		sysUserCashAccountDao.incrAccount(rechargeDto.getUserId(),rechargeDto.getRechargeAmount());
+
+		return true;
+	}
 }

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysUserCashAccountServiceImpl.java

@@ -19,5 +19,5 @@ public class SysUserCashAccountServiceImpl extends BaseServiceImpl<Integer, SysU
 	public BaseDAO<Integer, SysUserCashAccount> getDAO() {
 		return sysUserCashAccountDao;
 	}
-	
+
 }

+ 4 - 0
mec-biz/src/main/resources/config/mybatis/SysUserCashAccountMapper.xml

@@ -84,4 +84,8 @@
     <select id="queryCount" resultType="int">
 		SELECT COUNT(*) FROM sys_user_cash_account
 	</select>
+
+    <update id="incrAccount">
+        update sys_user_cash_account set balance_ = balance_ + #{amount} where  user_id_ = #{userId}
+    </update>
 </mapper>

+ 55 - 0
mec-student/src/main/java/com/ym/mec/student/controller/RechargeController.java

@@ -0,0 +1,55 @@
+package com.ym.mec.student.controller;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dto.RechargeDto;
+import com.ym.mec.biz.dal.entity.SysUserCashAccount;
+import com.ym.mec.biz.service.StudentRechargeService;
+import com.ym.mec.biz.service.SysUserCashAccountService;
+import com.ym.mec.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * @version V1.0
+ * @Description: 充值
+ * @date Date : 2019年09月23日 16:56
+ */
+
+@RequestMapping("recharge")
+@Api(tags = "账户充值")
+@RestController
+public class RechargeController extends BaseController {
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private StudentRechargeService rechargeService;
+
+    @Autowired
+    private SysUserCashAccountService sysUserCashAccountService;
+
+    @ApiOperation("充值")
+    @GetMapping(value = "/recharge")
+    private Object recharge(RechargeDto rechargeDto){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            return failed("请重新登录");
+        }
+        SysUserCashAccount userCashAccount = sysUserCashAccountService.get(sysUser.getId());
+        if(userCashAccount == null || !userCashAccount.getStatus().equals(1)){
+            return failed("账户不存在");
+        }
+
+        if(!userCashAccount.getStatus().equals(1)){
+            return failed("账户已冻结");
+        }
+
+        return succeed(rechargeService.recharge(rechargeDto));
+    }
+}

+ 150 - 0
mec-util/src/main/java/com/ym/mec/util/string/IdWorker.java

@@ -0,0 +1,150 @@
+package com.ym.mec.util.string;
+
+import java.text.SimpleDateFormat;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class IdWorker {
+
+    // ==============================Fields===========================================
+    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+
+    /** 开始时间截 (2019-09-23) */
+    private final long twepoch = 1569242822135L;
+
+    /** 机器id所占的位数 */
+    private final long workerIdBits = 5L;
+
+    /** 数据标识id所占的位数 */
+    private final long datacenterIdBits = 5L;
+
+    /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /** 支持的最大数据标识id,结果是31 */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /** 序列在id中占的位数 */
+    private final long sequenceBits = 12L;
+
+    /** 机器ID向左移12位 */
+    private final long workerIdShift = sequenceBits;
+
+    /** 数据标识id向左移17位(12+5) */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /** 时间截向左移22位(5+5+12) */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /** 工作机器ID(0~31) */
+    private long workerId;
+
+    /** 数据中心ID(0~31) */
+    private long datacenterId;
+
+    /** 毫秒内序列(0~4095) */
+    private long sequence = 0L;
+
+    /** 上次生成ID的时间截 */
+    private long lastTimestamp = -1L;
+
+    //==============================Constructors=====================================
+    /**
+     * 构造函数
+     * @param workerId 工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public IdWorker(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * @return SnowflakeId
+     */
+    public synchronized String   nextId() {
+        long timestamp = timeGen();
+
+        //获取时间部分字符串
+        String nowStr = sdf.format(timestamp);
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+        //移位并通过或运算拼到一起组成64位的ID
+        long id = ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift)| sequence;
+        return nowStr + id;
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+    //==============================Test=============================================
+    /** 测试 */
+    public static void main(String[] args) {
+        IdWorker idWorker = new IdWorker(0, 0);
+
+        for (int i = 0; i < 100; i++) {
+            String  id = idWorker.nextId();
+            System.out.println(id);
+        }
+    }
+}