Kaynağa Gözat

feat: add vote result api.

eric 2 yıl önce
ebeveyn
işleme
cdf4ab4a8e

+ 6 - 0
src/main/java/com/finikes/oc/vote/controller/VoteController.java

@@ -155,6 +155,12 @@ public class VoteController {
         return ApiResponse.successful();
     }
 
+    @GetMapping("/vote/result")
+    public ApiResponse<List<VoteResultDto>> voteResult(@RequestParam("activityId") Integer activityId) {
+        List<VoteResultDto> list = voteService.voteResult(activityId);
+        return ApiResponse.successful(list);
+    }
+
 
     /**
      * 异常处理器

+ 5 - 0
src/main/java/com/finikes/oc/vote/dao/ChoiceDao.java

@@ -1,13 +1,18 @@
 package com.finikes.oc.vote.dao;
 
 import com.finikes.oc.common.BaseDao;
+import com.finikes.oc.vote.dto.OptionSummary;
 import com.finikes.oc.vote.entity.Choice;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 @Mapper
 public interface ChoiceDao extends BaseDao<Choice, Long> {
 
     boolean isHouseHolderInThisVote(@Param("voteId") Integer voteId, @Param("certificateNo") String certificateNo);
 
+    List<OptionSummary> selectByVoteIds(@Param("voteIds") List<Integer> voteIds);
+
 }

+ 50 - 0
src/main/java/com/finikes/oc/vote/dto/OptionSummary.java

@@ -0,0 +1,50 @@
+package com.finikes.oc.vote.dto;
+
+public class OptionSummary {
+    private Integer voteId;
+    private Integer optionId;
+    private String value;
+    private Integer quantity;
+
+    @Override
+    public String toString() {
+        return "OptionSummary{" +
+                "voteId=" + voteId +
+                ", optionId=" + optionId +
+                ", value='" + value + '\'' +
+                ", quantity=" + quantity +
+                '}';
+    }
+
+    public Integer getVoteId() {
+        return voteId;
+    }
+
+    public void setVoteId(Integer voteId) {
+        this.voteId = voteId;
+    }
+
+    public Integer getOptionId() {
+        return optionId;
+    }
+
+    public void setOptionId(Integer optionId) {
+        this.optionId = optionId;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Integer getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(Integer quantity) {
+        this.quantity = quantity;
+    }
+}

+ 34 - 0
src/main/java/com/finikes/oc/vote/dto/VoteResultDto.java

@@ -0,0 +1,34 @@
+package com.finikes.oc.vote.dto;
+
+import java.util.List;
+
+public class VoteResultDto {
+
+    private Integer voteId;
+
+    private List<VoteResultItemDto> items;
+
+    @Override
+    public String toString() {
+        return "VoteResultDto{" +
+                "voteId=" + voteId +
+                ", items=" + items +
+                '}';
+    }
+
+    public Integer getVoteId() {
+        return voteId;
+    }
+
+    public void setVoteId(Integer voteId) {
+        this.voteId = voteId;
+    }
+
+    public List<VoteResultItemDto> getItems() {
+        return items;
+    }
+
+    public void setItems(List<VoteResultItemDto> items) {
+        this.items = items;
+    }
+}

+ 50 - 0
src/main/java/com/finikes/oc/vote/dto/VoteResultItemDto.java

@@ -0,0 +1,50 @@
+package com.finikes.oc.vote.dto;
+
+public class VoteResultItemDto {
+    private Integer optionId;
+    private String value;
+    private Integer quantity;
+    private Integer percent;
+
+    @Override
+    public String toString() {
+        return "VoteResultItemDto{" +
+                "optionId=" + optionId +
+                ", value='" + value + '\'' +
+                ", quantity=" + quantity +
+                ", percent=" + percent +
+                '}';
+    }
+
+    public Integer getOptionId() {
+        return optionId;
+    }
+
+    public void setOptionId(Integer optionId) {
+        this.optionId = optionId;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Integer getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(Integer quantity) {
+        this.quantity = quantity;
+    }
+
+    public Integer getPercent() {
+        return percent;
+    }
+
+    public void setPercent(Integer percent) {
+        this.percent = percent;
+    }
+}

+ 1 - 0
src/main/java/com/finikes/oc/vote/service/VoteService.java

@@ -69,4 +69,5 @@ public interface VoteService {
      */
     void madeChoiceDelegation(ChoiceDelegationDto dto);
 
+    List<VoteResultDto> voteResult(Integer voteActivityId);
 }

+ 80 - 1
src/main/java/com/finikes/oc/vote/service/VoteServiceImpl.java

