From 1b412546eb9914d28fc394c8cc46f5c38d249a2e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 26 Jul 2025 19:49:50 +0800 Subject: [PATCH 1/8] =?UTF-8?q?fix=EF=BC=9A=E3=80=90Mall=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E3=80=91=E4=BF=AE=E5=A4=8D=E7=A7=AF=E5=88=86=E5=95=86?= =?UTF-8?q?=E5=93=81=E6=96=B0=E5=A2=9E=E6=97=B6=E6=A0=A1=E9=AA=8C=E5=95=86?= =?UTF-8?q?=E5=93=81=E6=98=AF=E5=90=A6=E5=8F=82=E4=B8=8E=E5=85=B6=E4=BB=96?= =?UTF-8?q?=E6=B4=BB=E5=8A=A8=E6=A0=A1=E9=AA=8C=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../promotion/service/point/PointActivityServiceImpl.java | 1 + .../core/client/dto/kd100/Kd100ExpressQueryRespDTO.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java index 582cadb0d4..0b945794ad 100644 --- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java @@ -222,6 +222,7 @@ public class PointActivityServiceImpl implements PointActivityService { if (spu == null) { throw exception(SPU_NOT_EXISTS); } + products.forEach(product -> product.setSpuId(spuId)); // 2. 校验商品 sku 都存在 List skus = productSkuApi.getSkuListBySpuId(singletonList(spuId)); diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java index 0cf5c96caa..d5442cbeeb 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java @@ -2,10 +2,11 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import lombok.Data; import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.List; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; From 77193102a2038fafb71e03ac31e680257c40af75 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 26 Jul 2025 20:08:04 +0800 Subject: [PATCH 2/8] =?UTF-8?q?feat=EF=BC=9A=E6=B7=BB=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E9=80=82=E5=BA=94=E5=88=97=E5=AE=BD=E5=A4=84=E7=90=86=E5=99=A8?= =?UTF-8?q?=E5=B9=B6=E6=9B=BF=E6=8D=A2=E9=BB=98=E8=AE=A4=E5=88=97=E5=AE=BD?= =?UTF-8?q?=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ColumnWidthMatchStyleStrategy.java | 78 +++++++++++++++++++ .../core/handler/SelectSheetWriteHandler.java | 2 +- .../framework/excel/core/util/ExcelUtils.java | 14 ++-- .../yudao/framework/excel/package-info.java | 2 +- 4 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java new file mode 100644 index 0000000000..49a5b31572 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/ColumnWidthMatchStyleStrategy.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.framework.excel.core.handler; + +import cn.hutool.core.collection.CollUtil; +import cn.idev.excel.enums.CellDataTypeEnum; +import cn.idev.excel.metadata.Head; +import cn.idev.excel.metadata.data.WriteCellData; +import cn.idev.excel.util.MapUtils; +import cn.idev.excel.write.metadata.holder.WriteSheetHolder; +import cn.idev.excel.write.style.column.AbstractColumnWidthStyleStrategy; +import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; +import org.apache.poi.ss.usermodel.Cell; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Excel 自适应列宽处理器 + * + * 相比 {@link LongestMatchColumnWidthStyleStrategy} 来说,额外处理了 DATE 类型! + * + * @see 添加自适应列宽处理器,并替换默认列宽策略 + * @author hmb + */ +public class ColumnWidthMatchStyleStrategy extends AbstractColumnWidthStyleStrategy { + + private static final int MAX_COLUMN_WIDTH = 255; + + private final Map> cache = MapUtils.newHashMapWithExpectedSize(8); + + @Override + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, + Head head, Integer relativeRowIndex, Boolean isHead) { + boolean needSetWidth = isHead || CollUtil.isNotEmpty(cellDataList); + if (!needSetWidth) { + return; + } + Map maxColumnWidthMap = cache.computeIfAbsent(writeSheetHolder.getSheetNo(), + key -> new HashMap<>(16)); + Integer columnWidth = dataLength(cellDataList, cell, isHead); + if (columnWidth < 0) { + return; + } + if (columnWidth > MAX_COLUMN_WIDTH) { + columnWidth = MAX_COLUMN_WIDTH; + } + Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex()); + if (maxColumnWidth == null || columnWidth > maxColumnWidth) { + maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth); + writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256); + } + } + + @SuppressWarnings("EnhancedSwitchMigration") + private Integer dataLength(List> cellDataList, Cell cell, Boolean isHead) { + if (isHead) { + return cell.getStringCellValue().getBytes().length; + } + WriteCellData cellData = cellDataList.get(0); + CellDataTypeEnum type = cellData.getType(); + if (type == null) { + return -1; + } + switch (type) { + case STRING: + return cellData.getStringValue().getBytes().length; + case BOOLEAN: + return cellData.getBooleanValue().toString().getBytes().length; + case NUMBER: + return cellData.getNumberValue().toString().getBytes().length; + case DATE: + return cellData.getDateValue().toString().getBytes().length; + default: + return -1; + } + } + +} \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java index cd6c87f68f..c55e1210a2 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java @@ -86,7 +86,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { /** * 判断字段是否是静态的、最终的、 transient 的 - * 原因:EasyExcel 默认是忽略 static final 或 transient 的字段,所以需要判断 + * 原因:FastExcel 默认是忽略 static final 或 transient 的字段,所以需要判断 * * @param field 字段 * @return 是否是静态的、最终的、transient 的 diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java index bae20d6c53..f05d3e51e5 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.framework.excel.core.util; -import cn.iocoder.yudao.framework.common.util.http.HttpUtils; -import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler; -import cn.idev.excel.EasyExcel; +import cn.idev.excel.FastExcelFactory; import cn.idev.excel.converters.longconverter.LongStringConverter; -import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; +import cn.iocoder.yudao.framework.common.util.http.HttpUtils; +import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy; +import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; @@ -32,9 +32,9 @@ public class ExcelUtils { public static void write(HttpServletResponse response, String filename, String sheetName, Class head, List data) throws IOException { // 输出 Excel - EasyExcel.write(response.getOutputStream(), head) + FastExcelFactory.write(response.getOutputStream(), head) .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 - .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度 + .registerWriteHandler(new ColumnWidthMatchStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度 .registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框 .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度 .sheet(sheetName).doWrite(data); @@ -44,7 +44,7 @@ public class ExcelUtils { } public static List read(MultipartFile file, Class head) throws IOException { - return EasyExcel.read(file.getInputStream(), head, null) + return FastExcelFactory.read(file.getInputStream(), head, null) .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 .doReadAllSync(); } diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java index 53bc5c01bf..72c3ac42e1 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/package-info.java @@ -1,4 +1,4 @@ /** - * 基于 EasyExcel 实现 Excel 相关的操作 + * 基于 FastExcel 实现 Excel 相关的操作 */ package cn.iocoder.yudao.framework.excel; From 99442ec05c29b8839dbf796628bad7f72b2b99da Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 26 Jul 2025 21:21:02 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix=EF=BC=9AApiErrorLogServiceImpl=20?= =?UTF-8?q?=E5=9C=A8=E5=BE=AE=E6=9C=8D=E5=8A=A1=E5=9C=BA=E6=99=AF=E4=B8=8B?= =?UTF-8?q?=EF=BC=8C=E8=AE=B0=E5=BD=95=E6=97=A5=E5=BF=97=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=9A=84=E5=BE=AA=E7=8E=AF=E8=B0=83=E7=94=A8=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/logger/ApiErrorLogServiceImpl.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java index e91c098941..536b265f93 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java @@ -40,11 +40,16 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService { ApiErrorLogDO apiErrorLog = BeanUtils.toBean(createDTO, ApiErrorLogDO.class) .setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); apiErrorLog.setRequestParams(StrUtils.maxLength(apiErrorLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH)); - if (TenantContextHolder.getTenantId() != null) { - apiErrorLogMapper.insert(apiErrorLog); - } else { - // 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败! - TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog)); + try { + if (TenantContextHolder.getTenantId() != null) { + apiErrorLogMapper.insert(apiErrorLog); + } else { + // 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败! + TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog)); + } + } catch (Exception ex) { + // 兜底处理,目前只有 yudao-cloud 会发生:https://gitee.com/yudaocode/yudao-cloud-mini/issues/IC1O0A + log.error("[createApiErrorLog][记录时({}) 发生异常]", createDTO, ex); } } From bf5ac4ede2ef8e0ba9736cff74c571d05baad981 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 26 Jul 2025 21:30:16 +0800 Subject: [PATCH 4/8] =?UTF-8?q?feat=EF=BC=9ACacheUtils=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20CACHE=5FMAX=5FSIZE=20=E9=BB=98=E8=AE=A4=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/cache/CacheUtils.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/cache/CacheUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/cache/CacheUtils.java index 12a6e17246..4d9168ebdb 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/cache/CacheUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/cache/CacheUtils.java @@ -14,6 +14,13 @@ import java.util.concurrent.Executors; */ public class CacheUtils { + /** + * 异步刷新的 LoadingCache 最大缓存数量 + * + * @see 本地缓存 CacheUtils 工具类建议 + */ + private static final Integer CACHE_MAX_SIZE = 10000; + /** * 构建异步刷新的 LoadingCache 对象 * @@ -29,6 +36,7 @@ public class CacheUtils { */ public static LoadingCache buildAsyncReloadingCache(Duration duration, CacheLoader loader) { return CacheBuilder.newBuilder() + .maximumSize(CACHE_MAX_SIZE) // 只阻塞当前数据加载线程,其他线程返回旧值 .refreshAfterWrite(duration) // 通过 asyncReloading 实现全异步加载,包括 refreshAfterWrite 被阻塞的加载线程 @@ -43,7 +51,11 @@ public class CacheUtils { * @return LoadingCache 对象 */ public static LoadingCache buildCache(Duration duration, CacheLoader loader) { - return CacheBuilder.newBuilder().refreshAfterWrite(duration).build(loader); + return CacheBuilder.newBuilder() + .maximumSize(CACHE_MAX_SIZE) + // 只阻塞当前数据加载线程,其他线程返回旧值 + .refreshAfterWrite(duration) + .build(loader); } } From 4a8c485b920d024112ba623f578828d8206e577a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 26 Jul 2025 23:06:21 +0800 Subject: [PATCH 5/8] =?UTF-8?q?fix=EF=BC=9A=E3=80=90=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9D=83=E9=99=90=E3=80=91=E5=BC=BA=E5=88=B6=E9=9C=80=E8=A6=81?= =?UTF-8?q?=20PermissionCommonApi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/YudaoDeptDataPermissionAutoConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/YudaoDeptDataPermissionAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/YudaoDeptDataPermissionAutoConfiguration.java index ab5b3bc7ec..46b6ca7c59 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/YudaoDeptDataPermissionAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/config/YudaoDeptDataPermissionAutoConfiguration.java @@ -18,7 +18,7 @@ import java.util.List; */ @AutoConfiguration @ConditionalOnClass(LoginUser.class) -@ConditionalOnBean(value = {PermissionCommonApi.class, DeptDataPermissionRuleCustomizer.class}) +@ConditionalOnBean(value = {DeptDataPermissionRuleCustomizer.class}) public class YudaoDeptDataPermissionAutoConfiguration { @Bean From 47ff2bf9225ae31b89c44e6f5de3415d9fb07820 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 27 Jul 2025 10:11:39 +0800 Subject: [PATCH 6/8] =?UTF-8?q?fix=EF=BC=9AXss=20=E5=BC=80=E5=90=AF?= =?UTF-8?q?=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98=20https:?= =?UTF-8?q?//t.zsxq.com/qq02q?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/xss/config/YudaoXssAutoConfiguration.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/config/YudaoXssAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/config/YudaoXssAutoConfiguration.java index 99b6a448f3..16f87dae1f 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/config/YudaoXssAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/xss/config/YudaoXssAutoConfiguration.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.xss.core.clean.JsoupXssCleaner; import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner; import cn.iocoder.yudao.framework.xss.core.filter.XssFilter; import cn.iocoder.yudao.framework.xss.core.json.XssStringJsonDeserializer; -import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -42,13 +41,13 @@ public class YudaoXssAutoConfiguration implements WebMvcConfigurer { */ @Bean @ConditionalOnMissingBean(name = "xssJacksonCustomizer") - @ConditionalOnBean(ObjectMapper.class) @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true") public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssProperties properties, PathMatcher pathMatcher, XssCleaner xssCleaner) { // 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理 - return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(properties, pathMatcher, xssCleaner)); + return builder -> + builder.deserializerByType(String.class, new XssStringJsonDeserializer(properties, pathMatcher, xssCleaner)); } /** From ae9e35f184614da50f15399c7fe52c5f9413e61b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 27 Jul 2025 11:04:19 +0800 Subject: [PATCH 7/8] =?UTF-8?q?feat=EF=BC=9A=E3=80=90infra=20=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E8=AE=BE=E6=96=BD=E3=80=91=E4=BC=98=E5=8C=96=20vben3?= =?UTF-8?q?=20=E6=A8=A1=E7=89=88=E8=B7=AF=E5=BE=84=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E5=9C=A8=E4=BD=BF=E7=94=A8=20vue3=20=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E8=AF=AF=E8=A7=A3=20https://github.com/yudaocode/yudao-ui-admi?= =?UTF-8?q?n-vben/issues/60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/codegen/inner/CodegenEngine.java | 81 ++++++++++--------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java index b69f0c6254..a0ce062cdc 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java @@ -139,85 +139,85 @@ public class CodegenEngine { vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) // VUE3_VBEN2_ANTD_SCHEMA .put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/data.ts"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/${classNameVar}.data.ts")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${classNameVar}.data.ts")) .put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/index.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/form.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Modal.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Modal.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("api/api.ts"), - vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) + vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts")) // VUE3_VBEN5_ANTD_SCHEMA .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/data.ts"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/data.ts")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/index.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/form.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("api/api.ts"), - vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) + vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) // VUE3_VBEN5_ANTD .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("api/api.ts"), - vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) + vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) // VUE3_VBEN5_EP_SCHEMA .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/data.ts"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/data.ts")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/index.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/form.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("api/api.ts"), - vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) + vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) // VUE3_VBEN5_EP .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/index.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/form.vue"), - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("api/api.ts"), - vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) + vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊:主子表专属逻辑 - vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) + vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) .build(); @Resource @@ -614,6 +614,11 @@ public class CodegenEngine { "src/" + path; } + private static String vue3VbenFilePath(String path) { + return "yudao-ui-${sceneEnum.basePackage}-vben/" + // 顶级目录 + "src/" + path; + } + private static String vue3VbenTemplatePath(String path) { return "codegen/vue3_vben/" + path + ".vm"; } From 8ffe9272e80ec9b07fce6b29d8f041bc5ac7a01b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 27 Jul 2025 19:18:04 +0800 Subject: [PATCH 8/8] =?UTF-8?q?feat=EF=BC=9A=E3=80=90pay=20=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E3=80=91=E5=A2=9E=E5=8A=A0=20userid=E3=80=81usertype?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E9=A2=9D=E5=A4=96=E6=94=AF=E6=8C=81=E6=9D=83?= =?UTF-8?q?=E9=99=90=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../convert/aftersale/AfterSaleConvert.java | 2 +- .../convert/order/TradeOrderConvert.java | 4 ++- .../aftersale/AfterSaleServiceImpl.java | 2 ++ .../BrokerageWithdrawServiceImpl.java | 1 + .../order/TradeOrderUpdateServiceImpl.java | 1 + .../api/order/dto/PayOrderCreateReqDTO.java | 13 +++++++ .../api/refund/dto/PayRefundCreateReqDTO.java | 13 +++++++ .../transfer/dto/PayTransferCreateReqDTO.java | 35 +++++++++++++------ .../admin/demo/PayDemoWithdrawController.java | 3 +- .../app/order/AppPayOrderController.java | 13 +++++-- .../pay/convert/order/PayOrderConvert.java | 5 +-- .../pay/dal/dataobject/order/PayOrderDO.java | 9 +++++ .../dal/dataobject/refund/PayRefundDO.java | 9 +++++ .../dataobject/transfer/PayTransferDO.java | 12 +++++-- .../service/demo/PayDemoOrderServiceImpl.java | 3 ++ .../service/demo/PayDemoWithdrawService.java | 3 +- .../demo/PayDemoWithdrawServiceImpl.java | 4 ++- .../wallet/PayWalletRechargeServiceImpl.java | 4 +-- .../src/test/resources/sql/clean.sql | 1 + .../src/test/resources/sql/create_tables.sql | 33 +++++++++++++++++ 20 files changed, 143 insertions(+), 27 deletions(-) diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleConvert.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleConvert.java index 54480f696b..0e508a4643 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleConvert.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleConvert.java @@ -43,7 +43,7 @@ public interface AfterSaleConvert { @Mapping(source = "afterSale.id", target = "merchantRefundId"), @Mapping(source = "afterSale.applyReason", target = "reason"), @Mapping(source = "afterSale.refundPrice", target = "price"), - @Mapping(source = "orderProperties.payAppKey", target = "appKey") + @Mapping(source = "orderProperties.payAppKey", target = "appKey"), }) PayRefundCreateReqDTO convert(String userIp, AfterSaleDO afterSale, TradeOrderProperties orderProperties); diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index fa0b9c8163..beacddab87 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.convert.order; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.string.StrUtils; @@ -101,7 +102,8 @@ public interface TradeOrderConvert { default PayOrderCreateReqDTO convert(TradeOrderDO order, List orderItems, TradeOrderProperties orderProperties) { PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() - .setAppKey(orderProperties.getPayAppKey()).setUserIp(order.getUserIp()); + .setAppKey(orderProperties.getPayAppKey()).setUserIp(order.getUserIp()) + .setUserId(order.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()); // 商户相关字段 createReqDTO.setMerchantOrderId(String.valueOf(order.getId())); String subject = orderItems.get(0).getSpuName(); diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java index f0c63a032d..7be62fc78d 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; @@ -362,6 +363,7 @@ public class AfterSaleServiceImpl implements AfterSaleService { private void createPayRefund(String userIp, AfterSaleDO afterSale) { // 创建退款单 PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) + .setUserId(afterSale.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); Long payRefundId = payRefundApi.createRefund(createReqDTO); diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index a873927f6c..fcadac827a 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -151,6 +151,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { .setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode) .setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice()) .setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP()) + .setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息 .setChannelExtras(channelExtras); // 1.3 发起请求 PayTransferCreateRespDTO transferRespDTO = payTransferApi.createTransfer(transferReqDTO); diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index bafe56c5be..690f3de52c 100644 --- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -952,6 +952,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { payRefundApi.createRefund(new PayRefundCreateReqDTO() .setAppKey(tradeOrderProperties.getPayAppKey()) // 支付应用 .setUserIp(NetUtil.getLocalhostStr()) // 使用本机 IP,因为是服务器发起退款的 + .setUserId(order.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 // 特殊:因为订单支持 AfterSale 单个售后退款,也支持整单退款,所以需要通过 order- 进行下区分 // 具体可见 AfterSaleController 的 updateAfterSaleRefunded 方法 diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java index 3a7b181be3..a2f035cddd 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.pay.api.order.dto; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; @@ -22,12 +24,23 @@ public class PayOrderCreateReqDTO implements Serializable { */ @NotNull(message = "应用标识不能为空") private String appKey; + /** * 用户 IP */ @NotEmpty(message = "用户 IP 不能为空") private String userIp; + /** + * 用户编号 + */ + private Long userId; + /** + * 用户类型 + */ + @InEnum(UserTypeEnum.class) + private Integer userType; + // ========== 商户相关字段 ========== /** diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundCreateReqDTO.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundCreateReqDTO.java index 6910fc2fe5..cc1743be64 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundCreateReqDTO.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundCreateReqDTO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.pay.api.refund.dto; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; @@ -19,12 +21,23 @@ public class PayRefundCreateReqDTO { */ @NotNull(message = "应用标识不能为空") private String appKey; + /** * 用户 IP */ @NotEmpty(message = "用户 IP 不能为空") private String userIp; + /** + * 用户编号 + */ + private Long userId; + /** + * 用户类型 + */ + @InEnum(UserTypeEnum.class) + private Integer userType; + // ========== 商户相关字段 ========== /** * 商户订单编号 diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java index 1ac5c04af6..86dd70cce5 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.pay.api.transfer.dto; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.common.validation.InEnum; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; @@ -26,23 +28,23 @@ public class PayTransferCreateReqDTO { @NotNull(message = "应用标识不能为空") private String appKey; - /** - * 转账渠道 - */ - @NotEmpty(message = "转账渠道不能为空") - private String channelCode; - - /** - * 转账渠道的额外参数 - */ - private Map channelExtras; - /** * 用户 IP */ @NotEmpty(message = "用户 IP 不能为空") private String userIp; + /** + * 用户编号 + */ + private Long userId; + /** + * 用户类型 + */ + @InEnum(UserTypeEnum.class) + private Integer userType; + + // ========== 商户相关字段 ========== /** * 商户转账单编号 */ @@ -75,6 +77,17 @@ public class PayTransferCreateReqDTO { */ private String userName; + /** + * 转账渠道 + */ + @NotEmpty(message = "转账渠道不能为空") + private String channelCode; + + /** + * 转账渠道的额外参数 + */ + private Map channelExtras; + /** * 【微信】现金营销场景 * diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java index 033bc95d79..ef5e4a8a9c 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java @@ -19,6 +19,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - 示例提现订单") // 目的:演示转账功能 @RestController @@ -40,7 +41,7 @@ public class PayDemoWithdrawController { @Operation(summary = "提现单转账") @Parameter(name = "id", required = true, description = "提现单编号", example = "1024") public CommonResult transferDemoWithdraw(@RequestParam("id") Long id) { - Long payTransferId = demoWithdrawService.transferDemoWithdraw(id); + Long payTransferId = demoWithdrawService.transferDemoWithdraw(id, getLoginUserId()); return success(payTransferId); } diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java index 88eeb0960a..4f57163841 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java @@ -1,12 +1,12 @@ package cn.iocoder.yudao.module.pay.controller.app.order; +import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO; import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; -import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.enums.PayChannelEnum; @@ -52,6 +52,15 @@ public class AppPayOrderController { public CommonResult getOrder(@RequestParam("id") Long id, @RequestParam(value = "sync", required = false) Boolean sync) { PayOrderDO order = payOrderService.getOrder(id); + if (order== null) { + return success(null); + } + // 重要:校验订单是否是当前用户,避免越权 + if (order.getUserId() != null // 特殊:早期订单未存储 userId,所以忽略 + && ObjUtil.notEqual(order.getUserId(), getLoginUserId())) { + return success(null); + } + // sync 仅在等待支付 if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) { payOrderService.syncOrderQuietly(order.getId()); @@ -75,7 +84,7 @@ public class AppPayOrderController { // 2. 提交支付 PayOrderSubmitRespVO respVO = payOrderService.submitOrder(reqVO, getClientIP()); - return success(PayOrderConvert.INSTANCE.convert3(respVO)); + return success(BeanUtils.toBean(respVO, AppPayOrderSubmitRespVO.class)); } } diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java index 8321de32ce..1813e2c2d7 100755 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java @@ -3,14 +3,13 @@ package cn.iocoder.yudao.module.pay.convert.order; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; -import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @@ -69,6 +68,4 @@ public interface PayOrderConvert { @Mapping(source = "order.status", target = "status") PayOrderSubmitRespVO convert(PayOrderDO order, cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderRespDTO respDTO); - AppPayOrderSubmitRespVO convert3(PayOrderSubmitRespVO bean); - } diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java index ac0ef34f2e..4eea1cc4ef 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java @@ -49,6 +49,15 @@ public class PayOrderDO extends BaseDO { */ private String channelCode; + /** + * 用户编号 + */ + private Long userId; + /** + * 用户类型 + */ + private Integer userType; + // ========== 商户相关字段 ========== /** diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java index 607483f91a..0804926820 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java @@ -77,6 +77,15 @@ public class PayRefundDO extends BaseDO { */ private String orderNo; + /** + * 用户编号 + */ + private Long userId; + /** + * 用户类型 + */ + private Integer userType; + // ========== 商户相关字段 ========== /** * 商户订单编号 diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java index 94f8521dbd..d0f3a80211 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java @@ -30,7 +30,6 @@ public class PayTransferDO extends BaseDO { */ @TableId private Long id; - /** * 转账单号 */ @@ -42,14 +41,12 @@ public class PayTransferDO extends BaseDO { * 关联 {@link PayAppDO#getId()} */ private Long appId; - /** * 转账渠道编号 * * 关联 {@link PayChannelDO#getId()} */ private Long channelId; - /** * 转账渠道编码 * @@ -57,6 +54,15 @@ public class PayTransferDO extends BaseDO { */ private String channelCode; + /** + * 用户编号 + */ + private Long userId; + /** + * 用户类型 + */ + private Integer userType; + // ========== 商户相关字段 ========== /** * 商户转账单编号 diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java index 76571f355c..ac756f5763 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.service.demo; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; @@ -90,6 +91,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { // 2.1 创建支付单 Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO() .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 + .setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息 .setMerchantOrderId(demoOrder.getId().toString()) // 业务的订单编号 .setSubject(spuName).setBody("").setPrice(price) // 价格信息 .setExpireTime(addTime(Duration.ofHours(2L)))); // 支付的过期时间 @@ -189,6 +191,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { // 2.2 创建退款单 Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() .setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用 + .setUserId(order.getUserId()).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号 .setMerchantRefundId(refundId) .setReason("想退钱").setPrice(order.getPrice()));// 价格信息 diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java index e8a5980ad8..6b55810257 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java @@ -26,9 +26,10 @@ public interface PayDemoWithdrawService { * 提现单转账 * * @param id 提现单编号 + * @param userId 用户编号 * @return 转账编号 */ - Long transferDemoWithdraw(Long id); + Long transferDemoWithdraw(Long id, Long userId); /** * 获得示例提现单分页 diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java index b1a3b91516..dddbceea0f 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.service.demo; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; @@ -60,7 +61,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService { } @Override - public Long transferDemoWithdraw(Long id) { + public Long transferDemoWithdraw(Long id, Long userId) { // 1.1 校验提现单 PayDemoWithdrawDO withdraw = validateDemoWithdrawCanTransfer(id); // 1.2 特殊:如果是转账失败的情况,需要充值下 @@ -76,6 +77,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService { // 2.1 创建支付单 PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO() .setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用 + .setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息 .setMerchantTransferId(String.valueOf(withdraw.getId())) // 业务的订单编号 .setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息 .setUserAccount(withdraw.getUserAccount()).setUserName(withdraw.getUserName()); // 收款信息 diff --git a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java index f1253f4765..95539b28d5 100644 --- a/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java +++ b/yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java @@ -64,8 +64,6 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { private PayWalletService payWalletService; @Resource private PayOrderService payOrderService; -// @Resource -// private PayRefundService payRefundService; @Resource private PayWalletRechargePackageService payWalletRechargePackageService; @@ -99,6 +97,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { // 2.1 创建支付单 Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp) + .setUserId(userId).setUserType(userType) // 用户信息 .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号 .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("") .setPrice(recharge.getPayPrice()) @@ -209,6 +208,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { String refundId = walletRechargeId + "-refund"; Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO() .setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp) + .setUserId(wallet.getUserId()).setUserType(wallet.getUserType()) // 用户信息 .setMerchantOrderId(walletRechargeId) .setMerchantRefundId(refundId) .setReason("想退钱").setPrice(walletRecharge.getPayPrice())); diff --git a/yudao-module-pay/src/test/resources/sql/clean.sql b/yudao-module-pay/src/test/resources/sql/clean.sql index 91fff0caee..e7bf56bfa4 100644 --- a/yudao-module-pay/src/test/resources/sql/clean.sql +++ b/yudao-module-pay/src/test/resources/sql/clean.sql @@ -3,5 +3,6 @@ DELETE FROM pay_channel; DELETE FROM pay_order; DELETE FROM pay_order_extension; DELETE FROM pay_refund; +DELETE FROM pay_transfer; DELETE FROM pay_notify_task; DELETE FROM pay_notify_log; diff --git a/yudao-module-pay/src/test/resources/sql/create_tables.sql b/yudao-module-pay/src/test/resources/sql/create_tables.sql index 3f9f764179..6af612f018 100644 --- a/yudao-module-pay/src/test/resources/sql/create_tables.sql +++ b/yudao-module-pay/src/test/resources/sql/create_tables.sql @@ -45,6 +45,8 @@ CREATE TABLE IF NOT EXISTS `pay_order` ( `channel_fee_price` bigint(20) DEFAULT 0, `status` tinyint(4) NOT NULL, `user_ip` varchar(50) NOT NULL, + `user_id` bigint(20) DEFAULT NULL, + `user_type` tinyint(4) DEFAULT NULL, `expire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `success_time` datetime(0) DEFAULT CURRENT_TIMESTAMP, `notify_time` datetime(0) DEFAULT CURRENT_TIMESTAMP, @@ -97,6 +99,8 @@ CREATE TABLE IF NOT EXISTS `pay_refund` ( `refund_price` bigint(20) NOT NULL, `reason` varchar(256) NOT NULL, `user_ip` varchar(50) NULL DEFAULT NULL, + `user_id` bigint(20) NULL DEFAULT NULL, + `user_type` tinyint(4) NULL DEFAULT NULL, `channel_order_no` varchar(64) NOT NULL, `channel_refund_no` varchar(64) NULL DEFAULT NULL, `success_time` datetime(0) NULL DEFAULT NULL, @@ -145,3 +149,32 @@ CREATE TABLE IF NOT EXISTS `pay_notify_log` ( `deleted` bit(1) NOT NULL DEFAULT FALSE, PRIMARY KEY ("id") ) COMMENT = '支付通知日志'; + +CREATE TABLE IF NOT EXISTS `pay_transfer` ( + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, + `no` varchar(64) NOT NULL, + `app_id` bigint(20) NOT NULL, + `channel_id` bigint(20) NOT NULL, + `channel_code` varchar(32) NOT NULL, + `user_id` bigint(20) NULL DEFAULT NULL, + `user_type` tinyint(4) NULL DEFAULT NULL, + `merchant_transfer_id` varchar(64) NOT NULL, + `price` bigint(20) NOT NULL, + `subject` varchar(256) NOT NULL, + `user_account` varchar(256) NOT NULL, + `user_name` varchar(64) NULL DEFAULT NULL, + `status` tinyint(4) NOT NULL, + `notify_url` varchar(1024) NULL DEFAULT NULL, + `channel_transfer_no` varchar(64) NULL DEFAULT NULL, + `success_time` datetime(0) NULL DEFAULT NULL, + `channel_error_code` varchar(128) NULL DEFAULT NULL, + `channel_error_msg` varchar(256) NULL DEFAULT NULL, + `channel_notify_data` varchar(1024) NULL DEFAULT NULL, + `channel_extras` varchar(1024) NULL DEFAULT NULL, + `creator` varchar(64) NULL DEFAULT '', + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updater` varchar(64) NULL DEFAULT '', + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `deleted` bit(1) NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT = '转账单';