Przeglądaj źródła

增加了账单和提现记录功能

ljh 2 lat temu
rodzic
commit
2c61f3d63e
19 zmienionych plików z 1386 dodań i 2 usunięć
  1. 35 0
      core/src/main/java/com/mooctest/crowd/domain/dao/BalanceDao.java
  2. 41 0
      core/src/main/java/com/mooctest/crowd/domain/dao/BookTestDao.java
  3. 21 0
      core/src/main/java/com/mooctest/crowd/domain/domainobject/Balance.java
  4. 61 0
      core/src/main/java/com/mooctest/crowd/domain/domainobject/BookTest.java
  5. 14 0
      core/src/main/java/com/mooctest/crowd/domain/domainobject/BookTestSummary.java
  6. 118 0
      core/src/main/java/com/mooctest/crowd/domain/domainobject/Condition.java
  7. 65 0
      core/src/main/java/com/mooctest/crowd/domain/model/BalancePO.java
  8. 163 0
      core/src/main/java/com/mooctest/crowd/domain/model/BookTestPO.java
  9. 303 0
      core/src/main/java/com/mooctest/crowd/domain/repository/BookTestRepo.java
  10. 3 0
      core/src/main/java/com/mooctest/crowd/domain/util/Converter.java
  11. 163 0
      site/src/main/java/com/mooctest/crowd/site/controller/BookTestController.java
  12. 2 1
      site/src/main/java/com/mooctest/crowd/site/controller/MixDefectController.java
  13. 11 0
      site/src/main/java/com/mooctest/crowd/site/data/dto/BalancePageDTO.java
  14. 13 0
      site/src/main/java/com/mooctest/crowd/site/data/dto/BookTestPageDTO.java
  15. 58 0
      site/src/main/java/com/mooctest/crowd/site/data/vo/BalanceVO.java
  16. 141 0
      site/src/main/java/com/mooctest/crowd/site/data/vo/BookTestVO.java
  17. 27 0
      site/src/main/java/com/mooctest/crowd/site/service/BookTestService.java
  18. 142 0
      site/src/main/java/com/mooctest/crowd/site/service/impl/BookTestServiceImpl.java
  19. 5 1
      site/src/main/java/com/mooctest/crowd/site/service/impl/TaskAmountServiceImpl.java

+ 35 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/BalanceDao.java

@@ -0,0 +1,35 @@
+package com.mooctest.crowd.domain.dao;
+
+import com.mooctest.crowd.domain.domainobject.Balance;
+import com.mooctest.crowd.domain.model.BookTestPO;
+import com.mooctest.crowd.domain.model.BalancePO;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import javax.transaction.Transactional;
+
+@Transactional
+public interface BalanceDao extends CrudRepository<BalancePO, Long>,
+        JpaSpecificationExecutor<BalancePO>,
+        PagingAndSortingRepository<BalancePO, Long>,
+        JpaRepository<BalancePO, Long> {
+
+    Page<BalancePO> findAll(Specification<BalancePO> spec , Pageable pageable);
+
+    @Override
+    <S extends BalancePO> S save(@NotNull S s);
+
+    @Modifying
+    @Query("update user_balance b set b.state= ?1 where b.id = ?2")
+    int updateStateById(int state, long id);
+
+    BalancePO findById(long id);
+}

+ 41 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/BookTestDao.java

@@ -0,0 +1,41 @@
+package com.mooctest.crowd.domain.dao;
+
+import com.mooctest.crowd.domain.domainobject.Balance;
+import com.mooctest.crowd.domain.domainobject.BookTest;
+import com.mooctest.crowd.domain.model.BookTestPO;
+import com.mooctest.crowd.domain.model.BalancePO;
+import com.mooctest.crowd.domain.model.CrowdTestTaskPO;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+@Transactional
+public interface BookTestDao extends CrudRepository<BookTestPO, Long>,
+        JpaSpecificationExecutor<BookTestPO>,
+        PagingAndSortingRepository<BookTestPO, Long>,
+        JpaRepository<BookTestPO, Long> {
+
+    Page<BookTestPO> findAll(Specification<BookTestPO> spec , Pageable pageable);
+    BookTestPO findById(long id);
+    BookTestPO findByCttcodeAndUid(String cttcode,long uid);
+    List<BookTestPO> findAllByRmid(long rmid);
+    BalancePO findByUid(long uid);
+    @Modifying
+    @Query("update book_test b set b.state = ?1 where b.id = ?2")
+    int updateStateById(int state, long id);
+
+    @Modifying
+    @Query("update book_test b set b.state = ?1 where b.uid = ?2 and b.cttcode =?3")
+    int updateStateByCttcodeAndUid(int state,long uid,String cttcode);
+
+    List<BookTestPO> findAllByUid(long uid);
+}

+ 21 - 0
core/src/main/java/com/mooctest/crowd/domain/domainobject/Balance.java

@@ -0,0 +1,21 @@
+package com.mooctest.crowd.domain.domainobject;
+
+import lombok.Data;
+
+import java.sql.Timestamp;
+import java.util.Date;
+
+@Data
+public class Balance {
+    private long id;
+    private long uid;
+    private int state;
+    private Date baltime;
+    private String balvalue;
+    private String uname;
+    private String cttcode;
+    private String cttname;
+    public final static int STATE_DEFAULT = 0;  //未提现
+    public final static int STATE_COMMIT = 1;  //待审核
+    public final static int STATE_AUDIT = 2;  //已审核
+}

+ 61 - 0
core/src/main/java/com/mooctest/crowd/domain/domainobject/BookTest.java

@@ -0,0 +1,61 @@
+package com.mooctest.crowd.domain.domainobject;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.Date;
+
+@Data
+public class BookTest {
+    private long id;
+    private long uid;
+    private long rmid;
+    private String cptcode;
+    private String cttcode;
+    private BigDecimal totalAmount = new BigDecimal("0.0");
+    private int state;
+    private String cptname;
+    private String cttname;
+    private Date acceptTime;
+    private Date submitTime;
+    public final static int STATE_DEFAULT = 0;  //未提现
+    public final static int STATE_COMMIT = 1;  //待审核
+    public final static int STATE_AUDIT = 2;  //已审核
+    //新增字段
+    private BigDecimal effectiveWorkloadAmount = new BigDecimal(0.0); //有效工作量金额
+    private BigDecimal defectExciationAmount = new BigDecimal(0.0); //缺陷激励金额
+    private BigDecimal extraRewardAmount = new BigDecimal(0.0); //额外奖励金额
+    private int effectiveTestCaseCount = 0;
+    private int notTopVeryHighDefectCount = 0; //不是最优质的超高风险缺陷数量
+    private int notTopHighDefectCount = 0; //不是最优质的高风险缺陷数量
+    private int notTopMidDefectCount = 0; //不是最优质的中风险缺陷数量
+    private int notTopLowDefectCount = 0; //不是最优质的低风险缺陷数量
+    private int notTopVeryLowDefectCount = 0; //不是最优质的超低风险缺陷数量
+    private int topVeryHighDefectCount = 0; //最优质的超高风险缺陷数量,且存在其他相类似的缺陷
+    private int topHighDefectCount = 0; //最优质的高风险缺陷数量,且存在其他相类似的缺陷
+    private int topMidDefectCount = 0; //最优质的中风险缺陷数量,且存在其他相类似的缺陷
+    private int topLowDefectCount = 0; //最优质的低风险缺陷数量,且存在其他相类似的缺陷
+    private int topVeryLowDefectCount = 0; //最优质的超低风险缺陷数量,且存在其他相类似的缺陷
+    private int onlyOneVeryHighDefectCount = 0; //只有一个人发现的超高风险缺陷数量
+    private int onlyOneHighDefectCount = 0; //只有一个人发现的高风险缺陷数量
+    private int onlyOneMidDefectCount = 0; //只有一个人发现的中风险缺陷数量
+    private int onlyOneLowDefectCount = 0; //只有一个人发现的低风险缺陷数量
+    private int onlyOneVeryLowDefectCount = 0;
+    private int notTopVeryHighDefectScore = 0;
+    private int notTopHighDefectScore = 0;
+    private int notTopMidDefectScore = 0;
+    private int notTopLowDefectScore = 0;
+    private int notTopVeryLowDefectScore = 0;
+    private int topVeryHighDefectScore = 0;
+    private int topHighDefectScore = 0;
+    private int topMidDefectScore = 0;
+    private int topLowDefectScore = 0;
+    private int topVeryLowDefectScore = 0;
+    private int onlyOneVeryHighDefectScore = 0;
+    private int onlyOneHighDefectScore = 0;
+    private int onlyOneMidDefectScore = 0;
+    private int onlyOneLowDefectScore = 0;
+    private int onlyOneVeryLowDefectScore = 0;
+    private int defectScore = 0;
+}