@@ -22,6 +22,8 @@ import com.github.pagehelper.PageHelper;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
@@ -91,7 +93,7 @@ public class VoteServiceImpl implements VoteService {
     public List<VoteActivityViewDto> searchVoteActivity(VoteActivitySearchDto dto) {
         List<VoteActivity> activities;
 
-        try (Page<VoteActivity> page = PageHelper.startPage(dto.getPageNum(), dto.getPageCapacity(), false)){
+        try (Page<VoteActivity> page = PageHelper.startPage(dto.getPageNum(), dto.getPageCapacity(), false)) {
             if (dto.getStartTime() == null || dto.getEndTime() == null) {
                 activities = voteActivityDao.selectByTitleAndStartTimeAndEndTime(dto.getKey(),
                         null, null);
@@ -355,4 +357,81 @@ public class VoteServiceImpl implements VoteService {
             lockService.unlock(houseResourceId, ownerId);
         }
     }
+
+    public List<VoteResultDto> voteResult(Integer voteActivityId) {
+        VoteActivity activity = voteActivityDao.selectByPrimaryKey(voteActivityId);
+        if (activity == null) {
+            throw new BusinessException("参与的投票不存在");
+        }
+        List<Vote> votes = voteDao.selectByVoteActivityId(voteActivityId)
+                .stream()
+                .sorted(Comparator.comparingInt(Vote::getSequence))
+                .collect(Collectors.toList());
+        if (votes.isEmpty()) {
+            throw new BusinessException("参与的投票不存在");
+        }
+
+        List<Integer> voteIds = votes.stream().map(Vote::getId).collect(Collectors.toList());
+
+        List<Option> options = optionDao.selectByVoteIds(voteIds);
+        Map<Integer, List<Option>> optionMap = new HashMap<>();
+        for (Option option : options) {
+            if (!optionMap.containsKey(option.getVoteId())) {
+                optionMap.put(option.getVoteId(), new ArrayList<>(3));
+            }
+            optionMap.get(option.getVoteId()).add(option);
+        }
+
+        List<OptionSummary> list = voteIds.isEmpty() ? Collections.emptyList() : choiceDao.selectByVoteIds(voteIds);
+        Map<Integer, OptionSummary> summaryMap = new HashMap<>();
+        for (OptionSummary summary : list) {
+            summaryMap.put(summary.getOptionId(), summary);
+        }
+
+        List<VoteResultDto> results = new ArrayList<>(votes.size());
+        for (Vote vote : votes) {
+            VoteResultDto resultDto = new VoteResultDto();
+            resultDto.setVoteId(vote.getId());
+
+            List<Option> matchedOptions = optionMap.get(vote.getId());
+            if (matchedOptions == null || matchedOptions.isEmpty()) {
+                resultDto.setItems(Collections.emptyList());
+                continue;
+            }
+
+            resultDto.setItems(new ArrayList<>());
+            int total = 0;
+            for (Option option : matchedOptions) {
+                VoteResultItemDto item = new VoteResultItemDto();
+
+                item.setOptionId(option.getId());
+                item.setValue(option.getValue());
+                item.setPercent(0);
+                OptionSummary summary = summaryMap.get(option.getId());
+                if (summary == null) {
+                    item.setQuantity(0);
+                } else {
+                    item.setQuantity(summary.getQuantity());
+                    total += summary.getQuantity();
+                }
+                resultDto.getItems().add(item);
+            }
+            if (total != 0) {
+                for (VoteResultItemDto item : resultDto.getItems()) {
+                    item.setPercent(calcPercent(total, item.getQuantity()));
+                }
+            }
+            results.add(resultDto);
+        }
+        return results;
+    }
+
+    private static int calcPercent(int total, int number) {
+        if (total == 0 || number == 0) {
+            return 0;
+        }
+        return new BigDecimal(number)
+                .divide(new BigDecimal(total), 2, RoundingMode.HALF_UP)
+                .multiply(new BigDecimal(100)).intValue();
+    }
 }

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

@@ -37,4 +37,15 @@
         WHERE id = #{primaryKey}
     </delete>
 
+    <select id="selectByVoteIds" resultType="com.finikes.oc.vote.dto.OptionSummary">
+        SELECT count(1), option_id, value, vote_id
+        FROM t_option,
+        t_choice
+        WHERE t_option.vote_id IN
+        <foreach collection="voteIds" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        AND t_choice.option_id = t_option.id
+        GROUP BY option_id;
+    </select>
 </mapper>

+ 34 - 0
src/test/java/com/finikes/oc/vote/dao/ChoiceDaoTest.java

@@ -0,0 +1,34 @@
+package com.finikes.oc.vote.dao;
+
+import com.finikes.oc.App;
+import com.finikes.oc.vote.dto.OptionSummary;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = App.class)
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+class ChoiceDaoTest {
+
+    @Autowired
+    private ChoiceDao choiceDao;
+
+    @Test
+    void selectByVoteIds() {
+        List<OptionSummary> list = choiceDao.selectByVoteIds(IntStream.range(0, 10).boxed().collect(Collectors.toList()));
+        list.forEach(System.out::println);
+    }
+}