diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/constants/AccWalletIdEnum.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/constants/AccWalletIdEnum.java new file mode 100644 index 0000000..1e3afa2 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/constants/AccWalletIdEnum.java @@ -0,0 +1,59 @@ +package com.bonus.canteen.core.account.constants; + +import cn.hutool.core.collection.ListUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +public enum AccWalletIdEnum { + WALLET(1, "个人钱包"), + SUBSIDY(2, "补贴钱包"); + private final Integer key; + private final String desc; + + // 使用 Map 提升查找效率 + private static final Map ENUM_MAP = Arrays.stream(values()) + .collect(Collectors.toMap(AccWalletIdEnum::getKey, Function.identity())); + + private AccWalletIdEnum(Integer key, String desc) { + this.key = key; + this.desc = desc; + } + + public static String getDesc(Integer key) { + AccWalletIdEnum enumValue = ENUM_MAP.get(key); + return enumValue != null ? enumValue.getDesc() : ""; + } + + public static AccWalletIdEnum getEnum(Integer key) { + return ENUM_MAP.get(key); + } + + public static Map getEnumMap() { + return ENUM_MAP; + } + + public static List checkAccCancelWallet() { + return Arrays.asList(WALLET.getKey(), SUBSIDY.getKey()); + } + + public static String getAllWalletId() { + return StringUtils.join(getAllWalletIdList(), ","); + } + + public static List getAllWalletIdList() { + return Arrays.stream(values()) + .map(AccWalletIdEnum::getKey) + .collect(Collectors.toList()); + } + + public Integer getKey() { + return this.key; + } + + public String getDesc() { + return this.desc; + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/constants/AccountStatusEnum.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/constants/AccountStatusEnum.java new file mode 100644 index 0000000..8d87954 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/constants/AccountStatusEnum.java @@ -0,0 +1,37 @@ +package com.bonus.canteen.core.account.constants; + +import java.util.*; +import java.util.stream.Collectors; + +public enum AccountStatusEnum { + NORMAL(1, "正常"), + DEACTIVATE(2, "停用"); + + private final Integer key; + private final String desc; + + private static final Map ENUM_MAP = Arrays.stream(values()) + .collect(Collectors.toMap(AccountStatusEnum::getKey, e -> e)); + + private AccountStatusEnum(Integer key, String desc) { + this.key = key; + this.desc = desc; + } + + public static String getDesc(Integer key) { + AccountStatusEnum enumValue = ENUM_MAP.get(key); + return enumValue != null ? enumValue.getDesc() : ""; + } + + public static AccountStatusEnum getEnum(Integer key) { + return ENUM_MAP.get(key); + } + + public Integer getKey() { + return this.key; + } + + public String getDesc() { + return this.desc; + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/controller/AccInfoController.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/controller/AccInfoController.java index 428c581..53a4e31 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/controller/AccInfoController.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/controller/AccInfoController.java @@ -2,8 +2,16 @@ package com.bonus.canteen.core.account.controller; import java.util.List; import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; -import com.bonus.common.houqin.constant.SourceTypeEnum; +import com.bonus.canteen.core.account.domain.AccInfo; +import com.bonus.canteen.core.account.domain.param.AccOperationQueryParam; +import com.bonus.canteen.core.account.domain.param.AccountBalanceEditParam; +import com.bonus.canteen.core.account.domain.param.AccountEnableDisableParam; +import com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO; +import com.bonus.canteen.core.account.domain.param.AccountInfoQueryParam; + +import com.bonus.canteen.core.account.service.AccOperationHistoryService; import com.bonus.common.log.enums.OperaType; import com.bonus.system.api.domain.SysUser; import io.swagger.annotations.Api; @@ -16,7 +24,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.bonus.common.log.annotation.SysLog; -import com.bonus.canteen.core.account.domain.AccInfo; import com.bonus.canteen.core.account.service.IAccInfoService; import com.bonus.common.core.web.controller.BaseController; import com.bonus.common.core.web.domain.AjaxResult; @@ -37,6 +44,8 @@ import static com.bonus.common.core.web.domain.AjaxResult.success; public class AccInfoController extends BaseController { @Autowired private IAccInfoService accInfoService; + @Autowired + private AccOperationHistoryService accOperationHistoryService; /** * 查询账户资料列表 @@ -44,10 +53,9 @@ public class AccInfoController extends BaseController { @ApiOperation(value = "查询账户资料列表") //@RequiresPermissions("account:info:list") @GetMapping("/list") - public TableDataInfo list(AccInfo accInfo) { + public TableDataInfo list(AccountInfoQueryParam accountInfoQueryParam) { startPage(); - List list = accInfoService.selectAccInfoList(accInfo); - return getDataTable(list); + return getDataTable(accInfoService.selectAccInfoList(accountInfoQueryParam)); } /** @@ -58,9 +66,9 @@ public class AccInfoController extends BaseController { //@RequiresPermissions("account:info:export") @SysLog(title = "账户资料", businessType = OperaType.EXPORT, logType = 1,module = "仓储管理->导出账户资料") @PostMapping("/export") - public void export(HttpServletResponse response, AccInfo accInfo) { - List list = accInfoService.selectAccInfoList(accInfo); - ExcelUtil util = new ExcelUtil(AccInfo.class); + public void export(HttpServletResponse response, AccountInfoQueryParam accountInfoQueryParam) { + List list = accInfoService.selectAccInfoList(accountInfoQueryParam); + ExcelUtil util = new ExcelUtil<>(AccInfoDetailsVO.class); util.exportExcel(response, list, "账户资料数据"); } @@ -109,18 +117,15 @@ public class AccInfoController extends BaseController { /** * 修改账户资料 */ - @ApiOperation(value = "修改账户资料") - //@PreventRepeatSubmit - //@RequiresPermissions("account:info:edit") - @SysLog(title = "账户资料", businessType = OperaType.UPDATE, logType = 1,module = "仓储管理->修改账户资料") - @PostMapping("/edit") - public AjaxResult edit(@RequestBody AccInfo accInfo) { - try { - return toAjax(accInfoService.updateAccInfo(accInfo)); - } catch (Exception e) { - return error("系统错误, " + e.getMessage()); - } - } +// @ApiOperation(value = "修改账户余额以及有效期") +// //@PreventRepeatSubmit +// //@RequiresPermissions("account:info:edit") +// @SysLog(title = "账户资料", businessType = OperaType.UPDATE, logType = 1,module = "仓储管理->修改账户资料") +// @PostMapping("/balance/edit") +// public AjaxResult edit(@RequestBody AccountBalanceEditParam accountBalanceEditParam) { +// this.accInfoService.updateAccInfo(accountBalanceEditParam); +// return AjaxResult.success(); +// } /** * 删除账户资料 @@ -134,6 +139,30 @@ public class AccInfoController extends BaseController { return toAjax(accInfoService.deleteAccInfoByIds(ids)); } +// @ApiOperation("账户注销/过期数量") +// @PostMapping({"/invalid/sum"}) +// public AjaxResult queryAccInfoExpiredCount() { +// return AjaxResult.success(this.accInfoService.queryAccInfoInvalidSum()); +// } + @ApiOperation("查询账户余额统计") + @PostMapping({"/balance/sum"}) + public AjaxResult queryAccInfoBalanceSum(@RequestBody AccountInfoQueryParam accountInfoQueryParam) { + return AjaxResult.success(this.accInfoService.queryAccInfoBalanceSum(accountInfoQueryParam)); + } + + @ApiOperation("账户启用、停用") + @PostMapping({"/status/edit"}) + public AjaxResult editAccountStatus(@RequestBody @Valid AccountEnableDisableParam accountEnableDisableParam) { + this.accInfoService.editAccountStatus(accountEnableDisableParam); + return AjaxResult.success(); + } + + @ApiOperation("账户操作记录") + @PostMapping({"/operation/list"}) + public AjaxResult queryPageAccOperationRecord(@RequestBody AccOperationQueryParam param) { + return AjaxResult.success(this.accOperationHistoryService.selectAccOperationHistory(param)); + } + /** * 删除账户资料 */ diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/AccInfo.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/AccInfo.java index 4ac866e..ec3eb34 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/AccInfo.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/AccInfo.java @@ -1,5 +1,7 @@ package com.bonus.canteen.core.account.domain; +import java.math.BigDecimal; +import java.time.LocalDate; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import com.bonus.common.core.annotation.Excel; @@ -110,13 +112,13 @@ public class AccInfo extends BaseEntity { @ApiModelProperty(value = "有效截止日期") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "有效截止日期", width = 30, dateFormat = "yyyy-MM-dd") - private Date endDate; + private LocalDate endDate; /** 红包过期时间 */ @ApiModelProperty(value = "红包过期时间") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "红包过期时间", width = 30, dateFormat = "yyyy-MM-dd") - private Date redValidityDate; + private LocalDate redValidityDate; /** 账户状态 1正常 2冻结 3销户 */ @Excel(name = "账户状态 1正常 2冻结 3销户") @@ -202,17 +204,17 @@ public class AccInfo extends BaseEntity { /** 个人钱包最低余额限制金额 */ @Excel(name = "个人钱包最低余额限制金额") @ApiModelProperty(value = "个人钱包最低余额限制金额") - private Long minWalletBalLimit; + private BigDecimal minWalletBalLimit; /** 补贴钱包最低余额限制金额 */ @Excel(name = "补贴钱包最低余额限制金额") @ApiModelProperty(value = "补贴钱包最低余额限制金额") - private Long minRedBalLimit; + private BigDecimal minRedBalLimit; /** 红包钱包最低余额限制金额 */ @Excel(name = "红包钱包最低余额限制金额") @ApiModelProperty(value = "红包钱包最低余额限制金额") - private Long minSubBalLimit; + private BigDecimal minSubBalLimit; /** 当月累计使用满减次数 */ @Excel(name = "当月累计使用满减次数") diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/bo/AccOperationHistory.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/bo/AccOperationHistory.java new file mode 100644 index 0000000..89b7b6d --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/bo/AccOperationHistory.java @@ -0,0 +1,40 @@ +package com.bonus.canteen.core.account.domain.bo; + +import com.alibaba.fastjson.annotation.JSONField; +import com.bonus.common.core.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; +@Data +public class AccOperationHistory { + @ApiModelProperty("主键") + private Integer id; + @ApiModelProperty("用户编号") + private Long userId; + @ApiModelProperty("用户姓名") + @Excel(name = "用户姓名") + private String userName; + @ApiModelProperty("用户手机号") + @Excel(name = "用户手机号") + private String phone; + @ApiModelProperty("组织全称") + @Excel(name = "组织名称") + private String deptName; + @Excel(name = "组织全称") + private String deptFullName; + @ApiModelProperty("操作类型 1启用 2停用") + private Integer type; + @ApiModelProperty("操作类型") + @Excel(name = "操作类型") + private String typeName; + @ApiModelProperty("操作员") + @Excel(name = "操作员") + private String createBy; + @ApiModelProperty("操作时间") + @JSONField( + format = "yyyy-MM-dd HH:mm:ss" + ) + @Excel(name = "操作时间") + private LocalDateTime createTime; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/bo/AccStatusChange.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/bo/AccStatusChange.java new file mode 100644 index 0000000..c21ae9d --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/bo/AccStatusChange.java @@ -0,0 +1,14 @@ +package com.bonus.canteen.core.account.domain.bo; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class AccStatusChange { + private String userId; + private String nickName; + private Long merchantId; + private Integer accStatus; + private LocalDateTime updateDateTime; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccOperationQueryParam.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccOperationQueryParam.java new file mode 100644 index 0000000..33eafe1 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccOperationQueryParam.java @@ -0,0 +1,22 @@ +package com.bonus.canteen.core.account.domain.param; + +import com.bonus.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +public class AccOperationQueryParam extends BaseEntity { + @ApiModelProperty("操作事件 1启用 2停用") + private Integer type; + @ApiModelProperty("查询组织id集合") + private List deptIdList; + @ApiModelProperty("开始时间") + private LocalDateTime startDateTime; + @ApiModelProperty("结束时间") + private LocalDateTime endDateTime; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountBalanceEditParam.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountBalanceEditParam.java new file mode 100644 index 0000000..1e35117 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountBalanceEditParam.java @@ -0,0 +1,28 @@ +package com.bonus.canteen.core.account.domain.param; + +import com.bonus.common.core.annotation.Excel; +import com.bonus.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Date; +import java.util.List; + +@Data +public class AccountBalanceEditParam { + @ApiModelProperty(value = "人员id") + private Long userId; + @ApiModelProperty(value = "有效截止日期") + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate endDate; + @ApiModelProperty(value = "个人钱包最低余额限制金额") + private BigDecimal minWalletBalLimit; + @ApiModelProperty(value = "红包钱包最低余额限制金额") + private BigDecimal minSubBalLimit; + @ApiModelProperty(value = "账户状态 1正常 2冻结 3销户") + private Long accStatus; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountEnableDisableParam.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountEnableDisableParam.java new file mode 100644 index 0000000..73c6380 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountEnableDisableParam.java @@ -0,0 +1,16 @@ +package com.bonus.canteen.core.account.domain.param; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; + +@Data +public class AccountEnableDisableParam { + @ApiModelProperty(value = "人员id") + private Long userId; + @ApiModelProperty(value = "账户状态 1正常 2冻结 3销户") + private Long accStatus; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountInfoQueryParam.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountInfoQueryParam.java new file mode 100644 index 0000000..a15c9d5 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/param/AccountInfoQueryParam.java @@ -0,0 +1,28 @@ +package com.bonus.canteen.core.account.domain.param; + +import com.bonus.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class AccountInfoQueryParam extends BaseEntity { + @ApiModelProperty("账户状态 1正常 2停用") + private List accStatusList; + @ApiModelProperty("筛选钱包类型 0-账户总余额 1-个人钱包 2-补贴钱包") + private Integer walletType; + @ApiModelProperty("查询组织id集合") + private List deptIdList; + @ApiModelProperty("开始时间") + private LocalDateTime startDateTime; + @ApiModelProperty("结束时间") + private LocalDateTime endDateTime; +// @ApiModelProperty("钱包最小金额") +// private BigDecimal walletMinAmount; +// @ApiModelProperty("钱包最大金额") +// private BigDecimal walletMaxAmount; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccInfoDetailsVO.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccInfoDetailsVO.java new file mode 100644 index 0000000..7bc2adc --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccInfoDetailsVO.java @@ -0,0 +1,72 @@ +package com.bonus.canteen.core.account.domain.vo; + +import com.bonus.common.core.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +@Data +public class AccInfoDetailsVO { + @ApiModelProperty("账户id") + private Long accId; + @ApiModelProperty("人员id") + private Long userId; + @ApiModelProperty("操作时间") + @Excel(name = "操作时间") + private LocalDateTime updateTime; + @ApiModelProperty("用户姓名") + @Excel(name = "用户姓名") + private String nickName; + @ApiModelProperty("用户手机号") + @Excel(name = "用户手机号") + private String phoneNumber; + @ApiModelProperty("所属组织") + @Excel(name = "所属组织") + private String orgFullName; + @ApiModelProperty("用户类别") + private Integer userType; + @ApiModelProperty("用户部门") + private String deptName; + @ApiModelProperty("用户类别(展示)") + @Excel(name = "用户类别(展示)") + private String userTypeName; + @ApiModelProperty("账户总余额") + @Excel(name = "账户总余额") + private BigDecimal accBalTotal; + @ApiModelProperty("账户可用总余额(不包含冻结金额)") + private BigDecimal accAvailableBal; + @ApiModelProperty("个人钱包余额/分") + @Excel(name = "个人钱包余额/分") + private BigDecimal walletBal; + @ApiModelProperty("补贴钱包余额/分") + @Excel(name = "补贴钱包余额/分") + private BigDecimal subsidyBal; + @ApiModelProperty("红包余额") + @Excel(name = "红包余额") + private BigDecimal redEnvelope; + @ApiModelProperty("冻结金额") + @Excel(name = "冻结金额") + private BigDecimal accFreezeBalTotal; + @ApiModelProperty("个人钱包允许最低余额限制") + @Excel(name = "个人钱包允许最低余额限制") + private BigDecimal minWalletBalLimit; + @ApiModelProperty("补贴钱包允许最低余额限制") + @Excel(name = "补贴钱包允许最低余额限制") + private BigDecimal minSubBalLimit; + @ApiModelProperty("账户状态 1正常 2冻结 3销户 4过期") + private Integer accStatus; + @ApiModelProperty("账户状态名称") + @Excel(name = "账户状态名称") + private String accStatusName; + @ApiModelProperty("账户有效期") + @Excel(name = "账户有效期") + private LocalDate endDate; + @ApiModelProperty("积分") + private Long scope; + @ApiModelProperty("个人钱包冻结金额") + private BigDecimal frozenWallet; + @ApiModelProperty("补贴冻结金额") + private BigDecimal frozenSub; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccInfoInvalidSumVO.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccInfoInvalidSumVO.java new file mode 100644 index 0000000..a2cc7bc --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccInfoInvalidSumVO.java @@ -0,0 +1,12 @@ +package com.bonus.canteen.core.account.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class AccInfoInvalidSumVO { + @ApiModelProperty("当天过期数量") + private Integer expiredCount; + @ApiModelProperty("当天注销数量") + private Integer cancelCount; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccWalletInfoVO.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccWalletInfoVO.java new file mode 100644 index 0000000..8a99e6a --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/domain/vo/AccWalletInfoVO.java @@ -0,0 +1,18 @@ +package com.bonus.canteen.core.account.domain.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class AccWalletInfoVO { + private Long userId; + private Long accId; + private Integer walletId; + private BigDecimal walletBal; + private BigDecimal limitBalance; + private BigDecimal frozenBalance; + private BigDecimal lastSubsidyAmount; + private LocalDateTime lastSubsidyTime; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccInfoMapper.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccInfoMapper.java index b00c82e..b98f987 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccInfoMapper.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccInfoMapper.java @@ -1,7 +1,14 @@ package com.bonus.canteen.core.account.mapper; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.bonus.canteen.core.account.domain.AccInfo; +import com.bonus.canteen.core.account.domain.param.AccountInfoQueryParam; +import com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO; +import org.apache.ibatis.annotations.Param; import com.bonus.canteen.core.account.domain.AccInfoVo; /** @@ -10,7 +17,7 @@ import com.bonus.canteen.core.account.domain.AccInfoVo; * @author xsheng * @date 2025-04-05 */ -public interface AccInfoMapper { +public interface AccInfoMapper extends BaseMapper { /** * 查询账户资料 * @@ -60,4 +67,13 @@ public interface AccInfoMapper { * @return 结果 */ public int deleteAccInfoByIds(Long[] ids); + + Integer queryAccInfoInvalidSum(@Param("startDateTime") LocalDateTime startDateTime, @Param("endDateTime") LocalDateTime endDateTime, @Param("accStatus") Integer accStatus); + + List queryAccInfoDetails(@Param("accountInfoQueryParam") AccountInfoQueryParam accountInfoQueryParam, + @Param("encryptedSearchValue") String encryptedSearchValue); + + AccInfoDetailsVO queryAccInfoBalanceSum(@Param("accountInfoQueryParam") AccountInfoQueryParam accountInfoQueryParam); + + void updateAccInfoEndDateByUserId(LocalDate endDate, List userIds, String updateBy); } diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccOperationHistoryMapper.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccOperationHistoryMapper.java new file mode 100644 index 0000000..3590dec --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccOperationHistoryMapper.java @@ -0,0 +1,15 @@ +package com.bonus.canteen.core.account.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.bonus.canteen.core.account.domain.bo.AccOperationHistory; +import com.bonus.canteen.core.account.domain.param.AccOperationQueryParam; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface AccOperationHistoryMapper extends BaseMapper { + List queryPageAccOperationRecord(@Param("param") AccOperationQueryParam param, + @Param("encryptedSearchValue") String encryptedSearchValue); +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccWalletInfoMapper.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccWalletInfoMapper.java index 91997df..f6081a6 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccWalletInfoMapper.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mapper/AccWalletInfoMapper.java @@ -1,8 +1,11 @@ package com.bonus.canteen.core.account.mapper; +import java.math.BigDecimal; +import java.time.LocalDate; import java.util.List; import com.bonus.canteen.core.account.domain.AccWalletInfo; import org.apache.ibatis.annotations.Param; +import com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO; /** * 钱包详情信息Mapper接口 @@ -19,6 +22,8 @@ public interface AccWalletInfoMapper { */ public AccWalletInfo selectAccWalletInfoByUserId(Long userId); + List selectAccWalletInfoByUserIds(@Param("userIds") List userIds); + /** * 查询钱包详情信息列表 * @@ -60,4 +65,11 @@ public interface AccWalletInfoMapper { * @return 结果 */ public int deleteAccWalletInfoByUserIds(Long[] userIds); + + void updateMinBalanceByUserId(@Param("minBalance") BigDecimal limitBalance, + @Param("walletId") Integer walletId, + @Param("userIds") List userIds, + @Param("updateBy") String updateBy, + @Param("updateTime") LocalDate updateTime); + } diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mq/AccMqSender.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mq/AccMqSender.java new file mode 100644 index 0000000..ad06386 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/mq/AccMqSender.java @@ -0,0 +1,103 @@ +package com.bonus.canteen.core.account.mq; + +import com.bonus.canteen.core.account.constants.AccountStatusEnum; +import com.bonus.canteen.core.account.domain.bo.AccStatusChange; +import com.bonus.canteen.core.common.utils.TenantContextHolder; +import com.bonus.common.core.constant.SecurityConstants; +import com.bonus.common.core.web.domain.AjaxResult; +import com.bonus.common.houqin.mq.constant.LeMqConstant; +import com.bonus.common.houqin.mq.util.MqUtil; +import com.bonus.common.houqin.utils.JacksonUtil; +import com.bonus.system.api.RemoteUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +@Component +public class AccMqSender { + private static final Logger log = LoggerFactory.getLogger(AccMqSender.class); + @Resource + private RemoteUserService remoteUserService; + public void accChangeMQ(List userIds, Integer accStatus) { + // 校验输入参数 + if (userIds == null || accStatus == null) { + log.warn("用户ID列表或账户状态为空,无法发送MQ。userIds: {}, accStatus: {}", userIds, accStatus); + return; + } + + if (!AccountStatusEnum.DEACTIVATE.getKey().equals(accStatus)) { + log.warn("账户状态不在允许范围内,无法发送MQ。accStatus: {}", accStatus); + return; + } + + try { + log.info("账户状态变动发送mq-入参人员数量: {} 账户状态: {}", userIds.size(), accStatus); + + AjaxResult resultList = remoteUserService.getUsers(userIds.toArray(EMPTY_LONG_ARRAY), SecurityConstants.INNER); + + // 校验远程调用结果 + if (resultList == null || resultList.get(AjaxResult.DATA_TAG) == null) { + log.error("远程用户服务返回数据为空"); + return; + } + + List sysUserList = resultList.getDataAs(List.class); + if (sysUserList == null || sysUserList.isEmpty()) { + log.warn("用户列表为空,无需发送MQ"); + return; + } + + Long tenantId = TenantContextHolder.getTenantId(); + if (tenantId == null) { + log.error("租户ID为空,无法发送MQ"); + return; + } + LocalDateTime now = LocalDateTime.now(); + sysUserList.stream() + .filter(Objects::nonNull) + .map(item -> processUserItem((Map) item, tenantId, accStatus, now)) + .filter(Objects::nonNull) + .forEach(accStatusChange -> sendMqMessage((AccStatusChange)accStatusChange)); + + } catch (Exception e) { + log.error("账户状态变动发送MQ失败", e); + } + } + + private AccStatusChange processUserItem(Map map, Long tenantId, Integer accStatus, LocalDateTime now) { + if (map == null || !map.containsKey("userId") || !map.containsKey("userName")) { + log.warn("用户数据不完整,跳过处理。map: {}", map); + return null; + } + + AccStatusChange accStatusChange = new AccStatusChange(); + accStatusChange.setUserId((String)map.get("userId")); + accStatusChange.setNickName((String) map.get("nickName")); + accStatusChange.setMerchantId(tenantId); + accStatusChange.setAccStatus(accStatus); + accStatusChange.setUpdateDateTime(now); + return accStatusChange; + } + + private void sendMqMessage(AccStatusChange accStatusChange) { + String jsonString = JacksonUtil.writeValueAsString(accStatusChange); + if (jsonString == null) { + log.error("序列化账户状态变更对象失败:{}", accStatusChange); + return; + } + + log.info("账户状态变动发送mq内容:{}", jsonString); + try { + MqUtil.send(jsonString, LeMqConstant.Topic.ACC_STATUS_CHANGE); + } catch (Exception e) { + log.error("发送MQ消息失败:{}", jsonString, e); + } + } + private static final Long[] EMPTY_LONG_ARRAY = new Long[0]; +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/AccOperationHistoryService.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/AccOperationHistoryService.java new file mode 100644 index 0000000..e319056 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/AccOperationHistoryService.java @@ -0,0 +1,12 @@ +package com.bonus.canteen.core.account.service; + + +import com.bonus.canteen.core.account.domain.bo.AccOperationHistory; +import com.bonus.canteen.core.account.domain.param.AccOperationQueryParam; + +import java.util.List; + +public interface AccOperationHistoryService { + List selectAccOperationHistory(AccOperationQueryParam param); + void addAccOperationHistory(Long userId, Integer type); +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/IAccInfoService.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/IAccInfoService.java index 38f2671..464f9d5 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/IAccInfoService.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/IAccInfoService.java @@ -4,6 +4,11 @@ import java.util.List; import com.bonus.canteen.core.account.domain.AccInfo; import com.bonus.canteen.core.account.domain.AccInfoVo; import com.bonus.canteen.core.account.domain.WalletBalanceVO; +import com.bonus.canteen.core.account.domain.param.AccountBalanceEditParam; +import com.bonus.canteen.core.account.domain.param.AccountEnableDisableParam; +import com.bonus.canteen.core.account.domain.param.AccountInfoQueryParam; +import com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO; +import com.bonus.canteen.core.account.domain.vo.AccInfoInvalidSumVO; import com.bonus.system.api.domain.SysUser; /** @@ -27,7 +32,7 @@ public interface IAccInfoService { * @param accInfo 账户资料 * @return 账户资料集合 */ - public List selectAccInfoList(AccInfo accInfo); + public List selectAccInfoList(AccountInfoQueryParam accountInfoQueryParam); // public List selectAccInfoVoList(AccInfo accInfo); @@ -45,7 +50,7 @@ public interface IAccInfoService { * @param accInfo 账户资料 * @return 结果 */ - public int updateAccInfo(AccInfo accInfo); + public void updateAccInfo(AccountBalanceEditParam accountBalanceEditParam); /** * 批量删除账户资料 @@ -55,12 +60,9 @@ public interface IAccInfoService { */ public int deleteAccInfoByIds(Long[] ids); - /** - * 删除账户资料信息 - * - * @param users 账户资料主键 - * @return 结果 - */ + AccInfoInvalidSumVO queryAccInfoInvalidSum(); + AccInfoDetailsVO queryAccInfoBalanceSum(AccountInfoQueryParam accountInfoQueryParam); + void editAccountStatus(AccountEnableDisableParam accountEnableDisableParam); public int deleteAccInfoByUserIds(List users); public int syncAccInfo(SysUser sysUser); diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/IAccWalletInfoService.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/IAccWalletInfoService.java index d172628..4d8f80b 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/IAccWalletInfoService.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/IAccWalletInfoService.java @@ -1,7 +1,11 @@ package com.bonus.canteen.core.account.service; +import java.math.BigDecimal; import java.util.List; +import java.util.Map; + import com.bonus.canteen.core.account.domain.AccWalletInfo; +import com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO; /** * 钱包详情信息Service接口 @@ -59,4 +63,9 @@ public interface IAccWalletInfoService { * @return 结果 */ public int deleteAccWalletInfoByUserId(Long userId); + + Map> selectAccWalletInfoByUserIds(List userIds); + + void updateMinBalance(List userIds, Integer walletId, BigDecimal minBalance); + } diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccInfoServiceImpl.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccInfoServiceImpl.java index 549f36d..fad1728 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccInfoServiceImpl.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccInfoServiceImpl.java @@ -1,6 +1,31 @@ package com.bonus.canteen.core.account.service.impl; import java.math.BigDecimal; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.bonus.canteen.core.account.constants.AccWalletIdEnum; +import com.bonus.canteen.core.account.constants.AccountStatusEnum; +import com.bonus.canteen.core.account.domain.*; +import com.bonus.canteen.core.account.domain.param.AccountBalanceEditParam; +import com.bonus.canteen.core.account.domain.param.AccountEnableDisableParam; +import com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO; +import com.bonus.canteen.core.account.domain.param.AccountInfoQueryParam; +import com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO; +import com.bonus.canteen.core.account.domain.vo.AccInfoInvalidSumVO; +import com.bonus.canteen.core.account.mq.AccMqSender; +import com.bonus.canteen.core.account.service.AccOperationHistoryService; +import com.bonus.canteen.core.account.service.IAccWalletInfoService; import java.util.ArrayList; import java.util.List; @@ -11,8 +36,6 @@ import com.bonus.canteen.core.account.domain.AccInfoVo; import com.bonus.canteen.core.account.domain.AccWalletInfo; import com.bonus.canteen.core.account.domain.WalletBalanceVO; import com.bonus.canteen.core.account.enums.AccStatusEnum; -import com.bonus.canteen.core.account.enums.AccWalletIdEnum; -import com.bonus.canteen.core.account.service.IAccWalletInfoService; import com.bonus.common.core.exception.ServiceException; import com.bonus.common.core.utils.DateUtils; import com.bonus.common.core.web.domain.AjaxResult; @@ -20,17 +43,23 @@ import com.bonus.common.houqin.constant.LeCodeUseSceneEnum; import com.bonus.common.houqin.constant.SourceTypeEnum; import com.bonus.common.security.utils.SecurityUtils; import com.bonus.system.api.domain.SysUser; +import com.bonus.common.houqin.utils.SM4EncryptUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.stereotype.Service; import com.bonus.canteen.core.account.mapper.AccInfoMapper; -import com.bonus.canteen.core.account.domain.AccInfo; import com.bonus.canteen.core.account.service.IAccInfoService; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import javax.annotation.Resource; + /** * 账户资料Service业务层处理 * @@ -40,10 +69,22 @@ import org.springframework.web.bind.annotation.RequestBody; @Service @Slf4j public class AccInfoServiceImpl implements IAccInfoService { + private static final Logger log = LoggerFactory.getLogger(AccInfoServiceImpl.class); + + @Autowired + private IAccWalletInfoService accWalletInfoService; @Autowired private AccInfoMapper accInfoMapper; @Autowired - private IAccWalletInfoService accWalletInfoService; + private AccOperationHistoryService accOperationHistoryService; + @Autowired + private AccMqSender accMqSender; + + @Resource( + name = "smartCanteenTaskExecutor" + ) + @Lazy + private AsyncTaskExecutor asyncTaskExecutor; /** * 查询账户资料 @@ -58,13 +99,14 @@ public class AccInfoServiceImpl implements IAccInfoService { /** * 查询账户资料列表 - * - * @param accInfo 账户资料 - * @return 账户资料 + * */ @Override - public List selectAccInfoList(AccInfo accInfo) { - return accInfoMapper.selectAccInfoList(accInfo); + public List selectAccInfoList(AccountInfoQueryParam accountInfoQueryParam) { + String encryptedSearchValue = SM4EncryptUtils.sm4Encrypt(accountInfoQueryParam.getSearchValue()); + List list = accInfoMapper.queryAccInfoDetails(accountInfoQueryParam, encryptedSearchValue); + handleResult(list); + return list; } // @Override @@ -90,20 +132,35 @@ public class AccInfoServiceImpl implements IAccInfoService { /** * 修改账户资料 - * - * @param accInfo 账户资料 - * @return 结果 + * */ @Override - public int updateAccInfo(AccInfo accInfo) { - accInfo.setUpdateTime(DateUtils.getNowDate()); + @Transactional(rollbackFor = Exception.class) + public void updateAccInfo(AccountBalanceEditParam accountBalanceEditParam) { + LocalDate accEndDate = accountBalanceEditParam.getEndDate(); + Map walletLimits = new HashMap<>(); + walletLimits.put(AccWalletIdEnum.WALLET, accountBalanceEditParam.getMinWalletBalLimit()); + walletLimits.put(AccWalletIdEnum.SUBSIDY, accountBalanceEditParam.getMinSubBalLimit()); + for (Map.Entry entry : walletLimits.entrySet()) { + accWalletInfoService.updateMinBalance(ListUtil.toList(accountBalanceEditParam.getUserId()), entry.getKey().getKey(), entry.getValue()); + } + updateAccountEndDate(ListUtil.toList(accountBalanceEditParam.getUserId()), accEndDate); + } + + protected void updateAccountEndDate(List userIds, LocalDate accEndDate) { + if (ObjectUtil.isEmpty(userIds)) { + log.info("更新账户有效期-账户信息为空"); + return; + } try { - return accInfoMapper.updateAccInfo(accInfo); + accInfoMapper.updateAccInfoEndDateByUserId(accEndDate, userIds, SecurityUtils.getUsername()); } catch (Exception e) { - throw new ServiceException("错误信息描述"); + log.error("[更新账户有效期失败", e); + throw new ServiceException("更新账户有效期失败"); } } + /** * 批量删除账户资料 * @@ -165,6 +222,103 @@ public class AccInfoServiceImpl implements IAccInfoService { return "bns{\"s\":" + SourceTypeEnum.WECHAT_SMALL_PRO.getKey() + ",\"y\":" + LeCodeUseSceneEnum.PAY.key() + ",\"p\":\"" + userId + "\",\"t\":" + "\"" + stime + "\"}"; } + public AccInfoInvalidSumVO queryAccInfoInvalidSum() { +// LocalDateTime now = LocalDateTime.now(); +// LocalDateTime startOfDay = now.toLocalDate().atTime(LocalTime.MIN); +// +// CompletableFuture cancelCountFuture = CompletableFuture.supplyAsync( +// () -> accInfoMapper.queryAccInfoInvalidSum(startOfDay, now, AccountStatusEnum.CANCEL.getKey()), +// this.asyncTaskExecutor +// ).exceptionally(ex -> { +// log.error("Failed to get cancel count", ex); +// return 0; +// }); +// +// CompletableFuture expiredCountFuture = CompletableFuture.supplyAsync( +// () -> accInfoMapper.queryAccInfoInvalidSum(startOfDay, now, AccountStatusEnum.OVERDUE.getKey()), +// this.asyncTaskExecutor +// ).exceptionally(ex -> { +// log.error("Failed to get expired count", ex); +// return 0; +// }); +// +// return cancelCountFuture.thenCombine(expiredCountFuture, (cancel, expired) -> { +// AccInfoInvalidSumVO accInfoInvalidSumVO = new AccInfoInvalidSumVO(); +// accInfoInvalidSumVO.setCancelCount(cancel); +// accInfoInvalidSumVO.setExpiredCount(expired); +// return accInfoInvalidSumVO; +// } +// ).join(); + return null; + } + private void handleResult(List list) { + if (CollUtil.isEmpty(list)) { + return; + } + + List custIdList = list.stream() + .map(AccInfoDetailsVO::getUserId) + .collect(Collectors.toList()); + Map> walletMap = accWalletInfoService.selectAccWalletInfoByUserIds(custIdList); + + list.forEach(item -> { + List walletInfoList = walletMap.getOrDefault(item.getUserId(), ListUtil.empty()); + setWalletBalances(item, walletInfoList); + setTotalBalances(item, walletInfoList); + }); + } + + private void setWalletBalances(AccInfoDetailsVO item, List walletInfoList) { + for (AccWalletInfoVO wallet : walletInfoList) { + switch (AccWalletIdEnum.getEnum(wallet.getWalletId())) { + case WALLET: + item.setWalletBal(wallet.getWalletBal()); + item.setFrozenWallet(wallet.getFrozenBalance()); + item.setMinWalletBalLimit(wallet.getLimitBalance()); + break; + case SUBSIDY: + item.setSubsidyBal(wallet.getWalletBal()); + item.setFrozenSub(wallet.getFrozenBalance()); + item.setMinSubBalLimit(wallet.getLimitBalance()); + break; + default: + break; + } + } + } + private void setTotalBalances(AccInfoDetailsVO item, List walletInfoList) { + BigDecimal frozenBalanceAll = walletInfoList.stream() + .map(AccWalletInfoVO::getFrozenBalance) + .filter(ObjectUtil::isNotNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal accAvailableBal = walletInfoList.stream() + .map(AccWalletInfoVO::getWalletBal) + .filter(ObjectUtil::isNotNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + item.setAccBalTotal(NumberUtil.add(accAvailableBal, frozenBalanceAll)); + item.setAccAvailableBal(accAvailableBal); + item.setAccFreezeBalTotal(frozenBalanceAll); + } + + public AccInfoDetailsVO queryAccInfoBalanceSum(AccountInfoQueryParam accountInfoQueryParam) { + return accInfoMapper.queryAccInfoBalanceSum(accountInfoQueryParam); + } + + @Transactional(rollbackFor = {Exception.class}) + public void editAccountStatus(AccountEnableDisableParam accountEnableDisableParam) { + int flag = accInfoMapper.update((((Wrappers.lambdaUpdate(AccInfo.class) + .set(AccInfo::getAccStatus, accountEnableDisableParam.getAccStatus())) + .set(AccInfo::getUpdateBy, SecurityUtils.getUserId())) + .set(AccInfo::getUpdateTime, LocalDateTime.now())) + .eq(AccInfo::getUserId, accountEnableDisableParam.getUserId())); + if (flag > 0) { + this.accOperationHistoryService.addAccOperationHistory(accountEnableDisableParam.getUserId(), accountEnableDisableParam.getAccStatus().intValue()); + this.accMqSender.accChangeMQ(Collections.singletonList(accountEnableDisableParam.getUserId()), accountEnableDisableParam.getAccStatus().intValue()); + } + } + + public WalletBalanceVO queryWalletBalance(AccInfo accInfo) { log.info("查询账户余额入参={}", JSONUtil.toJsonStr(accInfo)); AccInfoVo accInfoVO = accInfoMapper.selectAccInfoVo(accInfo); diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccOperationHistoryServiceImpl.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccOperationHistoryServiceImpl.java new file mode 100644 index 0000000..9b1e967 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccOperationHistoryServiceImpl.java @@ -0,0 +1,45 @@ +package com.bonus.canteen.core.account.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bonus.canteen.core.account.domain.bo.AccOperationHistory; +import com.bonus.canteen.core.account.domain.param.AccOperationQueryParam; +import com.bonus.canteen.core.account.mapper.AccOperationHistoryMapper; +import com.bonus.canteen.core.account.service.AccOperationHistoryService; +import com.bonus.common.core.constant.SecurityConstants; +import com.bonus.common.core.web.domain.AjaxResult; +import com.bonus.common.houqin.utils.SM4EncryptUtils; +import com.bonus.common.security.utils.SecurityUtils; +import com.bonus.system.api.RemoteUserService; +import com.bonus.system.api.domain.SysUser; +import com.github.pagehelper.page.PageMethod; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; + +@Service +public class AccOperationHistoryServiceImpl extends ServiceImpl implements AccOperationHistoryService { + @Resource + private RemoteUserService remoteUserService; + public List selectAccOperationHistory(AccOperationQueryParam param) { + String encryptedSearchValue = SM4EncryptUtils.sm4Encrypt(param.getSearchValue()); + return this.baseMapper.queryPageAccOperationRecord(param, encryptedSearchValue); + } + + public void addAccOperationHistory(Long userId, Integer type) { + AjaxResult userResult = remoteUserService.getInfo(userId , SecurityConstants.INNER); + if(Objects.nonNull(userResult)) { + SysUser sysUser = userResult.getDataAs(SysUser.class); + AccOperationHistory accOperationRecord = new AccOperationHistory(); + accOperationRecord.setType(type); + accOperationRecord.setUserId(userId); + accOperationRecord.setUserName(sysUser.getUserName()); + accOperationRecord.setPhone(sysUser.getPhonenumber()); + accOperationRecord.setCreateBy(SecurityUtils.getUsername()); + accOperationRecord.setCreateTime(LocalDateTime.now()); + this.baseMapper.insert(accOperationRecord); + } + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccWalletInfoServiceImpl.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccWalletInfoServiceImpl.java index 938e31f..2af21c2 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccWalletInfoServiceImpl.java +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/account/service/impl/AccWalletInfoServiceImpl.java @@ -1,9 +1,18 @@ package com.bonus.canteen.core.account.service.impl; +import java.math.BigDecimal; +import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import cn.hutool.core.util.ObjectUtil; +import com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO; import com.bonus.common.core.exception.ServiceException; import com.bonus.common.core.utils.DateUtils; import com.bonus.common.security.utils.SecurityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.bonus.canteen.core.account.mapper.AccWalletInfoMapper; @@ -18,6 +27,8 @@ import com.bonus.canteen.core.account.service.IAccWalletInfoService; */ @Service public class AccWalletInfoServiceImpl implements IAccWalletInfoService { + private static final Logger log = LoggerFactory.getLogger(AccWalletInfoServiceImpl.class); + @Autowired private AccWalletInfoMapper accWalletInfoMapper; @@ -78,11 +89,7 @@ public class AccWalletInfoServiceImpl implements IAccWalletInfoService { @Override public int updateAccWalletInfo(AccWalletInfo accWalletInfo) { accWalletInfo.setUpdateTime(DateUtils.getNowDate()); - try { - return accWalletInfoMapper.updateAccWalletInfo(accWalletInfo); - } catch (Exception e) { - throw new ServiceException("错误信息描述"); - } + return accWalletInfoMapper.updateAccWalletInfo(accWalletInfo); } /** @@ -106,4 +113,38 @@ public class AccWalletInfoServiceImpl implements IAccWalletInfoService { public int deleteAccWalletInfoByUserId(Long userId) { return accWalletInfoMapper.deleteAccWalletInfoByUserId(userId); } + + public Map> selectAccWalletInfoByUserIds(List userIds) { + List walletInfoList = accWalletInfoMapper.selectAccWalletInfoByUserIds(userIds); + return walletInfoList.stream() + .collect(Collectors.groupingBy(AccWalletInfoVO::getUserId)); + } + + @Override + public void updateMinBalance(List userIds, Integer walletId, BigDecimal minBalance) { + if (ObjectUtil.isNull(minBalance)) { + log.warn("修改钱包最低余额限制-最低余额不能为空"); + return; + } + + if (ObjectUtil.isNull(walletId)) { + log.warn("修改钱包最低余额限制-钱包编号为空"); + return; + } + + if (ObjectUtil.isEmpty(userIds)) { + log.warn("修改钱包最低余额限制-用户编号为空"); + return; + } + + try { + accWalletInfoMapper.updateMinBalanceByUserId(minBalance, walletId, userIds, + SecurityUtils.getUserId().toString(), DateUtils.toLocalDate(new Date())); + } catch (Exception e) { + log.error("修改钱包最低余额限制失败", e); + throw new ServiceException("修改钱包最低余额限制失败"); + } + } + + } diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/threadPool/AsyncConfig.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/threadPool/AsyncConfig.java new file mode 100644 index 0000000..6c35b97 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/threadPool/AsyncConfig.java @@ -0,0 +1,50 @@ +package com.bonus.canteen.core.common.threadPool; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +public class AsyncConfig { + + // 核心线程数和最大线程数的倍数 + private static final int THREAD_POOL_SIZE_MULTIPLIER = 2; + + // 线程池队列容量 + @Value("${async.threadPool.queueCapacity:1000}") + private int queueCapacity; + + // 线程池线程存活时间(秒) + @Value("${async.threadPool.keepAliveSeconds:60}") + private int keepAliveSeconds; + + // 线程池关闭时等待任务完成的时间(秒) + @Value("${async.threadPool.awaitTerminationSeconds:60}") + private int awaitTerminationSeconds; + + @Bean("smartCanteenTaskExecutor") + public AsyncTaskExecutor taskExecutor() { + int corePoolSize = Runtime.getRuntime().availableProcessors() * THREAD_POOL_SIZE_MULTIPLIER; + ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); + taskExecutor.setCorePoolSize(corePoolSize); + taskExecutor.setMaxPoolSize(corePoolSize); + taskExecutor.setThreadNamePrefix("smart-canteen-async-pool"); + taskExecutor.setQueueCapacity(queueCapacity); + taskExecutor.setKeepAliveSeconds(keepAliveSeconds); + taskExecutor.setWaitForTasksToCompleteOnShutdown(true); + taskExecutor.setAwaitTerminationSeconds(awaitTerminationSeconds); + taskExecutor.setTaskDecorator(new TenantTaskDecorator()); + taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + try { + taskExecutor.initialize(); + } catch (Exception e) { + throw new RuntimeException("Failed to initialize ThreadPoolTaskExecutor", e); + } + + return taskExecutor; + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/threadPool/TenantTaskDecorator.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/threadPool/TenantTaskDecorator.java new file mode 100644 index 0000000..ee1599e --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/threadPool/TenantTaskDecorator.java @@ -0,0 +1,29 @@ +package com.bonus.canteen.core.common.threadPool; + +import com.bonus.canteen.core.common.utils.TenantContextHolder; +import com.github.pagehelper.PageHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.task.TaskDecorator; + +public class TenantTaskDecorator implements TaskDecorator { + private static final Logger log = LoggerFactory.getLogger(TenantTaskDecorator.class); + + @Override + public Runnable decorate(Runnable runnable) { + Long tenantId = TenantContextHolder.getTenantId(); + return () -> { + try { + TenantContextHolder.setTenantId(tenantId); + runnable.run(); + } finally { + try { + TenantContextHolder.clear(); + PageHelper.clearPage(); + } catch (Exception e) { + log.error("Failed to clear tenant context or page helper", e); + } + } + }; + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/utils/TenantContextHolder.java b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/utils/TenantContextHolder.java new file mode 100644 index 0000000..f6dd117 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/java/com/bonus/canteen/core/common/utils/TenantContextHolder.java @@ -0,0 +1,21 @@ +package com.bonus.canteen.core.common.utils; + +public final class TenantContextHolder { + private static final ThreadLocal THREAD_LOCAL_TENANT = new InheritableThreadLocal(); + + public static Long getTenantId() { + return (Long)THREAD_LOCAL_TENANT.get(); + } + + public static void setTenantId(Long tenantId) { + THREAD_LOCAL_TENANT.set(tenantId); + } + + public static void clear() { + THREAD_LOCAL_TENANT.remove(); + } + + private TenantContextHolder() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } +} diff --git a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccInfoMapper.xml b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccInfoMapper.xml index 7b8d738..856c1dc 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccInfoMapper.xml +++ b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccInfoMapper.xml @@ -181,7 +181,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and reserved3 = #{reserved3} - + + SELECT count( a.acc_id ) FROM acc_info a + WHERE a.acc_status = #{accStatus} AND a.update_time BETWEEN #{startDateTime} and #{endDateTime} + + + + + + + + + t1.acc_status in + + #{accStatus} + + + and (t2.nick_name = #{accountInfoQueryParam.searchValue} + or t2.phonenumber = #{encryptedSearchValue} + or t2.nick_name_like LIKE CONCAT('%',#{accountInfoQueryParam.searchValue},'%') + ) + + + and t2.dept_id in + + #{deptId} + + + + and t1.uptime = ]]> #{accountInfoQueryParam.startDateTime} + + + and t1.uptime #{accountInfoQueryParam.endDateTime} + + + AND EXISTS( + SELECT null FROM + ( + SELECT + user_id, + SUM( CASE WHEN wallet_id = 1 THEN wallet_bal ELSE 0 END ) AS walletBal, + SUM( CASE WHEN wallet_id = 2 THEN wallet_bal ELSE 0 END ) AS subsidyBal, + SUM( a.wallet_bal ) + SUM( a.frozen_balance ) accBalTotal + FROM + acc_wallet_info a + GROUP BY + user_id + ) AS t4 + + t4.user_id = t1.user_id + + + ) + + + + + + update acc_info + set end_date = #{endDate}, + update_by = #{updateBy}, + update_time = now() + where user_id in + + #{userId} + + + \ No newline at end of file diff --git a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccOperationHistoryMapper.xml b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccOperationHistoryMapper.xml new file mode 100644 index 0000000..c31dfa7 --- /dev/null +++ b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccOperationHistoryMapper.xml @@ -0,0 +1,45 @@ + + + + + diff --git a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccWalletInfoMapper.xml b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccWalletInfoMapper.xml index 279eca9..5f3a92d 100644 --- a/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccWalletInfoMapper.xml +++ b/bonus-modules/bonus-smart-canteen/src/main/resources/mapper/account/AccWalletInfoMapper.xml @@ -40,6 +40,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where user_id = #{userId} + + insert into acc_wallet_info @@ -115,4 +132,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{userId} + + + UPDATE + acc_wallet_info + SET limit_balance = #{minBalance}, + update_by = #{updateBy}, + update_time = #{updateTime} + + + AND user_id IN + + #{userId} + + + AND wallet_id = #{walletId} + + \ No newline at end of file