Ver Fonte

【feat】【v3】
1.优化结算逻辑代码
2.增加结算时的账户数据处理
3.优化表结构

ChenYL há 11 meses atrás
pai
commit
8bc2d9d5e1
27 ficheiros alterados com 478 adições e 210 exclusões
  1. 2 1
      doc/sql/update-v3.sql
  2. 19 18
      doc/技术文档.md
  3. 4 2
      src/main/java/com/punchsettle/server/atomic/entity/Account.java
  4. 8 0
      src/main/java/com/punchsettle/server/atomic/entity/AccountTransferHistory.java
  5. 2 1
      src/main/java/com/punchsettle/server/atomic/mapper/AccountMapper.java
  6. 2 1
      src/main/java/com/punchsettle/server/atomic/mapper/AccountTransferHistoryMapper.java
  7. 18 0
      src/main/java/com/punchsettle/server/atomic/service/IAccountService.java
  8. 10 0
      src/main/java/com/punchsettle/server/atomic/service/IAccountTransferHistoryService.java
  9. 37 0
      src/main/java/com/punchsettle/server/atomic/service/impl/AccountServiceImpl.java
  10. 15 0
      src/main/java/com/punchsettle/server/atomic/service/impl/AccountTransferHistoryServiceImpl.java
  11. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/PiMultiTaskExtServiceImpl.java
  12. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/PiMultiTaskHistoryServiceImpl.java
  13. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/PiMultiTaskRelaServiceImpl.java
  14. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/PiMultiTaskServiceImpl.java
  15. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/PiStatusServiceImpl.java
  16. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/PiTaskExtServiceImpl.java
  17. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/PiTaskHistoryServiceImpl.java
  18. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/StatPiTaskMonthServiceImpl.java
  19. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/SysDictItemServiceImpl.java
  20. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/SysDictServiceImpl.java
  21. 1 1
      src/main/java/com/punchsettle/server/atomic/service/impl/UserServiceImpl.java
  22. 23 0
      src/main/java/com/punchsettle/server/constant/AccountCategoryEnum.java
  23. 23 0
      src/main/java/com/punchsettle/server/constant/TransferCategoryEnum.java
  24. 26 0
      src/main/java/com/punchsettle/server/pojo/punchIn/AccountQuery.java
  25. 6 0
      src/main/java/com/punchsettle/server/pojo/punchIn/PunchInSettleData.java
  26. 271 175
      src/main/java/com/punchsettle/server/service/manager/impl/PunchInSettleManagerImpl.java
  27. 1 1
      src/main/java/com/punchsettle/server/service/manager/impl/StatPiTaskWeekServiceImpl.java

+ 2 - 1
doc/sql/update-v3.sql