+ 14 - 0
core/src/main/java/com/mooctest/crowd/domain/domainobject/BookTestSummary.java

@@ -0,0 +1,14 @@
+package com.mooctest.crowd.domain.domainobject;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class BookTestSummary {
+    BigDecimal sum;    //酬劳总得
+    BigDecimal defaultSum;
+    BigDecimal commitSum;
+    BigDecimal auditSum;
+    BigDecimal completeSum;
+}

+ 118 - 0
core/src/main/java/com/mooctest/crowd/domain/domainobject/Condition.java

@@ -0,0 +1,118 @@
+package com.mooctest.crowd.domain.domainobject;
+
+import org.springframework.data.jpa.domain.Specification;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 封装查询方法类
+ *
+ */
+public class Condition {
+    public static final String LIKE = "like";
+    public static final String EQ = "eq";
+    public static final String IN = "in";
+    private String key;
+    private String value;
+    private String type;
+
+    public Condition(String key, String type, Object value) {
+        this.setKey(key);
+        this.setValue(value);
+        this.type = type;
+    }
+
+    public String getKey() {
+        return this.key;
+    }
+
+    public void setKey(String key) {
+        if (key != null) {
+            for (int i = 0; i < key.length(); ++i) {
+                char ch = key.charAt(i);
+                if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z') && (ch < '0' || ch > '9') && ch != '_') {
+                    key = key.substring(0, i);
+                }
+            }
+            this.key = key;
+        }
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Object getValue() {
+        return this.value;
+    }
+
+    public void setValue(Object ov) {
+        if (ov != null) {
+            this.value = String.valueOf(ov);
+        } else {
+            this.value = "";
+        }
+    }
+
+    public boolean isValid() {
+        return key != null && key.length() > 0 && type != null && type.length() > 0 && value != null && value.length() > 0;
+    }
+
+    public static <T> Specification<T> getSpecification(Condition condition) {
+        List<Condition> list = new ArrayList<>();
+        list.add(condition);
+        return getSpecification(list);
+    }
+
+    public static <T> Specification<T> getSpecification(List<Condition> conditionList) {
+        return (Specification<T>) (root, query, builder) -> {
+            Predicate predicate = builder.conjunction();
+            List<Expression<Boolean>> expressions = predicate.getExpressions();
+            if (conditionList != null && conditionList.size() > 0) {
+                for (Condition condition : conditionList) {
+                    if (condition == null)
+                        continue;
+                    String key = condition.getKey();
+                    String type = condition.getType();
+                    String value = String.valueOf(condition.getValue());
+                    if (condition.isValid()) {
+                        Predicate temp = null;
+                        switch (type) {
+                            case Condition.EQ:
+                                temp = builder.equal(root.get(key), value);
+                                break;
+                            case Condition.LIKE:
+                                temp = builder.like(root.get(key), "%" + value + "&");
+                                break;
+                            case Condition.IN:
+                                CriteriaBuilder.In<Object> in = builder.in(root.get(key));
+                                for (String inValue : value.split(","))
+                                    in.value(inValue);
+                                temp = in;
+                                break;
+                            default:
+                                break;
+                        }
+                        if (expressions.size() > 0)
+                            expressions.add(builder.and(temp));
+                        else
+                            expressions.add(temp);
+                    }
+                }
+            }
+            return predicate;
+        };
+    }
+
+    public String toString() {
+        return String.format("Cond-[%s %s %s]", this.key, this.type, this.value);
+    }
+}

+ 65 - 0
core/src/main/java/com/mooctest/crowd/domain/model/BalancePO.java

@@ -0,0 +1,65 @@
+package com.mooctest.crowd.domain.model;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.sql.Timestamp;
+import java.util.Date;
+
+/**
+ * @author xxx
+ * @date 2022/3/16
+ */
+@Data
+@Entity(name = "user_balance")
+public class BalancePO {
+    @Id
+    @Column(name = "bal_id")
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private long id;
+
+    @Column(name = "bal_user_id")
+    private long uid;
+
+    @Column(name = "bal_value")
+    private String balvalue;
+
+    @Column(name = "bal_time")
+    private Date baltime;
+
+    @Column(name = "bal_state")
+    private int state;
+
+    @Column(name = "bal_user_name")
+    private String uname;
+
+    @Column(name = "bal_task_code")
+    private String cttcode;
+
+    @Column(name = "bal_task_name")
+    private String cttname;
+
+    public BalancePO() {
+    }
+
+    public BalancePO(long id, long uid, String balvalue, Date baltime, int state,String uname,String cttcode,String cttname) {
+        this.id = id;
+        this.uid = uid;
+        this.state = state;
+        this.baltime = baltime;
+        this.balvalue = balvalue;
+        this.uname = uname;
+        this.cttcode = cttcode;
+        this.cttname = cttname;
+    }
+
+//    public static List<BookTestPO> getFakeData() {
+//        BookTestPO bookTestPO1 = new BookTestPO(1,"2",1, "hhh", "1", 1.0, "test");
+//        BookTestPO bookTestPO2 = new BookTestPO(2, "3",2, "lll", "1", 1.0, "test");
+//        List<BookTestPO> result = new ArrayList<>();
+//        result.add(bookTestPO1);
+//        result.add(bookTestPO2);
+//        return result;
+//    }
+
+}

+ 163 - 0
core/src/main/java/com/mooctest/crowd/domain/model/BookTestPO.java

