diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/enums/StatisticsUnit.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/enums/StatisticsUnit.java new file mode 100644 index 000000000..fdcd50645 --- /dev/null +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/enums/StatisticsUnit.java @@ -0,0 +1,34 @@ +package com.cf.imes.framework.common.enums; + +/** + * 统计维度单位 + * @author Gqr + * @since 2024/8/6 10:04 + */ +public enum StatisticsUnit { + //季度、月、周、日 + QUARTER(0), + MONTH(1), + WEEK(2), + DAY(3); + + StatisticsUnit(Integer value) { + this.value = value; + } + + private Integer value; + + public Integer getValue() { + return value; + } + + // from value + public static StatisticsUnit fromValue(Integer value) { + for (StatisticsUnit unit : StatisticsUnit.values()) { + if (unit.getValue().equals(value)) { + return unit; + } + } + return null; + } +} diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonStatisticsReqVO.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonStatisticsReqVO.java new file mode 100644 index 000000000..cb07cc30b --- /dev/null +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/pojo/CommonStatisticsReqVO.java @@ -0,0 +1,29 @@ +package com.cf.imes.framework.common.pojo; + +import com.cf.imes.framework.common.util.validation.statistics.StatisticsUnitInEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +/** + * 通用统计 ReqVO + * @author Gqr + * @since 2025/9/29 16:50 + */ +@Data +public class CommonStatisticsReqVO { + @Schema(description = "创建时间") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate[] createTime; + + /** + * 统计维度单位 + */ + @Schema(description = "统计维度单位", example = "0", allowableValues = {"0", "1", "2", "3"}, type = "integer") + @NotNull(message = "统计维度单位不能为空") + @StatisticsUnitInEnum + private Integer unit; +} diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/time/StatisticsChangeUtils.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/time/StatisticsChangeUtils.java index 044ffe248..30b9067ce 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/time/StatisticsChangeUtils.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/time/StatisticsChangeUtils.java @@ -1,7 +1,10 @@ package com.cf.imes.framework.common.util.time; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import com.cf.imes.framework.common.enums.OrderStatisticsUnit; +import com.cf.imes.framework.common.enums.StatisticsUnit; +import com.cf.imes.framework.common.pojo.CommonStatisticsReqVO; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -22,12 +25,15 @@ public class StatisticsChangeUtils { * 3、返回所有日期的集合 * @return */ - public static List getDateList(LocalDate[] createTime, Integer unit) { + public static List getDateList(CommonStatisticsReqVO reqVO) { // 计算时间跨度 - getTimeSpan(createTime, unit); + getTimeSpan(reqVO); + + // 重新计算开始时间和结束时间 + computeTimeSpan(reqVO); // 所有的日期集合 - return generateDateRange(createTime, unit); + return generateDateRange(reqVO); } /** @@ -35,13 +41,14 @@ public class StatisticsChangeUtils { * 计算起止时间:前端不传入时间就根据维度单位从当前日期计算 * */ - public static LocalDate[] getTimeSpan(LocalDate[] createTime, Integer unit) { + public static void getTimeSpan(CommonStatisticsReqVO reqVO) { + LocalDate[] createTime = reqVO.getCreateTime(); LocalDate startTime = null; LocalDate endTime; LocalDate now = LocalDate.now(); - if (ObjectUtil.isNull(createTime) || ObjectUtil.isNull(createTime[0]) || ObjectUtil.isNull(createTime[1])) { + if (ArrayUtil.isEmpty(createTime) || ObjectUtil.isNull(createTime[0]) || ObjectUtil.isNull(createTime[1])) { endTime = now; - switch (OrderStatisticsUnit.fromValue(unit)) { + switch (StatisticsUnit.fromValue(reqVO.getUnit())) { case QUARTER: // 从now往前的2年 startTime = now.minusYears(2); @@ -62,10 +69,45 @@ public class StatisticsChangeUtils { break; } // 声明一个LocalDateTime的数组,把startTime和endTime放进去 - createTime[0] = startTime; - createTime[1] = endTime; + reqVO.setCreateTime(new LocalDate[]{startTime, endTime}); } - return createTime; + } + + /** + * 根据传入信息重新计算时间范围 + * + * @param reqVO + */ + public static void computeTimeSpan(CommonStatisticsReqVO reqVO) { + Integer unit = reqVO.getUnit(); + // 计算后的开始和结束时间 + LocalDate startDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); + LocalDate endDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); + + if (startDate.isAfter(endDate)) { + startDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); + endDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); + } + LocalDate first = startDate; + LocalDate end = endDate; + switch (OrderStatisticsUnit.fromValue(unit)) { + case QUARTER -> { + first = firstDayOfQuarter(startDate); + end = lastDayOfQuarter(endDate); + } + case MONTH -> { + first = startDate.with(TemporalAdjusters.firstDayOfMonth()); + end = endDate.with(TemporalAdjusters.lastDayOfMonth()); + } + case WEEK -> { + first = startDate.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY)); + end = endDate.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY)); + } + default -> { + return; + } + } + reqVO.setCreateTime(new LocalDate[]{first, end}); } /** @@ -73,12 +115,13 @@ public class StatisticsChangeUtils { * * @return */ - public static List generateDateRange(LocalDate[] createTime, Integer unit) { + public static List generateDateRange(CommonStatisticsReqVO reqVO) { + Integer unit = reqVO.getUnit(); // 计算时间跨度 - getTimeSpan(createTime, unit); - // 计算后的开始和结束时间 - LocalDate startDate = ObjectUtil.clone(createTime[0]); - LocalDate endDate = ObjectUtil.clone(createTime[1]); + getTimeSpan(reqVO); +// 计算后的开始和结束时间 + LocalDate startDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); + LocalDate endDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); List dates = new ArrayList<>(); while (!startDate.isAfter(endDate)) { @@ -146,4 +189,30 @@ public class StatisticsChangeUtils { } return newDateStrBuffer.toString(); } + + /** + * 获取指定日期所在季度的开始日期 + * + * @param date + * @return + */ + private static LocalDate firstDayOfQuarter(LocalDate date) { + int month = date.getMonthValue(); + int quarter = (month - 1) / 3 + 1; + int startMonth = (quarter - 1) * 3 + 1; + return LocalDate.of(date.getYear(), startMonth, 1); + } + + /** + * 获取指定日期所在季度的结束日期 + * + * @param date + * @return + */ + private static LocalDate lastDayOfQuarter(LocalDate date) { + int month = date.getMonthValue(); + int quarter = (month - 1) / 3 + 1; + int endMonth = (quarter - 1) * 3 + 3; + return LocalDate.of(date.getYear(), endMonth, 1).with(TemporalAdjusters.lastDayOfMonth()); + } } diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnum.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnum.java new file mode 100644 index 000000000..48521e491 --- /dev/null +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnum.java @@ -0,0 +1,37 @@ +package com.cf.imes.framework.common.util.validation.statistics; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 统计维度单位入参校验注解 + * + * @author Gqr + * @since 2024/7/17 9:33 + */ +@Target({ + ElementType.METHOD, + ElementType.FIELD, + ElementType.ANNOTATION_TYPE, + ElementType.CONSTRUCTOR, + ElementType.PARAMETER, + ElementType.TYPE_USE +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint( + validatedBy = {StatisticsUnitInEnumValidator.class} +) +public @interface StatisticsUnitInEnum { + String message() default "统计维度单位[unit]错误,请检查"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnumValidator.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnumValidator.java new file mode 100644 index 000000000..def51bc1e --- /dev/null +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/validation/statistics/StatisticsUnitInEnumValidator.java @@ -0,0 +1,35 @@ +package com.cf.imes.framework.common.util.validation.statistics; + +import cn.hutool.core.util.ObjectUtil; +import com.cf.imes.framework.common.enums.StatisticsUnit; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +/** + * 统计维度单位入参校验器 + * + * @author Gqr + * @since 2024/7/17 9:33 + */ +public class StatisticsUnitInEnumValidator implements ConstraintValidator { + + @Override + public void initialize(StatisticsUnitInEnum constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Integer value, ConstraintValidatorContext context) { + if (ObjectUtil.isNull(value)) { + return true; + } + StatisticsUnit unit = StatisticsUnit.fromValue(value); + if (ObjectUtil.isNotNull(unit)) { + return true; + } else { + return false; + } + } + +} + diff --git a/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/config/ChenfengIDAutoConfiguration.java b/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/config/ChenfengIDAutoConfiguration.java index f641cbac0..8b2fb13a1 100644 --- a/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/config/ChenfengIDAutoConfiguration.java +++ b/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/config/ChenfengIDAutoConfiguration.java @@ -1,6 +1,7 @@ package com.cf.imes.framework.id.config; import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd; +import com.cf.imes.framework.id.core.util.SnowflakeSerialNoWorker3rd; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.context.annotation.Bean; @@ -16,4 +17,9 @@ public class ChenfengIDAutoConfiguration { public SnowflakeIdWorker3rd idWorker() { return new SnowflakeIdWorker3rd(); } + + @Bean + public SnowflakeSerialNoWorker3rd serialNoWorker3rd() { + return new SnowflakeSerialNoWorker3rd(); + } } \ No newline at end of file diff --git a/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SerialNoMinuteCounter.java b/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SerialNoMinuteCounter.java new file mode 100644 index 000000000..0c36945e1 --- /dev/null +++ b/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SerialNoMinuteCounter.java @@ -0,0 +1,25 @@ +package com.cf.imes.framework.id.core.util; + +import java.util.concurrent.atomic.AtomicLong; + +public class SerialNoMinuteCounter { + private static final long MASK = 0x7FFFFFFFFFFFFFFFL; + private final AtomicLong atom; + + public SerialNoMinuteCounter() { + atom = new AtomicLong(0); + } + + public final long incrementAndGet() { + return atom.incrementAndGet() & MASK; + } + + public long get() { + return atom.get() & MASK; + } + + public void set(long newValue) { + atom.set(newValue & MASK); + } + +} diff --git a/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SnowflakeIdWorker3rd.java b/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SnowflakeIdWorker3rd.java index 6971e37e4..cdd3fb530 100644 --- a/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SnowflakeIdWorker3rd.java +++ b/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SnowflakeIdWorker3rd.java @@ -4,9 +4,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.concurrent.atomic.AtomicReference; /** * @ClassName: SnowflakeIdWorker3rd @@ -39,10 +36,6 @@ public class SnowflakeIdWorker3rd { private final MinuteCounter counter = new MinuteCounter(); /** 预支时间标志 */ boolean isAdvance = false; - /** 时间格式 */ - private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyMMddHHmmss"); - /** 上次时间格式 */ - private final AtomicReference lastTimestampStr = new AtomicReference<>(""); // ==============================Constructors===================================== @@ -133,37 +126,4 @@ public class SnowflakeIdWorker3rd { // String timestamp = String.valueOf(System.currentTimeMillis() / 1000); return Integer.valueOf(timestamp); } - - /** - * 获取下一个流水号 - * - * @return SerialNo - */ - public String nextSerialNo() { - String now = LocalDateTime.now().format(FORMATTER); - - // 跨秒重置序列号 - String last = lastTimestampStr.get(); - if (!now.equals(last)) { - // 仅在跨秒时重置序列号 - if (lastTimestampStr.compareAndSet(last, now)) { - counter.set(0); - } - } - - // 原子递增序列号 - int seq = counter.incrementAndGet(); - - // 序列号100000(5位)以内 - if (seq > 9999) { - if (counter.compareAndSet(seq, 1)) { - seq = 1; - } else { - seq = counter.incrementAndGet(); - } - } - - // 拼接时间 + 序列号 - return String.format("%s%05d", now, seq); - } } diff --git a/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SnowflakeSerialNoWorker3rd.java b/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SnowflakeSerialNoWorker3rd.java new file mode 100644 index 000000000..7ed25adb4 --- /dev/null +++ b/cf-framework/cf-spring-boot-starter-biz-id/src/main/java/com/cf/imes/framework/id/core/util/SnowflakeSerialNoWorker3rd.java @@ -0,0 +1,124 @@ +package com.cf.imes.framework.id.core.util; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * @ClassName: SnowflakeSerialNoWorker3rd + * @Description:snowflake算法改进 + * @author: yonnie + * @date: 2025/09/29 16:00 + * @version V1.1 + * + * 将产生的Id类型更改为Integer 64bit
+ * 把时间戳的单位改为秒,使用48bit的时间戳 + * 16bit作为自增值即 2^16 = 65535 + */ +@Slf4j +@Component +public class SnowflakeSerialNoWorker3rd { + /** 初始时间 (2025-01-01 00:00:00: 1735660800) */ + // private final long twepoch = 28927680;// 1735660800000L/1000/60; + private final long twepoch = 1735660800; + /** 序列在id中占位数 */ + private final long sequenceBits = 16L; + /** 时间截向左移16bit */ + private final long timestampLeftShift = sequenceBits; + /** 生成序列的MASK (0xFFFF) */ + private final long sequenceMask = -1 ^ (-1 << sequenceBits); + /** 分钟内序 (0~65535) */ + private long sequence = 0; + private long laterSequence = 0; + /** 上次生成ID的时间戳 */ + private long lastTimestamp = -1; + private final SerialNoMinuteCounter counter = new SerialNoMinuteCounter(); + /** 预支时间标志 */ + boolean isAdvance = false; + /** 时间格式 */ + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyMMddHHmmss"); + + // ==============================Constructors===================================== + + public SnowflakeSerialNoWorker3rd() { + // constructor + } + + // ==============================Test============================================= + + /** 测试 */ + public static void main(String[] args) { + SnowflakeSerialNoWorker3rd idWorker = new SnowflakeSerialNoWorker3rd(); + for (long i = 0; i < 1000; i++) { + System.out.println(i + ": " + idWorker.nextSerialNo()); + } + } + + // ==============================Methods========================================== + + /** + * 获得下一个ID (该方法是线程安全) + * + * @return SnowflakeId + */ + public synchronized long nextId() { + long timestamp = timeGen(); + // System.out.println("timeGen: " + Long.toString(timestamp)); + // 如果当前时间小于上一次ID生成的时间戳,说明系统时钟修改过 + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format( + "Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + if (timestamp > counter.get()) { + counter.set(timestamp); + isAdvance = false; + } + + // 如果是同时间生成的,则进行秒内序列 + if (lastTimestamp == timestamp || isAdvance) { + if (!isAdvance) { + sequence = (sequence + 1) & sequenceMask; + } + + // 秒内自增列溢出 + if (sequence == 0) { + // 预支下一秒获得新的时间戳 + isAdvance = true; + long laterTimestamp = counter.get(); + if (laterSequence == 0) { + laterTimestamp = counter.incrementAndGet(); + } + long nextId = ((laterTimestamp - twepoch) << timestampLeftShift) | laterSequence; + laterSequence = (laterSequence + 1) & sequenceMask; + return nextId; + } + } else { // 时间戳改变,秒内序列置0 + sequence = 0; + laterSequence = 0; + } + // 上次生成ID的时间截 + lastTimestamp = timestamp; + // 移位并或运算拼成64位的ID + return ((timestamp - twepoch) << timestampLeftShift) | sequence; + } + + public String nextSerialNo() { + return LocalDateTime.now().format(FORMATTER) + String.valueOf(nextId()).substring(8); + } + + /** + * 返回以秒为单位的当前时间 + * + * @return 当前时间(秒) + */ + protected long timeGen() { + // String timestamp = String.valueOf(System.currentTimeMillis() / 1000 / 60); + // String timestamp = String.valueOf(System.currentTimeMillis() / 1000); + // return Long.valueOf(timestamp); + return System.currentTimeMillis() / 1000; + } + +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderSupStatisticsController.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderSupStatisticsController.java index 55ba92f11..c56df4c4d 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderSupStatisticsController.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderSupStatisticsController.java @@ -1,10 +1,7 @@ package com.cf.imes.module.executor.controller.admin.order; import com.cf.imes.framework.common.pojo.CommonResult; -import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderStatisticsReqVO; import com.cf.imes.module.executor.service.order.OrderSupStatisticsService; -import com.cf.imes.module.system.api.organ.OrganApi; -import com.cf.imes.module.system.api.organ.dto.OrgStatisticsReqDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; @@ -15,8 +12,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import jakarta.annotation.Resource; -import jakarta.validation.Valid; -import java.util.List; import java.util.Map; import static com.cf.imes.framework.common.pojo.CommonResult.success; @@ -31,9 +26,6 @@ public class OrderSupStatisticsController { @Resource private OrderSupStatisticsService orderSupStatisticsService; - @Resource - private OrganApi organApi; - @GetMapping("/total/order") @Operation(summary = "生产单总数") @PreAuthorize("@ss.hasPermission('homePage:analysis:org-statistic')") @@ -46,24 +38,4 @@ public class OrderSupStatisticsController { public CommonResult> getPlateAreaTotal() { return success(orderSupStatisticsService.plateAreaTotal()); } - - @GetMapping("/separate/order") - @Operation(summary = "有效、无效生产单数量统计") - @PreAuthorize("@ss.hasPermission('homePage:analysis:order-count')") - public CommonResult> getOrderSeparate(@Valid OrderStatisticsReqVO reqVO) { - return success(orderSupStatisticsService.orderSeparate(reqVO)); - } - - @GetMapping("/separate/org") - @Operation(summary = "新增、注销组织数量统计") - @PreAuthorize("@ss.hasPermission('homePage:analysis:org-count')") - public CommonResult> getOrgSeparate(@Valid OrgStatisticsReqDTO reqVO) { - return organApi.getOrgSeparate(reqVO); - } - - @GetMapping("/warn/org") - @Operation(summary = "组织过期日期统计") - public CommonResult>> getWarnToOrg() { - return organApi.getWarnToOrg(); - } } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/vo/order/OrderStatisticsReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/vo/order/OrderStatisticsReqVO.java index da1e8bf5f..13e1dec02 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/vo/order/OrderStatisticsReqVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/vo/order/OrderStatisticsReqVO.java @@ -1,12 +1,8 @@ package com.cf.imes.module.executor.controller.admin.order.vo.order; -import com.cf.imes.module.executor.validation.order.OrderStatisticsUnitInEnum; +import com.cf.imes.framework.common.pojo.CommonStatisticsReqVO; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDate; /** * @author Gqr @@ -14,19 +10,7 @@ import java.time.LocalDate; */ @Schema(description = "管理后台 - 生产单统计 Request VO") @Data -public class OrderStatisticsReqVO { +public class OrderStatisticsReqVO extends CommonStatisticsReqVO { @Schema(description = "组织id") private Long organId; - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = "yyyy-MM-dd") - private LocalDate[] createTime; - - /** - * 统计维度单位 - */ - @Schema(description = "统计维度单位", example = "0", allowableValues = {"0", "1", "2", "3"}, type = "integer") - @NotNull(message = "统计维度单位不能为空") - @OrderStatisticsUnitInEnum - private Integer unit; } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderStatisticsServiceImpl.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderStatisticsServiceImpl.java index 46bec2495..3c8c5649f 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderStatisticsServiceImpl.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderStatisticsServiceImpl.java @@ -1,7 +1,6 @@ package com.cf.imes.module.executor.service.order; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.FieldValue; @@ -45,6 +44,8 @@ import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.stream.Collectors; +import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.generateDateRangeAxis; +import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.getDateList; import static com.cf.imes.module.executor.enums.EsIndexEnum.ORDER_OPTIMIZE_PLATE_MODEL; /** @@ -623,194 +624,6 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService { return dateStr; } - - - /** - * 获取日期区间格式下的所有日期字符串 - * 1、reqVO设置机构id - * 2、计算时间跨度设置到reqVO - * 3、返回所有日期的集合 - * @param reqVO - * @return - */ - private List getDateList(OrderStatisticsReqVO reqVO) { - // 计算时间跨度 - getTimeSpan(reqVO); - - // 重新计算开始时间喝结束时间 - countTimeSpan(reqVO); - - // 所有的日期集合 - return generateDateRange(reqVO); - } - - /** - * 获取统计的时间跨度 - * 计算起止时间:前端不传入时间就根据维度单位从当前日期计算 - * - * @param reqVO - */ - private void getTimeSpan(OrderStatisticsReqVO reqVO) { - LocalDate[] createTime = reqVO.getCreateTime(); - LocalDate startTime = null; - LocalDate endTime; - LocalDate now = LocalDate.now(); - if (ArrayUtil.isEmpty(createTime) || ObjectUtil.isNull(createTime[0]) || ObjectUtil.isNull(createTime[1])) { - endTime = now; - switch (OrderStatisticsUnit.fromValue(reqVO.getUnit())) { - case QUARTER: - // 从now往前的1年 - startTime = now.minusYears(1); - break; - case MONTH: - // 包含now往前的12个月 - startTime = now.minusMonths(11); - break; - case WEEK: - // 包含now往前的12周 - startTime = now.minusWeeks(11); - break; - case DAY: - // 包含now往前的15天 - startTime = now.minusDays(14); - break; - default: - break; - } - // 声明一个LocalDateTime的数组,把startTime和endTime放进去 - reqVO.setCreateTime(new LocalDate[]{startTime, endTime}); - } - } - - /** - * 根据传入信息重新计算时间范围 - * - * @param reqVO - */ - private void countTimeSpan(OrderStatisticsReqVO reqVO) { - Integer unit = reqVO.getUnit(); - // 计算时间跨度 - getTimeSpan(reqVO); - // 计算后的开始和结束时间 - LocalDate startDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); - LocalDate endDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); - - if (startDate.isAfter(endDate)) { - startDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); - endDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); - } - LocalDate first = startDate; - LocalDate end = endDate; - switch (OrderStatisticsUnit.fromValue(unit)) { - case QUARTER -> { - first = firstDayOfQuarter(startDate); - end = lastDayOfQuarter(endDate); - } - case MONTH -> { - first = startDate.with(TemporalAdjusters.firstDayOfMonth()); - end = endDate.with(TemporalAdjusters.lastDayOfMonth()); - } - case WEEK -> { - first = startDate.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY)); - end = endDate.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY)); - } - default -> { - return; - } - } - reqVO.setCreateTime(new LocalDate[]{first, end}); - } - - private LocalDate firstDayOfQuarter(LocalDate date) { - int month = date.getMonthValue(); - int quarter = (month - 1) / 3 + 1; - int startMonth = (quarter - 1) * 3 + 1; - return LocalDate.of(date.getYear(), startMonth, 1); - } - - private LocalDate lastDayOfQuarter(LocalDate date) { - int month = date.getMonthValue(); - int quarter = (month - 1) / 3 + 1; - int endMonth = (quarter - 1) * 3 + 3; - return LocalDate.of(date.getYear(), endMonth, 1).with(TemporalAdjusters.lastDayOfMonth()); - } - - /** - * 获取日期范围内的所有格式字符串 - * - * @param reqVO - * @return - */ - private List generateDateRange(OrderStatisticsReqVO reqVO) { - Integer unit = reqVO.getUnit(); - // 计算时间跨度 - getTimeSpan(reqVO); - // 计算后的开始和结束时间 - LocalDate startDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); - LocalDate endDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); - - List dates = new ArrayList<>(); - while (!startDate.isAfter(endDate)) { - String dateStr; - switch (OrderStatisticsUnit.fromValue(unit)) { - case QUARTER: - dateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-Q")); - // 加一季度(3个月) - startDate = startDate.plusMonths(3); - break; - case MONTH: - dateStr = startDate.format(DateTimeFormatter.ofPattern(DATE_TIME_FORMATTER_PATTERN_YEAR_MONTH)); - // 加一月 - startDate = startDate.plusMonths(1); - break; - case WEEK: - dateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-M-ww")); - // 加一周 - startDate = startDate.plusWeeks(1); - break; - case DAY: - dateStr = startDate.format(DateTimeFormatter.ofPattern(DATE_TIME_FORMATTER_PATTERN_YEAR_MONTH_DAY)); - // 加一天 - startDate = startDate.plusDays(1); - break; - default: - throw new IllegalArgumentException("Unsupported unit: " + unit); - } - dates.add(dateStr); - } - return dates; - } - - /** - * 构建日期格式到图标横轴可用格式 - * 2024-1 -> 2024年第1季度 - * 2024-1-1 -> 2024年1月 - * ... - * @param unit - * @return - */ - private String generateDateRangeAxis(String date, Integer unit) { - OrderStatisticsUnit orderStatisticsUnit = OrderStatisticsUnit.fromValue(unit); - StringBuilder newDateStrBuffer = new StringBuilder(); - String[] dateSplit = date.split("-"); - switch (orderStatisticsUnit) { - case QUARTER: - newDateStrBuffer.append("第").append(dateSplit[1]).append("季度"); - break; - case MONTH: - newDateStrBuffer.append(dateSplit[1]).append("月"); - break; - case WEEK: - newDateStrBuffer.append("第").append(dateSplit[2]).append("周"); - break; - case DAY: - newDateStrBuffer.append(dateSplit[2]).append("日"); - break; - default: - } - return newDateStrBuffer.toString(); - } - /** * 移除尾数的0,600.000 -> 600 * diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderSupStatisticsService.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderSupStatisticsService.java index 70b5d9891..d60e8781f 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderSupStatisticsService.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderSupStatisticsService.java @@ -1,7 +1,5 @@ package com.cf.imes.module.executor.service.order; -import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderStatisticsReqVO; - import java.util.Map; /** @@ -18,9 +16,4 @@ public interface OrderSupStatisticsService { * 拆单板件平方数统计 */ Map plateAreaTotal(); - - /** - * 有效、无效生产单数量统计 - */ - Map orderSeparate(OrderStatisticsReqVO reqVO); } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderSupStatisticsServiceImpl.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderSupStatisticsServiceImpl.java index b2b68a7fa..1dfdc06a9 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderSupStatisticsServiceImpl.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderSupStatisticsServiceImpl.java @@ -1,10 +1,6 @@ package com.cf.imes.module.executor.service.order; -import cn.hutool.core.util.ObjectUtil; -import com.cf.imes.framework.common.enums.OrderStatisticsUnit; import com.cf.imes.framework.organ.core.aop.OrganIgnore; -import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderStatisticsIsLapseRespVO; -import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderStatisticsReqVO; import com.cf.imes.module.executor.dal.mysql.order.OrderStatisticsMapper; import com.cf.imes.module.executor.dal.mysql.order.OrderSupStatisticsMapper; import org.springframework.stereotype.Service; @@ -15,9 +11,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; -import java.util.stream.Collectors; -import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.*; @Service @Validated @@ -59,59 +53,4 @@ public class OrderSupStatisticsServiceImpl implements OrderSupStatisticsService{ return resultMap; } - - @Override - @OrganIgnore - public Map orderSeparate(OrderStatisticsReqVO reqVO) { - setOrderStatisticsReqVO(reqVO); - - Map resultMap = new LinkedHashMap<>(); - - // 所有的日期集合 - List dateList = getDateList(reqVO.getCreateTime(),reqVO.getUnit()); - - // 生产单有效数量 - Map> orderLapseRespMap = orderSupStatisticsMapper.selectOrderCountLapseByOrderDate(reqVO).stream() - .sorted(Comparator.naturalOrder()) - .collect(Collectors.groupingBy(OrderStatisticsIsLapseRespVO::getDate, LinkedHashMap::new, Collectors.toList())); - - // 生产单无效数量 - Map> orderNotLapseRespMap = orderSupStatisticsMapper.selectOrderCountNotLapseByOrderDate(reqVO).stream() - .sorted(Comparator.naturalOrder()) - .collect(Collectors.groupingBy(OrderStatisticsIsLapseRespVO::getDate, LinkedHashMap::new, Collectors.toList())); - - // 遍历时间跨度列表,匹配数量存入数组,没有补0存入数组 - for (String dateStr : dateList) { - int[] countArr = new int[2]; - // 生产单有效数量 - Integer orderNotLapseCount = Optional.ofNullable(orderNotLapseRespMap.get(dateStr)) - .map(list -> list.stream().findFirst().orElse(new OrderStatisticsIsLapseRespVO())) - .map(OrderStatisticsIsLapseRespVO::getOrderCount) - .orElse(0); - countArr[0] = orderNotLapseCount; - - - // 生产单无效数量 - Integer orderLapseCount = Optional.ofNullable(orderLapseRespMap.get(dateStr)) - .map(list -> list.stream().findFirst().orElse(new OrderStatisticsIsLapseRespVO())) - .map(OrderStatisticsIsLapseRespVO::getOrderCount) - .orElse(0); - countArr[1] = orderLapseCount; - - resultMap.put(generateDateRangeAxis(dateStr, reqVO.getUnit()), countArr); - } - - return resultMap; - } - - private void setOrderStatisticsReqVO(OrderStatisticsReqVO reqVO){ - if (ObjectUtil.isNull(reqVO.getUnit())){ - reqVO.setUnit(OrderStatisticsUnit.DAY.getValue()); - } - if (ObjectUtil.isNull(reqVO.getCreateTime())){ - reqVO.setCreateTime(new LocalDate[2]); - } - LocalDate[] time = reqVO.getCreateTime(); - reqVO.setCreateTime(new LocalDate[]{time[0], time[1]}); - } } diff --git a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/organ/OrganApi.java b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/organ/OrganApi.java index b5ba6e22b..d1b859808 100644 --- a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/organ/OrganApi.java +++ b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/organ/OrganApi.java @@ -1,7 +1,6 @@ package com.cf.imes.module.system.api.organ; import com.cf.imes.framework.common.pojo.CommonResult; -import com.cf.imes.module.system.api.organ.dto.OrgStatisticsReqDTO; import com.cf.imes.module.system.api.organ.dto.OrganizationDTO; import com.cf.imes.module.system.enums.ApiConstants; import io.swagger.v3.oas.annotations.Operation; @@ -9,12 +8,9 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; -import jakarta.validation.Valid; import java.util.List; -import java.util.Map; @FeignClient(name = ApiConstants.NAME) // TODO 晨丰:fallbackFactory = @Tag(name = "RPC 服务 - 多组织") @@ -31,15 +27,6 @@ public interface OrganApi { @Parameter(name = "id", description = "组织编号", required = true, example = "1024") CommonResult validOrgan(@RequestParam("id") Long id); - @PostMapping(PREFIX + "/separate/org") - @Operation(summary = "新增、注销组织数量统计") - CommonResult> getOrgSeparate(@Valid OrgStatisticsReqDTO reqVO); - - @GetMapping(PREFIX + "/warn/org") - @Operation(summary = "组织过期日期统计") - CommonResult>> getWarnToOrg(); - - @GetMapping(PREFIX + "/organ-details") @Operation(summary = "根据组织ID获取组织的详细信息") CommonResult getOrganDetails(@RequestParam("organId") Long organId); diff --git a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java index 5fe9fdef6..6fb0e4b45 100644 --- a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java +++ b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java @@ -139,7 +139,6 @@ public class ErrorCodeConstants { public static final ErrorCode ORGAN_ALREADY_EXISTS = new ErrorCode(1_002_015_007, "该新增组织已授权机台数量无需重复新增!"); public static final ErrorCode ORGAN_USER_OPER_NOT_ALLOW = new ErrorCode(1_002_015_008, "不允许操作用户自身组织"); public static final ErrorCode ORGAN_CONTACTMOBILE_DUPLICATE = new ErrorCode(1_002_015_009, "手机号为【{}】的组织已存在"); - public static final ErrorCode ORGAN_CREATE_PRODUCTLIST_EMPTY_ERROR = new ErrorCode(1_002_015_010, "组织创建购买产品列表不能为空"); // ========== 组织套餐 1-002-016-000 ========== public static final ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1_002_016_000, "组织套餐不存在"); @@ -475,6 +474,8 @@ public class ErrorCodeConstants { public static final ErrorCode PRODUCTS_DETAIL_DURATION_UNIT_NOT_SUPPORT = new ErrorCode(1_002_045_011, "不支持的时长单位,请检查该定价规则的时长单位"); public static final ErrorCode ORG_PRODUCT_PURCHASE_WAIT_PAY_ERROR = new ErrorCode(1_002_045_012, "组织下存在当前产品的待支付记录,请确认或取消支付后再次发起软件购买"); public static final ErrorCode PRODUCT_PRICE_NULL_ERROR = new ErrorCode(1_002_045_013, "产品建议价格为空,请联系客服"); + public static final ErrorCode ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR = new ErrorCode(1_002_045_014, "组织订购记录不存在,请检查数据"); + public static final ErrorCode ORG_PRODUCT_PURCHASE_EXIST_ERROR = new ErrorCode(1_002_045_014, "组织[{}]订购记录已存在,请勿重复定义订购机构"); //=========== 广告相关 1-002-046-000 ============ public static final ErrorCode ADVERTISEMENT_POSITION_NO_EXIST = new ErrorCode(1_002_046_001, "广告所选放置位置不存在"); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/organ/OrganApiImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/organ/OrganApiImpl.java index eb4e54870..8ef5b9981 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/organ/OrganApiImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/organ/OrganApiImpl.java @@ -2,15 +2,11 @@ package com.cf.imes.module.system.api.organ; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; -import com.cf.imes.framework.common.enums.OrderStatisticsUnit; import com.cf.imes.framework.common.pojo.CommonResult; import com.cf.imes.framework.common.util.object.BeanUtils; -import com.cf.imes.module.system.api.organ.dto.OrgStatisticsIsLapseRespDTO; -import com.cf.imes.module.system.api.organ.dto.OrgStatisticsReqDTO; import com.cf.imes.module.system.api.organ.dto.OrganizationDTO; import com.cf.imes.module.system.controller.admin.funds.delay.vo.PreviouProductDelayRespVO; import com.cf.imes.module.system.controller.admin.funds.delay.vo.ProductDelayRespVO; -import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganRespVO; import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO; import com.cf.imes.module.system.service.funds.delay.ProductDelayService; import com.cf.imes.module.system.service.organ.OrganService; @@ -19,15 +15,11 @@ import org.springframework.web.bind.annotation.RestController; import jakarta.annotation.Resource; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.*; -import java.util.stream.Collectors; import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.ORG_PRODUCT_EXPIRED; import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.cf.imes.framework.common.pojo.CommonResult.success; -import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.generateDateRangeAxis; -import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.getDateList; @RestController // 提供 RESTful API 接口,给 Feign 调用 @Validated @@ -50,70 +42,6 @@ public class OrganApiImpl implements OrganApi { return success(true); } - @Override - public CommonResult> getOrgSeparate(OrgStatisticsReqDTO reqVO) { - setOrgStatisticsReqVO(reqVO); - - Map resultMap = new LinkedHashMap<>(); - - // 所有的日期集合 - List dateList = getDateList(reqVO.getCreateTime(),reqVO.getUnit()); - - - // 组织有效数量 - Map> orderNotLapseRespMap = organService.orgCountAddByOrderDateAdd(reqVO).stream() - .sorted(Comparator.naturalOrder()) - .collect(Collectors.groupingBy(OrgStatisticsIsLapseRespDTO::getDate, LinkedHashMap::new, Collectors.toList())); - - // 组织无效数量 - Map> orderLapseRespMap = organService.orgCountLapseByOrderDate(reqVO).stream() - .sorted(Comparator.naturalOrder()) - .collect(Collectors.groupingBy(OrgStatisticsIsLapseRespDTO::getDate, LinkedHashMap::new, Collectors.toList())); - - // 遍历时间跨度列表,匹配数量存入数组,没有补0存入数组 - for (String dateStr : dateList) { - int[] countArr = new int[2]; - // 组织有效数量 - Integer orderNotLapseCount = Optional.ofNullable(orderNotLapseRespMap.get(dateStr)) - .map(list -> list.stream().findFirst().orElse(new OrgStatisticsIsLapseRespDTO())) - .map(OrgStatisticsIsLapseRespDTO::getOrgCount) - .orElse(0); - countArr[0] = orderNotLapseCount; - - - // 组织无效数量 - Integer orderLapseCount = Optional.ofNullable(orderLapseRespMap.get(dateStr)) - .map(list -> list.stream().findFirst().orElse(new OrgStatisticsIsLapseRespDTO())) - .map(OrgStatisticsIsLapseRespDTO::getOrgCount) - .orElse(0); - countArr[1] = orderLapseCount; - - resultMap.put(generateDateRangeAxis(dateStr, reqVO.getUnit()), countArr); - } - - return success(resultMap); - - } - - @Override - public CommonResult>> getWarnToOrg() { - Map> map = new HashMap<>(); - - LocalDateTime today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0); - LocalDateTime afterDay = today.plusDays(15).withHour(23).withMinute(59).withSecond(59); - LocalDateTime alertDay = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59); - - // 即将过期组织 - List expireOrg = organService.orgCountExpire(today, afterDay); - map.put("expireOrg", Collections.singletonList(expireOrg)); - - // 已过期组织 - List lapseOrg = organService.orgCountExpired(alertDay); - map.put("expiredOrg", Collections.singletonList(lapseOrg)); - - return success(map); - } - @Override public CommonResult getOrganDetails(Long organId) { @@ -127,18 +55,6 @@ public class OrganApiImpl implements OrganApi { return null; } - - private void setOrgStatisticsReqVO(OrgStatisticsReqDTO reqVO){ - if (ObjectUtil.isNull(reqVO.getUnit())){ - reqVO.setUnit(OrderStatisticsUnit.DAY.getValue()); - } - if (ObjectUtil.isNull(reqVO.getCreateTime())){ - reqVO.setCreateTime(new LocalDate[2]); - } - LocalDate[] time = reqVO.getCreateTime(); - reqVO.setCreateTime(new LocalDate[]{time[0], time[1]}); - } - @Override public CommonResult validOrganProduct(Long organId, Long productId) { PreviouProductDelayRespVO recordsByProductId = productDelayService.getActiveRecordsByProductId(productId, organId); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/balancedetails/BalanceDetailsController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/balancedetails/BalanceDetailsController.java index 863923593..efeee4adf 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/balancedetails/BalanceDetailsController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/balancedetails/BalanceDetailsController.java @@ -43,6 +43,7 @@ public class BalanceDetailsController { @GetMapping("") @Operation(summary = "查询组织账户明细分页") public CommonResult> getBalanceDetailsPage(@Valid BalanceDetailsPageReqVO pageReqVO) { + // 非管理端只能查看本组织数据 boolean manageEndPoint = SecurityFrameworkUtils.isManageEndPoint(); if (!manageEndPoint) { pageReqVO.setOrganId(SecurityFrameworkUtils.getUserOrganId()); @@ -55,9 +56,10 @@ public class BalanceDetailsController { @OperateLog(type = EXPORT) public void balanceDetailsExport(@Valid BalanceDetailsPageReqVO pageReqVO, HttpServletResponse response) throws IOException { + // 非管理端只能查看本组织数据 boolean manageEndPoint = SecurityFrameworkUtils.isManageEndPoint(); if (!manageEndPoint) { - pageReqVO.setOrganId(null); + pageReqVO.setOrganId(SecurityFrameworkUtils.getUserOrganId()); } pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); List list = incomeExpenseService.getBalanceDetailsPage(pageReqVO).getList(); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/organamount/vo/OrganFundsStatisticsReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/organamount/vo/OrganFundsStatisticsReqVO.java index 4c046082f..0503a2c19 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/organamount/vo/OrganFundsStatisticsReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/organamount/vo/OrganFundsStatisticsReqVO.java @@ -1,12 +1,8 @@ package com.cf.imes.module.system.controller.admin.funds.organamount.vo; -import com.cf.imes.module.system.validation.pay.FundsStatisticsUnitInEnum; +import com.cf.imes.framework.common.pojo.CommonStatisticsReqVO; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDate; /** * @author Gqr @@ -14,17 +10,5 @@ import java.time.LocalDate; */ @Schema(description = "管理后台 - 资金统计趋势 Request VO") @Data -public class OrganFundsStatisticsReqVO { - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = "yyyy-MM-dd") - private LocalDate[] createTime; - - /** - * 统计维度单位 - */ - @Schema(description = "统计维度单位", example = "0", allowableValues = {"0", "1", "2", "3"}, type = "integer") - @NotNull(message = "统计维度单位不能为空") - @FundsStatisticsUnitInEnum - private Integer unit; +public class OrganFundsStatisticsReqVO extends CommonStatisticsReqVO { } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/PurchaseController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/PurchaseController.java index 79166b3d6..1105ee2a6 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/PurchaseController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/purchase/PurchaseController.java @@ -43,7 +43,11 @@ public class PurchaseController { @GetMapping("") @Operation(summary = "获取软件的购买记录") public CommonResult> getPurchaseRecord(@Valid PurchaseRecordPageReqVO pageReqVO) { - + // 非管理端只能查看本组织数据 + boolean manageEndPoint = SecurityFrameworkUtils.isManageEndPoint(); + if (!manageEndPoint) { + pageReqVO.setOrganId(SecurityFrameworkUtils.getUserOrganId()); + } return success(purchaseService.getPurchaseRecord(pageReqVO)); } @@ -53,6 +57,11 @@ public class PurchaseController { @OperateLog(type = EXPORT) public void billDetailsExport(@Valid PurchaseRecordPageReqVO pageReqVO, HttpServletResponse response) throws IOException { + // 非管理端只能查看本组织数据 + boolean manageEndPoint = SecurityFrameworkUtils.isManageEndPoint(); + if (!manageEndPoint) { + pageReqVO.setOrganId(SecurityFrameworkUtils.getUserOrganId()); + } pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); List list = purchaseService.getPurchaseRecord(pageReqVO).getList(); if (SecurityFrameworkUtils.isManageEndPoint()) { diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/OrganController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/OrganController.java index 885136021..da06ac032 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/OrganController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/OrganController.java @@ -17,6 +17,7 @@ import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO; import com.cf.imes.module.system.dal.dataobject.organ.TenantPackageDO; import com.cf.imes.module.system.dal.mysql.organ.TenantPackageMapper; import com.cf.imes.module.system.enums.pay.DurationUnitEnum; +import com.cf.imes.module.system.enums.pay.PurchaseRecordStatusEnum; import com.cf.imes.module.system.service.funds.delay.ProductDelayService; import com.cf.imes.module.system.service.funds.purchase.PurchaseService; import com.cf.imes.module.system.service.organ.OrganService; @@ -89,7 +90,7 @@ public class OrganController { @PutMapping("/update") @Operation(summary = "更新组织") @PreAuthorize("@ss.hasPermission('organizationLIst:update')") - public CommonResult updateOrgan(@Valid @RequestBody OrganSaveReqVO updateReqVO) { + public CommonResult updateOrgan(@Validated(OrganSaveUpdateGroup.class) @RequestBody OrganSaveReqVO updateReqVO) { organService.updateOrgan(updateReqVO); return success(true); } @@ -115,10 +116,13 @@ public class OrganController { OrganRespVO bean = BeanUtils.toBean(organ, OrganRespVO.class); Long organId = bean.getId(); - // 查询当次列表组织下的所有购买记录 - List orgPurchaseList = BeanUtil.copyToList(purchaseService.getOrgPurchaseNotInitialList(Set.of(organId)), OrganPagePurchaseRespVO.class); + // 查询当次列表组织下的所有产品的首购记录 + List orgPurchaseList = BeanUtil.copyToList( + purchaseService.getOrgPurchaseList(Set.of(organId)).stream().filter(p -> p.getInitial()).collect(Collectors.toList()), OrganPagePurchaseRespVO.class + ); // 查询购买记录下的延期记录 orgPurchaseList.forEach(p -> { + p.setPrice(p.getTotalAmount()); List delayRecordsByPurchaseId = productDelayService.getRecordsByPurchaseId(p.getId(), organId); if (CollUtil.isNotEmpty(delayRecordsByPurchaseId)) { // 产品有效时间展示为第一项的计算延期时间 @@ -143,7 +147,8 @@ public class OrganController { Set organIds = bean.getList().stream().map(OrganRespVO::getId).collect(Collectors.toSet()); // 查询当次列表组织下的所有购买记录 - List orgPurchaseList = purchaseService.getOrgPurchaseNotInitialList(organIds); + List orgPurchaseList = purchaseService.getOrgPurchaseList(organIds) + .stream().filter(p -> PurchaseRecordStatusEnum.ACTIVE.getStatus().equals(p.getStatus())).collect(Collectors.toList()); // 匹配到对应的组织下 bean.getList().forEach(e -> { List purchaseRespVOList = orgPurchaseList.stream() @@ -152,6 +157,7 @@ public class OrganController { .toList(); // 查询购买记录下的延期记录 purchaseRespVOList.forEach(p -> { + p.setPrice(p.getTotalAmount()); List delayRecordsByPurchaseId = productDelayService.getRecordsByPurchaseId(p.getId(), e.getId()); if (CollUtil.isNotEmpty(delayRecordsByPurchaseId)) { // 产品有效时间展示为第一项的计算延期时间 diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganCreateProductPurchaseReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganCreateProductPurchaseReqVO.java index 638dd8d24..7dc121516 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganCreateProductPurchaseReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganCreateProductPurchaseReqVO.java @@ -13,13 +13,16 @@ import java.math.BigDecimal; @Data public class OrganCreateProductPurchaseReqVO { @Schema(description = "产品编号", example = "1") - @NotNull(message = "产品编号不能为空", groups = {OrganSaveCreateGroup.class}) + @NotNull(message = "产品编号不能为空") private Long productId; @Schema(description = "产品购买金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - @NotNull(message = "产品购买金额不能为空", groups = {OrganSaveCreateGroup.class}) + @NotNull(message = "产品购买金额不能为空") @DecimalMin(value = "0.01", message = "产品购买金额必须大于零") @DecimalMax(value = "100000", message = "产品购买金额不能超过十万") @Digits(integer = 6, fraction = 2, message = "产品购买金额格式不正确") private BigDecimal price; + + @Schema(description = "产品购买编号", example = "1") + private Long purchaseId; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganPagePurchaseRespVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganPagePurchaseRespVO.java index c2b302485..f997cb33c 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganPagePurchaseRespVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganPagePurchaseRespVO.java @@ -19,6 +19,9 @@ public class OrganPagePurchaseRespVO { @Schema(description = "购买记录编号") private Long id; + @Schema(description = "产品编号") + private Long productId; + @Schema(description = "产品名称") private String productName; @@ -44,4 +47,6 @@ public class OrganPagePurchaseRespVO { @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY) private LocalDate endTime; + @Schema(description = "订购价格") + private BigDecimal price; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganSaveUpdateGroup.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganSaveUpdateGroup.java new file mode 100644 index 000000000..2eee40c8c --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/organ/vo/organ/OrganSaveUpdateGroup.java @@ -0,0 +1,10 @@ +package com.cf.imes.module.system.controller.admin.organ.vo.organ; + +/** + * 组织更新请求校验组 + * + * @author Gqr + * @since 2025/9/24 16:28 + */ +public interface OrganSaveUpdateGroup { +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/ManageStatisticsController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/ManageStatisticsController.java index fd10a9809..3562c34ea 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/ManageStatisticsController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/ManageStatisticsController.java @@ -1,20 +1,29 @@ package com.cf.imes.module.system.controller.admin.statistics; import com.cf.imes.framework.common.pojo.CommonResult; +import com.cf.imes.framework.common.pojo.PageParam; +import com.cf.imes.framework.common.pojo.PageResult; +import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganRespVO; import com.cf.imes.module.system.controller.admin.statistics.vo.ManageOrgTotalStatisticRespVO; +import com.cf.imes.module.system.controller.admin.statistics.vo.ManageSalesTotalStatisticRespVO; import com.cf.imes.module.system.controller.admin.statistics.vo.ManageUserActTotalStatisticRespVO; import com.cf.imes.module.system.controller.admin.statistics.vo.ManageUserTotalStatisticRespVO; +import com.cf.imes.module.system.controller.admin.statistics.vo.OrgStatusGroupStatisticsReqVO; +import com.cf.imes.module.system.service.funds.purchase.PurchaseService; import com.cf.imes.module.system.service.organ.OrganService; import com.cf.imes.module.system.service.user.AdminUserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.Map; + import static com.cf.imes.framework.common.pojo.CommonResult.success; @Tag(name = "管理后台 - 管理端分析页管理") @@ -24,15 +33,15 @@ import static com.cf.imes.framework.common.pojo.CommonResult.success; @Slf4j public class ManageStatisticsController { -// @Resource -// private OrderSupStatisticsService orderSupStatisticsService; - @Resource private OrganService organService; @Resource private AdminUserService userService; + @Resource + private PurchaseService purchaseService; + @GetMapping("/total/org") @Operation(summary = "组织总数") public CommonResult getOrgTotal() { @@ -45,42 +54,33 @@ public class ManageStatisticsController { return success(userService.getUserTotal()); } + @GetMapping("/total/sales") + @Operation(summary = "销售额") + public CommonResult getSalesTotal() { + return success(purchaseService.getSalesTotalStatistics()); + } + @GetMapping("/total/userAct") @Operation(summary = "用户活跃数") public CommonResult getUserActTotal() { return success(userService.getUserActTotal()); } -// @GetMapping("/total/order") -// @Operation(summary = "生产单总数") -// @PreAuthorize("@ss.hasPermission('homePage:analysis:org-statistic')") -// public CommonResult> getOrderTotal() { -// return success(orderSupStatisticsService.orderTotal()); -// } -// -// @GetMapping("/total/plateArea") -// @Operation(summary = "拆单板件平方数") -// public CommonResult> getPlateAreaTotal() { -// return success(orderSupStatisticsService.plateAreaTotal()); -// } -// -// @GetMapping("/separate/order") -// @Operation(summary = "有效、无效生产单数量统计") -// @PreAuthorize("@ss.hasPermission('homePage:analysis:order-count')") -// public CommonResult> getOrderSeparate(@Valid OrderStatisticsReqVO reqVO) { -// return success(orderSupStatisticsService.orderSeparate(reqVO)); -// } -// -// @GetMapping("/separate/org") -// @Operation(summary = "新增、注销组织数量统计") -// @PreAuthorize("@ss.hasPermission('homePage:analysis:org-count')") -// public CommonResult> getOrgSeparate(@Valid OrgStatisticsReqDTO reqVO) { -// return organApi.getOrgSeparate(reqVO); -// } -// -// @GetMapping("/warn/org") -// @Operation(summary = "组织过期日期统计") -// public CommonResult>> getWarnToOrg() { -// return organApi.getWarnToOrg(); -// } + @GetMapping("/org/status/group") + @Operation(summary = "新增、注销组织数量统计") + public CommonResult> getOrgStatusGroupStatistics(@Valid OrgStatusGroupStatisticsReqVO reqVO) { + return success(organService.getOrgStatusGroupStatistics(reqVO)); + } + + @GetMapping("/org/expiring") + @Operation(summary = "获取即将过期组织分页") + public CommonResult> getAboutExpireOrg(@Valid PageParam param) { + return success(organService.getOrgAboutExpire(param)); + } + + @GetMapping("/org/expired") + @Operation(summary = "获取已过期组织分页") + public CommonResult> getExpiredOrg(@Valid PageParam param) { + return success(organService.getOrgExpired(param)); + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/vo/ManageSalesTotalStatisticRespVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/vo/ManageSalesTotalStatisticRespVO.java new file mode 100644 index 000000000..30ef8370b --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/vo/ManageSalesTotalStatisticRespVO.java @@ -0,0 +1,21 @@ +package com.cf.imes.module.system.controller.admin.statistics.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author Gqr + * @since 2025/9/29 14:37 + */ +@Schema(description = "管理后台 - 管理端销售额统计 Response VO") +@Data +public class ManageSalesTotalStatisticRespVO { + + @Schema(description = "当日销售额") + private BigDecimal salesToday; + + @Schema(description = "销售总额") + private BigDecimal salesTotal; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/vo/OrgStatusGroupStatisticsReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/vo/OrgStatusGroupStatisticsReqVO.java new file mode 100644 index 000000000..ce438d8c0 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/statistics/vo/OrgStatusGroupStatisticsReqVO.java @@ -0,0 +1,14 @@ +package com.cf.imes.module.system.controller.admin.statistics.vo; + +import com.cf.imes.framework.common.pojo.CommonStatisticsReqVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + + +/** + * 统计集合 --- 组织数量统计 + */ +@Schema(description = "管理后台 - 组织数量统计 Request VO") +@Data +public class OrgStatusGroupStatisticsReqVO extends CommonStatisticsReqVO { +} \ No newline at end of file diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/purchase/PurchaseRecordMapper.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/purchase/PurchaseRecordMapper.java index 492cbdb92..fff807f10 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/purchase/PurchaseRecordMapper.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/purchase/PurchaseRecordMapper.java @@ -92,6 +92,12 @@ public interface PurchaseRecordMapper extends BaseMapperX { */ TotalSalesAmountRespVO getTotalSales(); + /** + * 查询当日销售总额 + * @return + */ + BigDecimal getTodaySales(); + /** * 查询购买记录中的现金使用金额总数 * diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/organ/OrganMapper.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/organ/OrganMapper.java index 4cdc98f16..c85c6d286 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/organ/OrganMapper.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/organ/OrganMapper.java @@ -1,13 +1,16 @@ package com.cf.imes.module.system.dal.mysql.organ; import cn.hutool.core.text.CharSequenceUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.cf.imes.framework.common.pojo.PageParam; import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX; import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX; import com.cf.imes.module.executor.enums.OrderDeletedEnum; import com.cf.imes.module.system.api.organ.dto.OrgStatisticsIsLapseRespDTO; -import com.cf.imes.module.system.api.organ.dto.OrgStatisticsReqDTO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganPageReqVO; +import com.cf.imes.module.system.controller.admin.statistics.vo.OrgStatusGroupStatisticsReqVO; import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -105,24 +108,41 @@ public interface OrganMapper extends BaseMapperX { /** * 组织按时间统计新增数量 */ - List selectOrgCountAddByOrderDate(@Param("req") OrgStatisticsReqDTO reqVO); + List selectOrgCountAddByOrderDate(@Param("req") OrgStatusGroupStatisticsReqVO reqVO); /** * 组织按时间分组统计注销数量 */ - List selectOrgCountLapseByOrderDate(@Param("req") OrgStatisticsReqDTO reqVO); + List selectOrgCountLapseByOrderDate(@Param("req") OrgStatusGroupStatisticsReqVO reqVO); - default List selectOrgCountExpire(LocalDateTime today, LocalDateTime afterDay){ - return selectList(new LambdaQueryWrapperX() - .eq(OrganizationDO::getDeleted,false) - .between(OrganizationDO::getExpireTime,today,afterDay)); + /** + * 分页查询即将过期的组织 + * @param param + * @return + */ + default IPage selectOrgCountExpire(PageParam param) { + Page page = new Page<>(param.getPageNo(), param.getPageSize()); + LocalDateTime today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0); + LocalDateTime afterDay = today.plusDays(15).withHour(23).withMinute(59).withSecond(59); + return selectPage(page, new LambdaQueryWrapperX() + .eq(OrganizationDO::getDeleted, false) + .between(OrganizationDO::getExpireTime, today, afterDay) + .orderByDesc(OrganizationDO::getId)); } - default List selectOrgCountExpired(LocalDateTime alertDay){ - return selectList(new LambdaQueryWrapperX() - .eq(OrganizationDO::getDeleted,false) - .lt(OrganizationDO::getExpireTime,alertDay)); + /** + * 分页查询过期的组织 + * @param param + * @return + */ + default IPage selectOrgCountExpired(PageParam param) { + Page page = new Page<>(param.getPageNo(), param.getPageSize()); + return selectPage(page, new LambdaQueryWrapperX() + .eq(OrganizationDO::getDeleted, false) + .lt(OrganizationDO::getExpireTime, LocalDateTime.now().withHour(23).withMinute(59).withSecond(59)) + .orderByDesc(OrganizationDO::getId)); } + default List selectOrganListByName(String organName) { return selectList(new LambdaQueryWrapperX() .eqIfPresent(OrganizationDO::getDeleted,false) diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/manualadjust/ManualAdjustAccountBalanceServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/manualadjust/ManualAdjustAccountBalanceServiceImpl.java index 00ba1e90d..a5baecf2a 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/manualadjust/ManualAdjustAccountBalanceServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/manualadjust/ManualAdjustAccountBalanceServiceImpl.java @@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.common.util.Assert.AssertUtils; import com.cf.imes.framework.common.util.object.BeanUtils; -import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd; +import com.cf.imes.framework.id.core.util.SnowflakeSerialNoWorker3rd; import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX; import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalancePageReqVO; import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalanceRespVO; @@ -73,7 +73,7 @@ public class ManualAdjustAccountBalanceServiceImpl implements ManualAdjustAccoun private IncomeExpenseDetailsMapper incomeExpenseDetailsMapper; @Resource - private SnowflakeIdWorker3rd snowflakeIdWorker3rd; + private SnowflakeSerialNoWorker3rd snowflakeSerialNoWorker3rd; @Override @Transactional(rollbackFor = Exception.class) @@ -128,7 +128,7 @@ public class ManualAdjustAccountBalanceServiceImpl implements ManualAdjustAccoun IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) .orderNo(payOrderDO.getPayNo()) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .tradeType(TradeTypeEnum.MANUAL_ADJUST.getCode()) .incomeExpenseType(incomeExpenseType) .cashAmountChange(rechargeAmount) diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/organamount/OrganAmountServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/organamount/OrganAmountServiceImpl.java index c25895181..7bdf9d16a 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/organamount/OrganAmountServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/organamount/OrganAmountServiceImpl.java @@ -47,6 +47,8 @@ import java.util.stream.Collectors; import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER; import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.generateDateRangeAxis; +import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.getDateList; import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAN_AMOUNT_NO_EXIST; import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAN_PRODUCT_PAY_AMOUNT_CHANGE_ERROR; import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAN_RECHARGE_AMOUNT_UPDATE_ERROR; @@ -277,192 +279,6 @@ public class OrganAmountServiceImpl implements OrganAmountService { return resultMap; } - /** - * 获取日期区间格式下的所有日期字符串 - * 1、reqVO设置机构id - * 2、计算时间跨度设置到reqVO - * 3、返回所有日期的集合 - * @param reqVO - * @return - */ - private List getDateList(OrganFundsStatisticsReqVO reqVO) { - // 计算时间跨度 - getTimeSpan(reqVO); - - // 重新计算开始时间喝结束时间 - countTimeSpan(reqVO); - - // 所有的日期集合 - return generateDateRange(reqVO); - } - - /** - * 获取统计的时间跨度 - * 计算起止时间:前端不传入时间就根据维度单位从当前日期计算 - * - * @param reqVO - */ - private void getTimeSpan(OrganFundsStatisticsReqVO reqVO) { - LocalDate[] createTime = reqVO.getCreateTime(); - LocalDate startTime = null; - LocalDate endTime; - LocalDate now = LocalDate.now(); - if (ArrayUtil.isEmpty(createTime) || ObjectUtil.isNull(createTime[0]) || ObjectUtil.isNull(createTime[1])) { - endTime = now; - switch (OrderStatisticsUnit.fromValue(reqVO.getUnit())) { - case QUARTER: - // 从now往前的1年 - startTime = now.minusYears(1); - break; - case MONTH: - // 包含now往前的12个月 - startTime = now.minusMonths(11); - break; - case WEEK: - // 包含now往前的12周 - startTime = now.minusWeeks(11); - break; - case DAY: - // 包含now往前的15天 - startTime = now.minusDays(14); - break; - default: - break; - } - // 声明一个LocalDateTime的数组,把startTime和endTime放进去 - reqVO.setCreateTime(new LocalDate[]{startTime, endTime}); - } - } - - /** - * 根据传入信息重新计算时间范围 - * - * @param reqVO - */ - private void countTimeSpan(OrganFundsStatisticsReqVO reqVO) { - Integer unit = reqVO.getUnit(); - // 计算时间跨度 - getTimeSpan(reqVO); - // 计算后的开始和结束时间 - LocalDate startDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); - LocalDate endDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); - - if (startDate.isAfter(endDate)) { - startDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); - endDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); - } - LocalDate first = startDate; - LocalDate end = endDate; - switch (OrderStatisticsUnit.fromValue(unit)) { - case QUARTER -> { - first = firstDayOfQuarter(startDate); - end = lastDayOfQuarter(endDate); - } - case MONTH -> { - first = startDate.with(TemporalAdjusters.firstDayOfMonth()); - end = endDate.with(TemporalAdjusters.lastDayOfMonth()); - } - case WEEK -> { - first = startDate.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY)); - end = endDate.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY)); - } - default -> { - return; - } - } - reqVO.setCreateTime(new LocalDate[]{first, end}); - } - - private LocalDate firstDayOfQuarter(LocalDate date) { - int month = date.getMonthValue(); - int quarter = (month - 1) / 3 + 1; - int startMonth = (quarter - 1) * 3 + 1; - return LocalDate.of(date.getYear(), startMonth, 1); - } - - private LocalDate lastDayOfQuarter(LocalDate date) { - int month = date.getMonthValue(); - int quarter = (month - 1) / 3 + 1; - int endMonth = (quarter - 1) * 3 + 3; - return LocalDate.of(date.getYear(), endMonth, 1).with(TemporalAdjusters.lastDayOfMonth()); - } - - /** - * 获取日期范围内的所有格式字符串 - * - * @param reqVO - * @return - */ - private List generateDateRange(OrganFundsStatisticsReqVO reqVO) { - Integer unit = reqVO.getUnit(); - // 计算时间跨度 - getTimeSpan(reqVO); - // 计算后的开始和结束时间 - LocalDate startDate = ObjectUtil.clone(reqVO.getCreateTime()[0]); - LocalDate endDate = ObjectUtil.clone(reqVO.getCreateTime()[1]); - - List dates = new ArrayList<>(); - while (!startDate.isAfter(endDate)) { - String dateStr; - switch (OrderStatisticsUnit.fromValue(unit)) { - case QUARTER: - dateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-Q")); - // 加一季度(3个月) - startDate = startDate.plusMonths(3); - break; - case MONTH: - dateStr = startDate.format(DateTimeFormatter.ofPattern(DATE_TIME_FORMATTER_PATTERN_YEAR_MONTH)); - // 加一月 - startDate = startDate.plusMonths(1); - break; - case WEEK: - dateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-M-ww")); - // 加一周 - startDate = startDate.plusWeeks(1); - break; - case DAY: - dateStr = startDate.format(DateTimeFormatter.ofPattern(DATE_TIME_FORMATTER_PATTERN_YEAR_MONTH_DAY)); - // 加一天 - startDate = startDate.plusDays(1); - break; - default: - throw new IllegalArgumentException("Unsupported unit: " + unit); - } - dates.add(dateStr); - } - return dates; - } - - /** - * 构建日期格式到图标横轴可用格式 - * 2024-1 -> 2024年第1季度 - * 2024-1-1 -> 2024年1月 - * ... - * @param unit - * @return - */ - private String generateDateRangeAxis(String date, Integer unit) { - OrderStatisticsUnit orderStatisticsUnit = OrderStatisticsUnit.fromValue(unit); - StringBuilder newDateStrBuffer = new StringBuilder(); - String[] dateSplit = date.split("-"); - switch (orderStatisticsUnit) { - case QUARTER: - newDateStrBuffer.append("第").append(dateSplit[1]).append("季度"); - break; - case MONTH: - newDateStrBuffer.append(dateSplit[1]).append("月"); - break; - case WEEK: - newDateStrBuffer.append("第").append(dateSplit[2]).append("周"); - break; - case DAY: - newDateStrBuffer.append(dateSplit[2]).append("日"); - break; - default: - } - return newDateStrBuffer.toString(); - } - @Override public void fixOrganAmount() { List organizationDOS = organMapper.selectList(new LambdaQueryWrapper().select(OrganizationDO::getId)); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/purchase/PurchaseService.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/purchase/PurchaseService.java index 84b635946..100390170 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/purchase/PurchaseService.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/purchase/PurchaseService.java @@ -9,6 +9,7 @@ import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseReco import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailRespVO; import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailsPageReqVO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganCreateProductPurchaseReqVO; +import com.cf.imes.module.system.controller.admin.statistics.vo.ManageSalesTotalStatisticRespVO; import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO; import java.math.BigDecimal; @@ -82,12 +83,20 @@ public interface PurchaseService { void createOrgInitProductPurchaseRecord(Long organId, List productPurchaseReqVOS); /** - * 查询组织下的非首购的产品购买记录 + * 更新组织首购记录 + * + * @param organId + * @param productPurchaseReqVOS + */ + void updateOrgInitProductPurchaseRecord(Long organId, List productPurchaseReqVOS); + + /** + * 查询组织下产品购买记录 * * @param organIds * @return */ - List getOrgPurchaseNotInitialList(Set organIds); + List getOrgPurchaseList(Set organIds); /** * 查询销售总额 @@ -148,4 +157,10 @@ public interface PurchaseService { * @param purchaseRecordId */ void activateHistoryOrganProductPurchaseRecord(Long organId, Long purchaseRecordId); + + /** + * 管理端获取销售总额统计 + * @return + */ + ManageSalesTotalStatisticRespVO getSalesTotalStatistics(); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/purchase/PurchaseServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/purchase/PurchaseServiceImpl.java index 581345cd1..71485861a 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/purchase/PurchaseServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/purchase/PurchaseServiceImpl.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.cf.imes.framework.common.exception.ServiceException; +import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil; import com.cf.imes.framework.common.pojo.PageParam; import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.common.util.date.LocalDateTimeUtils; @@ -20,6 +21,7 @@ import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseReco import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailRespVO; import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailsPageReqVO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganCreateProductPurchaseReqVO; +import com.cf.imes.module.system.controller.admin.statistics.vo.ManageSalesTotalStatisticRespVO; import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO; import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO; import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO; @@ -44,8 +46,13 @@ import java.math.RoundingMode; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; +import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_EXIST_ERROR; +import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR; import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCT_PRICE_NULL_ERROR; import static com.cf.imes.module.system.enums.pay.PayConstants.PAY_PRODUCT_DETAIL_AUTO_GENERATE_MONTH_ID_FORMAT; @@ -187,10 +194,80 @@ public class PurchaseServiceImpl implements PurchaseService { } @Override - public List getOrgPurchaseNotInitialList(Set organIds) { + public void updateOrgInitProductPurchaseRecord(Long organId, List productPurchaseReqVOS) { + // 1、查询组织下的产品首购记录 + List currOrgProductInitialPurchaseList = purchaseRecordMapper.selectList(new LambdaQueryWrapper() + .eq(PurchaseRecordDO::getOrganId, organId) + .eq(PurchaseRecordDO::getInitial, true) + .eq(PurchaseRecordDO::getDeleted, false)); + + // 2、入参整理为新增列表和修改列表 + List createList = productPurchaseReqVOS.stream().filter(purchaseReqVO -> ObjectUtil.isNull(purchaseReqVO.getPurchaseId())).collect(Collectors.toList()); + List updateList = productPurchaseReqVOS.stream().filter(purchaseReqVO -> ObjectUtil.isNotNull(purchaseReqVO.getPurchaseId())).collect(Collectors.toList()); + + // 3、筛选出修改列表和当前记录中有差集的部分提示首购不存在 + Set currPurchaseIds = currOrgProductInitialPurchaseList.stream() + .map(PurchaseRecordDO::getId) + .collect(Collectors.toSet()); + + boolean updateNotExist = updateList.stream() + .map(OrganCreateProductPurchaseReqVO::getPurchaseId) + .anyMatch(purchaseId -> !currPurchaseIds.contains(purchaseId)); + if (updateNotExist) { + throw new ServiceException(ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR); + } + + // 4、筛选出新增列表和当前记录中有产品id重复的提示订购记录已存在 + Map currProductMap = currOrgProductInitialPurchaseList.stream() + .collect(Collectors.toMap(PurchaseRecordDO::getProductId, PurchaseRecordDO::getProductName)); + + Optional duplicateOpt = createList.stream() + .filter(req -> currProductMap.containsKey(req.getProductId())) + .findFirst(); + + if (duplicateOpt.isPresent()) { + throw ServiceExceptionUtil.exception(ORG_PRODUCT_PURCHASE_EXIST_ERROR, currProductMap.get(duplicateOpt.get().getProductId())); + } + + // 5、删选出当前记录和入参列表中purchaseId不重复的,作为删除的部分 + Set inputPurchaseIds = updateList.stream().map(OrganCreateProductPurchaseReqVO::getPurchaseId).collect(Collectors.toSet()); + List deleteIdList = currOrgProductInitialPurchaseList.stream() + .filter(record -> !inputPurchaseIds.contains(record.getId())) + .map(PurchaseRecordDO::getId) + .collect(Collectors.toList()); + + // 6、修改 + for (OrganCreateProductPurchaseReqVO purchaseReqVO : updateList) { + // 购买记录id + Long purchaseId = purchaseReqVO.getPurchaseId(); + // 订购价格 + BigDecimal price = purchaseReqVO.getPrice(); + + // 2、更新购买记录的订购价格 + purchaseRecordMapper.update(new LambdaUpdateWrapper() + .eq(PurchaseRecordDO::getId, purchaseId) + .eq(PurchaseRecordDO::getOrganId, organId) + .eq(PurchaseRecordDO::getInitial, true) + .set(PurchaseRecordDO::getTotalAmount, price) + .set(PurchaseRecordDO::getMonthAverageAmount, price.divide(new BigDecimal(10), 2, RoundingMode.DOWN)) + .set(PurchaseRecordDO::getOriginalAmount, price)); + } + + // 7、新增 + if (CollUtil.isNotEmpty(createList)) { + createOrgInitProductPurchaseRecord(organId, createList); + } + + // 8、删除 + if (CollUtil.isNotEmpty(deleteIdList)) { + purchaseRecordMapper.deleteByIds(deleteIdList); + } + } + + @Override + public List getOrgPurchaseList(Set organIds) { return purchaseRecordMapper.selectList(new LambdaQueryWrapper() .in(PurchaseRecordDO::getOrganId, organIds) - .eq(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.ACTIVE.getStatus()) .eq(PurchaseRecordDO::getDeleted, false)); } @@ -384,4 +461,12 @@ public class PurchaseServiceImpl implements PurchaseService { .eq(PurchaseRecordDO::getDeleted, false) .set(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.ACTIVE.getStatus())); } + + @Override + public ManageSalesTotalStatisticRespVO getSalesTotalStatistics() { + ManageSalesTotalStatisticRespVO respVO = new ManageSalesTotalStatisticRespVO(); + respVO.setSalesTotal(purchaseRecordMapper.getTotalSales().getAmount()); + respVO.setSalesToday(purchaseRecordMapper.getTodaySales()); + return respVO; + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/organ/OrganService.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/organ/OrganService.java index 8288fb2f4..cb87854e0 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/organ/OrganService.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/organ/OrganService.java @@ -1,20 +1,20 @@ package com.cf.imes.module.system.service.organ; +import com.cf.imes.framework.common.pojo.PageParam; import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.organ.core.context.OrganContextHolder; -import com.cf.imes.module.system.api.organ.dto.OrgStatisticsIsLapseRespDTO; -import com.cf.imes.module.system.api.organ.dto.OrgStatisticsReqDTO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganPageReqVO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganRespVO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganSaveReqVO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganSimpleRespVO; import com.cf.imes.module.system.controller.admin.statistics.vo.ManageOrgTotalStatisticRespVO; +import com.cf.imes.module.system.controller.admin.statistics.vo.OrgStatusGroupStatisticsReqVO; import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO; import com.cf.imes.module.system.service.organ.handler.OrganInfoHandler; import com.cf.imes.module.system.service.organ.handler.OrganMenuHandler; import jakarta.validation.Valid; -import java.time.LocalDateTime; + import java.util.List; import java.util.Map; import java.util.Set; @@ -150,23 +150,25 @@ public interface OrganService { */ ManageOrgTotalStatisticRespVO getOrgTotal(); - /** - * 组织新增统计 - */ - List orgCountAddByOrderDateAdd(OrgStatisticsReqDTO reqVO); - - /** - * 组织注销统计 - */ - List orgCountLapseByOrderDate(OrgStatisticsReqDTO reqVO); - /** * 即将过期组织统计 + * + * @param param 分页参数 */ - List orgCountExpire(LocalDateTime today, LocalDateTime afterDay); + PageResult getOrgAboutExpire(PageParam param); /** * 已过期组织统计 + * + * @param param 分页参数 */ - List orgCountExpired(LocalDateTime alertDay); + PageResult getOrgExpired(PageParam param); + + /** + * 查询新增、注销组织数量统计 + * + * @param reqVO + * @return + */ + Map getOrgStatusGroupStatistics(OrgStatusGroupStatisticsReqVO reqVO); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/organ/OrganServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/organ/OrganServiceImpl.java index cecfd3287..edfbc0c72 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/organ/OrganServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/organ/OrganServiceImpl.java @@ -6,9 +6,10 @@ import cn.hutool.core.lang.Assert; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.dynamic.datasource.annotation.DSTransactional; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.cf.imes.framework.common.enums.CommonStatusEnum; +import com.cf.imes.framework.common.pojo.PageParam; import com.cf.imes.framework.common.pojo.PageResult; -import com.cf.imes.framework.common.util.Assert.AssertUtils; import com.cf.imes.framework.common.util.collection.CollectionUtils; import com.cf.imes.framework.common.util.date.DateUtils; import com.cf.imes.framework.common.util.json.JsonUtils; @@ -20,7 +21,6 @@ import com.cf.imes.framework.organ.core.context.OrganContextHolder; import com.cf.imes.framework.organ.core.util.OrganUtils; import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; import com.cf.imes.module.system.api.organ.dto.OrgStatisticsIsLapseRespDTO; -import com.cf.imes.module.system.api.organ.dto.OrgStatisticsReqDTO; import com.cf.imes.module.system.constants.permission.InternalRoleConstants; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganCreateProductPurchaseReqVO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganPageReqVO; @@ -28,6 +28,7 @@ import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganRespVO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganSaveReqVO; import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganSimpleRespVO; import com.cf.imes.module.system.controller.admin.statistics.vo.ManageOrgTotalStatisticRespVO; +import com.cf.imes.module.system.controller.admin.statistics.vo.OrgStatusGroupStatisticsReqVO; import com.cf.imes.module.system.controller.admin.systemconfig.vo.ProcessSchemeConfig; import com.cf.imes.module.system.controller.admin.tokenconfig.vo.JwtConfig; import com.cf.imes.module.system.controller.admin.user.vo.user.UserSaveReqVO; @@ -72,12 +73,14 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import jakarta.annotation.Resource; -import java.time.LocalDateTime; + import java.util.*; import java.util.stream.Collectors; import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.cf.imes.framework.common.util.json.JsonUtils.parseArray; +import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.generateDateRangeAxis; +import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.getDateList; import static com.cf.imes.module.system.dal.redis.RedisKeyConstants.OAUTH2_ACCESS_TOKEN; import static com.cf.imes.module.system.enums.ErrorCodeConstants.*; import static com.cf.imes.module.system.service.tokenconfig.TokenConfigServiceImpl.generateBaseToken; @@ -243,7 +246,6 @@ public class OrganServiceImpl implements OrganService { // 创建产品购买记录 List productPurchaseReqVOS = createReqVO.getProductPurchaseReqVOS(); - AssertUtils.notEmpty(productPurchaseReqVOS, ORGAN_CREATE_PRODUCTLIST_EMPTY_ERROR); // 根据productId去重,初次订购每个产品只能有一种订购 productPurchaseReqVOS = productPurchaseReqVOS.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(OrganCreateProductPurchaseReqVO::getProductId))), ArrayList::new)); purchaseService.createOrgInitProductPurchaseRecord(organId, productPurchaseReqVOS); @@ -301,6 +303,9 @@ public class OrganServiceImpl implements OrganService { OrganizationDO updateObj = BeanUtils.toBean(updateReqVO, OrganizationDO.class); organMapper.updateById(updateObj); + // 更新产品购买记录 + purchaseService.updateOrgInitProductPurchaseRecord(organId, updateReqVO.getProductPurchaseReqVOS()); + if (CommonStatusEnum.DISABLE.getStatus().equals(updateReqVO.getStatus())) { // 移除机构下用户的token scanAndCompareDeptAndDelToken(String.format(OAUTH2_ACCESS_TOKEN, "*"), organId); @@ -542,28 +547,17 @@ public class OrganServiceImpl implements OrganService { } @Override - public List orgCountAddByOrderDateAdd(OrgStatisticsReqDTO reqVO) { - return organMapper.selectOrgCountAddByOrderDate(reqVO); + public PageResult getOrgAboutExpire(PageParam param) { + IPage organPage = organMapper.selectOrgCountExpire(param); + return new PageResult<>(BeanUtils.toBean(organPage.getRecords(), OrganRespVO.class), organPage.getTotal()); } @Override - public List orgCountLapseByOrderDate(OrgStatisticsReqDTO reqVO) { - return organMapper.selectOrgCountLapseByOrderDate(reqVO); + public PageResult getOrgExpired(PageParam param) { + IPage organPage = organMapper.selectOrgCountExpired(param); + return new PageResult<>(BeanUtils.toBean(organPage.getRecords(), OrganRespVO.class), organPage.getTotal()); } - @Override - public List orgCountExpire(LocalDateTime today, LocalDateTime afterDay) { - return BeanUtils.toBean(organMapper.selectOrgCountExpire(today, afterDay), OrganRespVO.class); - } - - @Override - public List orgCountExpired(LocalDateTime alertDay) { - return BeanUtils.toBean(organMapper.selectOrgCountExpired(alertDay), OrganRespVO.class); - } - - - - // 系统配置数据复制 private void copySystemConfig(Long organId) { @@ -747,6 +741,45 @@ public class OrganServiceImpl implements OrganService { } } + @Override + public Map getOrgStatusGroupStatistics(OrgStatusGroupStatisticsReqVO reqVO) { + + Map resultMap = new LinkedHashMap<>(); + + // 所有的日期集合 + List dateList = getDateList(reqVO); + + // 组织有效数量 + Map> orderNotLapseRespMap = organMapper.selectOrgCountAddByOrderDate(reqVO).stream() + .sorted(Comparator.naturalOrder()) + .collect(Collectors.groupingBy(OrgStatisticsIsLapseRespDTO::getDate, LinkedHashMap::new, Collectors.toList())); + + // 组织无效数量 + Map> orderLapseRespMap = organMapper.selectOrgCountLapseByOrderDate(reqVO).stream() + .sorted(Comparator.naturalOrder()) + .collect(Collectors.groupingBy(OrgStatisticsIsLapseRespDTO::getDate, LinkedHashMap::new, Collectors.toList())); + + // 遍历时间跨度列表,匹配数量存入数组,没有补0存入数组 + for (String dateStr : dateList) { + int[] countArr = new int[2]; + // 组织有效数量 + Integer orderNotLapseCount = Optional.ofNullable(orderNotLapseRespMap.get(dateStr)) + .map(list -> list.stream().findFirst().orElse(new OrgStatisticsIsLapseRespDTO())) + .map(OrgStatisticsIsLapseRespDTO::getOrgCount) + .orElse(0); + countArr[0] = orderNotLapseCount; + // 组织无效数量 + Integer orderLapseCount = Optional.ofNullable(orderLapseRespMap.get(dateStr)) + .map(list -> list.stream().findFirst().orElse(new OrgStatisticsIsLapseRespDTO())) + .map(OrgStatisticsIsLapseRespDTO::getOrgCount) + .orElse(0); + countArr[1] = orderLapseCount; + + resultMap.put(generateDateRangeAxis(dateStr, reqVO.getUnit()), countArr); + } + + return resultMap; + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java index 19bdb5be3..e4bc15db7 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java @@ -18,7 +18,7 @@ import com.cf.imes.framework.common.util.Assert.AssertUtils; import com.cf.imes.framework.common.util.json.JsonUtils; import com.cf.imes.framework.common.util.object.BeanUtils; import com.cf.imes.framework.common.util.validation.ValidationUtils; -import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd; +import com.cf.imes.framework.id.core.util.SnowflakeSerialNoWorker3rd; import com.cf.imes.framework.organ.core.context.OrganContextHolder; import com.cf.imes.framework.pay.config.ChenfengAlipayConfig; import com.cf.imes.framework.pay.config.ChenfengPayConfig; @@ -164,7 +164,7 @@ public class PayOrderServiceImpl implements PayOrderService { private TransactionTemplate transactionTemplate; @Resource - private SnowflakeIdWorker3rd snowflakeIdWorker3rd; + private SnowflakeSerialNoWorker3rd snowflakeSerialNoWorker3rd; @Override @Transactional(rollbackFor = Exception.class) @@ -209,7 +209,7 @@ public class PayOrderServiceImpl implements PayOrderService { PreviouProductDelayRespVO previouProductDelayRespVO = productDelayService.getActiveRecordsByProductId(productId, organId); // 根据购买类型做价格处理 - PayProductProcessor payProductProcessor = new PayProductProcessor(productsDO, productsDetailDO, orgInitialPurchaseRecord, previouProductDelayRespVO, organAmount, organId, payConfig, mybatisIdProperties, snowflakeIdWorker3rd); + PayProductProcessor payProductProcessor = new PayProductProcessor(productsDO, productsDetailDO, orgInitialPurchaseRecord, previouProductDelayRespVO, organAmount, organId, payConfig, mybatisIdProperties, snowflakeSerialNoWorker3rd); ProductProcessorRespVO productProcessorRespVO = payProductProcessor.processPayment(PayProductChannelCodeEnum.fromType(payProductOrderUnifiedReqVO.getProductChannelCode())); PayOrderDO payOrder = productProcessorRespVO.getPayOrderDO(); @@ -622,7 +622,7 @@ public class PayOrderServiceImpl implements PayOrderService { IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) .orderNo(payNo) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .tradeType(TradeTypeEnum.RECHARGE.getCode()) .incomeExpenseType(IncomeExpenseTypeEnum.INCOME.getCode()) .cashAmountChange(price) @@ -757,7 +757,7 @@ public class PayOrderServiceImpl implements PayOrderService { IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) .orderNo(String.valueOf(record.getId())) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .tradeType(TradeTypeEnum.PRODUCT.getCode()) .incomeExpenseType(IncomeExpenseTypeEnum.INCOME.getCode()) .cashAmountChange(accountBalanceSpent) diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayProductProcessor.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayProductProcessor.java index 821eb9198..986635b20 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayProductProcessor.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayProductProcessor.java @@ -8,8 +8,7 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import com.cf.imes.framework.common.exception.ServiceException; import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil; -import com.cf.imes.framework.common.util.date.LocalDateTimeUtils; -import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd; +import com.cf.imes.framework.id.core.util.SnowflakeSerialNoWorker3rd; import com.cf.imes.framework.pay.config.ChenfengPayConfig; import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; import com.cf.imes.module.system.controller.admin.funds.delay.vo.PreviouProductDelayRespVO; @@ -78,7 +77,7 @@ public class PayProductProcessor { private MybatisIdProperties mybatisIdProperties; // id生成器 - private SnowflakeIdWorker3rd snowflakeIdWorker3rd; + private SnowflakeSerialNoWorker3rd snowflakeSerialNoWorker3rd; // 标记本次订购是否首次 private boolean initialized = false; @@ -102,7 +101,7 @@ public class PayProductProcessor { private BigDecimal originalPrice; public PayProductProcessor(ProductsDO productsDO, ProductsDetailDO productsDetailDO, PurchaseRecordDO orgInitialPurchaseRecord, PreviouProductDelayRespVO previouProductDelayRespVO, - OrganAmountDO organAmountDO, Long organId, ChenfengPayConfig payConfig, MybatisIdProperties mybatisIdProperties, SnowflakeIdWorker3rd snowflakeIdWorker3rd) { + OrganAmountDO organAmountDO, Long organId, ChenfengPayConfig payConfig, MybatisIdProperties mybatisIdProperties, SnowflakeSerialNoWorker3rd snowflakeSerialNoWorker3rd) { this.productsDO = productsDO; this.productsDetailDO = productsDetailDO; this.orgInitialPurchaseRecord = orgInitialPurchaseRecord; @@ -117,7 +116,7 @@ public class PayProductProcessor { this.organId = organId; this.payConfig = payConfig; this.mybatisIdProperties = mybatisIdProperties; - this.snowflakeIdWorker3rd = snowflakeIdWorker3rd; + this.snowflakeSerialNoWorker3rd = snowflakeSerialNoWorker3rd; } /** @@ -210,7 +209,7 @@ public class PayProductProcessor { BigDecimal giftAmount = organAmountDO.getGiftAmount(); IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .orderNo(String.format(PayConstants.PAY_PRODUCT_DETAIL_BUSINESSNO_PREFIX_FORMAT, organId, purchaseId)) .purchaseId(purchaseRecordDO.getId()) .tradeType(TradeTypeEnum.PRODUCT.getCode()) @@ -268,7 +267,7 @@ public class PayProductProcessor { BigDecimal amount = organAmountDO.getAmount(); IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .orderNo(String.format(PayConstants.PAY_PRODUCT_DETAIL_BUSINESSNO_PREFIX_FORMAT, organId, purchaseId)) .purchaseId(purchaseRecordDO.getId()) .tradeType(TradeTypeEnum.PRODUCT.getCode()) @@ -421,7 +420,7 @@ public class PayProductProcessor { BigDecimal newGift = gift.subtract(usedGift); IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .orderNo(String.format(PayConstants.PAY_PRODUCT_DETAIL_BUSINESSNO_PREFIX_FORMAT, organId, purchaseId)) .purchaseId(purchaseRecordDO.getId()) .tradeType(TradeTypeEnum.PRODUCT.getCode()) @@ -486,7 +485,7 @@ public class PayProductProcessor { BigDecimal giftAmount = organAmountDO.getGiftAmount(); IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .orderNo(String.format(PayConstants.PAY_PRODUCT_DETAIL_BUSINESSNO_PREFIX_FORMAT, organId, purchaseId)) .purchaseId(purchaseRecordDO.getId()) .tradeType(TradeTypeEnum.PRODUCT.getCode()) @@ -563,7 +562,7 @@ public class PayProductProcessor { BigDecimal amount = organAmountDO.getAmount(); IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .orderNo(String.format(PayConstants.PAY_PRODUCT_DETAIL_BUSINESSNO_PREFIX_FORMAT, organId, purchaseId)) .purchaseId(purchaseId) .tradeType(TradeTypeEnum.PRODUCT.getCode()) @@ -649,7 +648,7 @@ public class PayProductProcessor { BigDecimal newGift = gift.subtract(usedGift); IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder() .organId(organId) - .businessNo(snowflakeIdWorker3rd.nextSerialNo()) + .businessNo(snowflakeSerialNoWorker3rd.nextSerialNo()) .orderNo(String.format(PayConstants.PAY_PRODUCT_DETAIL_BUSINESSNO_PREFIX_FORMAT, organId, purchaseId)) .purchaseId(purchaseId) .tradeType(TradeTypeEnum.PRODUCT.getCode()) diff --git a/cf-module-system/cf-module-system-biz/src/main/resources/mapper/funds/purchase/PurchaseMapper.xml b/cf-module-system/cf-module-system-biz/src/main/resources/mapper/funds/purchase/PurchaseMapper.xml index 100d8c563..0f2fde302 100644 --- a/cf-module-system/cf-module-system-biz/src/main/resources/mapper/funds/purchase/PurchaseMapper.xml +++ b/cf-module-system/cf-module-system-biz/src/main/resources/mapper/funds/purchase/PurchaseMapper.xml @@ -61,6 +61,16 @@ where deleted = false and initial != true; + +