diff --git a/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/constant/enums/DateRangeTypeEnum.java b/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/constant/enums/DateRangeTypeEnum.java new file mode 100644 index 000000000..a26292552 --- /dev/null +++ b/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/constant/enums/DateRangeTypeEnum.java @@ -0,0 +1,33 @@ +package com.bsd.pjcloud.common.core.constant.enums; + +import cn.hutool.core.util.ObjectUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 日期范围类型 + */ +@AllArgsConstructor +@Getter +public enum DateRangeTypeEnum { + + YESTERDAY("0", "昨天"), + TODAY("1", "今日"), + THIS_WEEK("2", "本周"), + THIS_MONTH("3", "本月"), + CURRENT_SEASON("4", "本季度"), + HALF_YEAR("5", "近半年"), + THIS_YEAR("6", "本年"), + ; + + private final String type; + private final String description; + + public static DateRangeTypeEnum valueOfByType(String type) { + if (ObjectUtil.isEmpty(type)) return null; + return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get(); + } + +} diff --git a/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/util/DateRangeTool.java b/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/util/DateRangeTool.java new file mode 100644 index 000000000..8ff7bdcf5 --- /dev/null +++ b/pjcloud-common/pjcloud-common-core/src/main/java/com/bsd/pjcloud/common/core/util/DateRangeTool.java @@ -0,0 +1,59 @@ +package com.bsd.pjcloud.common.core.util; + +import com.bsd.pjcloud.common.core.constant.enums.DateRangeTypeEnum; +import lombok.experimental.UtilityClass; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.TemporalAdjusters; + +/** + * 时间范围工具类 + */ +@UtilityClass +public class DateRangeTool { + + static public LocalDate[] transitionDateTypeToDateList(DateRangeTypeEnum dateType) { + LocalDateTime[] localDateTimes = transitionDateTypeToDateTimeList(dateType); + return new LocalDate[]{localDateTimes[0].toLocalDate(), localDateTimes[1].toLocalDate(),}; + } + + static public LocalDateTime[] transitionDateTypeToDateTimeList(DateRangeTypeEnum dateType) { + LocalDateTime now = LocalDateTime.now(); + switch (dateType) { + case YESTERDAY: + return new LocalDateTime[]{ + LocalDateTime.now().minusDays(1).withHour(0).withMinute(0).withSecond(0), + LocalDateTime.now().minusDays(1).withHour(23).withMinute(59).withSecond(59) + }; + case TODAY: + return new LocalDateTime[]{ + LocalDateTime.now().withHour(0).withMinute(0).withSecond(0), + LocalDateTime.now().withHour(23).withMinute(59).withSecond(59) + }; + case THIS_WEEK: + LocalDateTime weekStart = now.minusDays(7).withHour(0).withMinute(0).withSecond(0); + LocalDateTime weekEnd = now.withHour(23).withMinute(59).withSecond(59); + return new LocalDateTime[]{weekStart, weekEnd}; + case THIS_MONTH: + LocalDateTime monthStart = now.with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0); + LocalDateTime monthEnd = now.with(TemporalAdjusters.lastDayOfMonth()).withHour(23).withMinute(59).withSecond(59); + return new LocalDateTime[]{monthStart, monthEnd}; + case CURRENT_SEASON: + LocalDateTime quarterStart = now.with(now.getMonth().firstMonthOfQuarter()).with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0); + LocalDateTime quarterEnd = quarterStart.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth()).withHour(23).withMinute(59).withSecond(59); + return new LocalDateTime[]{quarterStart, quarterEnd}; + case HALF_YEAR: + LocalDateTime halfYearStart = now.with(now.getMonth().firstMonthOfQuarter()).with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0); + LocalDateTime halfYearEnd = halfYearStart.plusMonths(6).with(TemporalAdjusters.lastDayOfMonth()).withHour(23).withMinute(59).withSecond(59); + return new LocalDateTime[]{halfYearStart, halfYearEnd}; + case THIS_YEAR: + LocalDateTime yearStart = now.with(TemporalAdjusters.firstDayOfYear()).withHour(0).withMinute(0).withSecond(0); + LocalDateTime yearEnd = now.with(TemporalAdjusters.lastDayOfYear()).withHour(23).withMinute(59).withSecond(59); + return new LocalDateTime[]{yearStart, yearEnd}; + default: + return null; + } + } + +} diff --git a/pjcloud-common/pjcloud-common-data/src/main/java/com/bsd/pjcloud/common/data/datascope/DataScopeInnerInterceptor.java b/pjcloud-common/pjcloud-common-data/src/main/java/com/bsd/pjcloud/common/data/datascope/DataScopeInnerInterceptor.java index d77709fbe..293b6a47d 100644 --- a/pjcloud-common/pjcloud-common-data/src/main/java/com/bsd/pjcloud/common/data/datascope/DataScopeInnerInterceptor.java +++ b/pjcloud-common/pjcloud-common-data/src/main/java/com/bsd/pjcloud/common/data/datascope/DataScopeInnerInterceptor.java @@ -65,7 +65,7 @@ public class DataScopeInnerInterceptor implements DataScopeInterceptor { dataScope.getFunc().getType(), originalSql, dataScope.getScopeUserName(), dataScope.getUsername(), dataScope.getScopeDeptName(), join); } // 3. 如果为本人 - else if (StrUtil.isNotBlank(dataScope.getUsername())) { + else if (StrUtil.isNotBlank(dataScope.getUsername()) && ObjectUtil.isNotEmpty(dataScope.getScopeUserName())) { originalSql = String.format("SELECT %s FROM (%s) temp_data_scope WHERE temp_data_scope.%s = '%s'", dataScope.getFunc().getType(), originalSql, dataScope.getScopeUserName(), dataScope.getUsername()); } diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/panel/PanelCanteenDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/panel/PanelCanteenDto.java new file mode 100644 index 000000000..1d9127d37 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/panel/PanelCanteenDto.java @@ -0,0 +1,25 @@ +package com.bsd.pjcloud.hard.api.dto.panel; + +import com.bsd.pjcloud.common.core.constant.enums.DateRangeTypeEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PanelCanteenDto { + + private DateRangeTypeEnum dateRangeType = DateRangeTypeEnum.YESTERDAY; + + private LocalDateTime[] totalTimeList; + + private String hourType; + + private Long limit; + +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/hard/PanelCanteenVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/hard/PanelCanteenVo.java new file mode 100644 index 000000000..34fae2692 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/hard/PanelCanteenVo.java @@ -0,0 +1,103 @@ +package com.bsd.pjcloud.hard.api.vo.hard; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PanelCanteenVo { + + /** + * 商品名 + */ + private String productName; + + /** + * 用餐时间段(早中晚) + */ + private String hourType; + + /** + * 商品名 + */ + private String productStr; + + /** + * 用餐人数 + */ + private Long personCount; + + /** + * 购买次数 + */ + private Long buyCount; + + /** + * 购买商品数量 + */ + private Long buyProductCount; + + /** + * 购买总金额(分) + */ + private Long totalPrice; + + /** + * 时间 + */ + private LocalDate time; + + /** + * 时间字符串 + */ + private LocalDate timeStr; + + /** + * 周几 + */ + private String weekStr; + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class HourTypeItemVo { + + private String type; + + private String typeStr; + + private List list; + + } + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class HourTypeVo { + + /** + * 早 + */ + private HourTypeItemVo morning; + + /** + * 中 + */ + private HourTypeItemVo noon; + + /** + * 晚 + */ + private HourTypeItemVo evening; + } + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelCanteenController.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelCanteenController.java new file mode 100644 index 000000000..ddee43840 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelCanteenController.java @@ -0,0 +1,77 @@ +package com.bsd.pjcloud.hard.controller.panel; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.bsd.pjcloud.common.core.util.DateRangeTool; +import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto; +import com.bsd.pjcloud.hard.api.dto.panel.PanelCanteenDto; +import com.bsd.pjcloud.hard.api.vo.hard.PanelCanteenVo; +import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo; +import com.bsd.pjcloud.hard.service.HardOrderService; +import com.bsd.pjcloud.hard.service.PanelCanteenService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/panel-canteen") +@Tag(description = "panel-canteen", name = "食堂统计") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +public class PanelCanteenController { + + private final PanelCanteenService panelCanteenService; + private final HardOrderService hardwareOrderService; + + @PostMapping(value = "/group/by-time-and-hour-type") + @Operation(summary = "用餐数据统计(根据时间段和日期分类统计)") + public R groupByTimeAndHourType(PanelCanteenDto dto) { + if (ObjectUtil.isNotEmpty(dto.getDateRangeType()) && ObjectUtil.isNotEmpty(dto.getTotalTimeList())) { + dto.setTotalTimeList(DateRangeTool.transitionDateTypeToDateTimeList(dto.getDateRangeType())); + } + return R.ok(panelCanteenService.groupByTimeAndHourType(dto)); + } + + @PostMapping(value = "/group/classify/by-time-and-hour-type") + @Operation(summary = "菜品分类统计(根据时间段和日期分类统计)") + public R classifyGroupByTimeAndHourType(PanelCanteenDto dto) { + if (ObjectUtil.isNotEmpty(dto.getDateRangeType()) && ObjectUtil.isNotEmpty(dto.getTotalTimeList())) { + dto.setTotalTimeList(DateRangeTool.transitionDateTypeToDateTimeList(dto.getDateRangeType())); + } + return R.ok(panelCanteenService.classifyGroupByTimeAndHourType(dto)); + } + + @PostMapping(value = "/group/by-time-and-custom-hour") + @Operation(summary = "用餐数据统计(根据自定义时间段和日期分类统计)") + public R> groupByTimeAndCustomHour(PanelCanteenDto dto) { + if (ObjectUtil.isNotEmpty(dto.getDateRangeType()) && ObjectUtil.isNotEmpty(dto.getTotalTimeList())) { + dto.setTotalTimeList(DateRangeTool.transitionDateTypeToDateTimeList(dto.getDateRangeType())); + } + return R.ok(panelCanteenService.groupByTimeAndCustomHour(dto)); + } + + @PostMapping(value = "/top") + @Operation(summary = "排行榜") + public R> top(PanelCanteenDto dto) { + if (ObjectUtil.isNotEmpty(dto.getDateRangeType()) && ObjectUtil.isNotEmpty(dto.getTotalTimeList())) { + dto.setTotalTimeList(DateRangeTool.transitionDateTypeToDateTimeList(dto.getDateRangeType())); + } + dto.setLimit(5L); + return R.ok(panelCanteenService.top(dto)); + } + + @PostMapping(value = "/new-page") + @Operation(summary = "最新的吃饭数据") + public R> newPage(@ParameterObject Page page, HardOrderDto dto) { + return R.ok(hardwareOrderService.scopePageList(page, dto, null)); + } +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelMchController.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelMchController.java new file mode 100644 index 000000000..4dab39fdd --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelMchController.java @@ -0,0 +1,17 @@ +package com.bsd.pjcloud.hard.controller.panel; + +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/panel-mch") +@Tag(description = "panel-mch", name = "商户统计") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +public class PanelMchController { + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelSupermarketController.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelSupermarketController.java new file mode 100644 index 000000000..9ae6238cd --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/panel/PanelSupermarketController.java @@ -0,0 +1,17 @@ +package com.bsd.pjcloud.hard.controller.panel; + +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/panel-mch") +@Tag(description = "panel-mch", name = "超市统计") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +public class PanelSupermarketController { + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/mapper/order/HardOrderMapper.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/mapper/order/HardOrderMapper.java index 30dc645af..b58ff08e1 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/mapper/order/HardOrderMapper.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/mapper/order/HardOrderMapper.java @@ -10,8 +10,10 @@ import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper; import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum; import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto; import com.bsd.pjcloud.hard.api.dto.order.HardOrderSumAndCountDto; +import com.bsd.pjcloud.hard.api.dto.panel.PanelCanteenDto; import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity; import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity; +import com.bsd.pjcloud.hard.api.vo.hard.PanelCanteenVo; import com.bsd.pjcloud.hard.api.vo.order.*; import com.github.yulichang.wrapper.MPJLambdaWrapper; @@ -133,4 +135,14 @@ public interface HardOrderMapper extends PjcloudBaseMapper { List sumAndCountTotalByHourType(@Param("dto") HardOrderSumAndCountDto dto); HardZyCardSyncVo totalYearMonthDay(@Param("dto") HardOrderDto hardOrderDto); + + /** + * 用餐数据统计(根据时间段和日期分类统计) + */ + List groupByTimeAndHourType(@Param("dto") PanelCanteenDto dto); + + /** + * 用餐数据统计(根据时间段和日期分类统计) + */ + List top(@Param("dto") PanelCanteenDto dto); } \ No newline at end of file diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/redis/RedisKeyExpirationListener.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/redis/RedisKeyExpirationListener.java new file mode 100644 index 000000000..06d3066f6 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/redis/RedisKeyExpirationListener.java @@ -0,0 +1,68 @@ +package com.bsd.pjcloud.hard.redis; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.bsd.pjcloud.common.core.constant.CacheConstants; +import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum; +import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum; +import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum; +import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity; +import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper; +import jakarta.annotation.Resource; +import lombok.extern.log4j.Log4j2; +import org.springframework.data.redis.connection.Message; +import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; + +/** + * 监听Redis的Key过期事件 + */ +@Component +@Log4j2 +public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { + + @Resource + private HardOrderMapper hardOrderMapper; + + public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { + super(listenerContainer); + } + + @Override + public void onMessage(Message message, byte[] pattern) { + String expiredKey = message.toString(); + String expiredPattern = new String(pattern, StandardCharsets.UTF_8); + + // 过期订单(扫一扫支付) + if (expiredKey.startsWith(CacheConstants.HARDER_ORDER_NON_PAY)) { + log.info("hard模块RedisKey过期,pattern|{}|key|{}|", expiredPattern, expiredKey); + disposeExpiredQrCodeScanOrder(expiredKey); + } + } + + // 删除过期的扫一扫订单 + public void disposeExpiredQrCodeScanOrder(String expiredValue) { + if (ObjectUtil.isEmpty(expiredValue)) return; + + String orderId = expiredValue.substring(CacheConstants.HARDER_ORDER_NON_PAY.length() + 1); + + HardOrderEntity order = hardOrderMapper.selectOne(new LambdaQueryWrapper() + .eq(HardOrderEntity::getId, orderId) + .eq(HardOrderEntity::getPayType, HardPayTypeEnum.WALLET_QR_CODE_SCAN.getType()) + .eq(HardOrderEntity::getOrderStatus, HardOrderStatusEnum.CREATE.getType()) + ); + if (ObjectUtil.isEmpty(order)) { + log.info("删除过期的扫一扫订单,订单不存在orderId|{}|", orderId); + return; + } + if (ObjectUtil.isEmpty(order.getWalletId()) && ObjectUtil.equals(order.getUserId(), -1L)) { + // 删除订单 + hardOrderMapper.deleteById(order.getId()); + log.info("删除过期的扫一扫订单,orderId|{}|", expiredValue); + } + } + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelCanteenService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelCanteenService.java new file mode 100644 index 000000000..b0a163919 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelCanteenService.java @@ -0,0 +1,29 @@ +package com.bsd.pjcloud.hard.service; + +import com.bsd.pjcloud.hard.api.dto.panel.PanelCanteenDto; +import com.bsd.pjcloud.hard.api.vo.hard.PanelCanteenVo; + +import java.util.List; + +public interface PanelCanteenService { + + /** + * 用餐数据统计(根据时间段和日期分类统计) + */ + PanelCanteenVo.HourTypeVo groupByTimeAndHourType(PanelCanteenDto dto); + + /** + * 菜品分类统计(根据时间段和日期分类统计) + */ + PanelCanteenVo.HourTypeVo classifyGroupByTimeAndHourType(PanelCanteenDto dto); + + /** + * 用餐数据统计(根据自定义时间段和日期分类统计) + */ + List groupByTimeAndCustomHour(PanelCanteenDto dto); + + /** + * 排行榜 + */ + List top(PanelCanteenDto dto); +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelMchService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelMchService.java new file mode 100644 index 000000000..64e1ca0f7 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelMchService.java @@ -0,0 +1,4 @@ +package com.bsd.pjcloud.hard.service; + +public interface PanelMchService { +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelSupermarketService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelSupermarketService.java new file mode 100644 index 000000000..588b73fec --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/PanelSupermarketService.java @@ -0,0 +1,5 @@ +package com.bsd.pjcloud.hard.service; + +public interface PanelSupermarketService { + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java index dfce50910..68a41257e 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java @@ -1,5 +1,7 @@ package com.bsd.pjcloud.hard.service.impl.order; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.json.JSONUtil; @@ -1376,9 +1378,31 @@ public class HardOrderServiceImpl extends ServiceImpl userIds = list.stream().map(HardOrderVo::getUserId).filter(ObjectUtil::isNotEmpty).distinct().toList(); if (ObjectUtil.isNotEmpty(userIds)) { - List userList = userService.getUserDeptByIds(new ArrayList<>(userIds)).getData(); + List userList = userService.getUserDeptByIds(userIds).getData(); if (ObjectUtil.isNotEmpty(userList)) { - DataUtil.convertUserDeptList(list, CollectionUtils.convertMap(userList, UserVO::getUserId)); + Map map = CollectionUtils.convertMap(userList, UserVO::getUserId); + for (HardOrderVo item : list) { + UserVO userVO = map.get(item.getUserId()); + if (ObjectUtil.isEmpty(userVO)) continue; + item.setUsername(userVO.getName()); + item.setUserMobile(userVO.getPhone()); + item.setUserAvatar(userVO.getAvatar()); + } + } + } + }); + // 当前部门 + CompletableFuture currentDeptFuture = CompletableFuture.runAsync(() -> { + RequestContextHolder.setRequestAttributes(requestAttributes); + List deptIds = list.stream().map(HardOrderVo::getUserDeptId).filter(ObjectUtil::isNotEmpty).distinct().toList(); + if (ObjectUtil.isNotEmpty(deptIds)) { + Map deptList = deptService.getDeptByDeptIds(deptIds).getData(); + if (ObjectUtil.isNotEmpty(deptList)) { + for (HardOrderVo item : list) { + SysDept dept = deptList.get(item.getUserDeptId()); + if (ObjectUtil.isEmpty(dept)) continue; + item.setUserDeptName(dept.getName()); + } } } }); @@ -1428,6 +1452,6 @@ public class HardOrderServiceImpl extends ServiceImpl dateList = generatePanelCanteenList(dto.getTotalTimeList()); + PanelCanteenVo.HourTypeVo result = new PanelCanteenVo.HourTypeVo(); + + List hourTypeList = List.of(HardHourTypeEnum.MORNING, HardHourTypeEnum.NOONING, HardHourTypeEnum.NIGHT); + hourTypeList.stream().map(hourType -> CompletableFuture.runAsync(() -> { + RequestContextHolder.setRequestAttributes(requestAttributes); + PanelCanteenDto queryDto = BeanUtil.toBean(dto, PanelCanteenDto.class); + queryDto.setHourType(hourType.getType()); + List sqlList = hardOrderMapper.groupByTimeAndHourType(queryDto); + // 处理查询出来的数据 + List resultList = BeanUtil.copyToList(dateList, PanelCanteenVo.class); + for (PanelCanteenVo v : resultList) { + sqlList.stream().filter(item -> ObjectUtil.equals(item.getTime(), v.getTime())).forEach(target -> { + v.setHourType(target.getHourType()); + v.setPersonCount(target.getPersonCount()); + v.setBuyCount(target.getBuyCount()); + v.setBuyProductCount(target.getBuyProductCount()); + v.setTotalPrice(target.getTotalPrice()); + }); + } + // 组装数据 + PanelCanteenVo.HourTypeItemVo vo = PanelCanteenVo.HourTypeItemVo.builder().list(resultList).type(hourType.getType()).typeStr(hourType.getDescription()).build(); + switch (hourType) { + case MORNING: + result.setMorning(vo); + break; + case NOONING: + result.setNoon(vo); + break; + case NIGHT: + result.setEvening(vo); + break; + } + })).toList().forEach(CompletableFuture::join); + return result; + } + + /** + * 菜品分类统计(根据时间段和日期分类统计) + */ + @Override + public PanelCanteenVo.HourTypeVo classifyGroupByTimeAndHourType(PanelCanteenDto dto) { + List sqlList = hardOrderMapper.groupByTimeAndHourType(dto); + return null; + } + + /** + * 用餐数据统计(根据时间段和日期分类统计) + */ + @Override + public List groupByTimeAndCustomHour(PanelCanteenDto dto) { + return null; + } + + /** + * 排行榜 + */ + @Override + public List top(PanelCanteenDto dto) { + return hardOrderMapper.top(dto); + } + + private List generatePanelCanteenList(LocalDateTime[] totalTimeList) { + List dateList = new LinkedList<>(); + LocalDate startTime = totalTimeList[0].toLocalDate(); + LocalDate endTime = totalTimeList[1].toLocalDate(); + LocalDate currentDate = startTime; + while (!currentDate.isAfter(endTime)) { + PanelCanteenVo entity = new PanelCanteenVo(); + entity.setPersonCount(0L); + entity.setBuyCount(0L); + entity.setBuyProductCount(0L); + entity.setTime(currentDate); + entity.setWeekStr(LocalDateTimeUtil.dayOfWeek(currentDate).toChinese()); + dateList.add(entity); + currentDate = currentDate.plusDays(1); + } + return dateList; + } + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/panel/PanelMchServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/panel/PanelMchServiceImpl.java new file mode 100644 index 000000000..eb2d42bcb --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/panel/PanelMchServiceImpl.java @@ -0,0 +1,15 @@ +package com.bsd.pjcloud.hard.service.impl.panel; + +import com.bsd.pjcloud.hard.service.PanelMchService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +@Validated +@Slf4j +@RequiredArgsConstructor +@Service +public class PanelMchServiceImpl implements PanelMchService { + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/panel/PanelSupermarketServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/panel/PanelSupermarketServiceImpl.java new file mode 100644 index 000000000..943a3bde8 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/panel/PanelSupermarketServiceImpl.java @@ -0,0 +1,15 @@ +package com.bsd.pjcloud.hard.service.impl.panel; + +import com.bsd.pjcloud.hard.service.PanelSupermarketService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +@Validated +@Slf4j +@RequiredArgsConstructor +@Service +public class PanelSupermarketServiceImpl implements PanelSupermarketService { + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/mapper/order/HardOrderMapper.xml b/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/mapper/order/HardOrderMapper.xml index 2ce89e880..da11eef8b 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/mapper/order/HardOrderMapper.xml +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/resources/mapper/order/HardOrderMapper.xml @@ -549,4 +549,55 @@ + + + + + \ No newline at end of file diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserServiceImpl.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserServiceImpl.java index 81b9dfce8..2838ebdc3 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserServiceImpl.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserServiceImpl.java @@ -258,7 +258,7 @@ public class SysUserServiceImpl extends ServiceImpl impl @Override public IPage getUsersWithRolePage(Page page, UserDTO userDTO) { DataScope dataScope = DataScope.of(); -// dataScope.setScopeUserName(null); + dataScope.setScopeUserName(null); IPage list = baseMapper.getUserVosPage(page, userDTO, dataScope); if (ObjectUtil.isNotEmpty(list.getRecords())) { List userIds = list.getRecords().stream().map(UserVO::getUserId).distinct().toList(); diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/rule/WalletRuleJoinEntity.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/rule/WalletRuleJoinEntity.java index 672287860..0c907f52b 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/rule/WalletRuleJoinEntity.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/rule/WalletRuleJoinEntity.java @@ -57,6 +57,12 @@ public class WalletRuleJoinEntity extends Model { @Schema(description = "是否启用") private String status; + /** + * 是否保留100元(用户跨单位支付) + */ + @Schema(description = "是否保留100元(用户跨单位支付)") + private String isReservePrice; + /** * 创建人 */ diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/rule/WalletRuleJoinUserConfigVo.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/rule/WalletRuleJoinUserConfigVo.java index cecfe5aed..ae172ad45 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/rule/WalletRuleJoinUserConfigVo.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/rule/WalletRuleJoinUserConfigVo.java @@ -67,4 +67,9 @@ public class WalletRuleJoinUserConfigVo { */ private Integer balanceMultiple; + /** + * 是否保留100元用于钱包支付 + */ + private String isReservePrice; + } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java index 15f46f01a..c25ae7d10 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java @@ -55,7 +55,7 @@ public class WalletRechargeApplyController { @PostMapping("/save-topup") @Operation(summary = "新增充值") - @Idempotent(expireTime = 3, info = "正在充值中,请勿重复操作") + @Idempotent(expireTime = 3, key = "'/wallet-recharge-apply/save-topup' + #dto.getInvoiceId()", info = "正在充值中,请勿重复操作") public R comparePageJoin(@RequestBody WalletRechargeSaveTopupDto dto) { walletRechargeApplyService.saveTopup(dto); return R.ok(); diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeInvoiceController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeInvoiceController.java index 8272a83e5..b06501219 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeInvoiceController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeInvoiceController.java @@ -12,7 +12,9 @@ import com.bsd.pjcloud.common.log.annotation.SysLog; import com.bsd.pjcloud.common.security.annotation.Inner; import com.bsd.pjcloud.common.security.service.PjcloudUser; import com.bsd.pjcloud.common.security.util.SecurityUtils; +import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum; import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto; +import com.bsd.pjcloud.wallet.api.constant.WalletInvoiceStatusCheckEnum; import com.bsd.pjcloud.wallet.api.dto.WalletManageBalanceDto; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeBindInvoiceDto; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeInvoiceApplyDto; @@ -97,6 +99,7 @@ public class WalletRechargeInvoiceController { @GetMapping("/select") public R select(@ParameterObject Page page, @ParameterObject WalletRechargeBindInvoiceDto dto) { DataScope dataScope = null; + dto.setProcessStatus(TaskCheckStatusEnum.RESULT.getCode()); return R.ok(walletRechargeInvoiceService.scopePageList(page, dto, dataScope)); } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeApplyServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeApplyServiceImpl.java index 638fdf59a..f0c4ba4d6 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeApplyServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeApplyServiceImpl.java @@ -117,7 +117,9 @@ public class WalletRechargeApplyServiceImpl extends ServiceImpl未配置未打开"); } configVo.setBalanceMultiple(walletRuleJoin.getBalanceMultiple()); + configVo.setIsReservePrice(walletRuleJoin.getIsReservePrice()); // 计算最大可以转过去的金额 Long maxTransferBalance = BigDecimal.valueOf(sourceWallet.getTotalRecharge()).multiply(BigDecimal.valueOf(walletRuleJoin.getBalanceMultiple())).divide(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).longValue(); configVo.setMaxTransferBalance(maxTransferBalance); diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/rule/WalletRuleTransactionServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/rule/WalletRuleTransactionServiceImpl.java index 4f11eeea3..98722d373 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/rule/WalletRuleTransactionServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/rule/WalletRuleTransactionServiceImpl.java @@ -130,7 +130,10 @@ public class WalletRuleTransactionServiceImpl extends ServiceImpl a.del_flag = 0 + + and a.target_dept_id = #{dto.targetDeptId} + + + and a.status = #{dto.status} + and a.source_wallet_type_id = #{dto.sourceWalletTypeId}