@@ -0,0 +1,163 @@
+package com.mooctest.crowd.domain.model;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.Date;
+
+/**
+ * @author xxx
+ * @date 2022/3/16
+ */
+@Data
+@Entity(name = "book_test")
+public class BookTestPO {
+    @Id
+    @Column(name = "id")
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private long id;
+
+    @Column(name = "b_u_id")
+    private long uid;
+
+    @Column(name = "b_rm_id")
+    private long rmid;
+
+    @Column(name = "b_ctp_code")
+    private String cptcode;
+
+    @Column(name = "b_ctt_code")
+    private String cttcode;
+
+    @Column(name = "b_state")
+    private int state;
+
+    //新增字段
+    @Column(name = "effective_workload_amount")
+    private BigDecimal effectiveWorkloadAmount;
+
+    @Column(name = "defect_exciation_amount")
+    private BigDecimal defectExciationAmount;
+
+    @Column(name = "extra_reward_amount")
+    private BigDecimal extraRewardAmount;
+
+    @Column(name = "total_amount")
+    private BigDecimal totalAmount;
+
+    @Column(name = "defect_score")
+    private int defectScore;
+
+    @Column(name = "nottop_veryhigh_defectcount")
+    private int notTopVeryHighDefectCount;
+
+    @Column(name = "nottop_high_defectcount")
+    private int notTopHighDefectCount;
+
+    @Column(name = "nottop_mid_defectcount")
+    private int notTopMidDefectCount;
+
+    @Column(name = "nottop_low_defectcount")
+    private int notTopLowDefectCount;
+
+    @Column(name = "nottop_verylow_defectcount")
+    private int notTopVeryLowDefectCount;
+
+    @Column(name = "top_veryhigh_defectcount")
+    private int topVeryHighDefectCount;
+
+    @Column(name = "top_high_defectcount")
+    private int topHighDefectCount;
+
+    @Column(name = "top_mid_defectcount")
+    private int topMidDefectCount;
+
+    @Column(name = "top_low_defectcount")
+    private int topLowDefectCount;
+
+    @Column(name = "top_verylow_defectcount")
+    private int topVeryLowDefectCount;
+
+    @Column(name = "only_one_veryhigh_defectcount")
+    private int onlyOneVeryHighDefectCount;
+
+    @Column(name = "only_one_high_defectcount")
+    private int onlyOneHighDefectCount;
+
+    @Column(name = "only_one_mid_defectcount")
+    private int onlyOneMidDefectCount;
+
+    @Column(name = "only_one_low_defectcount")
+    private int onlyOneLowDefectCount;
+
+    @Column(name = "only_one_verylow_defectcount")
+    private int onlyOneVeryLowDefectCount;
+
+    @Column(name = "nottop_veryhigh_defectscore")
+    private int notTopVeryHighDefectScore;
+
+    @Column(name = "nottop_high_defectscore")
+    private int notTopHighDefectScore;
+
+    @Column(name = "nottop_mid_defectscore")
+    private int notTopMidDefectScore;
+
+    @Column(name = "nottop_low_defectscore")
+    private int notTopLowDefectScore;
+
+    @Column(name = "nottop_verylow_defectscore")
+    private int notTopVeryLowDefectScore;
+
+    @Column(name = "top_veryhigh_defectscore")
+    private int topVeryHighDefectScore;
+
+    @Column(name = "top_high_defectscore")
+    private int topHighDefectScore;
+
+    @Column(name = "top_mid_defectscore")
+    private int topMidDefectScore;
+
+    @Column(name = "top_low_defectscore")
+    private int topLowDefectScore;
+
+    @Column(name = "top_verylow_defectscore")
+    private int topVeryLowDefectScore;
+
+    @Column(name = "only_one_veryhigh_defectscore")
+    private int onlyOneVeryHighDefectScore;
+
+    @Column(name = "only_one_high_defectscore")
+    private int onlyOneHighDefectScore;
+
+    @Column(name = "only_one_mid_defectscore")
+    private int onlyOneMidDefectScore;
+
+    @Column(name = "only_one_low_defectscore")
+    private int onlyOneLowDefectScore;
+
+    @Column(name = "only_one_verylow_defectscore")
+    private int onlyOneVeryLowDefectScore;
+
+    public BookTestPO() {
+    }
+
+    public BookTestPO(long id,long uid,String cptcode,String cttcode,int state) {
+        this.id = id;
+        this.uid = uid;
+        this.state = state;
+        this.cptcode = cptcode;
+        this.cttcode = cttcode;
+    }
+
+//    public static List<BookTestPO> getFakeData() {
+//        BookTestPO bookTestPO1 = new BookTestPO(1,"2",1, "hhh", "1", 1.0, "test");
+//        BookTestPO bookTestPO2 = new BookTestPO(2, "3",2, "lll", "1", 1.0, "test");
+//        List<BookTestPO> result = new ArrayList<>();
+//        result.add(bookTestPO1);
+//        result.add(bookTestPO2);
+//        return result;
+//    }
+
+}

+ 303 - 0
core/src/main/java/com/mooctest/crowd/domain/repository/BookTestRepo.java

