【积分银行】积分
This commit is contained in:
+38
-5
@@ -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() {
|
||||
|
||||
+3
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
+47
@@ -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
|
||||
|
||||
+90
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -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);
|
||||
}
|
||||
}
|
||||
+12
-2
@@ -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();
|
||||
|
||||
+252
-15
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user