【积分银行】积分

This commit is contained in:
2026-02-09 16:30:50 +08:00
parent 03f8be4c98
commit 6e005f2f4e
20 changed files with 719 additions and 48 deletions
@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.renkang.bank.model.dto.UpdUserPointsDTO;
import com.renkang.bank.model.dto.UserPointsPageDTO;
import com.renkang.bank.model.dto.UserPointsRankingDTO;
import com.renkang.bank.model.po.UserPointsDetails;
import com.renkang.bank.model.vo.*;
import com.renkang.bank.service.IUserPointsService;
import io.swagger.v3.oas.annotations.Operation;
@@ -30,9 +29,9 @@ public class UserPointsController {
private IUserPointsService iUserPointsService;
@Operation(summary = "测试积分变更", description = "测试积分变更")
@PostMapping(value = "/updateUserPoints")
public Result<Boolean> updateUserPoints(@RequestBody UpdUserPointsDTO dto) {
return Result.OK(iUserPointsService.updateUserPoints(dto));
@PostMapping(value = "/testUpdateUserPoints")
public Result<Boolean> testUpdateUserPoints(@RequestBody UpdUserPointsDTO dto) {
return Result.OK(iUserPointsService.testUpdateUserPoints(dto));
}
@Operation(summary = "用户积分信息-分页列表", description = "用户积分信息-分页列表")
@@ -41,12 +40,26 @@ public class UserPointsController {
return Result.OK(iUserPointsService.pageList(dto));
}
@Operation(summary = "用户积分信息-分页列表(导出)", description = "用户积分信息-分页列表(导出)")
@PostMapping(value = "/exportUserPoints")
public Result<String> exportUserPoints(@RequestBody UserPointsPageDTO dto) {
iUserPointsService.exportUserPoints(dto);
return Result.OK("导出成功,请在导出记录查看");
}
@Operation(summary = "用户积分信息-积分明细", description = "用户积分信息-积分明细")
@PostMapping(value = "/detailPageList")
public Result<IPage<UserPointsDetails>> detailPageList(@RequestBody UserPointsPageDTO dto) {
public Result<IPage<UserPointsDetailsVO>> detailPageList(@RequestBody UserPointsPageDTO dto) {
return Result.OK(iUserPointsService.detailPageList(dto));
}
@Operation(summary = "用户积分信息-积分明细(导出)", description = "用户积分信息-积分明细(导出)")
@PostMapping(value = "/exportPointsDetail")
public Result<String> exportPointsDetail(@RequestBody UserPointsPageDTO dto) {
iUserPointsService.exportPointsDetail(dto);
return Result.OK("导出成功,请在导出记录查看");
}
@Operation(summary = "用户积分信息-扣除积分", description = "用户积分信息-扣除积分")
@PostMapping(value = "/deductPoint")
public Result<Boolean> deductPoint(@RequestBody UpdUserPointsDTO dto) {
@@ -59,6 +72,26 @@ public class UserPointsController {
return Result.OK(iUserPointsService.clockInMonitor(dto));
}
@Operation(summary = "用户积分信息-员工打卡监测(导出)", description = "用户积分信息-员工打卡监测(导出)")
@PostMapping(value = "/exportClockInMonitor")
public Result<String> exportClockInMonitor(@RequestBody UserPointsPageDTO dto) {
iUserPointsService.exportClockInMonitor(dto);
return Result.OK("导出成功,请在导出记录查看");
}
@Operation(summary = "用户积分信息-员工积分排名", description = "用户积分信息-员工积分排名")
@PostMapping(value = "/userRanking")
public Result<IPage<UserPointRankingVO>> userRanking(@RequestBody UserPointsRankingDTO dto) {
return Result.OK(iUserPointsService.userRanking(dto));
}
@Operation(summary = "用户积分信息-员工积分排名(导出)", description = "用户积分信息-员工积分排名(导出)")
@PostMapping(value = "/exportUserRanking")
public Result<String> exportUserRanking(@RequestBody UserPointsRankingDTO dto) {
iUserPointsService.exportUserRanking(dto);
return Result.OK("导出成功,请在导出记录查看");
}
@Operation(summary = "用户积分信息-app我的积分", description = "用户积分信息-app我的积分")
@GetMapping(value = "/app/myPoints")
public Result<UserPointsInfoVO> myPoints() {
@@ -2,6 +2,7 @@ package com.renkang.bank.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.base.MPJBaseMapper;
import com.renkang.bank.model.dto.UserPointsRankingDTO;
import com.renkang.bank.model.po.UserPointsDetails;
import com.renkang.bank.model.vo.UserPointRankingVO;
import org.apache.ibatis.annotations.Mapper;
@@ -11,6 +12,8 @@ import java.util.Date;
@Mapper
public interface UserPointsDetailsMapper extends MPJBaseMapper<UserPointsDetails> {
IPage<UserPointRankingVO> userRanking(IPage<UserPointRankingVO> page, Date startTime, Date endTime, UserPointsRankingDTO dto);
IPage<UserPointRankingVO> pointRanking(IPage<UserPointRankingVO> page, Date startTime, Date endTime, String secondOrgCode);
}
@@ -3,6 +3,53 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.renkang.bank.mapper.UserPointsDetailsMapper">
<select id="userRanking" resultType="com.renkang.bank.model.vo.UserPointRankingVO">
<!--定义公共表表达式用于计算每个用户的总积分-->
WITH UserPointsSummary AS (
SELECT
a.user_id,
SUM(CASE WHEN a.change_type = 1 THEN a.points ELSE 0 END) -
SUM(CASE WHEN a.change_type = 2 THEN a.points ELSE 0 END) AS pointSum
FROM
bank_user_points_details a
INNER JOIN bank_user_points b ON a.user_id = b.user_id
<if test="null != dto.orgCode and '' != dto.orgCode">
AND b.org_code like concat(#{dto.orgCode},'%')
</if>
<if test="null != dto.deptCode and '' != dto.deptCode">
AND b.org_code like concat(#{dto.deptCode},'%')
</if>
GROUP BY
a.user_id
),
<!--计算所有用户的排名-->
RankedUsers AS (
SELECT
user_id,
pointSum,
ROW_NUMBER() OVER (ORDER BY pointSum DESC, user_id ASC) AS ranking
FROM
UserPointsSummary
)
<!--主查询:根据是否传入用户 ID 返回结果-->
SELECT
ranking,
user_id,
pointSum
FROM
RankedUsers
<where>
<if test="dto.userIds != null and dto.userIds.size() > 0">
AND user_id in
<foreach collection="dto.userIds" item="userId" open="(" separator="," close=")">
#{userId}
</foreach>
</if>
</where>
ORDER BY
pointSum DESC, user_id ASC
</select>
<select id="pointRanking" resultType="com.renkang.bank.model.vo.UserPointRankingVO">
WITH UserPointsSummary AS (
SELECT
@@ -0,0 +1,90 @@
package com.renkang.bank.redis.config;
import com.renkang.bank.redis.listener.BankAsyncListener;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.vo.SysUserModel;
import org.jeecg.enums.ServerEnum;
import org.jeecg.redis.RedisStreamKeyEnum;
import org.jeecg.util.IPUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.stream.Consumer;
import org.springframework.data.redis.connection.stream.ObjectRecord;
import org.springframework.data.redis.connection.stream.ReadOffset;
import org.springframework.data.redis.connection.stream.StreamOffset;
import org.springframework.data.redis.hash.Jackson2HashMapper;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.stream.StreamMessageListenerContainer;
/**
* @author Shunzhi Jiang
* @since 2023/6/13
*/
@Configuration
@Slf4j
public class BankRedisStreamConfig {
private final Consumer consumer = Consumer.from(ServerEnum.BANK.getCustomGroup(), IPUtil.getCurrentServiceIp());
private final ReadOffset readOffset = ReadOffset.lastConsumed();
private BankAsyncListener bankAsyncListener;
@Autowired
public void setDepartAsyncListener(BankAsyncListener bankAsyncListener) {
this.bankAsyncListener = bankAsyncListener;
}
@Bean
public StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, ObjectRecord<String, SysUserModel>> sysUserModelInterveneStreamOptions(
@Qualifier("asyncTaskExecutor") TaskExecutor taskExecutor,
StringRedisSerializer stringSerializer,
GenericJackson2JsonRedisSerializer jsonSerializer
) {
return StreamMessageListenerContainer.StreamMessageListenerContainerOptions
.builder()
// 一次最多获取多少条消息
.batchSize(10)
// 运行 Stream 的 poll task
.executor(taskExecutor)
// 可以理解为 Stream Key 的序列化方式
.keySerializer(stringSerializer)
// 可以理解为 Stream 后方的字段的 key 的序列化方式
.hashKeySerializer(stringSerializer)
// 可以理解为 Stream 后方的字段的 value 的序列化方式
.hashValueSerializer(jsonSerializer)
// ObjectRecord 时,将 对象的 filed 和 value 转换成一个 Map 比如:将Book对象转换成map
.objectMapper(new Jackson2HashMapper(true))
// 将发送到Stream中的Record转换成ObjectRecord,转换成具体的类型是这个地方指定的类型
.targetType(SysUserModel.class)
.build();
}
@Bean(initMethod = "start", destroyMethod = "stop")
public StreamMessageListenerContainer<String, ObjectRecord<String, SysUserModel>> sysUserModelInterveneStreamMessageListenerContainer(
RedisConnectionFactory redisConnectionFactory,
StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, ObjectRecord<String, SysUserModel>> options
) {
StreamMessageListenerContainer<String, ObjectRecord<String, SysUserModel>> container =
StreamMessageListenerContainer.create(redisConnectionFactory, options);
// 修改用户
container.receive(
consumer,
createStreamOffset(RedisStreamKeyEnum.CHANGE_USER_DEPART),
bankAsyncListener
);
log.info("redisStream配置完成");
return container;
}
private StreamOffset<String> createStreamOffset(RedisStreamKeyEnum streamKeyEnum) {
return StreamOffset.create(streamKeyEnum.getKey(), readOffset);
}
}
@@ -0,0 +1,63 @@
package com.renkang.bank.redis.listener;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.renkang.bank.mapper.UserPointsMapper;
import com.renkang.bank.model.po.UserPoints;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.vo.SysUserModel;
import org.jeecg.enums.ServerEnum;
import org.jeecg.redis.RedisStreamKeyEnum;
import org.jeecg.redis.RedisStreamUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.stream.ObjectRecord;
import org.springframework.data.redis.connection.stream.RecordId;
import org.springframework.data.redis.stream.StreamListener;
import org.springframework.stereotype.Component;
/**
* @author Shunzhi Jiang
* @since 2023/6/13
*/
@Component
@Slf4j
public class BankAsyncListener implements StreamListener<String, ObjectRecord<String, SysUserModel>> {
@Autowired
private RedisStreamUtil redisStreamUtil;
@Autowired
private UserPointsMapper userPointsMapper;
@Override
public void onMessage(ObjectRecord<String, SysUserModel> message) {
String streamKey = message.getStream();
SysUserModel model = message.getValue();
log.info("收到Redis Stream Key{}", streamKey);
RecordId recordId = message.getId();
log.info("ID{}, DATA: {}", recordId, JSON.toJSONString(model));
try {
if (RedisStreamKeyEnum.CHANGE_USER_DEPART.getKey().equals(streamKey)) {
if (StrUtil.isBlank(model.getId()) || StrUtil.isBlank(model.getOrgCode())) {
return;
}
// 修改用户积分主表单位信息
updateUserPointsInfo(model);
}
ack(message);
log.info("Redis Stream消费成功:Key: {}, ID: {}", streamKey, recordId);
} catch (Exception e) {
log.error("Redis Stream消费异常:Key: {}, ID: {}", streamKey, recordId, e);
}
}
private void updateUserPointsInfo(SysUserModel model) {
userPointsMapper.update(new LambdaUpdateWrapper<UserPoints>()
.eq(UserPoints::getUserId, model.getId())
.set(UserPoints::getOrgCode, model.getOrgCode())
);
}
private void ack(ObjectRecord<String, SysUserModel> message) {
redisStreamUtil.ack(ServerEnum.BANK.getCustomGroup(), message);
}
}
@@ -11,16 +11,26 @@ import java.util.List;
public interface IUserPointsService {
boolean updateUserPoints(UpdUserPointsDTO dto);
boolean testUpdateUserPoints(UpdUserPointsDTO dto);
IPage<UserPointsListVO> pageList(UserPointsPageDTO dto);
IPage<UserPointsDetails> detailPageList(UserPointsPageDTO dto);
void exportUserPoints(UserPointsPageDTO dto);
IPage<UserPointsDetailsVO> detailPageList(UserPointsPageDTO dto);
void exportPointsDetail(UserPointsPageDTO dto);
boolean deductPoint(UpdUserPointsDTO dto);
IPage<UserPointsMonitorVO> clockInMonitor(UserPointsPageDTO dto);
void exportClockInMonitor(UserPointsPageDTO dto);
IPage<UserPointRankingVO> userRanking(UserPointsRankingDTO dto);
void exportUserRanking(UserPointsRankingDTO dto);
UserPointsInfoVO myPoints();
List<UserPointsTaskVO> pointsTaskList();
@@ -1,5 +1,6 @@
package com.renkang.bank.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
@@ -27,13 +28,18 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.ExceptionAssertsUtil;
import org.jeecg.common.export.GenericExportHandler;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.enums.ExportExcelEnum;
import org.jeecg.global.GlobalUtils;
import org.jeecg.modules.manager.ISysCache;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@@ -108,28 +114,106 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
return voPage;
}
@Resource
private AsyncTaskExecutor asyncTaskExecutor;
/**
* @description: 导出数据(设备数据)
* @author PengJ
* @date 2025/11/18 14:57
*/
@Override
public IPage<UserPointsDetails> detailPageList(UserPointsPageDTO dto) {
public void exportUserPoints(UserPointsPageDTO dto) {
GenericExportHandler<UserPointsListVO, UserPointsPageDTO> handler =
new GenericExportHandler<>(
UserPointsListVO.class,
ExportExcelEnum.BANK_USER_POINTS,
asyncTaskExecutor,
log,
filter -> {
filter.setPageNo(1);
filter.setPageSize(-1);
List<UserPointsListVO> records = pageList(filter).getRecords();
return GenericExportHandler.handleData(records, UserPointsListVO.class);
}
);
handler.exportAsync(dto);
}
@Override
public IPage<UserPointsDetailsVO> detailPageList(UserPointsPageDTO dto) {
if (StringUtils.isBlank(dto.getUserId())) {
ExceptionAssertsUtil.fail("用户id不能为空");
}
if (ObjectUtil.isNull(dto.getChangeType())) {
ExceptionAssertsUtil.fail("收支类型不能为空");
}
Page<UserPointsDetails> page = new Page<>(dto.getPageNo(), dto.getPageSize());
LambdaQueryWrapper<UserPointsDetails> queryWrapper = new LambdaQueryWrapper<>();
Page<UserPointsDetailsVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
MPJLambdaWrapper<UserPointsDetails> queryWrapper = new MPJLambdaWrapper<>();
queryWrapper.select(UserPointsDetails::getId, UserPointsDetails::getBusinessInfo,
UserPointsDetails::getPoints, UserPointsDetails::getCreateTime, UserPointsDetails::getChangeType);
UserPointsDetails::getPoints, UserPointsDetails::getCreateTime, UserPointsDetails::getChangeType,
UserPointsDetails::getRemark, UserPointsDetails::getBusinessId, UserPointsDetails::getUserId);
queryWrapper.select(PointsRule::getFrequency);
queryWrapper.leftJoin(PointsRule.class, PointsRule::getId, UserPointsDetails::getBusinessId);
queryWrapper.eq(UserPointsDetails::getUserId, dto.getUserId());
queryWrapper.eq(UserPointsDetails::getChangeType, dto.getChangeType());
queryWrapper.orderByDesc(UserPointsDetails::getCreateTime);
return userPointsDetailsMapper.selectPage(page, queryWrapper);
Page<UserPointsDetailsVO> voPage = userPointsDetailsMapper.selectJoinPage(page, UserPointsDetailsVO.class, queryWrapper);
if (dto.getChangeType().equals(HealthBankConstants.CHANGE_TYPE_DEDUCT)) {
voPage.getRecords().forEach(vo -> {
vo.setPoints(vo.getPoints().multiply(new BigDecimal(-1)));
});
}
return voPage;
}
@Override
public void exportPointsDetail(UserPointsPageDTO dto) {
if (StringUtils.isBlank(dto.getUserId())) {
ExceptionAssertsUtil.fail("用户id不能为空");
}
if (ObjectUtil.isNull(dto.getChangeType())) {
ExceptionAssertsUtil.fail("收支类型不能为空");
}
if (dto.getChangeType().equals(HealthBankConstants.CHANGE_TYPE_ADD)) {
GenericExportHandler<UserPointsDetailsVO, UserPointsPageDTO> handler =
new GenericExportHandler<>(
UserPointsDetailsVO.class,
ExportExcelEnum.BANK_POINTS_DETAIL,
asyncTaskExecutor,
log,
filter -> {
filter.setPageNo(1);
filter.setPageSize(-1);
List<UserPointsDetailsVO> records = detailPageList(filter).getRecords();
return GenericExportHandler.handleData(records, UserPointsDetailsVO.class);
}
);
handler.exportAsync(dto);
} else if (dto.getChangeType().equals(HealthBankConstants.CHANGE_TYPE_DEDUCT)) {
GenericExportHandler<UserPointsDeductDetailsVO, UserPointsPageDTO> handler =
new GenericExportHandler<>(
UserPointsDeductDetailsVO.class,
ExportExcelEnum.BANK_POINTS_DETAIL,
asyncTaskExecutor,
log,
filter -> {
filter.setPageNo(1);
filter.setPageSize(-1);
List<UserPointsDetailsVO> records = detailPageList(filter).getRecords();
List<UserPointsDeductDetailsVO> voList = BeanUtil.copyToList(records, UserPointsDeductDetailsVO.class);
return GenericExportHandler.handleData(voList, UserPointsDeductDetailsVO.class);
}
);
handler.exportAsync(dto);
}
}
@Override
public boolean deductPoint(UpdUserPointsDTO dto) {
dto.setSourceType(PointsSourceEnum.TYPE_2_VIOLATION.getSource());
return updateUserPoints(dto);
LoginUser loginUser = GlobalUtils.getLoginUser();
return updateUserPoints(dto, loginUser);
}
@Override
@@ -138,14 +222,12 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
MPJLambdaWrapper<UserPointsDetails> queryWrapper = new MPJLambdaWrapper<>();
queryWrapper.selectAll(UserPointsDetails.class);
queryWrapper.select(PointsRule::getFrequency);
queryWrapper.eq(UserPointsDetails::getChangeType, 1);
queryWrapper.eq(UserPointsDetails::getSource, PointsSourceEnum.TYPE_1_SURVEY.getSource());
if (StringUtils.isNotBlank(dto.getRealName()) || StringUtils.isNotBlank(dto.getWorkNo())) {
//根据姓名和工号查询用户
List<String> userIdList = iSysBaseAPI.getUserIdsByDepartAndUsername(null, dto.getRealName(), null, dto.getWorkNo());
queryWrapper.in(!userIdList.isEmpty(), UserPoints::getUserId, userIdList);
}
// 动态排序
queryWrapper.orderByDesc(UserPointsDetails::getCreateTime);
if (StringUtils.isNotBlank(dto.getOrgCode())) {
queryWrapper.likeRight(UserPoints::getOrgCode, dto.getOrgCode());
@@ -154,6 +236,7 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
queryWrapper.likeRight(UserPoints::getOrgCode, dto.getDeptCode());
}
queryWrapper.leftJoin(PointsRule.class, PointsRule::getId, UserPointsDetails::getBusinessId);
queryWrapper.orderByDesc(UserPointsDetails::getCreateTime);
Page<UserPointsMonitorVO> voPage = userPointsDetailsMapper.selectJoinPage(page, UserPointsMonitorVO.class, queryWrapper);
List<String> userIds = voPage.getRecords().stream().map(UserPointsMonitorVO::getUserId).collect(Collectors.toList());
if (!userIds.isEmpty()) {
@@ -179,15 +262,140 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
return voPage;
}
@Override
public void exportClockInMonitor(UserPointsPageDTO dto) {
GenericExportHandler<UserPointsMonitorVO, UserPointsPageDTO> handler =
new GenericExportHandler<>(
UserPointsMonitorVO.class,
ExportExcelEnum.BANK_CLOCK_IN_RECORD,
asyncTaskExecutor,
log,
filter -> {
filter.setPageNo(1);
filter.setPageSize(-1);
List<UserPointsMonitorVO> records = clockInMonitor(filter).getRecords();
return GenericExportHandler.handleData(records, UserPointsMonitorVO.class);
}
);
handler.exportAsync(dto);
}
@Override
public IPage<UserPointRankingVO> userRanking(UserPointsRankingDTO dto) {
Page<UserPointRankingVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
Date startTime = null;
Date endTime = null;
Date now = new Date();
if (StringUtils.isNotBlank(dto.getRankType())) {
if ("0".equals(dto.getRankType())) {
// 获取当天的开始时间
startTime = DateUtil.beginOfDay(now);
// 获取当天的结束时间
endTime = DateUtil.endOfDay(now);
} else if ("1".equals(dto.getRankType())) {
// 获取本周的开始时间(周一)
startTime = DateUtil.beginOfWeek(now, true);
// 获取本周的结束时间(周日)
endTime = DateUtil.endOfWeek(now, true);
} else if ("2".equals(dto.getRankType())) {
// 获取本月的开始时间
startTime = DateUtil.beginOfMonth(now);
// 获取本月的结束时间
endTime = DateUtil.endOfMonth(now);
} else if ("3".equals(dto.getRankType())) {
// 获取本季度的开始时间
startTime = DateUtil.beginOfQuarter(now);
// 获取本季度的结束时间
endTime = DateUtil.endOfQuarter(now);
} else if ("4".equals(dto.getRankType())) {
// 获取本年度的开始时间
startTime = DateUtil.beginOfYear(now);
// 获取本年度的结束时间
endTime = DateUtil.endOfYear(now);
} else if ("5".equals(dto.getRankType())) {
// 获取指定时间的开始时间
startTime = DateUtil.beginOfDay(dto.getStartTime());
// 获取指定时间的结束时间
endTime = DateUtil.endOfDay(dto.getEndTime());
}
}
if (StringUtils.isNotBlank(dto.getRealName()) || StringUtils.isNotBlank(dto.getWorkNo())) {
List<String> sysUserIds = iSysBaseAPI.getUserIdsByDepartAndUsername(
StringUtils.isNotBlank(dto.getDeptCode()) ? dto.getDeptCode() : dto.getOrgCode(),
dto.getRealName(),
null,
dto.getWorkNo()
);
if (!sysUserIds.isEmpty()) {
dto.setUserIds(sysUserIds);
}
}
IPage<UserPointRankingVO> voiPage = userPointsDetailsMapper.userRanking(page, startTime, endTime, dto);
List<String> userIds = voiPage.getRecords().stream().map(UserPointRankingVO::getUserId).collect(Collectors.toList());
List<LoginUser> loginUsers = iSysBaseAPI.listUserByIdsNew(userIds);
voiPage.getRecords().forEach(vo -> {
loginUsers.forEach(loginUser -> {
if (vo.getUserId().equals(loginUser.getId())) {
vo.setRealName(loginUser.getRealname());
vo.setAvatar(loginUser.getAvatar());
vo.setSex(loginUser.getSex());
vo.setSexName(ObjectUtil.isNotNull(loginUser.getSex()) && loginUser.getSex().equals(1) ? "" : "");
vo.setWorkNo(loginUser.getWorkNo());
vo.setAge(ObjectUtil.isNotNull(loginUser.getAge()) && loginUser.getAge() > 0 ? loginUser.getAge() : null);
SysDepart secondDepart = sysCache.getDepartByOrgCode(GlobalUtils.getSecondDepartOrgCode(loginUser.getOrgCode()));
if (ObjUtil.isNotEmpty(secondDepart)) {
vo.setDeptName(secondDepart.getDepartName());
}
SysDepart thirdDepart = sysCache.getDepartByOrgCode(GlobalUtils.getThirdDepartOrgCode(loginUser.getOrgCode()));
if (ObjUtil.isNotEmpty(thirdDepart)) {
vo.setOrgName(thirdDepart.getDepartName());
}
}
});
});
return voiPage;
}
@Override
public void exportUserRanking(UserPointsRankingDTO dto) {
GenericExportHandler<UserPointRankingVO, UserPointsRankingDTO> handler =
new GenericExportHandler<>(
UserPointRankingVO.class,
ExportExcelEnum.BANK_USER_RANKING,
asyncTaskExecutor,
log,
filter -> {
filter.setPageNo(1);
filter.setPageSize(-1);
List<UserPointRankingVO> records = userRanking(filter).getRecords();
return GenericExportHandler.handleData(records, UserPointRankingVO.class);
}
);
handler.exportAsync(dto);
}
@Override
public boolean testUpdateUserPoints(UpdUserPointsDTO dto) {
LoginUser loginUser = GlobalUtils.getLoginUser();
List<String> sysUserIds = iSysBaseAPI.findSysUserIds(new SysUser());
List<LoginUser> loginUsers = iSysBaseAPI.listUserByIdsNew(sysUserIds);
loginUsers.forEach(user -> {
try {
updateUserPoints(dto, user);
} catch (Exception e) {
log.error("用户:{}({})更新积分异常,入参:{}", loginUser.getRealname(), loginUser.getUsername(), dto, e);
}
});
return true;
}
/**
* 更新用户积分
*
* @param dto
* @return
*/
@Override
public boolean updateUserPoints(UpdUserPointsDTO dto) {
LoginUser loginUser = GlobalUtils.getLoginUser();
public boolean updateUserPoints(UpdUserPointsDTO dto, LoginUser loginUser) {
log.info("------用户:{}({})开始更新积分,入参:{}------", loginUser.getRealname(), loginUser.getUsername(), dto);
PointsSourceEnum sourceEnum = PointsSourceEnum.getBySource(dto.getSourceType());
if (sourceEnum == null) {
@@ -203,7 +411,7 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
//违规扣除
userId = dto.getUserId();
} else {
userId = GlobalUtils.getLoginUser().getId();
userId = loginUser.getId();
}
UserPoints userPoints = baseMapper.selectOne(new LambdaQueryWrapper<UserPoints>()
.eq(UserPoints::getUserId, userId)
@@ -253,7 +461,7 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
List<UserPointsDetails> details = userPointsDetailsMapper.selectList(new LambdaQueryWrapper<UserPointsDetails>()
.eq(UserPointsDetails::getUserId, userId)
.eq(UserPointsDetails::getChangeType, HealthBankConstants.CHANGE_TYPE_ADD)
.apply("DATE_FORMAT(create_time, '%Y-%m-%d') = '" + DateUtil.today() + "'")
.apply("DATE_FORMAT(create_time, '%Y-%m-%d') = {0}", DateUtil.today())
);
double sum = details.stream().map(UserPointsDetails::getPoints).mapToDouble(BigDecimal::doubleValue).sum();
userPoints.setLatestAddDaySum(new BigDecimal(sum).add(pointsRule.getPoints()));
@@ -365,6 +573,11 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
}
}
/**
* app我的积分
*
* @return 积分信息
*/
@Override
public UserPointsInfoVO myPoints() {
String userId = GlobalUtils.getLoginUser().getId();
@@ -380,18 +593,36 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
return vo;
}
/**
* app积分任务
*
* @return 列表
*/
@Override
public List<UserPointsTaskVO> pointsTaskList() {
String userId = GlobalUtils.getLoginUser().getId();
return pointsRuleMapper.pointsTaskList(userId);
}
/**
* app积分打卡
*
* @param dto 参数
* @return 结果
*/
@Override
public boolean pointCheckIn(UpdUserPointsDTO dto) {
dto.setSourceType(PointsSourceEnum.TYPE_1_SURVEY.getSource());
return updateUserPoints(dto);
LoginUser loginUser = GlobalUtils.getLoginUser();
return updateUserPoints(dto, loginUser);
}
/**
* app积分明细
*
* @param dto 参数
* @return 结果
*/
@Override
public IPage<UserPointRecordVO> pointRecord(UserPointsPageDTO dto) {
if (ObjectUtil.isNull(dto.getChangeType())) {
@@ -406,6 +637,12 @@ public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoi
return userPointsDetailsMapper.selectJoinPage(page, UserPointRecordVO.class, wrapper);
}
/**
* app积分榜单
*
* @param dto 参数
* @return 结果
*/
@Override
public IPage<UserPointRankingVO> pointRanking(UserPointsRankingDTO dto) {
String orgCode = GlobalUtils.getLoginUser().getOrgCode();