@@ -0,0 +1,303 @@
+package com.mooctest.crowd.domain.repository;
+
+import com.mooctest.crowd.domain.dao.*;
+import com.mooctest.crowd.domain.domainobject.*;
+import com.mooctest.crowd.domain.model.*;
+import com.mooctest.crowd.domain.util.Converter;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.domain.Specifications;
+import org.springframework.stereotype.Component;
+import sun.reflect.generics.tree.VoidDescriptor;
+
+import javax.persistence.criteria.*;
+import java.math.BigDecimal;
+import java.util.*;
+
+@Component
+public class BookTestRepo {
+
+    @Autowired
+    private BookTestDao bookTestDao;
+    @Autowired
+    private BalanceDao balanceDao;
+    @Autowired
+    private CrowdTestProjectDao crowdTestProjectDao;
+    @Autowired
+    private CrowdTestTaskDao crowdTestTaskDao;
+    @Autowired
+    private TaskToUserDao taskToUserDao;
+    @Autowired
+    private UserDao userDao;
+
+    public Page<BookTest> findAllBookTestByPage(Pageable pageable, Map<String, String> extraCondition, String keyword) {
+        List<Condition> conditionList = new ArrayList<>();
+        conditionList.add(new Condition("uid", Condition.EQ, extraCondition.get("userId")));
+        conditionList.add(getInCondition(extraCondition, keyword));
+        Specifications<BookTestPO> where = Specifications.where(Condition.getSpecification(conditionList));
+        Page<BookTest> bookTestPage = bookTestDao.findAll(where, pageable).map(bookTestPO -> Converter.convert(BookTest.class, bookTestPO));
+        List<BookTest> content = bookTestPage.getContent();
+        if (content.size() > 0) {
+            for (BookTest bookTest : content) {
+                //查询项目信息
+                String cptcode = bookTest.getCptcode();
+                if (cptcode == null || cptcode.length() == 0) {
+                    continue;
+                }
+                CrowdTestProjectPO project = crowdTestProjectDao.findByCodeAndIsDeleted(cptcode, 0);
+                if (project == null || project.getName() == null) {
+                    continue;
+                }
+                bookTest.setCptname(project.getName());
+
+                //查询任务信息
+                long uid = bookTest.getUid();
+                String cttcode = bookTest.getCttcode();
+                if (uid == 0 || cttcode == null || cttcode.length() == 0) {
+                    continue;
+                }
+                TaskToUserPO taskToUser = taskToUserDao.findByUserIdAndTaskCode(uid, cttcode);
+                if (taskToUser == null) {
+                    continue;
+                }
+                bookTest.setAcceptTime(taskToUser.getAcceptTime());
+                bookTest.setSubmitTime(taskToUser.getCommitTaskTime());
+                CrowdTestTaskPO task = crowdTestTaskDao.findByCodeAndIsDeleted(cttcode, 0);
+                if (task == null || task.getName() == null) {
+                    continue;
+                }
+                bookTest.setCttname(task.getName());
+            }
+        }
+        return bookTestPage;
+    }
+
+    public Page<BookTest> findAllProjectBookTestByPage(Pageable pageable, Map<String, String> extraCondition, String keyword) {
+        List<Condition> conditionList = new ArrayList<>();
+        conditionList.add(new Condition("rmid", Condition.EQ, extraCondition.get("userId")));
+        conditionList.add(getInCondition(extraCondition, keyword));
+        Specifications<BookTestPO> where = Specifications.where(Condition.getSpecification(conditionList));
+        Page<BookTest> bookTestPage = bookTestDao.findAll(where, pageable).map(bookTestPO -> Converter.convert(BookTest.class, bookTestPO));
+        List<BookTest> content = bookTestPage.getContent();
+        if (content.size() > 0) {
+            for (BookTest bookTest : content) {
+                //查询项目信息
+                String cptcode = bookTest.getCptcode();
+                if (cptcode == null || cptcode.length() == 0) {
+                    continue;
+                }
+                CrowdTestProjectPO project = crowdTestProjectDao.findByCodeAndIsDeleted(cptcode, 0);
+                if (project == null || project.getName() == null) {
+                    continue;
+                }
+                bookTest.setCptname(project.getName());
+
+                //查询任务信息
+                long uid = bookTest.getUid();
+                String cttcode = bookTest.getCttcode();
+                if (uid == 0 || cttcode == null || cttcode.length() == 0) {
+                    continue;
+                }
+                TaskToUserPO taskToUser = taskToUserDao.findByUserIdAndTaskCode(uid, cttcode);
+                if (taskToUser == null) {
+                    continue;
+                }
+                bookTest.setAcceptTime(taskToUser.getAcceptTime());
+                bookTest.setSubmitTime(taskToUser.getCommitTaskTime());
+                CrowdTestTaskPO task = crowdTestTaskDao.findByCodeAndIsDeleted(cttcode, 0);
+                if (task == null || task.getName() == null) {
+                    continue;
+                }
+                bookTest.setCttname(task.getName());
+            }
+        }
+        return bookTestPage;
+    }
+
+    private Condition getInCondition(Map<String, String> extraCondition, String keyword) {
+        Condition condition = null;
+        if (keyword != null && keyword.length() > 0) {
+            String key = extraCondition.get("type");
+            StringBuilder valueBuilder = new StringBuilder();
+            boolean needSpilt = false;
+            if (key.equals("cptcode")) {
+                List<CrowdTestProjectPO> list = crowdTestProjectDao.findByNameLikeAndIsDeleted("%" + keyword + "%", 0);
+                if (list != null && list.size() > 0) {
+                    for (CrowdTestProjectPO projectPO : list) {
+                        if (needSpilt) {
+                            valueBuilder.append(",");
+                        } else {
+                            needSpilt = true;
+                        }
+                        valueBuilder.append(projectPO.getCode());
+                    }
+                }
+            } else if (key.equals("cttcode")) {
+                List<CrowdTestTaskPO> list = crowdTestTaskDao.findByNameLike("%" + keyword + "%");
+                if (list != null && list.size() > 0) {
+                    for (CrowdTestTaskPO taskPO : list) {
+                        if (needSpilt) {
+                            valueBuilder.append(",");
+                        } else {
+                            needSpilt = true;
+                        }
+                        valueBuilder.append(taskPO.getCode());
+                    }
+                }
+            }
+            condition = new Condition(key, Condition.IN, valueBuilder.toString());
+        }
+        return condition;
+    }
+
+    public BookTest findById(int id) {
+        BookTestPO bookTestPO = bookTestDao.findById(id);
+        BookTest bookTest = Converter.convert(BookTest.class, bookTestPO);
+        //查询项目信息
+        String cptcode = bookTest.getCptcode();
+        if (cptcode != null && cptcode.length() > 0) {
+            CrowdTestProjectPO project = crowdTestProjectDao.findByCodeAndIsDeleted(cptcode, 0);
+            if (project != null && project.getName() != null) {
+                bookTest.setCptname(project.getName());
+            }
+        }
+        //查询任务信息
+        long uid = bookTest.getUid();
+        String cttcode = bookTest.getCttcode();
+        if (uid > 0 && cttcode != null && cttcode.length() > 0) {
+            TaskToUserPO taskToUser = taskToUserDao.findByUserIdAndTaskCode(uid, cttcode);
+            if (taskToUser != null) {
+                bookTest.setAcceptTime(taskToUser.getAcceptTime());
+                bookTest.setSubmitTime(taskToUser.getCommitTaskTime());
+            }
+            CrowdTestTaskPO task = crowdTestTaskDao.findByCodeAndIsDeleted(cttcode, 0);
+            if (task != null && task.getName() != null) {
+                bookTest.setCttname(task.getName());
+            }
+        }
+        return bookTest;
+    }
+
+    public Page<Balance> findAllBookTestByPage(Pageable pageable, Map<String, String> extraCondition) {
+        Specifications<BalancePO> where = Specifications.where(Condition.getSpecification(new Condition("uid", Condition.EQ, extraCondition.get("userId"))));
+        return balanceDao.findAll(where, pageable).map(balancePO -> Converter.convert(Balance.class, balancePO));
+    }
+
+    public Page<Balance> findprojectAllBookTestByPage(Pageable pageable, Map<String, String> extraCondition) {
+        Specifications<BalancePO> where = Specifications.where(getProjectBalResource(extraCondition));
+        return balanceDao.findAll(where, pageable).map(balancePO -> Converter.convert(Balance.class, balancePO));
+    }
+
+    private Specification<BalancePO> getProjectBalResource(Map<String, String> extraCondition) {
+        return new Specification<BalancePO>() {
+            @Override
+            public Predicate toPredicate(Root<BalancePO> a, CriteriaQuery<?> q, CriteriaBuilder cb) {
+                Predicate predicate = cb.conjunction();
+                long rmid = Long.parseLong(extraCondition.get("userId"));
+                if (rmid != 0) {
+                    Path<Object> path = a.get("cttcode");  //定义查询的字段
+                    CriteriaBuilder.In<Object> in = cb.in(path);
+                    List<BookTestPO> bookTestPOList = bookTestDao.findAllByRmid(rmid);
+                    if (bookTestPOList != null && bookTestPOList.size() > 0) {
+                        for (BookTestPO bookTestPO : bookTestPOList) {
+                            in.value(bookTestPO.getCttcode());
+                        }
+                    } else {
+                        in.value("ABCDE");
+                    }
+                    predicate.getExpressions().add(
+                            cb.and(in)
+                    );
+                }
+                return predicate;
+            }
+        };
+    }
+
+    public int updateState(int state, int id) {
+        int sum = bookTestDao.updateStateById(state, id);
+        if (sum == 1) {
+            BookTestPO bookTest = bookTestDao.findById(id);
+            if (bookTest != null) {
+                //查询任务信息
+                long uid = bookTest.getUid();
+                String cttcode = bookTest.getCttcode();
+                if (uid != 0 && cttcode != null) {
+                    TaskToUserPO taskToUser = taskToUserDao.findByUserIdAndTaskCode(uid, cttcode);
+                    //根据id找名字
+                    UserPO user = userDao.findById(uid).orElse(null);
+                    //根据code找项目名字
+                    CrowdTestTaskPO task = crowdTestTaskDao.findByCodeAndIsDeleted(cttcode, 0);
+                    if (taskToUser != null) {
+                        BalancePO balance = new BalancePO();
+                        balance.setUid(bookTest.getUid());
+                        balance.setUname(user == null ? "-" : user.getName());
+                        balance.setCttcode(taskToUser.getTaskCode());
+                        balance.setCttname(task.getName());
+                        balance.setBalvalue(taskToUser.getQuotedPrice() + "");
+                        balance.setBaltime(new Date());
+                        balance.setState(state);
+                        balanceDao.save(balance);
+                    }
+                }
+            }
+        }
+        return sum;
+    }
+
+    public int examineState(int state, int id) {
+        int sum = balanceDao.updateStateById(state, id);
+        if (sum == 1) {
+            BalancePO balance = balanceDao.findById(id);
+            String code = balance.getCttcode();
+            long uid = balance.getUid();
+            bookTestDao.updateStateByCttcodeAndUid(state, uid,code);
+        }
+        return sum;
+    }
+
+    public BookTestSummary findSummaryByUid(String userId) {
+        BookTestSummary summary = new BookTestSummary();
+        if (userId != null && userId.length() > 0) {
+            long uid = Long.parseLong(userId);
+            List<BookTestPO> bookTestPOList = bookTestDao.findAllByUid(uid);
+            HashMap<String, Integer> stateMap = new HashMap<>();
+            if (bookTestPOList != null && bookTestPOList.size() > 0) {
+                for (BookTestPO bookTestPO : bookTestPOList) {
+                    String key = bookTestPO.getUid() + "_" + bookTestPO.getCttcode();
+                    stateMap.put(key, bookTestPO.getState());
+                    Integer state = stateMap.get(key);
+                    if (state != null) {
+                        BigDecimal totalAmount = bookTestPO.getTotalAmount();
+                        switch (state) {
+                            case BookTest.STATE_DEFAULT:
+                                BigDecimal defaultSum = Optional.ofNullable(summary.getDefaultSum()).orElse(new BigDecimal("0.0"));
+                                summary.setDefaultSum(defaultSum.add(totalAmount));
+                                break;
+                            case BookTest.STATE_COMMIT:
+                                BigDecimal commitSum = Optional.ofNullable(summary.getCommitSum()).orElse(new BigDecimal("0.0"));
+                                summary.setCommitSum(commitSum.add(totalAmount));
+                                break;
+                            case BookTest.STATE_AUDIT:
+                                BigDecimal auditSum = Optional.ofNullable(summary.getAuditSum()).orElse(new BigDecimal("0.0"));
+                                summary.setAuditSum(auditSum.add(totalAmount));
+                                break;
+                            default:
+                        }
+                }
+            }
+                summary.setSum(summary.getDefaultSum().add(summary.getCommitSum()).add(summary.getAuditSum()));
+            }
+        }
+        return summary;
+    }
+    public BookTestPO saveBookTest(BookTestPO book) {
+//        int sum = 0;
+//        BookTestPO bookTest= bookTestDao.save(book);
+        BookTestPO bookTest = bookTestDao.save(book);
+        return bookTest;
+    }
+}

