Эх сурвалжийг харах

fix(投票): 限制一个房产只能投一票.

eric 2 жил өмнө
parent
commit
cdb3d77c8c

+ 2 - 1
src/main/java/com/finikes/oc/vote/dao/ChoiceDao.java

@@ -2,10 +2,11 @@ package com.finikes.oc.vote.dao;
 
 import com.finikes.oc.vote.entity.Choice;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface ChoiceDao extends BaseDao<Choice, Long> {
 
-
+    boolean isHouseHolderInThisVote(@Param("voteId") Integer voteId, @Param("certificateNo") String certificateNo);
 
 }

+ 41 - 13
src/main/java/com/finikes/oc/vote/service/VoteServiceImpl.java

@@ -1,6 +1,8 @@
 package com.finikes.oc.vote.service;
 
 import com.finikes.oc.base.entity.Passport;
+import com.finikes.oc.management.dao.HouseRelationDAO;
+import com.finikes.oc.management.entity.HouseRelation;
 import com.finikes.oc.vote.LockService;
 import com.finikes.oc.vote.PassportHelper;
 import com.finikes.oc.vote.dao.ChoiceDao;
@@ -23,7 +25,6 @@ import org.springframework.transaction.annotation.Transactional;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -39,13 +40,16 @@ public class VoteServiceImpl implements VoteService {
 
     private final LockService lockService;
 
+    private final HouseRelationDAO houseRelationDAO;
+
     public VoteServiceImpl(ChoiceDao choiceDao, OptionDao optionDao, VoteActivityDao voteActivityDao, VoteDao voteDao,
-                           LockService lockService) {
+                           LockService lockService, HouseRelationDAO houseRelationDAO) {
         this.choiceDao = choiceDao;
         this.optionDao = optionDao;
         this.voteActivityDao = voteActivityDao;
         this.voteDao = voteDao;
         this.lockService = lockService;
+        this.houseRelationDAO = houseRelationDAO;
     }
 
     @Override
@@ -226,17 +230,26 @@ public class VoteServiceImpl implements VoteService {
         if (passport == null) {
             throw new BusinessException("获取登录状态异常");
         }
-        // TODO 需要方法获取登录用户信息
-
-        // TODO 这里需要锁住 用户ID 防止单个用户的并发调用, 锁住用户具有的房产主键已达到一房一票的需求.
-        String resourceId = "vote:" + passport.getId();
+        String voteResourceId = "vote:" + passport.getId();
         String ownerId = UUID.randomUUID().toString();
-        boolean locked = lockService.lock(resourceId, ownerId, 60, TimeUnit.SECONDS);
+        boolean locked = lockService.lock(voteResourceId, ownerId, 60, TimeUnit.SECONDS);
         if (!locked) {
             throw new BusinessException("请稍后再试");
         }
-
+        String houseResourceId = null;
         try {
+
+            HouseRelation houseRelation = houseRelationDAO.findByPassport(passport.getId());
+            if (houseRelation == null || houseRelation.getState() != 1) {
+                throw new BusinessException("无投票资格, 请绑定房产");
+            }
+
+            houseResourceId = "vote:house:" + houseRelation.getCertificateNo();
+            boolean secondLock = lockService.lock(houseResourceId, ownerId, 60, TimeUnit.SECONDS);
+            if (!secondLock) {
+                throw new BusinessException("请稍后再试");
+            }
+
             long now = System.currentTimeMillis();
 
             Option option = optionDao.selectByPrimaryKey(dto.getOptionId());
@@ -262,7 +275,9 @@ public class VoteServiceImpl implements VoteService {
                 throw new BusinessException("投票日期已过");
             }
 
-            // TODO 检查此登录人员的房产下的绑定人员是否参与过此抽奖.
+            if (choiceDao.isHouseHolderInThisVote(vote.getId(), houseRelation.getCertificateNo())) {
+                throw new BusinessException("此房产已经参与过投票了");
+            }
 
             Choice choice = new Choice();
             choice.setAssigneeId(passport.getId());
@@ -272,7 +287,8 @@ public class VoteServiceImpl implements VoteService {
 
             choiceDao.insert(choice);
         } finally {
-            lockService.unlock(resourceId, ownerId);
+            lockService.unlock(voteResourceId, ownerId);
+            lockService.unlock(houseResourceId, ownerId);
         }
     }
 
@@ -282,16 +298,23 @@ public class VoteServiceImpl implements VoteService {
         if (passport == null) {
             throw new BusinessException("获取登录状态异常");
         }
-        String resourceId = "vote:" + passport.getId();
+        String voteResourceId = "vote:" + passport.getId();
         String ownerId = UUID.randomUUID().toString();
-        boolean locked = lockService.lock(resourceId, ownerId, 60, TimeUnit.SECONDS);
+        boolean locked = lockService.lock(voteResourceId, ownerId, 60, TimeUnit.SECONDS);
         if (!locked) {
             throw new BusinessException("请稍后再试");
         }
+        String houseResourceId = null;
 
         try {
             long now = System.currentTimeMillis();
 
+            HouseRelation houseRelation = houseRelationDAO.findByPassport(passport.getId());
+            if (houseRelation == null || houseRelation.getState() != 1) {
+                throw new BusinessException("无投票资格, 请绑定房产");
+            }
+            houseResourceId = "vote:house:" + houseRelation.getCertificateNo();
+
             Option option = optionDao.selectByPrimaryKey(dto.getOptionId());
             if (option == null) {
                 throw new BusinessException("参与的投票不存在");
@@ -315,6 +338,10 @@ public class VoteServiceImpl implements VoteService {
                 throw new BusinessException("投票日期已过");
             }
 
+            if (choiceDao.isHouseHolderInThisVote(vote.getId(), houseRelation.getCertificateNo())) {
+                throw new BusinessException("此房产已经参与过投票了");
+            }
+
             Choice choice = new Choice();
             choice.setAssigneeId(dto.getPrincipalId());
             choice.setOptionId(dto.getOptionId());
@@ -324,7 +351,8 @@ public class VoteServiceImpl implements VoteService {
 
             choiceDao.insert(choice);
         } finally {
-            lockService.unlock(resourceId, ownerId);
+            lockService.unlock(voteResourceId, ownerId);
+            lockService.unlock(houseResourceId, ownerId);
         }
     }
 }

+ 10 - 0
src/main/resources/mapper/ChoiceMapper.xml

@@ -20,6 +20,16 @@
         FROM t_choice
         WHERE id = #{primaryKey}
     </select>
+    <select id="isHouseHolderInThisVote" resultType="java.lang.Boolean">
+        SELECT count(1)
+        FROM t_option vote_option,
+        t_choice choice,
+        t_house_relation relation
+        WHERE vote_option.vote_id = #{voteId}
+        AND choice.assignee_id = relation.passportId
+        AND certificateNo = #{certificateNo}
+        AND state = 1
+    </select>
 
     <delete id="deleteByPrimaryKey" parameterType="integer">
         DELETE