Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/yudao-cloud
# Conflicts: # yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java # yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundCreateReqDTO.java # yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.javapull/150/MERGE
commit
e909c1bdf6
|
@ -14,6 +14,13 @@ import java.util.concurrent.Executors;
|
||||||
*/
|
*/
|
||||||
public class CacheUtils {
|
public class CacheUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步刷新的 LoadingCache 最大缓存数量
|
||||||
|
*
|
||||||
|
* @see <a href="">本地缓存 CacheUtils 工具类建议</a>
|
||||||
|
*/
|
||||||
|
private static final Integer CACHE_MAX_SIZE = 10000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建异步刷新的 LoadingCache 对象
|
* 构建异步刷新的 LoadingCache 对象
|
||||||
*
|
*
|
||||||
|
@ -29,6 +36,7 @@ public class CacheUtils {
|
||||||
*/
|
*/
|
||||||
public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) {
|
public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) {
|
||||||
return CacheBuilder.newBuilder()
|
return CacheBuilder.newBuilder()
|
||||||
|
.maximumSize(CACHE_MAX_SIZE)
|
||||||
// 只阻塞当前数据加载线程,其他线程返回旧值
|
// 只阻塞当前数据加载线程,其他线程返回旧值
|
||||||
.refreshAfterWrite(duration)
|
.refreshAfterWrite(duration)
|
||||||
// 通过 asyncReloading 实现全异步加载,包括 refreshAfterWrite 被阻塞的加载线程
|
// 通过 asyncReloading 实现全异步加载,包括 refreshAfterWrite 被阻塞的加载线程
|
||||||
|
@ -43,7 +51,11 @@ public class CacheUtils {
|
||||||
* @return LoadingCache 对象
|
* @return LoadingCache 对象
|
||||||
*/
|
*/
|
||||||
public static <K, V> LoadingCache<K, V> buildCache(Duration duration, CacheLoader<K, V> loader) {
|
public static <K, V> LoadingCache<K, V> buildCache(Duration duration, CacheLoader<K, V> loader) {
|
||||||
return CacheBuilder.newBuilder().refreshAfterWrite(duration).build(loader);
|
return CacheBuilder.newBuilder()
|
||||||
|
.maximumSize(CACHE_MAX_SIZE)
|
||||||
|
// 只阻塞当前数据加载线程,其他线程返回旧值
|
||||||
|
.refreshAfterWrite(duration)
|
||||||
|
.build(loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
@ConditionalOnClass(LoginUser.class)
|
@ConditionalOnClass(LoginUser.class)
|
||||||
@ConditionalOnBean(value = {PermissionCommonApi.class, DeptDataPermissionRuleCustomizer.class})
|
@ConditionalOnBean(value = {DeptDataPermissionRuleCustomizer.class})
|
||||||
public class YudaoDeptDataPermissionAutoConfiguration {
|
public class YudaoDeptDataPermissionAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
@ -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 <a href="https://github.com/YunaiV/yudao-cloud/pull/196/">添加自适应列宽处理器,并替换默认列宽策略</a>
|
||||||
|
* @author hmb
|
||||||
|
*/
|
||||||
|
public class ColumnWidthMatchStyleStrategy extends AbstractColumnWidthStyleStrategy {
|
||||||
|
|
||||||
|
private static final int MAX_COLUMN_WIDTH = 255;
|
||||||
|
|
||||||
|
private final Map<Integer, Map<Integer, Integer>> cache = MapUtils.newHashMapWithExpectedSize(8);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell,
|
||||||
|
Head head, Integer relativeRowIndex, Boolean isHead) {
|
||||||
|
boolean needSetWidth = isHead || CollUtil.isNotEmpty(cellDataList);
|
||||||
|
if (!needSetWidth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Integer, Integer> 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<WriteCellData<?>> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import cn.idev.excel.FastExcelFactory;
|
||||||
import cn.idev.excel.converters.longconverter.LongStringConverter;
|
import cn.idev.excel.converters.longconverter.LongStringConverter;
|
||||||
import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
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 cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ public class ExcelUtils {
|
||||||
// 输出 Excel
|
// 输出 Excel
|
||||||
FastExcelFactory.write(response.getOutputStream(), head)
|
FastExcelFactory.write(response.getOutputStream(), head)
|
||||||
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
|
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
|
||||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
|
.registerWriteHandler(new ColumnWidthMatchStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
|
||||||
.registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框
|
.registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框
|
||||||
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
|
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
|
||||||
.sheet(sheetName).doWrite(data);
|
.sheet(sheetName).doWrite(data);
|
||||||
|
|
|
@ -42,13 +42,13 @@ public class YudaoXssAutoConfiguration implements WebMvcConfigurer {
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(name = "xssJacksonCustomizer")
|
@ConditionalOnMissingBean(name = "xssJacksonCustomizer")
|
||||||
@ConditionalOnBean(ObjectMapper.class)
|
|
||||||
@ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
|
@ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
|
||||||
public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssProperties properties,
|
public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssProperties properties,
|
||||||
PathMatcher pathMatcher,
|
PathMatcher pathMatcher,
|
||||||
XssCleaner xssCleaner) {
|
XssCleaner xssCleaner) {
|
||||||
// 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理
|
// 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理
|
||||||
return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(properties, pathMatcher, xssCleaner));
|
return builder ->
|
||||||
|
builder.deserializerByType(String.class, new XssStringJsonDeserializer(properties, pathMatcher, xssCleaner));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,4 +3,5 @@ cn.iocoder.yudao.framework.jackson.config.YudaoJacksonAutoConfiguration
|
||||||
cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration
|
cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration
|
||||||
cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration
|
cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration
|
||||||
cn.iocoder.yudao.framework.apilog.config.YudaoApiLogRpcAutoConfiguration
|
cn.iocoder.yudao.framework.apilog.config.YudaoApiLogRpcAutoConfiguration
|
||||||
|
cn.iocoder.yudao.framework.xss.config.YudaoXssAutoConfiguration
|
||||||
cn.iocoder.yudao.framework.banner.config.YudaoBannerAutoConfiguration
|
cn.iocoder.yudao.framework.banner.config.YudaoBannerAutoConfiguration
|
|
@ -74,6 +74,12 @@
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<!-- 必须引入,否则会有 https://gitee.com/yudaocode/yudao-cloud-mini/issues/IB5PXW 告警 -->
|
||||||
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ public class AccessLogFilter implements GlobalFilter, Ordered {
|
||||||
// TODO 芋艿:暂未实现
|
// TODO 芋艿:暂未实现
|
||||||
|
|
||||||
// 方式三:打印到控制台,方便排查错误
|
// 方式三:打印到控制台,方便排查错误
|
||||||
|
try {
|
||||||
Map<String, Object> values = MapUtil.newHashMap(15, true); // 手工拼接,保证排序;15 保证不用扩容
|
Map<String, Object> values = MapUtil.newHashMap(15, true); // 手工拼接,保证排序;15 保证不用扩容
|
||||||
values.put("userId", gatewayLog.getUserId());
|
values.put("userId", gatewayLog.getUserId());
|
||||||
values.put("userType", gatewayLog.getUserType());
|
values.put("userType", gatewayLog.getUserType());
|
||||||
|
@ -94,6 +95,10 @@ public class AccessLogFilter implements GlobalFilter, Ordered {
|
||||||
values.put("endTime", LocalDateTimeUtil.format(gatewayLog.getEndTime(), NORM_DATETIME_MS_FORMATTER));
|
values.put("endTime", LocalDateTimeUtil.format(gatewayLog.getEndTime(), NORM_DATETIME_MS_FORMATTER));
|
||||||
values.put("duration", gatewayLog.getDuration() != null ? gatewayLog.getDuration() + " ms" : null);
|
values.put("duration", gatewayLog.getDuration() != null ? gatewayLog.getDuration() + " ms" : null);
|
||||||
log.info("[writeAccessLog][网关日志:{}]", JsonUtils.toJsonPrettyString(values));
|
log.info("[writeAccessLog][网关日志:{}]", JsonUtils.toJsonPrettyString(values));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 兜底处理,参见 https://gitee.com/zhijiantianya/yudao-cloud/issues/IC9A70
|
||||||
|
log.error("[writeAccessLog][打印网关日志时,发生异常]", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -139,85 +139,85 @@ public class CodegenEngine {
|
||||||
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||||
// VUE3_VBEN2_ANTD_SCHEMA
|
// VUE3_VBEN2_ANTD_SCHEMA
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/data.ts"),
|
.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"),
|
.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"),
|
.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"),
|
.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
|
// VUE3_VBEN5_ANTD_SCHEMA
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/data.ts"),
|
.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"),
|
.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"),
|
.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"),
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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
|
// VUE3_VBEN5_ANTD
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"),
|
.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"),
|
.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"),
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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
|
// VUE3_VBEN5_EP_SCHEMA
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/data.ts"),
|
.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"),
|
.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"),
|
.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"),
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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
|
// VUE3_VBEN5_EP
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/index.vue"),
|
.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"),
|
.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"),
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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"), // 特殊:主子表专属逻辑
|
.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();
|
.build();
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -614,6 +614,11 @@ public class CodegenEngine {
|
||||||
"src/" + path;
|
"src/" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String vue3VbenFilePath(String path) {
|
||||||
|
return "yudao-ui-${sceneEnum.basePackage}-vben/" + // 顶级目录
|
||||||
|
"src/" + path;
|
||||||
|
}
|
||||||
|
|
||||||
private static String vue3VbenTemplatePath(String path) {
|
private static String vue3VbenTemplatePath(String path) {
|
||||||
return "codegen/vue3_vben/" + path + ".vm";
|
return "codegen/vue3_vben/" + path + ".vm";
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,17 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService {
|
||||||
ApiErrorLogDO apiErrorLog = BeanUtils.toBean(createDTO, ApiErrorLogDO.class)
|
ApiErrorLogDO apiErrorLog = BeanUtils.toBean(createDTO, ApiErrorLogDO.class)
|
||||||
.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus());
|
.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus());
|
||||||
apiErrorLog.setRequestParams(StrUtils.maxLength(apiErrorLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH));
|
apiErrorLog.setRequestParams(StrUtils.maxLength(apiErrorLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH));
|
||||||
|
try {
|
||||||
if (TenantContextHolder.getTenantId() != null) {
|
if (TenantContextHolder.getTenantId() != null) {
|
||||||
apiErrorLogMapper.insert(apiErrorLog);
|
apiErrorLogMapper.insert(apiErrorLog);
|
||||||
} else {
|
} else {
|
||||||
// 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败!
|
// 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败!
|
||||||
TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog));
|
TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog));
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
// 兜底处理,目前只有 yudao-cloud 会发生:https://gitee.com/yudaocode/yudao-cloud-mini/issues/IC1O0A
|
||||||
|
log.error("[createApiErrorLog][记录时({}) 发生异常]", createDTO, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -222,6 +222,7 @@ public class PointActivityServiceImpl implements PointActivityService {
|
||||||
if (spu == null) {
|
if (spu == null) {
|
||||||
throw exception(SPU_NOT_EXISTS);
|
throw exception(SPU_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
products.forEach(product -> product.setSpuId(spuId));
|
||||||
|
|
||||||
// 2. 校验商品 sku 都存在
|
// 2. 校验商品 sku 都存在
|
||||||
List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(singletonList(spuId)).getCheckedData();
|
List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(singletonList(spuId)).getCheckedData();
|
||||||
|
|
|
@ -43,7 +43,7 @@ public interface AfterSaleConvert {
|
||||||
@Mapping(source = "afterSale.id", target = "merchantRefundId"),
|
@Mapping(source = "afterSale.id", target = "merchantRefundId"),
|
||||||
@Mapping(source = "afterSale.applyReason", target = "reason"),
|
@Mapping(source = "afterSale.applyReason", target = "reason"),
|
||||||
@Mapping(source = "afterSale.refundPrice", target = "price"),
|
@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);
|
PayRefundCreateReqDTO convert(String userIp, AfterSaleDO afterSale, TradeOrderProperties orderProperties);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.convert.order;
|
||||||
|
|
||||||
import cn.hutool.core.util.BooleanUtil;
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
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.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
|
@ -101,7 +102,8 @@ public interface TradeOrderConvert {
|
||||||
default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
|
default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
|
||||||
TradeOrderProperties orderProperties) {
|
TradeOrderProperties orderProperties) {
|
||||||
PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO()
|
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()));
|
createReqDTO.setMerchantOrderId(String.valueOf(order.getId()));
|
||||||
String subject = orderItems.get(0).getSpuName();
|
String subject = orderItems.get(0).getSpuName();
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
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.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||||
import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
|
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) {
|
private void createPayRefund(String userIp, AfterSaleDO afterSale) {
|
||||||
// 创建退款单
|
// 创建退款单
|
||||||
PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties)
|
PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties)
|
||||||
|
.setUserId(afterSale.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue())
|
||||||
.setReason(StrUtil.format("退款【{}】", afterSale.getSpuName()));
|
.setReason(StrUtil.format("退款【{}】", afterSale.getSpuName()));
|
||||||
Long payRefundId = payRefundApi.createRefund(createReqDTO).getCheckedData();
|
Long payRefundId = payRefundApi.createRefund(createReqDTO).getCheckedData();
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
.setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode)
|
.setAppKey(tradeOrderProperties.getPayAppKey()).setChannelCode(channelCode)
|
||||||
.setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice())
|
.setMerchantTransferId(withdraw.getId().toString()).setSubject("佣金提现").setPrice(withdraw.getPrice())
|
||||||
.setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP())
|
.setUserAccount(userAccount).setUserName(userName).setUserIp(getClientIP())
|
||||||
|
.setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息
|
||||||
.setChannelExtras(channelExtras);
|
.setChannelExtras(channelExtras);
|
||||||
// 1.3 发起请求
|
// 1.3 发起请求
|
||||||
PayTransferCreateRespDTO transferRespDTO = payTransferApi.createTransfer(transferReqDTO).getCheckedData();
|
PayTransferCreateRespDTO transferRespDTO = payTransferApi.createTransfer(transferReqDTO).getCheckedData();
|
||||||
|
|
|
@ -427,7 +427,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
.addMessage("phrase6", TradeOrderStatusEnum.DELIVERED.getName()) // 订单状态
|
.addMessage("phrase6", TradeOrderStatusEnum.DELIVERED.getName()) // 订单状态
|
||||||
.addMessage("date4", LocalDateTimeUtil.formatNormal(LocalDateTime.now()))// 发货时间
|
.addMessage("date4", LocalDateTimeUtil.formatNormal(LocalDateTime.now()))// 发货时间
|
||||||
.addMessage("character_string5", StrUtil.blankToDefault(deliveryReqVO.getLogisticsNo(), "-")) // 快递单号
|
.addMessage("character_string5", StrUtil.blankToDefault(deliveryReqVO.getLogisticsNo(), "-")) // 快递单号
|
||||||
.addMessage("thing9", order.getReceiverDetailAddress())).checkError(); // 收货地址
|
.addMessage("thing9", order.getReceiverDetailAddress())); // 收货地址
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -729,7 +729,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
tradeOrderItemMapper.updateBatch(updateItems);
|
tradeOrderItemMapper.updateBatch(updateItems);
|
||||||
|
|
||||||
// 4. 更新支付订单
|
// 4. 更新支付订单
|
||||||
payOrderApi.updatePayOrderPrice(order.getPayOrderId(), newPayPrice).checkError();
|
payOrderApi.updatePayOrderPrice(order.getPayOrderId(), newPayPrice);
|
||||||
|
|
||||||
// 5. 记录订单日志
|
// 5. 记录订单日志
|
||||||
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus(),
|
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus(),
|
||||||
|
@ -952,11 +952,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
payRefundApi.createRefund(new PayRefundCreateReqDTO()
|
payRefundApi.createRefund(new PayRefundCreateReqDTO()
|
||||||
.setAppKey(tradeOrderProperties.getPayAppKey()) // 支付应用
|
.setAppKey(tradeOrderProperties.getPayAppKey()) // 支付应用
|
||||||
.setUserIp(NetUtil.getLocalhostStr()) // 使用本机 IP,因为是服务器发起退款的
|
.setUserIp(NetUtil.getLocalhostStr()) // 使用本机 IP,因为是服务器发起退款的
|
||||||
|
.setUserId(order.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) // 用户信息
|
||||||
.setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
|
.setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
|
||||||
// 特殊:因为订单支持 AfterSale 单个售后退款,也支持整单退款,所以需要通过 order- 进行下区分
|
// 特殊:因为订单支持 AfterSale 单个售后退款,也支持整单退款,所以需要通过 order- 进行下区分
|
||||||
// 具体可见 AfterSaleController 的 updateAfterSaleRefunded 方法
|
// 具体可见 AfterSaleController 的 updateAfterSaleRefunded 方法
|
||||||
.setMerchantRefundId("order-" + order.getId())
|
.setMerchantRefundId("order-" + order.getId())
|
||||||
.setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice())).checkError(); // 价格信息
|
.setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice())); // 价格信息
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package cn.iocoder.yudao.module.pay.api.order.dto;
|
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;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
import javax.validation.constraints.DecimalMin;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@ -22,12 +24,23 @@ public class PayOrderCreateReqDTO implements Serializable {
|
||||||
*/
|
*/
|
||||||
@NotNull(message = "应用标识不能为空")
|
@NotNull(message = "应用标识不能为空")
|
||||||
private String appKey;
|
private String appKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户 IP
|
* 用户 IP
|
||||||
*/
|
*/
|
||||||
@NotEmpty(message = "用户 IP 不能为空")
|
@NotEmpty(message = "用户 IP 不能为空")
|
||||||
private String userIp;
|
private String userIp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 用户类型
|
||||||
|
*/
|
||||||
|
@InEnum(UserTypeEnum.class)
|
||||||
|
private Integer userType;
|
||||||
|
|
||||||
// ========== 商户相关字段 ==========
|
// ========== 商户相关字段 ==========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package cn.iocoder.yudao.module.pay.api.refund.dto;
|
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;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
import javax.validation.constraints.Min;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退款单创建 Request DTO
|
* 退款单创建 Request DTO
|
||||||
*
|
*
|
||||||
|
@ -20,12 +21,23 @@ public class PayRefundCreateReqDTO {
|
||||||
*/
|
*/
|
||||||
@NotNull(message = "应用标识不能为空")
|
@NotNull(message = "应用标识不能为空")
|
||||||
private String appKey;
|
private String appKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户 IP
|
* 用户 IP
|
||||||
*/
|
*/
|
||||||
@NotEmpty(message = "用户 IP 不能为空")
|
@NotEmpty(message = "用户 IP 不能为空")
|
||||||
private String userIp;
|
private String userIp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 用户类型
|
||||||
|
*/
|
||||||
|
@InEnum(UserTypeEnum.class)
|
||||||
|
private Integer userType;
|
||||||
|
|
||||||
// ========== 商户相关字段 ==========
|
// ========== 商户相关字段 ==========
|
||||||
/**
|
/**
|
||||||
* 商户订单编号
|
* 商户订单编号
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.pay.api.transfer.dto;
|
package cn.iocoder.yudao.module.pay.api.transfer.dto;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
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.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;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.Min;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -26,23 +28,23 @@ public class PayTransferCreateReqDTO {
|
||||||
@NotNull(message = "应用标识不能为空")
|
@NotNull(message = "应用标识不能为空")
|
||||||
private String appKey;
|
private String appKey;
|
||||||
|
|
||||||
/**
|
|
||||||
* 转账渠道
|
|
||||||
*/
|
|
||||||
@NotEmpty(message = "转账渠道不能为空")
|
|
||||||
private String channelCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转账渠道的额外参数
|
|
||||||
*/
|
|
||||||
private Map<String, String> channelExtras;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户 IP
|
* 用户 IP
|
||||||
*/
|
*/
|
||||||
@NotEmpty(message = "用户 IP 不能为空")
|
@NotEmpty(message = "用户 IP 不能为空")
|
||||||
private String userIp;
|
private String userIp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 用户类型
|
||||||
|
*/
|
||||||
|
@InEnum(UserTypeEnum.class)
|
||||||
|
private Integer userType;
|
||||||
|
|
||||||
|
// ========== 商户相关字段 ==========
|
||||||
/**
|
/**
|
||||||
* 商户转账单编号
|
* 商户转账单编号
|
||||||
*/
|
*/
|
||||||
|
@ -75,6 +77,17 @@ public class PayTransferCreateReqDTO {
|
||||||
*/
|
*/
|
||||||
private String userName;
|
private String userName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账渠道
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "转账渠道不能为空")
|
||||||
|
private String channelCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账渠道的额外参数
|
||||||
|
*/
|
||||||
|
private Map<String, String> channelExtras;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【微信】现金营销场景
|
* 【微信】现金营销场景
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,6 +20,7 @@ import javax.annotation.security.PermitAll;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
|
|
||||||
@Tag(name = "管理后台 - 示例提现订单") // 目的:演示转账功能
|
@Tag(name = "管理后台 - 示例提现订单") // 目的:演示转账功能
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -41,7 +42,7 @@ public class PayDemoWithdrawController {
|
||||||
@Operation(summary = "提现单转账")
|
@Operation(summary = "提现单转账")
|
||||||
@Parameter(name = "id", required = true, description = "提现单编号", example = "1024")
|
@Parameter(name = "id", required = true, description = "提现单编号", example = "1024")
|
||||||
public CommonResult<Long> transferDemoWithdraw(@RequestParam("id") Long id) {
|
public CommonResult<Long> transferDemoWithdraw(@RequestParam("id") Long id) {
|
||||||
Long payTransferId = demoWithdrawService.transferDemoWithdraw(id);
|
Long payTransferId = demoWithdrawService.transferDemoWithdraw(id, getLoginUserId());
|
||||||
return success(payTransferId);
|
return success(payTransferId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package cn.iocoder.yudao.module.pay.controller.app.order;
|
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.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
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.PayOrderRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
|
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.AppPayOrderSubmitReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
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.order.PayOrderDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
|
||||||
import cn.iocoder.yudao.module.pay.enums.PayChannelEnum;
|
import cn.iocoder.yudao.module.pay.enums.PayChannelEnum;
|
||||||
|
@ -52,6 +52,15 @@ public class AppPayOrderController {
|
||||||
public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id,
|
public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id,
|
||||||
@RequestParam(value = "sync", required = false) Boolean sync) {
|
@RequestParam(value = "sync", required = false) Boolean sync) {
|
||||||
PayOrderDO order = payOrderService.getOrder(id);
|
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 仅在等待支付
|
// sync 仅在等待支付
|
||||||
if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) {
|
if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) {
|
||||||
payOrderService.syncOrderQuietly(order.getId());
|
payOrderService.syncOrderQuietly(order.getId());
|
||||||
|
@ -75,7 +84,7 @@ public class AppPayOrderController {
|
||||||
|
|
||||||
// 2. 提交支付
|
// 2. 提交支付
|
||||||
PayOrderSubmitRespVO respVO = payOrderService.submitOrder(reqVO, getClientIP());
|
PayOrderSubmitRespVO respVO = payOrderService.submitOrder(reqVO, getClientIP());
|
||||||
return success(PayOrderConvert.INSTANCE.convert3(respVO));
|
return success(BeanUtils.toBean(respVO, AppPayOrderSubmitRespVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
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.PayOrderCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
|
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.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.app.PayAppDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
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.dal.dataobject.order.PayOrderExtensionDO;
|
||||||
|
import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
@ -69,6 +68,4 @@ public interface PayOrderConvert {
|
||||||
@Mapping(source = "order.status", target = "status")
|
@Mapping(source = "order.status", target = "status")
|
||||||
PayOrderSubmitRespVO convert(PayOrderDO order, cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderRespDTO respDTO);
|
PayOrderSubmitRespVO convert(PayOrderDO order, cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderRespDTO respDTO);
|
||||||
|
|
||||||
AppPayOrderSubmitRespVO convert3(PayOrderSubmitRespVO bean);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,15 @@ public class PayOrderDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
private String channelCode;
|
private String channelCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 用户类型
|
||||||
|
*/
|
||||||
|
private Integer userType;
|
||||||
|
|
||||||
// ========== 商户相关字段 ==========
|
// ========== 商户相关字段 ==========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -77,6 +77,15 @@ public class PayRefundDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
private String orderNo;
|
private String orderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 用户类型
|
||||||
|
*/
|
||||||
|
private Integer userType;
|
||||||
|
|
||||||
// ========== 商户相关字段 ==========
|
// ========== 商户相关字段 ==========
|
||||||
/**
|
/**
|
||||||
* 商户订单编号
|
* 商户订单编号
|
||||||
|
|
|
@ -30,7 +30,6 @@ public class PayTransferDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
@TableId
|
@TableId
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转账单号
|
* 转账单号
|
||||||
*/
|
*/
|
||||||
|
@ -42,14 +41,12 @@ public class PayTransferDO extends BaseDO {
|
||||||
* 关联 {@link PayAppDO#getId()}
|
* 关联 {@link PayAppDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long appId;
|
private Long appId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转账渠道编号
|
* 转账渠道编号
|
||||||
*
|
*
|
||||||
* 关联 {@link PayChannelDO#getId()}
|
* 关联 {@link PayChannelDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long channelId;
|
private Long channelId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转账渠道编码
|
* 转账渠道编码
|
||||||
*
|
*
|
||||||
|
@ -57,6 +54,15 @@ public class PayTransferDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
private String channelCode;
|
private String channelCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
/**
|
||||||
|
* 用户类型
|
||||||
|
*/
|
||||||
|
private Integer userType;
|
||||||
|
|
||||||
// ========== 商户相关字段 ==========
|
// ========== 商户相关字段 ==========
|
||||||
/**
|
/**
|
||||||
* 商户转账单编号
|
* 商户转账单编号
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.service.demo;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
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.PageParam;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
|
import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
|
||||||
|
@ -90,6 +91,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
|
||||||
// 2.1 创建支付单
|
// 2.1 创建支付单
|
||||||
Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO()
|
Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO()
|
||||||
.setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用
|
.setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用
|
||||||
|
.setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息
|
||||||
.setMerchantOrderId(demoOrder.getId().toString()) // 业务的订单编号
|
.setMerchantOrderId(demoOrder.getId().toString()) // 业务的订单编号
|
||||||
.setSubject(spuName).setBody("").setPrice(price) // 价格信息
|
.setSubject(spuName).setBody("").setPrice(price) // 价格信息
|
||||||
.setExpireTime(addTime(Duration.ofHours(2L)))).getCheckedData(); // 支付的过期时间
|
.setExpireTime(addTime(Duration.ofHours(2L)))).getCheckedData(); // 支付的过期时间
|
||||||
|
@ -189,6 +191,7 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
|
||||||
// 2.2 创建退款单
|
// 2.2 创建退款单
|
||||||
Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO()
|
Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO()
|
||||||
.setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用
|
.setAppKey(PAY_APP_KEY).setUserIp(getClientIP()) // 支付应用
|
||||||
|
.setUserId(order.getUserId()).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息
|
||||||
.setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
|
.setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
|
||||||
.setMerchantRefundId(refundId)
|
.setMerchantRefundId(refundId)
|
||||||
.setReason("想退钱").setPrice(order.getPrice())).getCheckedData();// 价格信息
|
.setReason("想退钱").setPrice(order.getPrice())).getCheckedData();// 价格信息
|
||||||
|
|
|
@ -26,9 +26,10 @@ public interface PayDemoWithdrawService {
|
||||||
* 提现单转账
|
* 提现单转账
|
||||||
*
|
*
|
||||||
* @param id 提现单编号
|
* @param id 提现单编号
|
||||||
|
* @param userId 用户编号
|
||||||
* @return 转账编号
|
* @return 转账编号
|
||||||
*/
|
*/
|
||||||
Long transferDemoWithdraw(Long id);
|
Long transferDemoWithdraw(Long id, Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得示例提现单分页
|
* 获得示例提现单分页
|
||||||
|
|
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.service.demo;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
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.PageParam;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
|
@ -61,7 +62,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long transferDemoWithdraw(Long id) {
|
public Long transferDemoWithdraw(Long id, Long userId) {
|
||||||
// 1.1 校验提现单
|
// 1.1 校验提现单
|
||||||
PayDemoWithdrawDO withdraw = validateDemoWithdrawCanTransfer(id);
|
PayDemoWithdrawDO withdraw = validateDemoWithdrawCanTransfer(id);
|
||||||
// 1.2 特殊:如果是转账失败的情况,需要充值下
|
// 1.2 特殊:如果是转账失败的情况,需要充值下
|
||||||
|
@ -77,6 +78,7 @@ public class PayDemoWithdrawServiceImpl implements PayDemoWithdrawService {
|
||||||
// 2.1 创建支付单
|
// 2.1 创建支付单
|
||||||
PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO()
|
PayTransferCreateReqDTO transferReqDTO = new PayTransferCreateReqDTO()
|
||||||
.setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用
|
.setAppKey(PAY_APP_KEY).setChannelCode(withdraw.getTransferChannelCode()).setUserIp(getClientIP()) // 支付应用
|
||||||
|
.setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()) // 用户信息
|
||||||
.setMerchantTransferId(String.valueOf(withdraw.getId())) // 业务的订单编号
|
.setMerchantTransferId(String.valueOf(withdraw.getId())) // 业务的订单编号
|
||||||
.setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息
|
.setSubject(withdraw.getSubject()).setPrice(withdraw.getPrice()) // 价格信息
|
||||||
.setUserAccount(withdraw.getUserAccount()).setUserName(withdraw.getUserName()); // 收款信息
|
.setUserAccount(withdraw.getUserAccount()).setUserName(withdraw.getUserName()); // 收款信息
|
||||||
|
|
|
@ -64,8 +64,6 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
|
||||||
private PayWalletService payWalletService;
|
private PayWalletService payWalletService;
|
||||||
@Resource
|
@Resource
|
||||||
private PayOrderService payOrderService;
|
private PayOrderService payOrderService;
|
||||||
// @Resource
|
|
||||||
// private PayRefundService payRefundService;
|
|
||||||
@Resource
|
@Resource
|
||||||
private PayWalletRechargePackageService payWalletRechargePackageService;
|
private PayWalletRechargePackageService payWalletRechargePackageService;
|
||||||
|
|
||||||
|
@ -99,6 +97,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
|
||||||
// 2.1 创建支付单
|
// 2.1 创建支付单
|
||||||
Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO()
|
Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO()
|
||||||
.setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp)
|
.setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp)
|
||||||
|
.setUserId(userId).setUserType(userType) // 用户信息
|
||||||
.setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号
|
.setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号
|
||||||
.setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("")
|
.setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("")
|
||||||
.setPrice(recharge.getPayPrice())
|
.setPrice(recharge.getPayPrice())
|
||||||
|
@ -169,7 +168,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
|
||||||
.addMessage("character_string1", String.valueOf(payOrderId)) // 支付单编号
|
.addMessage("character_string1", String.valueOf(payOrderId)) // 支付单编号
|
||||||
.addMessage("amount2", fenToYuanStr(walletRecharge.getTotalPrice())) // 充值金额
|
.addMessage("amount2", fenToYuanStr(walletRecharge.getTotalPrice())) // 充值金额
|
||||||
.addMessage("time3", LocalDateTimeUtil.formatNormal(walletRecharge.getCreateTime())) // 充值时间
|
.addMessage("time3", LocalDateTimeUtil.formatNormal(walletRecharge.getCreateTime())) // 充值时间
|
||||||
.addMessage("phrase4", "充值成功")).checkError(); // 充值状态
|
.addMessage("phrase4", "充值成功")); // 充值状态
|
||||||
|
|
||||||
// 2. 调用接口上传虚拟物品发货信息
|
// 2. 调用接口上传虚拟物品发货信息
|
||||||
// 注意:只有微信小程序支付的订单,才需要同步
|
// 注意:只有微信小程序支付的订单,才需要同步
|
||||||
|
@ -183,7 +182,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
|
||||||
.setItemDesc(payOrder.getSubject())
|
.setItemDesc(payOrder.getSubject())
|
||||||
.setLogisticsType(SocialWxaOrderUploadShippingInfoReqDTO.LOGISTICS_TYPE_VIRTUAL); // 虚拟物品发货类型
|
.setLogisticsType(SocialWxaOrderUploadShippingInfoReqDTO.LOGISTICS_TYPE_VIRTUAL); // 虚拟物品发货类型
|
||||||
try {
|
try {
|
||||||
socialClientApi.uploadWxaOrderShippingInfo(UserTypeEnum.MEMBER.getValue(), reqDTO).checkError();
|
socialClientApi.uploadWxaOrderShippingInfo(UserTypeEnum.MEMBER.getValue(), reqDTO);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("[sendWalletRechargerPaidMessage][订单({}) 上传订单物流信息到微信小程序失败]", payOrder, ex);
|
log.error("[sendWalletRechargerPaidMessage][订单({}) 上传订单物流信息到微信小程序失败]", payOrder, ex);
|
||||||
}
|
}
|
||||||
|
@ -209,6 +208,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
|
||||||
String refundId = walletRechargeId + "-refund";
|
String refundId = walletRechargeId + "-refund";
|
||||||
Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO()
|
Long payRefundId = payRefundApi.createRefund(new PayRefundCreateReqDTO()
|
||||||
.setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp)
|
.setAppKey(payProperties.getWalletPayAppKey()).setUserIp(userIp)
|
||||||
|
.setUserId(wallet.getUserId()).setUserType(wallet.getUserType()) // 用户信息
|
||||||
.setMerchantOrderId(walletRechargeId)
|
.setMerchantOrderId(walletRechargeId)
|
||||||
.setMerchantRefundId(refundId)
|
.setMerchantRefundId(refundId)
|
||||||
.setReason("想退钱").setPrice(walletRecharge.getPayPrice())).getCheckedData();
|
.setReason("想退钱").setPrice(walletRecharge.getPayPrice())).getCheckedData();
|
||||||
|
|
|
@ -3,5 +3,6 @@ DELETE FROM pay_channel;
|
||||||
DELETE FROM pay_order;
|
DELETE FROM pay_order;
|
||||||
DELETE FROM pay_order_extension;
|
DELETE FROM pay_order_extension;
|
||||||
DELETE FROM pay_refund;
|
DELETE FROM pay_refund;
|
||||||
|
DELETE FROM pay_transfer;
|
||||||
DELETE FROM pay_notify_task;
|
DELETE FROM pay_notify_task;
|
||||||
DELETE FROM pay_notify_log;
|
DELETE FROM pay_notify_log;
|
||||||
|
|
|
@ -45,6 +45,8 @@ CREATE TABLE IF NOT EXISTS `pay_order` (
|
||||||
`channel_fee_price` bigint(20) DEFAULT 0,
|
`channel_fee_price` bigint(20) DEFAULT 0,
|
||||||
`status` tinyint(4) NOT NULL,
|
`status` tinyint(4) NOT NULL,
|
||||||
`user_ip` varchar(50) 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,
|
`expire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`success_time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
|
`success_time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
|
||||||
`notify_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,
|
`refund_price` bigint(20) NOT NULL,
|
||||||
`reason` varchar(256) NOT NULL,
|
`reason` varchar(256) NOT NULL,
|
||||||
`user_ip` varchar(50) NULL DEFAULT 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_order_no` varchar(64) NOT NULL,
|
||||||
`channel_refund_no` varchar(64) NULL DEFAULT NULL,
|
`channel_refund_no` varchar(64) NULL DEFAULT NULL,
|
||||||
`success_time` datetime(0) 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,
|
`deleted` bit(1) NOT NULL DEFAULT FALSE,
|
||||||
PRIMARY KEY ("id")
|
PRIMARY KEY ("id")
|
||||||
) COMMENT = '支付通知日志';
|
) 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 = '转账单';
|
||||||
|
|
Loading…
Reference in New Issue