+ 3 - 0
core/src/main/java/com/mooctest/crowd/domain/util/Converter.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springframework.cglib.beans.BeanCopier;
 
+import java.math.BigDecimal;
 import java.util.Map;
 
 public class Converter {
@@ -67,6 +68,8 @@ public class Converter {
                     return num.doubleValue();
                 else if (target.equals(byte.class) || target.equals(Byte.class))
                     return num.byteValue();
+                else if(target.equals(BigDecimal.class))
+                    return value;
             } else if (target.isAssignableFrom(value.getClass()))
                 return value;
             return null;

+ 163 - 0
site/src/main/java/com/mooctest/crowd/site/controller/BookTestController.java

@@ -0,0 +1,163 @@
+package com.mooctest.crowd.site.controller;
+
+import com.mooctest.crowd.domain.domainobject.Balance;
+import com.mooctest.crowd.domain.domainobject.BookTest;
+import com.mooctest.crowd.domain.domainobject.DeletedStatus;
+import com.mooctest.crowd.domain.exception.BaseException;
+import com.mooctest.crowd.domain.model.BookTestPO;
+import com.mooctest.crowd.site.command.CrowdTestReportCommand;
+import com.mooctest.crowd.site.command.ModifyCommand;
+import com.mooctest.crowd.site.data.dto.BalancePageDTO;
+import com.mooctest.crowd.site.data.dto.BookTestPageDTO;
+import com.mooctest.crowd.site.data.dto.ReportDetailsDTO;
+import com.mooctest.crowd.site.data.response.ResponseVO;
+import com.mooctest.crowd.site.data.response.ServerCode;
+import com.mooctest.crowd.site.data.vo.*;
+import com.mooctest.crowd.site.service.BookTestService;
+import com.mooctest.crowd.site.service.CommonService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+@RestController
+@RequestMapping("/api/bookTest")
+@Api(tags = "台账功能相关接口", description = "提供台账功能相关的 Rest API")
+public class BookTestController extends BaseSearchController{
+
+    @Autowired
+    private BookTestService bookTestService;
+
+    @Override
+    public Page<?> search(String searchCondition) {
+        return null;
+    }
+
+
+    /**
+     * 个人台账功能
+     *
+     * @return
+     */
+    @RequestMapping(value = "/pageList", method = RequestMethod.POST)
+    public ResponseVO<BookTestPageDTO> getBookTest(@RequestBody SearchConditionVO searchConditionVO) {
+        Map<String, String> extraCondition = searchConditionVO.getColumnFilters() == null ? new HashMap<>() : super.getExtraCondition(searchConditionVO);
+        Pageable pageable = this.getPageable(searchConditionVO);
+        String keyword = searchConditionVO.getKeyword();
+        return new ResponseVO<>(ServerCode.SUCCESS,bookTestService.getBookTestPageInfo(pageable, extraCondition, keyword, DeletedStatus.isNotDeleted));
+    }
+    /**
+     * 企业查看项目台账功能
+     *
+     * @return
+     */
+    @RequestMapping(value = "/projectpageList", method = RequestMethod.POST)
+    public ResponseVO<BookTestPageDTO> getProjectBookTest(@RequestBody SearchConditionVO searchConditionVO) {
+        Map<String, String> extraCondition = searchConditionVO.getColumnFilters() == null ? new HashMap<>() : super.getExtraCondition(searchConditionVO);
+        Pageable pageable = this.getPageable(searchConditionVO);
+        String keyword = searchConditionVO.getKeyword();
+        return new ResponseVO<>(ServerCode.SUCCESS,bookTestService.getBookProjectTestPageInfo(pageable, extraCondition, keyword, DeletedStatus.isNotDeleted));
+    }
+    /**
+     * 查看详情功能
+     */
+    @RequestMapping(value = "/bookDetail/{id}", method = RequestMethod.GET)
+    public ResponseVO<BookTestVO> getBookDetailed(@PathVariable("id") int id) {
+        return new ResponseVO<>(ServerCode.SUCCESS, bookTestService.getBookDetailed(id));
+    }
+    /**
+     * 个人查看提现记录功能
+     */
+    @RequestMapping(value = "/balDetail", method = RequestMethod.POST)
+    public ResponseVO<BalancePageDTO> getBalDetailed(@RequestBody SearchConditionVO searchConditionVO) {
+        Map<String, String> extraCondition = searchConditionVO.getColumnFilters() == null ? new HashMap<>() : super.getExtraCondition(searchConditionVO);
+        Pageable pageable = this.getPageable(searchConditionVO);
+        return new ResponseVO<>(ServerCode.SUCCESS,bookTestService.getBalDetailed(pageable, extraCondition, DeletedStatus.isNotDeleted));
+    }
+    /**
+     * 企业查看提现记录功能
+     */
+    @RequestMapping(value = "/projectbalDetail", method = RequestMethod.POST)
+    public ResponseVO<BalancePageDTO> getProjetcBalDetailed(@RequestBody SearchConditionVO searchConditionVO) {
+        Map<String, String> extraCondition = searchConditionVO.getColumnFilters() == null ? new HashMap<>() : super.getExtraCondition(searchConditionVO);
+        Pageable pageable = this.getPageable(searchConditionVO);
+        return new ResponseVO<>(ServerCode.SUCCESS,bookTestService.getBalDetailedBycode(pageable, extraCondition, DeletedStatus.isNotDeleted));
+    }
+    /**
+     * 提现功能
+     */
+    @RequestMapping(value = "/updateState/{id}", method = RequestMethod.GET)
+    public ResponseVO<Integer> updateState(@PathVariable("id") int id) {
+        int updateSum = bookTestService.updateState(id);
+        if(updateSum>0){
+            return new ResponseVO<>(ServerCode.SUCCESS,updateSum);
+        }else {
+            return new ResponseVO<>(ServerCode.ERROR);
+        }
+    }
+    /**
+     * 审核功能
+     */
+    @RequestMapping(value = "/examineState/{id}", method = RequestMethod.GET)
+    public ResponseVO<Integer> examineState(@PathVariable("id") int id) {
+        int examineSum = bookTestService.examineState(id);
+        if(examineSum>0){
+            return new ResponseVO<>(ServerCode.SUCCESS,examineSum);
+        }else {
+            return new ResponseVO<>(ServerCode.ERROR);
+        }
+    }
+    /**
+     * 批量提现功能
+     */
+    @RequestMapping(value = "/batchUpdateState/{ids}", method = RequestMethod.GET)
+    public ResponseVO<Integer> updateState(@PathVariable("ids") String ids) {
+        String[] idList = ids.split(",");
+        int sum = 0;
+        for (String id : idList) {
+            sum += bookTestService.updateState(Integer.parseInt(id));
+        }
+        if(sum>1) {
+            return new ResponseVO<>(ServerCode.SUCCESS);
+        }else {
+            return new ResponseVO<>(ServerCode.ERROR);
+        }
+    }
+    /**
+     * 批量审核功能
+     */
+    @RequestMapping(value = "/batchExamineState/{ids}", method = RequestMethod.GET)
+    public ResponseVO<Integer> examineState(@PathVariable("ids") String ids) {
+        String[] idList = ids.split(",");
+        int sum = 0;
+        for (String id : idList) {
+            sum += bookTestService.examineState(Integer.parseInt(id));
+        }
+        if(sum>1) {
+            return new ResponseVO<>(ServerCode.SUCCESS);
+        }else {
+            return new ResponseVO<>(ServerCode.ERROR);
+        }
+    }
+    /**
+     * 台账生成方法
+     */
+    @RequestMapping(value = "/savebook", method = RequestMethod.POST)
+    public void saveBookTest(@RequestBody TaskAmountVO taskAmountVO) {
+
+        bookTestService.saveBookTest(taskAmountVO);
+    }
+}

+ 2 - 1
site/src/main/java/com/mooctest/crowd/site/controller/MixDefectController.java

@@ -44,7 +44,8 @@ public class MixDefectController {
     @GetMapping("/generate/{taskCode}")
     @LoginRequired
     public ResponseVO generate(HttpServletRequest request, @PathVariable("taskCode") String taskCode) {
-        boolean res = mixDefectService.post(RequestUtils.getUserId(request), taskCode);
+//        boolean res = mixDefectService.post(RequestUtils.getUserId(request), taskCode);
+        boolean res = mixDefectService.post(taskCode);
         return new ResponseVO(res ? ServerCode.SUCCESS : ServerCode.ERROR);
     }
 

+ 11 - 0
site/src/main/java/com/mooctest/crowd/site/data/dto/BalancePageDTO.java

@@ -0,0 +1,11 @@
+package com.mooctest.crowd.site.data.dto;
+
+import com.mooctest.crowd.domain.domainobject.Balance;
+import com.mooctest.crowd.site.data.vo.*;
+import lombok.Data;
+import org.springframework.data.domain.Page;
+
+@Data
+public class BalancePageDTO {
+    Page<BalanceVO> balancePageDTOPage;
+}

+ 13 - 0
site/src/main/java/com/mooctest/crowd/site/data/dto/BookTestPageDTO.java

@@ -0,0 +1,13 @@
+package com.mooctest.crowd.site.data.dto;
+
+import com.mooctest.crowd.domain.domainobject.BookTestSummary;
+import com.mooctest.crowd.site.data.vo.*;
+import lombok.Data;
+import org.springframework.data.domain.Page;
+
+@Data
+public class BookTestPageDTO {
+    Page<BookTestVO> bookTestPageDTOPage;
+    BookTestSummary summary;
+}
+

+ 58 - 0
site/src/main/java/com/mooctest/crowd/site/data/vo/BalanceVO.java

@@ -0,0 +1,58 @@
+package com.mooctest.crowd.site.data.vo;
+
+import com.mooctest.crowd.domain.domainobject.Balance;
+import com.mooctest.crowd.domain.domainobject.BookTest;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class BalanceVO implements Serializable {
+    private long id;
+    private long uid;
+    private String uname;
+    private int state;
+    private String stateName;
+    private String baltime;
+    private String balvalue;
+    private String cttname;
+
+    public BalanceVO(Balance balance){
+        id = balance.getId();
+        uid = balance.getUid();
+        uname = balance.getUname();
+        balvalue = balance.getBalvalue();
+        baltime = formatTime(balance.getBaltime());
+        state = balance.getState();
+        formatStateName(state);
+        cttname = balance.getCttname();
+    }
+    String formatTime(Date date) {
+        if (date == null) {
+            return "-";
+        }
+        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
+    }
+    void formatStateName(int state){
+        switch (state) {
+            case Balance.STATE_DEFAULT:
+                stateName = "未提现";
+                break;
+            case Balance.STATE_COMMIT:
+                stateName = "待审核";
+                break;
+            case Balance.STATE_AUDIT:
+                stateName = "已审核";
+                break;
+            default:
+        }
+    }
+}

+ 141 - 0
site/src/main/java/com/mooctest/crowd/site/data/vo/BookTestVO.java

@@ -0,0 +1,141 @@
+package com.mooctest.crowd.site.data.vo;
+
+import com.mooctest.crowd.domain.domainobject.BookTest;
+import com.mooctest.crowd.domain.domainobject.CrowdTestProject;
+import com.mooctest.crowd.domain.domainobject.TaskToUser;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class BookTestVO implements Serializable {
+    private long id;
+    private long uid;
+    private String cptcode;
+    private String cttcode;
+    private BigDecimal totalAmount= new BigDecimal(0.0);
+    private int state;
+    private String stateName;
+    private String cptname;
+    private String cttname;
+    private String acceptTime;
+    private String submitTime;
+    //新增字段
+    private BigDecimal effectiveWorkloadAmount = new BigDecimal(0.0); //有效工作量金额
+    private BigDecimal defectExciationAmount = new BigDecimal(0.0); //缺陷激励金额
+    private BigDecimal extraRewardAmount = new BigDecimal(0.0); //额外奖励金额
+    private Integer effectiveTestCaseCount = 0;//有效测试用例数量
+    private Integer notTopVeryHighDefectCount = 0; //不是最优质的超高风险缺陷数量
+    private Integer notTopHighDefectCount = 0; //不是最优质的高风险缺陷数量
+    private Integer notTopMidDefectCount = 0; //不是最优质的中风险缺陷数量
+    private Integer notTopLowDefectCount = 0; //不是最优质的低风险缺陷数量
+    private Integer notTopVeryLowDefectCount = 0; //不是最优质的超低风险缺陷数量
+    private Integer topVeryHighDefectCount = 0; //最优质的超高风险缺陷数量,且存在其他相类似的缺陷
+    private Integer topHighDefectCount = 0; //最优质的高风险缺陷数量,且存在其他相类似的缺陷
+    private Integer topMidDefectCount = 0; //最优质的中风险缺陷数量,且存在其他相类似的缺陷
+    private Integer topLowDefectCount = 0; //最优质的低风险缺陷数量,且存在其他相类似的缺陷
+    private Integer topVeryLowDefectCount = 0; //最优质的超低风险缺陷数量,且存在其他相类似的缺陷
+    private Integer onlyOneVeryHighDefectCount = 0; //只有一个人发现的超高风险缺陷数量
+    private Integer onlyOneHighDefectCount = 0; //只有一个人发现的高风险缺陷数量
+    private Integer onlyOneMidDefectCount = 0; //只有一个人发现的中风险缺陷数量
+    private Integer onlyOneLowDefectCount = 0; //只有一个人发现的低风险缺陷数量
+    private Integer onlyOneVeryLowDefectCount = 0;
+    private Integer notTopVeryHighDefectScore = 0;
+    private Integer notTopHighDefectScore = 0;
+    private Integer notTopMidDefectScore = 0;
+    private Integer notTopLowDefectScore = 0;
+    private Integer notTopVeryLowDefectScore = 0;
+    private Integer topVeryHighDefectScore = 0;
+    private Integer topHighDefectScore = 0;
+    private Integer topMidDefectScore = 0;
+    private Integer topLowDefectScore = 0;
+    private Integer topVeryLowDefectScore = 0;
+    private Integer onlyOneVeryHighDefectScore = 0;
+    private Integer onlyOneHighDefectScore = 0;
+    private Integer onlyOneMidDefectScore = 0;
+    private Integer onlyOneLowDefectScore = 0;
+    private Integer onlyOneVeryLowDefectScore = 0;
+    private Integer defectScore = 0;//缺陷得分
+
+    public BookTestVO(BookTest bookTest) {
+        id = bookTest.getId();
+        uid = bookTest.getUid();
+        cptcode = bookTest.getCptcode();
+        cptname = bookTest.getCptname();
+        cttcode = bookTest.getCttcode();
+        cttname = bookTest.getCttname();
+        state = bookTest.getState();
+        formatStateName(state);
+        acceptTime = formatTime(bookTest.getAcceptTime());
+        submitTime = formatTime(bookTest.getSubmitTime());
+        totalAmount = bookTest.getTotalAmount();
+        effectiveWorkloadAmount = bookTest.getEffectiveWorkloadAmount();
+        defectExciationAmount = bookTest.getDefectExciationAmount();
+        extraRewardAmount = bookTest.getExtraRewardAmount();
+        effectiveTestCaseCount = bookTest.getEffectiveTestCaseCount();
+        notTopVeryHighDefectCount = bookTest.getNotTopVeryHighDefectCount();
+        notTopHighDefectCount = bookTest.getNotTopHighDefectCount();
+        notTopMidDefectCount = bookTest.getNotTopMidDefectCount();
+        notTopLowDefectCount = bookTest.getNotTopLowDefectCount();
+        notTopVeryLowDefectCount = bookTest.getNotTopVeryLowDefectCount();
+        topVeryHighDefectCount = bookTest.getTopVeryHighDefectCount();
+        topHighDefectCount = bookTest.getTopHighDefectCount();
+        topMidDefectCount = bookTest.getTopMidDefectCount();
+        topLowDefectCount = bookTest.getTopLowDefectCount();
+        topVeryLowDefectCount = bookTest.getTopVeryLowDefectCount();
+        onlyOneVeryHighDefectCount = bookTest.getOnlyOneVeryHighDefectCount();
+        onlyOneHighDefectCount = bookTest.getOnlyOneHighDefectCount();
+        onlyOneMidDefectCount = bookTest.getOnlyOneMidDefectCount();
+        onlyOneLowDefectCount = bookTest.getOnlyOneLowDefectCount();
+        onlyOneVeryLowDefectCount = bookTest.getOnlyOneVeryLowDefectCount();
+        notTopVeryHighDefectScore = bookTest.getNotTopVeryHighDefectScore();
+        notTopHighDefectScore = bookTest.getNotTopHighDefectScore();
+        notTopMidDefectScore = bookTest.getNotTopMidDefectScore();
+        notTopLowDefectScore = bookTest.getNotTopLowDefectScore();
+        notTopVeryLowDefectScore = bookTest.getNotTopVeryLowDefectScore();
+        topVeryHighDefectScore = bookTest.getTopVeryHighDefectScore();
+        topHighDefectScore = bookTest.getTopHighDefectScore();
+        topMidDefectScore = bookTest.getTopMidDefectScore();
+        topLowDefectScore = bookTest.getTopLowDefectScore();
+        topVeryLowDefectScore = bookTest.getTopVeryLowDefectScore();
+        onlyOneVeryHighDefectScore = bookTest.getOnlyOneVeryHighDefectScore();
+        onlyOneHighDefectScore = bookTest.getOnlyOneHighDefectScore();
+        onlyOneMidDefectScore = bookTest.getOnlyOneMidDefectScore();
+        onlyOneLowDefectScore = bookTest.getOnlyOneLowDefectScore();
+        onlyOneVeryLowDefectScore = bookTest.getOnlyOneVeryLowDefectScore();
+        defectScore = bookTest.getDefectScore();
+    }
+
+    String formatTime(Date date) {
+        if (date == null) {
+            return "-";
+        }
+        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
+    }
+
+    void formatStateName(int state){
+        switch (state) {
+            case BookTest.STATE_DEFAULT:
+                stateName = "未提现";
+                break;
+            case BookTest.STATE_COMMIT:
+                stateName = "待审核";
+                break;
+            case BookTest.STATE_AUDIT:
+                stateName = "已审核";
+                break;
+            default:
+        }
+    }
+}

+ 27 - 0
site/src/main/java/com/mooctest/crowd/site/service/BookTestService.java

@@ -0,0 +1,27 @@
+package com.mooctest.crowd.site.service;
+
+import com.mooctest.crowd.domain.domainobject.BookTest;
+import com.mooctest.crowd.site.data.dto.BalancePageDTO;
+import com.mooctest.crowd.site.data.dto.BookTestPageDTO;
+import com.mooctest.crowd.site.data.vo.BalanceVO;
+import com.mooctest.crowd.site.data.vo.BookTestVO;
+import com.mooctest.crowd.site.data.vo.ResourceVO;
+import com.mooctest.crowd.site.data.vo.TaskAmountVO;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public interface BookTestService {
+
+    BookTestPageDTO getBookTestPageInfo(Pageable pageable, Map<String, String> extraCondition, String keyword, int deletedStatus);
+    BookTestPageDTO getBookProjectTestPageInfo(Pageable pageable, Map<String, String> extraCondition, String keyword, int deletedStatus);
+    BookTestVO getBookDetailed(int id);
+    BalancePageDTO getBalDetailed(Pageable pageable, Map<String, String> extraCondition, int deletedStatus);
+    BalancePageDTO getBalDetailedBycode(Pageable pageable, Map<String, String> extraCondition, int deletedStatus);
+    int updateState(int id);
+    int examineState(int id);
+    void saveBookTest(TaskAmountVO taskAmountVO);
+}

+ 142 - 0
site/src/main/java/com/mooctest/crowd/site/service/impl/BookTestServiceImpl.java

@@ -0,0 +1,142 @@
+package com.mooctest.crowd.site.service.impl;
+
+import com.mooctest.crowd.domain.dao.BookTestDao;
+import com.mooctest.crowd.domain.domainobject.*;
+import com.mooctest.crowd.domain.model.BalancePO;
+import com.mooctest.crowd.domain.model.BookTestPO;
+import com.mooctest.crowd.domain.model.ResourcePO;
+import com.mooctest.crowd.domain.model.ResourceTypePO;
+import com.mooctest.crowd.domain.repository.BookTestRepo;
+import com.mooctest.crowd.domain.repository.CrowdTestProjectRepo;
+import com.mooctest.crowd.domain.util.Converter;
+import com.mooctest.crowd.site.data.dto.BalancePageDTO;
+import com.mooctest.crowd.site.data.dto.BookTestPageDTO;
+import com.mooctest.crowd.site.data.vo.*;
+import com.mooctest.crowd.site.service.BookTestService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+import springfox.documentation.builders.BuilderDefaults;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@Service
+public class  BookTestServiceImpl implements BookTestService {
+
+    @Autowired
+    private BookTestRepo bookTestRepo;
+
+    private TaskAmountVO taskAmountVO;
+    @Autowired
+    private CrowdTestProjectRepo projectRepo;
+
+    @Override
+    public BookTestPageDTO getBookTestPageInfo(Pageable pageable, Map<String, String> extraCondition, String keyword, int deletedStatus) {
+        BookTestPageDTO bookTestPageDTO = new BookTestPageDTO();
+        bookTestPageDTO.setBookTestPageDTOPage(bookTestRepo.findAllBookTestByPage(pageable,extraCondition, keyword).map(BookTestVO::new));
+        bookTestPageDTO.setSummary(bookTestRepo.findSummaryByUid(extraCondition.get("userId")));
+        return bookTestPageDTO;
+    }
+
+    @Override
+    public BookTestPageDTO getBookProjectTestPageInfo(Pageable pageable, Map<String, String> extraCondition, String keyword, int deletedStatus) {
+        BookTestPageDTO bookTestPageDTO = new BookTestPageDTO();
+        bookTestPageDTO.setBookTestPageDTOPage(bookTestRepo.findAllProjectBookTestByPage(pageable,extraCondition, keyword).map(BookTestVO::new));
+        bookTestPageDTO.setSummary(bookTestRepo.findSummaryByUid(extraCondition.get("userId")));
+        return bookTestPageDTO;    }
+
+    @Override
+    public BookTestVO getBookDetailed(int id) {
+        BookTest bookTest = bookTestRepo.findById(id);
+        return new BookTestVO(bookTest);
+    }
+
+    @Override
+    public BalancePageDTO getBalDetailed(Pageable pageable, Map<String, String> extraCondition, int deletedStatus) {
+        BalancePageDTO balancePageDTO = new BalancePageDTO();
+        balancePageDTO.setBalancePageDTOPage(bookTestRepo.findAllBookTestByPage(pageable,extraCondition).map(BalanceVO::new));
+        return balancePageDTO;
+    }
+
+    @Override
+    public BalancePageDTO getBalDetailedBycode(Pageable pageable, Map<String, String> extraCondition, int deletedStatus) {
+        BalancePageDTO balancePageDTO = new BalancePageDTO();
+        balancePageDTO.setBalancePageDTOPage(bookTestRepo.findprojectAllBookTestByPage(pageable,extraCondition).map(BalanceVO::new));
+        return balancePageDTO;
+    }
+
+    public int updateState(int id) {
+        return bookTestRepo.updateState(BookTest.STATE_COMMIT,id);
+    }
+
+    public int examineState(int id) {
+        return bookTestRepo.examineState(BookTest.STATE_AUDIT,id);
+    }
+
+    @Override
+    public void saveBookTest(TaskAmountVO taskAmountVO) {
+        BookTestPO book = new BookTestPO();
+        List<TaskAmountVO.TesterAmountVO> testerAmounts = taskAmountVO.getTesterAmounts();
+        if (testerAmounts.size() > 0) {
+            for (TaskAmountVO.TesterAmountVO testerAmount : testerAmounts) {
+                book.setUid(testerAmount.getTesterId());
+                //根据项目编号查询发包机构ID
+                String cptcode = taskAmountVO.getProjectCode();
+                if (cptcode != null && cptcode.length() > 0) {
+                    CrowdTestProject project = projectRepo.getByProjectCode(cptcode);
+                    if(project != null)
+                    book.setRmid(project.getRegionalManagerId());
+                }
+                book.setCttcode(taskAmountVO.getTaskCode());
+                book.setCptcode(taskAmountVO.getProjectCode());
+                book.setEffectiveWorkloadAmount(testerAmount.getEffectiveWorkloadAmount());
+                book.setDefectExciationAmount(testerAmount.getDefectExciationAmount());
+                book.setExtraRewardAmount(testerAmount.getExtraRewardAmount());
+                book.setState(0);
+                BigDecimal effectiveWorkloadAmount = testerAmount.getEffectiveWorkloadAmount();
+                BigDecimal defectExciationAmount = testerAmount.getDefectExciationAmount();
+                BigDecimal extraRewardAmount = testerAmount.getExtraRewardAmount();
+                BigDecimal totalAmount = effectiveWorkloadAmount.add(defectExciationAmount).add(extraRewardAmount);
+                book.setTotalAmount(totalAmount);
+                //缺陷数量
+                book.setNotTopHighDefectCount(testerAmount.getNotTopHighDefectCount());
+                book.setNotTopLowDefectCount(testerAmount.getNotTopLowDefectCount());
+                book.setNotTopMidDefectCount(testerAmount.getNotTopMidDefectCount());
+                book.setNotTopVeryHighDefectCount(testerAmount.getNotTopVeryHighDefectCount());
+                book.setNotTopVeryLowDefectCount(testerAmount.getNotTopVeryLowDefectCount());
+                book.setOnlyOneHighDefectCount(testerAmount.getOnlyOneHighDefectCount());
+                book.setOnlyOneLowDefectCount(testerAmount.getOnlyOneLowDefectCount());
+                book.setOnlyOneMidDefectCount(testerAmount.getOnlyOneMidDefectCount());
+                book.setOnlyOneVeryHighDefectCount(testerAmount.getOnlyOneVeryHighDefectCount());
+                book.setOnlyOneVeryLowDefectCount(testerAmount.getOnlyOneVeryLowDefectCount());
+                book.setTopHighDefectCount(testerAmount.getTopHighDefectCount());
+                book.setTopLowDefectCount(testerAmount.getTopLowDefectCount());
+                book.setTopMidDefectCount(testerAmount.getTopMidDefectCount());
+                book.setTopVeryHighDefectCount(testerAmount.getTopVeryHighDefectCount());
+                book.setTopVeryLowDefectCount(testerAmount.getTopVeryLowDefectCount());
+                //缺陷得分
+                book.setNotTopHighDefectScore(testerAmount.getNotTopHighDefectScore());
+                book.setNotTopLowDefectScore(testerAmount.getNotTopLowDefectScore());
+                book.setNotTopMidDefectScore(testerAmount.getNotTopMidDefectScore());
+                book.setNotTopVeryHighDefectScore(testerAmount.getNotTopVeryHighDefectScore());
+                book.setNotTopVeryLowDefectScore(testerAmount.getNotTopVeryLowDefectScore());
+                book.setOnlyOneHighDefectScore(testerAmount.getOnlyOneHighDefectScore());
+                book.setOnlyOneLowDefectScore(testerAmount.getOnlyOneLowDefectScore());
+                book.setOnlyOneMidDefectScore(testerAmount.getOnlyOneMidDefectScore());
+                book.setOnlyOneVeryHighDefectScore(testerAmount.getOnlyOneVeryHighDefectScore());
+                book.setOnlyOneVeryLowDefectScore(testerAmount.getOnlyOneVeryLowDefectScore());
+                book.setTopHighDefectScore(testerAmount.getTopHighDefectScore());
+                book.setTopLowDefectScore(testerAmount.getTopLowDefectScore());
+                book.setTopMidDefectScore(testerAmount.getTopMidDefectScore());
+                book.setTopVeryHighDefectScore(testerAmount.getTopVeryHighDefectScore());
+                book.setTopVeryLowDefectScore(testerAmount.getTopVeryLowDefectScore());
+                bookTestRepo.saveBookTest(book);
+            }
+            }
+
+    }
+
+}

+ 5 - 1
site/src/main/java/com/mooctest/crowd/site/service/impl/TaskAmountServiceImpl.java

@@ -203,7 +203,11 @@ public class TaskAmountServiceImpl implements TaskAmountService {
         userIdTaskAmountInfoMap.values().stream().forEach(testerAmountVO -> {
             BigDecimal defectScoreDecimal = BigDecimal.valueOf(testerAmountVO.getDefectScore());
             BigDecimal effectiveTestCaseCountDecimal = BigDecimal.valueOf(testerAmountVO.getEffectiveTestCaseCount());
-            testerAmountVO.setDefectExciationAmount(taskAmountVO.getDefectExciationAmount().multiply(defectScoreDecimal.divide(totalDefectScoreDecimal, 10, RoundingMode.HALF_UP)).setScale(2, BigDecimal.ROUND_FLOOR));
+            if(totalDefectScoreDecimal.intValue()==0){
+                testerAmountVO.setDefectExciationAmount(BigDecimal.valueOf(0));
+            }else{
+                testerAmountVO.setDefectExciationAmount(taskAmountVO.getDefectExciationAmount().multiply(defectScoreDecimal.divide(totalDefectScoreDecimal, 10, RoundingMode.HALF_UP)).setScale(2, BigDecimal.ROUND_FLOOR));
+            }
             testerAmountVO.setEffectiveWorkloadAmount(taskAmountVO.getEffectiveWorkloadAmount().multiply(effectiveTestCaseCountDecimal.divide(totalEffectiveTestCaseCountDecimal, 10, RoundingMode.HALF_UP)).setScale(2, BigDecimal.ROUND_FLOOR));
             taskAmountVO.getTesterAmounts().add(testerAmountVO);
         });