@@ -160,7 +160,7 @@ CREATE TABLE `account` (
   `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
   `user_id` bigint NOT NULL COMMENT '用户id',
   `account_name` varchar(100) NOT NULL COMMENT '账户名称',
-  `account_type` varchar(10) NOT NULL COMMENT '账户类型(BASIC-基本户,GENERAL-一般户)',
+  `account_category` varchar(10) NOT NULL COMMENT '账户类型(BASIC-基本户,GENERAL-一般户)',
   `points` int NOT NULL COMMENT '奖励积分',
   `created_by` bigint NOT NULL COMMENT '创建人',
   `creation_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
@@ -177,6 +177,7 @@ CREATE TABLE `account_transfer_history` (
   `user_id` bigint NOT NULL COMMENT '用户id',
   `sender_account_id` bigint NOT NULL COMMENT '转出账户id',
   `recipient_account_id` bigint NOT NULL COMMENT '转入账户id',
+  `transfer_category` varchar(10) NOT NULL COMMENT '转账类型(转账-TRANSFER,结算-SETTLE)',
   `transfer_points` int NOT NULL COMMENT '转账积分',
   `sa_points_before_transfer` int NOT NULL COMMENT '转出账户转出前积分',
   `sa_points_after_transfer` int NOT NULL COMMENT '转出账户转出后积分',

+ 19 - 18
doc/技术文档.md

@@ -1076,7 +1076,7 @@ ui设计工具:即时设计
 | id               | bigint       | 主键                                     | 主键索引 |
 | user_id          | bigint       | 用户id                                   | 普通索引 |
 | account_name     | varchar(100) | 账户名称                                 |          |
-| account_type     | varchar(30)  | 账户类型(BASIC-基本户,GENERAL-一般户) |          |
+| account_category | varchar(30)  | 账户类型(BASIC-基本户,GENERAL-一般户) |          |
 | points           | int          | 奖励积分                                 |          |
 | created_by       | bigint       | 创建人                                   |          |
 | creation_time    | timestamp    | 创建时间                                 |          |
@@ -1091,23 +1091,24 @@ ui设计工具:即时设计
 
 表名:account_transfer_history
 
-| 字段                      | 类型      | 描述                               | 索引     |
-| ------------------------- | --------- | ---------------------------------- | -------- |
-| id                        | bigint    | 主键                               | 主键索引 |
-| user_id                   | bigint    | 用户id                             | 普通索引 |
-| sender_account_id         | bigint    | 转出账户id                         |          |
-| recipient_account_id      | bigint    | 转入账户id                         |          |
-| transfer_points           | int       | 转账积分                           |          |
-| sa_points_before_transfer | int       | 转出账户转出前积分                 |          |
-| sa_points_after_transfer  | int       | 转出账户转出后积分                 |          |
-| ra_points_before_transfer | int       | 转入账户转入前积分                 |          |
-| ra_points_after_transfer  | int       | 转入账户转入后积分                 |          |
-| created_by                | bigint    | 创建人                             |          |
-| creation_time             | timestamp | 创建时间                           | 普通索引 |
-| last_updated_by           | bigint    | 最后更新人                         |          |
-| last_update_time          | timestamp | 最后更新时间                       |          |
-| version                   | bigint    | 版本号                             |          |
-| delete_flag               | tinyint   | 逻辑删除标志(0-未删除,1-已删除) |          |
+| 字段                      | 类型        | 描述                                   | 索引     |
+| ------------------------- | ----------- | -------------------------------------- | -------- |
+| id                        | bigint      | 主键                                   | 主键索引 |
+| user_id                   | bigint      | 用户id                                 | 普通索引 |
+| sender_account_id         | bigint      | 转出账户id                             |          |
+| recipient_account_id      | bigint      | 转入账户id                             |          |
+| transfer_category         | varchar(10) | 转账类型(转账-TRANSFER,结算-SETTLE) |          |
+| transfer_points           | int         | 转账积分                               |          |
+| sa_points_before_transfer | int         | 转出账户转出前积分                     |          |
+| sa_points_after_transfer  | int         | 转出账户转出后积分                     |          |
+| ra_points_before_transfer | int         | 转入账户转入前积分                     |          |
+| ra_points_after_transfer  | int         | 转入账户转入后积分                     |          |
+| created_by                | bigint      | 创建人                                 |          |
+| creation_time             | timestamp   | 创建时间                               | 普通索引 |
+| last_updated_by           | bigint      | 最后更新人                             |          |
+| last_update_time          | timestamp   | 最后更新时间                           |          |
+| version                   | bigint      | 版本号                                 |          |
+| delete_flag               | tinyint     | 逻辑删除标志(0-未删除,1-已删除)     |          |
 
 
 

+ 4 - 2
src/main/java/com/punchsettle/server/atomic/entity/Account.java

@@ -5,6 +5,7 @@ import java.io.Serializable;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
 
+import com.punchsettle.server.constant.AccountCategoryEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
@@ -38,9 +39,10 @@ public class Account extends BaseEntity implements Serializable {
 
     /**
      * 账户类型(BASIC-基本户,GENERAL-一般户)
+     * @see AccountCategoryEnum
      */
-    @Column(name = "account_type")
-    private String accountType;
+    @Column(name = "account_category")
+    private AccountCategoryEnum accountCategory;
 
     /**
      * 奖励积分

+ 8 - 0
src/main/java/com/punchsettle/server/atomic/entity/AccountTransferHistory.java

@@ -5,6 +5,7 @@ import java.io.Serializable;
 
 import com.punchsettle.server.common.pojo.BaseEntity;
 
+import com.punchsettle.server.constant.TransferCategoryEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
@@ -42,6 +43,13 @@ public class AccountTransferHistory extends BaseEntity implements Serializable {
     @Column(name = "recipient_account_id")
     private Long recipientAccountId;
 
+    /**
+     * 转账类型(转账-TRANSFER,结算-SETTLE)
+     * @see TransferCategoryEnum
+     */
+    @Column(name ="transfer_category")
+    private TransferCategoryEnum transferCategory;
+
     /**
      * 转账积分
      */

+ 2 - 1
src/main/java/com/punchsettle/server/atomic/mapper/AccountMapper.java

@@ -1,6 +1,7 @@
 package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.Account;
+import tk.mybatis.mapper.additional.update.batch.BatchUpdateSelectiveMapper;
 import tk.mybatis.mapper.common.Mapper;
 
 /**
@@ -9,6 +10,6 @@ import tk.mybatis.mapper.common.Mapper;
  * @description 账户 Mapper
  * @date 2025/04/08 10:30
  */
-public interface AccountMapper extends Mapper<Account> {
+public interface AccountMapper extends Mapper<Account>, BatchUpdateSelectiveMapper<Account> {
 
 }

+ 2 - 1
src/main/java/com/punchsettle/server/atomic/mapper/AccountTransferHistoryMapper.java

@@ -2,6 +2,7 @@ package com.punchsettle.server.atomic.mapper;
 
 import com.punchsettle.server.atomic.entity.AccountTransferHistory;
 import tk.mybatis.mapper.common.Mapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
 
 /**
  * @author tyuio
@@ -9,6 +10,6 @@ import tk.mybatis.mapper.common.Mapper;
  * @description 账户转账记录 Mapper
  * @date 2025/04/08 10:30
  */
-public interface AccountTransferHistoryMapper extends Mapper<AccountTransferHistory> {
+public interface AccountTransferHistoryMapper extends Mapper<AccountTransferHistory>, InsertListMapper<AccountTransferHistory> {
 
 }

+ 18 - 0
src/main/java/com/punchsettle/server/atomic/service/IAccountService.java

@@ -1,5 +1,10 @@
 package com.punchsettle.server.atomic.service;
 
+import com.punchsettle.server.atomic.entity.Account;
+import com.punchsettle.server.pojo.punchIn.AccountQuery;
+
+import java.util.List;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -7,4 +12,17 @@ package com.punchsettle.server.atomic.service;
  * @description 账户 service
  */
 public interface IAccountService {
+
+    /**
+     * 获取账户
+     * @param accountQuery
+     * @return
+     */
+    List<Account> getAccountByCondition(AccountQuery accountQuery);
+
+    /**
+     * 批量更新
+     * @param accounts
+     */
+    void batchUpdate(List<Account> accounts);
 }

+ 10 - 0
src/main/java/com/punchsettle/server/atomic/service/IAccountTransferHistoryService.java

@@ -1,5 +1,9 @@
 package com.punchsettle.server.atomic.service;
 
+import com.punchsettle.server.atomic.entity.AccountTransferHistory;
+
+import java.util.List;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -7,4 +11,10 @@ package com.punchsettle.server.atomic.service;
  * @description 账户转账记录 service
  */
 public interface IAccountTransferHistoryService {
+
+    /**
+     * 批量插入
+     * @param accountTransferHistories
+     */
+    void batchInsert(List<AccountTransferHistory> accountTransferHistories);
 }

+ 37 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/AccountServiceImpl.java

@@ -1,7 +1,20 @@
 package com.punchsettle.server.atomic.service.impl;
 
+import com.punchsettle.server.atomic.entity.Account;
+import com.punchsettle.server.atomic.mapper.AccountMapper;
 import com.punchsettle.server.atomic.service.IAccountService;
+import com.punchsettle.server.common.utils.Assert;
+import com.punchsettle.server.constant.AccountCategoryEnum;
+import com.punchsettle.server.pojo.punchIn.AccountQuery;
+import com.punchsettle.server.utiis.WeekendUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import tk.mybatis.mapper.weekend.Weekend;
+import tk.mybatis.mapper.weekend.WeekendCriteria;
+
+import java.util.List;
+import java.util.Objects;
 
 /**
  * @author tyuio
@@ -11,4 +24,28 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class AccountServiceImpl implements IAccountService {
+
+    @Autowired
+    private AccountMapper accountMapper;
+
+    @Override
+    public List<Account> getAccountByCondition(AccountQuery accountQuery) {
+        Assert.isNull(accountQuery);
+
+        Weekend<Account> weekend = WeekendUtils.createExcludeAuditFields(Account.class);
+        WeekendCriteria<Account, Object> criteria = weekend.weekendCriteria();
+        if (Objects.nonNull(accountQuery.getAccountCategory())) {
+            criteria.andEqualTo(Account::getAccountCategory, accountQuery.getAccountCategory());
+        }
+        if (!CollectionUtils.isEmpty(accountQuery.getUserIds())) {
+            criteria.andIn(Account::getUserId, accountQuery.getUserIds());
+        }
+        return accountMapper.selectByExample(weekend);
+    }
+
+    @Override
+    public void batchUpdate(List<Account> accounts) {
+        Assert.notEmpty(accounts);
+        accountMapper.batchUpdateSelective(accounts);
+    }
 }

+ 15 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/AccountTransferHistoryServiceImpl.java

@@ -1,8 +1,14 @@
 package com.punchsettle.server.atomic.service.impl;
 
+import com.punchsettle.server.atomic.entity.AccountTransferHistory;
+import com.punchsettle.server.atomic.mapper.AccountTransferHistoryMapper;
 import com.punchsettle.server.atomic.service.IAccountTransferHistoryService;
+import com.punchsettle.server.common.utils.Assert;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -12,4 +18,13 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class AccountTransferHistoryServiceImpl implements IAccountTransferHistoryService {
+
+    @Autowired
+    private AccountTransferHistoryMapper accountTransferHistoryMapper;
+
+    @Override
+    public void batchInsert(List<AccountTransferHistory> accountTransferHistories) {
+        Assert.isNull(accountTransferHistories);
+        accountTransferHistoryMapper.insertList(accountTransferHistories);
+    }
 }

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/PiMultiTaskExtServiceImpl.java

@@ -30,7 +30,7 @@ public class PiMultiTaskExtServiceImpl implements IPiMultiTaskExtService {
     public List<PiMultiTaskExt> queryByCondition(PiMultiTaskExtQuery piMultiTaskExtQuery) {
         Assert.isNull(piMultiTaskExtQuery);
 
-        Weekend<PiMultiTaskExt> weekend = WeekendUtils.createExcludeProperties(PiMultiTaskExt.class);
+        Weekend<PiMultiTaskExt> weekend = WeekendUtils.createExcludeAuditFields(PiMultiTaskExt.class);
         WeekendCriteria<PiMultiTaskExt, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(piMultiTaskExtQuery.getMultiTaskIds())) {
             criteria.andIn(PiMultiTaskExt::getMultiTaskId, piMultiTaskExtQuery.getMultiTaskIds());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/PiMultiTaskHistoryServiceImpl.java

@@ -31,7 +31,7 @@ public class PiMultiTaskHistoryServiceImpl implements IPiMultiTaskHistoryService
     public List<PiMultiTaskHistory> queryByCondition(PiMultiTaskHistoryQuery piMultiTaskHistoryQuery) {
         Assert.isNull(piMultiTaskHistoryQuery);
 
-        Weekend<PiMultiTaskHistory> weekend = WeekendUtils.createExcludeProperties(PiMultiTaskHistory.class);
+        Weekend<PiMultiTaskHistory> weekend = WeekendUtils.createExcludeAuditFields(PiMultiTaskHistory.class);
         WeekendCriteria<PiMultiTaskHistory, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(piMultiTaskHistoryQuery.getPunchInMultiTaskUniqueIds())) {
             criteria.andIn(PiMultiTaskHistory::getMultiTaskUniqueId, piMultiTaskHistoryQuery.getPunchInMultiTaskUniqueIds());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/PiMultiTaskRelaServiceImpl.java

@@ -30,7 +30,7 @@ public class PiMultiTaskRelaServiceImpl implements IPiMultiTaskRelaService {
         if (!CollectionUtils.isEmpty(multiTaskIds)) {
             return List.of();
         }
-        Weekend<PiMultiTaskRela> weekend = WeekendUtils.createExcludeProperties(PiMultiTaskRela.class);
+        Weekend<PiMultiTaskRela> weekend = WeekendUtils.createExcludeAuditFields(PiMultiTaskRela.class);
         WeekendCriteria<PiMultiTaskRela, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(multiTaskIds)) {
             criteria.andIn(PiMultiTaskRela::getMultiTaskId, multiTaskIds);

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/PiMultiTaskServiceImpl.java

@@ -31,7 +31,7 @@ public class PiMultiTaskServiceImpl implements IPiMultiTaskService {
     public List<PiMultiTask> queryByCondition(PiMultiTaskQuery piMultiTaskQuery) {
         Assert.isNull(piMultiTaskQuery);
 
-        Weekend<PiMultiTask> weekend = WeekendUtils.createExcludeProperties(PiMultiTask.class);
+        Weekend<PiMultiTask> weekend = WeekendUtils.createExcludeAuditFields(PiMultiTask.class);
         WeekendCriteria<PiMultiTask, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(piMultiTaskQuery.getUserIds())) {
             criteria.andIn(PiMultiTask::getUserId, piMultiTaskQuery.getUserIds());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/PiStatusServiceImpl.java

@@ -30,7 +30,7 @@ public class PiStatusServiceImpl implements IPiStatusService {
     public List<PiStatus> queryByCondition(PiStatusQuery piStatusQuery) {
         Assert.isNull(piStatusQuery);
 
-        Weekend<PiStatus> weekend = WeekendUtils.createExcludeProperties(PiStatus.class);
+        Weekend<PiStatus> weekend = WeekendUtils.createExcludeAuditFields(PiStatus.class);
         WeekendCriteria<PiStatus, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(piStatusQuery.getTaskUniqueIds())) {
             criteria.andIn(PiStatus::getTaskUniqueId, piStatusQuery.getTaskUniqueIds());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/PiTaskExtServiceImpl.java

@@ -30,7 +30,7 @@ public class PiTaskExtServiceImpl implements IPiTaskExtService {
     public List<PiTaskExt> queryByCondition(PiTaskExtQuery piTaskExtQuery) {
         Assert.isNull(piTaskExtQuery);
 
-        Weekend<PiTaskExt> weekend = WeekendUtils.createExcludeProperties(PiTaskExt.class);
+        Weekend<PiTaskExt> weekend = WeekendUtils.createExcludeAuditFields(PiTaskExt.class);
         WeekendCriteria<PiTaskExt, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(piTaskExtQuery.getPunchInTaskIds())) {
             criteria.andIn(PiTaskExt::getTaskId, piTaskExtQuery.getPunchInTaskIds());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/PiTaskHistoryServiceImpl.java

@@ -31,7 +31,7 @@ public class PiTaskHistoryServiceImpl implements IPiTaskHistoryService {
     public List<PiTaskHistory> queryByCondition(PiTaskHistoryQuery piTaskHistoryQuery) {
         Assert.isNull(piTaskHistoryQuery);
 
-        Weekend<PiTaskHistory> weekend = WeekendUtils.createExcludeProperties(PiTaskHistory.class);
+        Weekend<PiTaskHistory> weekend = WeekendUtils.createExcludeAuditFields(PiTaskHistory.class);
         WeekendCriteria<PiTaskHistory, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(piTaskHistoryQuery.getUserIds())) {
             criteria.andIn(PiTaskHistory::getUserId, piTaskHistoryQuery.getUserIds());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/StatPiTaskMonthServiceImpl.java

@@ -31,7 +31,7 @@ public class StatPiTaskMonthServiceImpl implements IStatPiTaskMonthService {
     public List<StatPiTaskMonth> queryByCondition(PiStatsMonthQuery piStatsMonthQuery) {
         Assert.isNull(piStatsMonthQuery);
 
-        Weekend<StatPiTaskMonth> weekend = WeekendUtils.createExcludeProperties(StatPiTaskMonth.class);
+        Weekend<StatPiTaskMonth> weekend = WeekendUtils.createExcludeAuditFields(StatPiTaskMonth.class);
         WeekendCriteria<StatPiTaskMonth, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(piStatsMonthQuery.getTaskUniqueIds())) {
             criteria.andIn(StatPiTaskMonth::getTaskUniqueId, piStatsMonthQuery.getTaskUniqueIds());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/SysDictItemServiceImpl.java

@@ -33,7 +33,7 @@ public class SysDictItemServiceImpl implements ISysDictItemService {
             return List.of();
         }
 
-        Weekend<SysDictItem> weekend = WeekendUtils.createExcludeProperties(SysDictItem.class);
+        Weekend<SysDictItem> weekend = WeekendUtils.createExcludeAuditFields(SysDictItem.class);
         WeekendCriteria<SysDictItem, Object> criteria = weekend.weekendCriteria();
         if (Objects.nonNull(dictItemQuery.getDictId())) {
             criteria.andEqualTo(SysDictItem::getDictId, dictItemQuery.getDictId());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/SysDictServiceImpl.java

@@ -33,7 +33,7 @@ public class SysDictServiceImpl implements ISysDictService {
             return null;
         }
 
-        Weekend<SysDict> weekend = WeekendUtils.createExcludeProperties(SysDict.class);
+        Weekend<SysDict> weekend = WeekendUtils.createExcludeAuditFields(SysDict.class);
         WeekendCriteria<SysDict, Object> criteria = weekend.weekendCriteria();
         if (StringUtils.hasText(dictQuery.getDictCode())) {
             criteria.andEqualTo(SysDict::getDictCode, dictQuery.getDictCode());

+ 1 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/UserServiceImpl.java

@@ -71,7 +71,7 @@ public class UserServiceImpl implements IUserService {
             return List.of();
         }
 
-        Weekend<User> weekend = WeekendUtils.createExcludeProperties(User.class);
+        Weekend<User> weekend = WeekendUtils.createExcludeAuditFields(User.class);
         WeekendCriteria<User, Object> criteria = weekend.weekendCriteria();
         criteria.andIn(User::getId, ids);
         return userMapper.selectByExample(weekend);

+ 23 - 0
src/main/java/com/punchsettle/server/constant/AccountCategoryEnum.java

@@ -0,0 +1,23 @@
+package com.punchsettle.server.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/23 8:37
+ * @description 账户类型枚举(BASIC-基本户,GENERAL-一般户)
+ */
+@Getter
+@AllArgsConstructor
+public enum AccountCategoryEnum {
+
+    BASIC("基本户"),
+    GENERAL("一般户");
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 23 - 0
src/main/java/com/punchsettle/server/constant/TransferCategoryEnum.java

@@ -0,0 +1,23 @@
+package com.punchsettle.server.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/23 8:28
+ * @description 转账类型枚举(转账-TRANSFER,结算-SETTLE)
+ */
+@Getter
+@AllArgsConstructor
+public enum TransferCategoryEnum {
+
+    TRANSFER("转账"),
+    SETTLE("结算");
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 26 - 0
src/main/java/com/punchsettle/server/pojo/punchIn/AccountQuery.java

@@ -0,0 +1,26 @@
+package com.punchsettle.server.pojo.punchIn;
+
+import com.punchsettle.server.constant.AccountCategoryEnum;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/4/23 8:40
+ * @description 账户查询类
+ */
+@Data
+public class AccountQuery {
+
+    /**
+     * 用户id列表
+     */
+    private List<Long> userIds;
+
+    /**
+     * 账户类型
+     */
+    private AccountCategoryEnum accountCategory;
+}

+ 6 - 0
src/main/java/com/punchsettle/server/pojo/punchIn/PunchInSettleData.java

@@ -1,5 +1,6 @@
 package com.punchsettle.server.pojo.punchIn;
 
+import com.punchsettle.server.atomic.entity.Account;
 import com.punchsettle.server.atomic.entity.PiMultiTask;
 import com.punchsettle.server.atomic.entity.PiMultiTaskExt;
 import com.punchsettle.server.atomic.entity.PiMultiTaskHistory;
@@ -29,6 +30,11 @@ public class PunchInSettleData {
      */
     private User user;
 
+    /**
+     * 账户
+     */
+    private Account account;
+
     /**
      * 打卡多任务
      */

+ 271 - 175
src/main/java/com/punchsettle/server/service/manager/impl/PunchInSettleManagerImpl.java

@@ -13,6 +13,13 @@ import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import com.punchsettle.server.atomic.entity.Account;
+import com.punchsettle.server.atomic.entity.AccountTransferHistory;
+import com.punchsettle.server.atomic.service.IAccountService;
+import com.punchsettle.server.atomic.service.IAccountTransferHistoryService;
+import com.punchsettle.server.constant.AccountCategoryEnum;
+import com.punchsettle.server.constant.TransferCategoryEnum;
+import com.punchsettle.server.pojo.punchIn.AccountQuery;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -135,6 +142,12 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
     @Autowired
     private ISettleManager settleManager;
 
+    @Autowired
+    private IAccountService accountService;
+
+    @Autowired
+    private IAccountTransferHistoryService accountTransferHistoryService;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void punchInSettle(List<Long> userIds, String punchInDateStr, Long settleTaskHistoryId) {
@@ -161,6 +174,10 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
         List<StatPiTaskMonth> addStatPiTaskMonthList = new ArrayList<>();
         // 结算积分记录 新增列表
         List<SettlePointsHistory> addSettlePointsHistories = new ArrayList<>();
+        // 转张记录 新增列表
+        List<AccountTransferHistory> addAccountTransferHistories = new ArrayList<>();
+        // 账户 更新列表
+        List<Account> updateAccountList = new ArrayList<>();
         // 用户信息 更新列表
         List<User> updateUserList = new ArrayList<>();
         // 打卡状态 更新列表
@@ -168,7 +185,8 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
         // 打卡任务记录 更新列表
         List<PiTaskHistory> updatePunchInTaskHistories = new ArrayList<>();
         // 打卡多任务记录 更新列表
-        List<PiMultiTaskHistory> updatePunchInMultiTaskHistories = new ArrayList<>(userIds.size());
+        List<PiMultiTaskHistory> updatePunchInMultiTaskHistories = new ArrayList<>();
+        
         // 获取结算数据
         List<PunchInSettleData> punchInSettleData = getPunchInSettleData(userIds, punchInDateStr);
 
@@ -193,6 +211,7 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
                 BeanUtils.copyProperties(piStatus, piStatusHistoryInTask);
                 addPiStatusHistories.add(piStatusHistoryInTask);
 
+                // 打卡记录
                 PiTaskHistory updatePiTaskHistory = new PiTaskHistory();
                 updatePiTaskHistory.setId(piTaskHistory.getId());
 
@@ -209,126 +228,17 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
                 punchInSettle.getPiMultiTaskHistory().setPunchInResult(punchInResult);
                 updatePiTaskHistory.setPunchInResult(punchInResult);
 
-                // 更新状态表数据
+                // 更新打卡状态
                 piStatus.setStatusDate(punchInDateStr);
+                refreshPiStatus(piStatus, punchInResult, piTask, piTaskHistory, punchInDate, isMonday, isFirstDayOfMonth, yearWeek, yearMonth);
 
-                // 设置任务连续状态
-                ContinueStatusEnum oldTaskContinueStatus = piStatus.getTaskContinueStatus();
-                piStatus.setTaskContinueStatus(punchInResult.equals(PunchInResultEnum.DONE)
-                        ? ContinueStatusEnum.CONTINUE : ContinueStatusEnum.INTERRUPTED);
-                piStatus.setTaskContinueDay(oldTaskContinueStatus.equals(piStatus.getTaskContinueStatus())
-                        ? piStatus.getTaskContinueDay() + 1 : 1);
-
-                // 旧的连续阶段
-                ContinueStageEnum oldContinueStage = piStatus.getContinueStage();
-                // 判断当前处于的连续阶段
-                ContinueStageEnum continueStageResult =
-                        punchInManager.judgeContinueStageInTask(piTask, piTaskHistory, piStatus, punchInDate);
-                piStatus.setContinueStage(continueStageResult);
-                // 下面3种情况不处理:宽限期 变 宽限期;正常打卡期 变 正常打卡期;惩罚期 变 惩罚期;
-                // 宽限期 变 正常打卡期,则设置阶段开始时间,重置中断次数
-                if (ContinueStageEnum.GRACE_STAGE.equals(oldContinueStage)
-                        && ContinueStageEnum.NORMAL_STAGE.equals(continueStageResult)) {
-                    piStatus.setStageStartDate(punchInDate);
-                    piStatus.setContinueInterruptedCount(0);
-                }
-                // 如果正常打卡期 变 惩罚期,则设置阶段开始时间和阶段结束时间,增加中断次数
-                if (ContinueStageEnum.NORMAL_STAGE.equals(oldContinueStage)
-                        && ContinueStageEnum.PENALTY_STAGE.equals(continueStageResult)) {
-                    piStatus.setStageStartDate(punchInDate);
-                    piStatus.setStageEndDate(punchInDate.plusDays(piTask.getPenaltyDay()));
-                    piStatus.setContinueInterruptedCount(piStatus.getContinueInterruptedCount() + 1);
-                }
-                // 如果惩罚期 变 正常打卡期,则设置阶段开始时间
-                if (ContinueStageEnum.PENALTY_STAGE.equals(oldContinueStage)
-                        && ContinueStageEnum.NORMAL_STAGE.equals(continueStageResult)) {
-                    piStatus.setStageStartDate(punchInDate);
-                }
-
-                // 周一或月初
-                if (isMonday || isFirstDayOfMonth) {
-                    piStatus.setRepeatCategory(piTask.getRepeatCategory());
-                    piStatus.setRepeatCustomDay(piTask.getRepeatCustomDay());
-                }
-
-                // 周一
-                if (isMonday) {
-                    piStatus.setStatTimeInWeek(yearWeek);
-
-                    // 设置本周总打卡次数
-                    int PunchInTotalCountInWeek = punchInManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(),
-                            piTask.getRepeatCustomDay(), DateUtils.getFirstDayOfWeek(punchInDate),
-                            DateUtils.getLastDayOfWeek(punchInDate));
-                    piStatus.setPunchInTotalCountInWeek(PunchInTotalCountInWeek);
-
-                    // 重置数据
-                    piStatus.setPunchInCountInWeek(0);
-                    piStatus.setPunchInDoneCountInWeek(0);
-                    piStatus.setRepeatPrevTotalCountInWeek(0);
-                    piStatus.setRepeatStartDateInWeek(punchInDate);
-                }
-
-                // 打卡日所在月的第一天
-                if (isFirstDayOfMonth) {
-                    piStatus.setStatTimeInMonth(yearMonth);
-
-                    // 设置本月总打卡次数
-                    int PunchInTotalCountInMonth = punchInManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(),
-                            piTask.getRepeatCustomDay(), DateUtils.getFirstDayOfMonth(punchInDate),
-                            DateUtils.getLastDayOfMonth(punchInDate));
-                    piStatus.setPunchInTotalCountInMonth(PunchInTotalCountInMonth);
-
-                    // 重置数据
-                    piStatus.setPunchInCountInMonth(0);
-                    piStatus.setPunchInDoneCountInMonth(0);
-                    piStatus.setRepeatPrevTotalCountInMonth(0);
-                    piStatus.setRepeatStartDateInMonth(punchInDate);
-                }
-
-                // 重复类型发生变换,总打卡次数=历史真实发生的总打卡次数+变换前发生的总打卡次数+变换后可能的总打卡次数
-                if (!piStatus.getRepeatCategory().equals(piTask.getRepeatCategory())) {
-                    // 历史真实发生的总打卡次数(周)
-                    Integer oldPrevTotalCountInWeek = Optional.ofNullable(piStatus.getRepeatPrevTotalCountInWeek()).orElse(0);
-                    // 变换前发生的总打卡次数(周)
-                    int prevTotalCountInWeek = punchInManager.getPunchInTotalCountInRange(piStatus.getRepeatCategory(),
-                            piStatus.getRepeatCustomDay(), piStatus.getRepeatStartDateInWeek(),
-                            punchInDate.minusDays(1));
-                    // 变换后可能的总打卡次数(周)
-                    int punchInTotalCountInWeek = punchInManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(), piTask.getRepeatCustomDay(), punchInDate, DateUtils.getLastDayOfWeek(punchInDate));
-
-                    // 历史真实发生的总打卡次数(月)
-                    Integer oldPrevTotalCountInMonth = Optional.ofNullable(piStatus.getRepeatPrevTotalCountInMonth()).orElse(0);
-                    // 变换前发生的总打卡次数(月)
-                    int prevTotalCountInMonth = punchInManager.getPunchInTotalCountInRange(piStatus.getRepeatCategory(),
-                            piStatus.getRepeatCustomDay(), piStatus.getRepeatStartDateInMonth(),
-                            punchInDate.minusDays(1));
-                    // 变换后可能的总打卡次数(月 )
-                    int punchInTotalCountInMonth = punchInManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(), piTask.getRepeatCustomDay(), punchInDate, DateUtils.getLastDayOfMonth(punchInDate));
-
-                    // 设置实时数据
-                    piStatus.setRepeatPrevTotalCountInWeek(prevTotalCountInWeek + oldPrevTotalCountInWeek);
-                    piStatus.setPunchInTotalCountInWeek(piStatus.getRepeatPrevTotalCountInWeek() + punchInTotalCountInWeek);
-                    piStatus.setRepeatPrevTotalCountInMonth(prevTotalCountInMonth + oldPrevTotalCountInMonth);
-                    piStatus.setPunchInTotalCountInMonth(piStatus.getRepeatPrevTotalCountInMonth() + punchInTotalCountInMonth);
-                }
-
-                // 存在打卡记录则已打卡数加1
-                if (Objects.nonNull(piTaskHistory)) {
-                    piStatus.setPunchInCountInWeek(piStatus.getPunchInCountInWeek() + 1);
-                    piStatus.setPunchInCountInMonth(piStatus.getPunchInCountInMonth() + 1);
-                }
-
-                // 完成打卡则完成打卡数记录加一
-                if (PunchInResultEnum.DONE.equals(punchInResult)) {
-                    piStatus.setPunchInDoneCountInWeek(piStatus.getPunchInDoneCountInWeek() + 1);
-                    piStatus.setPunchInDoneCountInMonth(piStatus.getPunchInDoneCountInMonth() + 1);
-                }
-
-                // 计算积分
+                // 计算积分,要先刷新打卡状态
                 int taskPoints = settleManager.calculatePointsInTask(piTask, piTaskExtList, piTaskHistory, piStatus);
+                settlePoints += taskPoints;
+
+                // 更新打卡状态
                 piStatus.setPointsInWeek(piStatus.getPointsInWeek() + taskPoints);
                 piStatus.setPointsInMonth(piStatus.getPointsInMonth() + taskPoints);
-                settlePoints += taskPoints;
 
                 // 打卡记录 更新
                 updatePiTaskHistory.setSettlePoints(taskPoints);
@@ -338,61 +248,16 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
 
                 updatePiStatusList.add(piStatus);
                 updatePunchInTaskHistories.add(updatePiTaskHistory);
+                
+                // 周日构建周统计数据
                 if (isSunday) {
-                    StatPiTaskWeek statPiTaskWeek = new StatPiTaskWeek();
-                    statPiTaskWeek.setUserId(punchInSettle.getUserId());
-                    statPiTaskWeek.setTaskUniqueId(piTask.getUniqueId());
-                    statPiTaskWeek.setStatTime(piStatus.getStatTimeInWeek());
-                    statPiTaskWeek.setPunchInTotalCount(piStatus.getPunchInTotalCountInWeek());
-                    statPiTaskWeek.setPunchInCount(piStatus.getPunchInCountInWeek());
-                    statPiTaskWeek.setPunchInDoneCount(piStatus.getPunchInDoneCountInWeek());
-                    statPiTaskWeek.setPoints(piStatus.getPointsInWeek());
-
-                    Integer punchInTotalCount = Optional.ofNullable(piStatus.getPunchInTotalCountInWeek()).orElse(0);
-                    if (punchInTotalCount == 0) {
-                        statPiTaskWeek.setPunchInRate(ZERO_RATE);
-                        statPiTaskWeek.setPunchInDoneRate(ZERO_RATE);
-                    } else {
-                        Integer punchInCount = Optional.ofNullable(piStatus.getPunchInCountInWeek()).orElse(0);
-                        Integer punchInDoneCount = Optional.ofNullable(piStatus.getPunchInDoneCountInWeek()).orElse(0);
-                        BigDecimal totalCount = new BigDecimal(punchInTotalCount);
-
-                        BigDecimal punchInRate = BigDecimal.valueOf(punchInCount).divide(totalCount, 2, RoundingMode.HALF_UP).multiply(ONE_HUNDRED);
-                        statPiTaskWeek.setPunchInRate(punchInRate);
-
-                        BigDecimal punchInDoneRate = BigDecimal.valueOf(punchInDoneCount).divide(totalCount, 2, RoundingMode.HALF_UP).multiply(ONE_HUNDRED);
-                        statPiTaskWeek.setPunchInDoneRate(punchInDoneRate);
-                    }
-
+                    StatPiTaskWeek statPiTaskWeek = buildStatPiTaskWeek(punchInSettle.getUserId(), piTask, piStatus);
                     addStatPiTaskWeekList.add(statPiTaskWeek);
                 }
 
+                // 月末构建月统计数据
                 if (isLastDayOfMonth) {
-                    StatPiTaskMonth statPiTaskMonth = new StatPiTaskMonth();
-                    statPiTaskMonth.setUserId(punchInSettle.getUserId());
-                    statPiTaskMonth.setTaskUniqueId(piTask.getUniqueId());
-                    statPiTaskMonth.setStatTime(piStatus.getStatTimeInMonth());
-                    statPiTaskMonth.setPunchInTotalCount(piStatus.getPunchInTotalCountInMonth());
-                    statPiTaskMonth.setPunchInCount(piStatus.getPunchInCountInMonth());
-                    statPiTaskMonth.setPunchInDoneCount(piStatus.getPunchInDoneCountInMonth());
-                    statPiTaskMonth.setPoints(piStatus.getPointsInMonth());
-
-                    Integer punchInTotalCount = Optional.ofNullable(piStatus.getPunchInTotalCountInMonth()).orElse(0);
-                    if (punchInTotalCount == 0) {
-                        statPiTaskMonth.setPunchInRate(ZERO_RATE);
-                        statPiTaskMonth.setPunchInDoneRate(ZERO_RATE);
-                    } else {
-                        Integer punchInCount = Optional.ofNullable(piStatus.getPunchInCountInMonth()).orElse(0);
-                        Integer punchInDoneCount = Optional.ofNullable(piStatus.getPunchInDoneCountInMonth()).orElse(0);
-                        BigDecimal totalCount = new BigDecimal(punchInTotalCount);
-
-                        BigDecimal punchInRate = BigDecimal.valueOf(punchInCount).divide(totalCount, 2, RoundingMode.HALF_UP).multiply(ONE_HUNDRED);
-                        statPiTaskMonth.setPunchInRate(punchInRate);
-
-                        BigDecimal punchInDoneRate = BigDecimal.valueOf(punchInDoneCount).divide(totalCount, 2, RoundingMode.HALF_UP).multiply(ONE_HUNDRED);
-                        statPiTaskMonth.setPunchInDoneRate(punchInDoneRate);
-                    }
-
+                    StatPiTaskMonth statPiTaskMonth = buildStatPiTaskMonth(punchInSettle.getUserId(), piTask, piStatus);
                     addStatPiTaskMonthList.add(statPiTaskMonth);
                 }
             }
@@ -417,42 +282,60 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
             piMultiTaskHistory.setPunchInResult(punchInResult);
             updatePiMultiTaskHistory.setPunchInResult(punchInResult);
 
-            // 设置统计时间
+            // 设置多任务统计时间
             piStatusInMultiTask.setStatusDate(punchInDateStr);
-            // 设置任务连续状态
+            // 设置任务连续状态
             ContinueStatusEnum oldTaskContinueStatus = piStatusInMultiTask.getTaskContinueStatus();
             piStatusInMultiTask.setTaskContinueStatus(punchInResult.equals(PunchInResultEnum.DONE)
                     ? ContinueStatusEnum.CONTINUE : ContinueStatusEnum.INTERRUPTED);
             piStatusInMultiTask.setTaskContinueDay(oldTaskContinueStatus.equals(piStatusInMultiTask.getTaskContinueStatus())
                     ? piStatusInMultiTask.getTaskContinueDay() + 1 : 1);
 
+            // 计算多任务积分
             int multiTaskPoints = settleManager.calculatePointsInMultiTask(piMultiTask,
                     punchInSettle.getPiMultiTaskExtList(), piMultiTaskHistory,
                     punchInSettle.getPiStatus());
             settlePoints += multiTaskPoints;
 
+            // 设置打卡记录表信息
             updatePiMultiTaskHistory.setSettlePoints(multiTaskPoints);
             updatePiMultiTaskHistory.setSettleResult(SettleResultEnum.SETTLED);
             updatePiMultiTaskHistory.setSettleTaskHistoryId(settleTaskHistoryId);
             updatePunchInMultiTaskHistories.add(updatePiMultiTaskHistory);
 
+            // 获取并设置用户信息
             User user = punchInSettle.getUser();
-            Integer totalPoints = Optional.ofNullable(user.getTotalPoints()).orElse(0);
-            Integer unusedPoints = Optional.ofNullable(user.getUnusedPoints()).orElse(0);
-
+            Integer beforeTotalPoints = Optional.ofNullable(user.getTotalPoints()).orElse(0);
+            Integer beforeUnusedPoints = Optional.ofNullable(user.getUnusedPoints()).orElse(0);
             User updateUser = new User();
             updateUser.setId(user.getId());
-            updateUser.setTotalPoints(totalPoints);
-            updateUser.setUnusedPoints(unusedPoints + settlePoints);
+            updateUser.setTotalPoints(beforeTotalPoints + settlePoints);
+            updateUser.setUnusedPoints(beforeUnusedPoints + settlePoints);
             updateUserList.add(user);
 
+            // 更新账户信息
+            Account account = punchInSettle.getAccount();
+            Integer beforeAccountPoints = Optional.ofNullable(account.getPoints()).orElse(0);
+            account.setPoints(beforeAccountPoints + settlePoints);
+            updateAccountList.add(account);
+
+            // 增加账户转账记录
+            AccountTransferHistory accountTransferHistory = new AccountTransferHistory();
+            accountTransferHistory.setTransferPoints(settlePoints);
+            accountTransferHistory.setTransferCategory(TransferCategoryEnum.SETTLE);
+            accountTransferHistory.setRecipientAccountId(account.getId());
+            accountTransferHistory.setRaPointsAfterTransfer(beforeAccountPoints);
+            accountTransferHistory.setRaPointsAfterTransfer(account.getPoints());
+            addAccountTransferHistories.add(accountTransferHistory);
+
+            // 设置结算积分记录
             SettlePointsHistory addSettlePointsHistory = new SettlePointsHistory();
             addSettlePointsHistory.setSettleTaskHistoryId(settleTaskHistoryId);
             addSettlePointsHistory.setUserId(user.getId());
             addSettlePointsHistory.setSettleDate(punchInDateStr);
             addSettlePointsHistory.setSettlePoints(settlePoints);
-            addSettlePointsHistory.setBeforeSettlePoints(totalPoints);
-            addSettlePointsHistory.setAfterSettlePoints(totalPoints + settlePoints);
+            addSettlePointsHistory.setBeforeSettlePoints(beforeTotalPoints);
+            addSettlePointsHistory.setAfterSettlePoints(beforeTotalPoints + settlePoints);
             addSettlePointsHistories.add(addSettlePointsHistory);
         }
 
@@ -481,6 +364,12 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
         if (!CollectionUtils.isEmpty(updatePunchInMultiTaskHistories)) {
             piMultiTaskHistoryService.batchUpdate(updatePunchInMultiTaskHistories);
         }
+        if (!CollectionUtils.isEmpty(updateAccountList)) {
+            accountService.batchUpdate(updateAccountList);
+        }
+        if (!CollectionUtils.isEmpty(addAccountTransferHistories)) {
+            accountTransferHistoryService.batchInsert(addAccountTransferHistories);
+        }
     }
 
     /**
@@ -495,6 +384,13 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
         List<User> users = userService.listByIds(userIds);
         Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key1));
 
+        // 获取账户信息,用户ID-账户信息关联
+        AccountQuery accountQuery = new AccountQuery();
+        accountQuery.setAccountCategory(AccountCategoryEnum.BASIC);
+        accountQuery.setUserIds(userIds);
+        List<Account> accounts = accountService.getAccountByCondition(accountQuery);
+        Map<Long, Account> accountMap = accounts.stream().collect(Collectors.toMap(Account::getUserId, Function.identity(), (key1, key2) -> key1));
+
         // 获取多任务信息,用户ID-多任务关联
         PiMultiTaskQuery piMultiTaskQuery = new PiMultiTaskQuery();
         piMultiTaskQuery.setMultiTaskTaskStatus(ArchiveStatusEnum.ACTIVE);
@@ -575,6 +471,10 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
             User user = userMap.get(userId);
             punchInSettleData.setUser(user);
 
+            // 获取并设置账户信息
+            Account account = accountMap.get(userId);
+            punchInSettleData.setAccount(account);
+
             // TODO 获取并设置多任务打卡信息,这个不可能为空,为空则用户初始注册时创建时有问题
             PiMultiTask piMultiTask = piMultiTaskMap.get(userId);
             punchInSettleData.setPiMultiTask(piMultiTask);
@@ -633,4 +533,200 @@ public class PunchInSettleManagerImpl implements IPunchInSettleManager {
             return punchInSettleData;
         }).collect(Collectors.toList());
     }
+
+    /**
+     * 更新打卡任务状态
+     * @param piStatus 打卡任务状态
+     * @param punchInResult 打卡结果
+     * @param piTask 打卡任务
+     * @param piTaskHistory 打卡任务记录
+     * @param punchInDate 打卡日期
+     * @param isMonday 是否周一
+     * @param isFirstDayOfMonth 是否本月第一天
+     * @param yearWeek 周数
+     * @param yearMonth 月份数
+     */
+    private void refreshPiStatus(PiStatus piStatus, PunchInResultEnum punchInResult, PiTask piTask, PiTaskHistory piTaskHistory, LocalDate punchInDate, boolean isMonday, boolean isFirstDayOfMonth, String yearWeek, String yearMonth) {
+        // 设置任务连续状态
+        ContinueStatusEnum oldTaskContinueStatus = piStatus.getTaskContinueStatus();
+        piStatus.setTaskContinueStatus(punchInResult.equals(PunchInResultEnum.DONE)
+                ? ContinueStatusEnum.CONTINUE : ContinueStatusEnum.INTERRUPTED);
+        piStatus.setTaskContinueDay(oldTaskContinueStatus.equals(piStatus.getTaskContinueStatus())
+                ? piStatus.getTaskContinueDay() + 1 : 1);
+
+        // 旧的连续阶段
+        ContinueStageEnum oldContinueStage = piStatus.getContinueStage();
+        // 判断当前处于的连续阶段
+        ContinueStageEnum continueStageResult =
+                punchInManager.judgeContinueStageInTask(piTask, piTaskHistory, piStatus, punchInDate);
+        piStatus.setContinueStage(continueStageResult);
+        // 下面3种情况不处理:宽限期 变 宽限期;正常打卡期 变 正常打卡期;惩罚期 变 惩罚期;
+        // 宽限期 变 正常打卡期,则设置阶段开始时间,重置中断次数
+        if (ContinueStageEnum.GRACE_STAGE.equals(oldContinueStage)
+                && ContinueStageEnum.NORMAL_STAGE.equals(continueStageResult)) {
+            piStatus.setStageStartDate(punchInDate);
+            piStatus.setContinueInterruptedCount(0);
+        }
+        // 如果正常打卡期 变 惩罚期,则设置阶段开始时间和阶段结束时间,增加中断次数
+        if (ContinueStageEnum.NORMAL_STAGE.equals(oldContinueStage)
+                && ContinueStageEnum.PENALTY_STAGE.equals(continueStageResult)) {
+            piStatus.setStageStartDate(punchInDate);
+            piStatus.setStageEndDate(punchInDate.plusDays(piTask.getPenaltyDay()));
+            piStatus.setContinueInterruptedCount(piStatus.getContinueInterruptedCount() + 1);
+        }
+        // 如果惩罚期 变 正常打卡期,则设置阶段开始时间
+        if (ContinueStageEnum.PENALTY_STAGE.equals(oldContinueStage)
+                && ContinueStageEnum.NORMAL_STAGE.equals(continueStageResult)) {
+            piStatus.setStageStartDate(punchInDate);
+        }
+
+        // 周一或月初
+        if (isMonday || isFirstDayOfMonth) {
+            piStatus.setRepeatCategory(piTask.getRepeatCategory());
+            piStatus.setRepeatCustomDay(piTask.getRepeatCustomDay());
+        }
+
+        // 周一
+        if (isMonday) {
+            piStatus.setStatTimeInWeek(yearWeek);
+
+            // 设置本周总打卡次数
+            int PunchInTotalCountInWeek = punchInManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(),
+                    piTask.getRepeatCustomDay(), DateUtils.getFirstDayOfWeek(punchInDate),
+                    DateUtils.getLastDayOfWeek(punchInDate));
+            piStatus.setPunchInTotalCountInWeek(PunchInTotalCountInWeek);
+
+            // 重置数据
+            piStatus.setPunchInCountInWeek(0);
+            piStatus.setPunchInDoneCountInWeek(0);
+            piStatus.setRepeatPrevTotalCountInWeek(0);
+            piStatus.setRepeatStartDateInWeek(punchInDate);
+        }
+
+        // 打卡日所在月的第一天
+        if (isFirstDayOfMonth) {
+            piStatus.setStatTimeInMonth(yearMonth);
+
+            // 设置本月总打卡次数
+            int PunchInTotalCountInMonth = punchInManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(),
+                    piTask.getRepeatCustomDay(), DateUtils.getFirstDayOfMonth(punchInDate),
+                    DateUtils.getLastDayOfMonth(punchInDate));
+            piStatus.setPunchInTotalCountInMonth(PunchInTotalCountInMonth);
+
+            // 重置数据
+            piStatus.setPunchInCountInMonth(0);
+            piStatus.setPunchInDoneCountInMonth(0);
+            piStatus.setRepeatPrevTotalCountInMonth(0);
+            piStatus.setRepeatStartDateInMonth(punchInDate);
+        }
+
+        // 重复类型发生变换,总打卡次数=历史真实发生的总打卡次数+变换前发生的总打卡次数+变换后可能的总打卡次数
+        if (!piStatus.getRepeatCategory().equals(piTask.getRepeatCategory())) {
+            // 历史真实发生的总打卡次数(周)
+            Integer oldPrevTotalCountInWeek = Optional.ofNullable(piStatus.getRepeatPrevTotalCountInWeek()).orElse(0);
+            // 变换前发生的总打卡次数(周)
+            int prevTotalCountInWeek = punchInManager.getPunchInTotalCountInRange(piStatus.getRepeatCategory(),
+                    piStatus.getRepeatCustomDay(), piStatus.getRepeatStartDateInWeek(),
+                    punchInDate.minusDays(1));
+            // 变换后可能的总打卡次数(周)
+            int punchInTotalCountInWeek = punchInManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(), piTask.getRepeatCustomDay(), punchInDate, DateUtils.getLastDayOfWeek(punchInDate));
+
+            // 历史真实发生的总打卡次数(月)
+            Integer oldPrevTotalCountInMonth = Optional.ofNullable(piStatus.getRepeatPrevTotalCountInMonth()).orElse(0);
+            // 变换前发生的总打卡次数(月)
+            int prevTotalCountInMonth = punchInManager.getPunchInTotalCountInRange(piStatus.getRepeatCategory(),
+                    piStatus.getRepeatCustomDay(), piStatus.getRepeatStartDateInMonth(),
+                    punchInDate.minusDays(1));
+            // 变换后可能的总打卡次数(月 )
+            int punchInTotalCountInMonth = punchInManager.getPunchInTotalCountInRange(piTask.getRepeatCategory(), piTask.getRepeatCustomDay(), punchInDate, DateUtils.getLastDayOfMonth(punchInDate));
+
+            // 设置实时数据
+            piStatus.setRepeatPrevTotalCountInWeek(prevTotalCountInWeek + oldPrevTotalCountInWeek);
+            piStatus.setPunchInTotalCountInWeek(piStatus.getRepeatPrevTotalCountInWeek() + punchInTotalCountInWeek);
+            piStatus.setRepeatPrevTotalCountInMonth(prevTotalCountInMonth + oldPrevTotalCountInMonth);
+            piStatus.setPunchInTotalCountInMonth(piStatus.getRepeatPrevTotalCountInMonth() + punchInTotalCountInMonth);
+        }
+
+        // 存在打卡记录则已打卡数加1
+        if (Objects.nonNull(piTaskHistory)) {
+            piStatus.setPunchInCountInWeek(piStatus.getPunchInCountInWeek() + 1);
+            piStatus.setPunchInCountInMonth(piStatus.getPunchInCountInMonth() + 1);
+        }
+
+        // 完成打卡则完成打卡数记录加一
+        if (PunchInResultEnum.DONE.equals(punchInResult)) {
+            piStatus.setPunchInDoneCountInWeek(piStatus.getPunchInDoneCountInWeek() + 1);
+            piStatus.setPunchInDoneCountInMonth(piStatus.getPunchInDoneCountInMonth() + 1);
+        }
+    }
+
+    /**
+     * 构建周统计数据
+     * @param userId 用户ID
+     * @param piTask 打卡任务
+     * @param piStatus 打卡任务状态
+     * @return
+     */
+    private static StatPiTaskWeek buildStatPiTaskWeek(Long userId, PiTask piTask, PiStatus piStatus) {
+        StatPiTaskWeek statPiTaskWeek = new StatPiTaskWeek();
+        statPiTaskWeek.setUserId(userId);
+        statPiTaskWeek.setTaskUniqueId(piTask.getUniqueId());
+        statPiTaskWeek.setStatTime(piStatus.getStatTimeInWeek());
+        statPiTaskWeek.setPunchInTotalCount(piStatus.getPunchInTotalCountInWeek());
+        statPiTaskWeek.setPunchInCount(piStatus.getPunchInCountInWeek());
+        statPiTaskWeek.setPunchInDoneCount(piStatus.getPunchInDoneCountInWeek());
+        statPiTaskWeek.setPoints(piStatus.getPointsInWeek());
+
+        Integer punchInTotalCount = Optional.ofNullable(piStatus.getPunchInTotalCountInWeek()).orElse(0);
+        if (punchInTotalCount == 0) {
+            statPiTaskWeek.setPunchInRate(ZERO_RATE);
+            statPiTaskWeek.setPunchInDoneRate(ZERO_RATE);
+        } else {
+            Integer punchInCount = Optional.ofNullable(piStatus.getPunchInCountInWeek()).orElse(0);
+            Integer punchInDoneCount = Optional.ofNullable(piStatus.getPunchInDoneCountInWeek()).orElse(0);
+            BigDecimal totalCount = new BigDecimal(punchInTotalCount);
+
+            BigDecimal punchInRate = BigDecimal.valueOf(punchInCount).divide(totalCount, 2, RoundingMode.HALF_UP).multiply(ONE_HUNDRED);
+            statPiTaskWeek.setPunchInRate(punchInRate);
+
+            BigDecimal punchInDoneRate = BigDecimal.valueOf(punchInDoneCount).divide(totalCount, 2, RoundingMode.HALF_UP).multiply(ONE_HUNDRED);
+            statPiTaskWeek.setPunchInDoneRate(punchInDoneRate);
+        }
+        return statPiTaskWeek;
+    }
+
+    /**
+     * 构建月统计数据
+     * @param userId 用户ID
+     * @param piTask 打卡任务
+     * @param piStatus 打卡任务状态
+     * @return
+     */
+    private static StatPiTaskMonth buildStatPiTaskMonth(Long userId, PiTask piTask, PiStatus piStatus) {
+        StatPiTaskMonth statPiTaskMonth = new StatPiTaskMonth();
+        statPiTaskMonth.setUserId(userId);
+        statPiTaskMonth.setTaskUniqueId(piTask.getUniqueId());
+        statPiTaskMonth.setStatTime(piStatus.getStatTimeInMonth());
+        statPiTaskMonth.setPunchInTotalCount(piStatus.getPunchInTotalCountInMonth());
+        statPiTaskMonth.setPunchInCount(piStatus.getPunchInCountInMonth());
+        statPiTaskMonth.setPunchInDoneCount(piStatus.getPunchInDoneCountInMonth());
+        statPiTaskMonth.setPoints(piStatus.getPointsInMonth());
+
+        Integer punchInTotalCount = Optional.ofNullable(piStatus.getPunchInTotalCountInMonth()).orElse(0);
+        if (punchInTotalCount == 0) {
+            statPiTaskMonth.setPunchInRate(ZERO_RATE);
+            statPiTaskMonth.setPunchInDoneRate(ZERO_RATE);
+        } else {
+            Integer punchInCount = Optional.ofNullable(piStatus.getPunchInCountInMonth()).orElse(0);
+            Integer punchInDoneCount = Optional.ofNullable(piStatus.getPunchInDoneCountInMonth()).orElse(0);
+            BigDecimal totalCount = new BigDecimal(punchInTotalCount);
+
+            BigDecimal punchInRate = BigDecimal.valueOf(punchInCount).divide(totalCount, 2, RoundingMode.HALF_UP).multiply(ONE_HUNDRED);
+            statPiTaskMonth.setPunchInRate(punchInRate);
+
+            BigDecimal punchInDoneRate = BigDecimal.valueOf(punchInDoneCount).divide(totalCount, 2, RoundingMode.HALF_UP).multiply(ONE_HUNDRED);
+            statPiTaskMonth.setPunchInDoneRate(punchInDoneRate);
+        }
+        return statPiTaskMonth;
+    }
 }

+ 1 - 1
src/main/java/com/punchsettle/server/service/manager/impl/StatPiTaskWeekServiceImpl.java

@@ -33,7 +33,7 @@ public class StatPiTaskWeekServiceImpl implements IStatPiTaskWeekService {
     public List<StatPiTaskWeek> queryByCondition(StatPiTaskWeekQuery statPiTaskWeekQuery) {
         Assert.isNull(statPiTaskWeekQuery);
 
-        Weekend<StatPiTaskWeek> weekend = WeekendUtils.createExcludeProperties(StatPiTaskWeek.class);
+        Weekend<StatPiTaskWeek> weekend = WeekendUtils.createExcludeAuditFields(StatPiTaskWeek.class);
         WeekendCriteria<StatPiTaskWeek, Object> criteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(statPiTaskWeekQuery.getTaskUniqueIds())) {
             criteria.andIn(StatPiTaskWeek::getTaskUniqueId, statPiTaskWeekQuery.getTaskUniqueIds());