添加order和pay模块
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
<module>tashow-module-system</module>
|
||||
<module>tashow-module-infra</module>
|
||||
<module>tashow-module-app</module>
|
||||
<module>tashow-module-pay</module>
|
||||
<module>tashow-module-trade</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -7,11 +7,11 @@ spring:
|
||||
username: nacos # Nacos 账号
|
||||
password: nacos # Nacos 密码
|
||||
discovery: # 【配置中心】配置项
|
||||
namespace: 76667956-2ac2-4e05-906b-4bca4ebcc5f0 # 命名空间。这里使用 dev 开发环境
|
||||
namespace: liwq # 命名空间。这里使用 dev 开发环境
|
||||
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
|
||||
metadata:
|
||||
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
|
||||
config: # 【注册中心】配置项
|
||||
namespace: 76667956-2ac2-4e05-906b-4bca4ebcc5f0 # 命名空间。这里使用 dev 开发环境
|
||||
namespace: liwq # 命名空间。这里使用 dev 开发环境
|
||||
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
|
||||
|
||||
|
||||
@@ -10,4 +10,4 @@ spring:
|
||||
- optional:classpath:application-${spring.profiles.active}.yaml # 加载【本地】配置
|
||||
- optional:nacos:application.yaml # 加载【Nacos】的配置
|
||||
- optional:nacos:tenant.yaml # 加载【Nacos】的配置
|
||||
- optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml # 加载【Nacos】的配置
|
||||
- optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml # 加载【Nacos】的配置
|
||||
@@ -1,253 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName};
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ${jakartaPackage}.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
#if ($sceneEnum.scene == 1)import org.springframework.security.access.prepost.PreAuthorize;#end
|
||||
|
||||
import ${jakartaPackage}.validation.constraints.*;
|
||||
import ${jakartaPackage}.validation.*;
|
||||
import ${jakartaPackage}.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import ${PageParamClassName};
|
||||
import ${PageResultClassName};
|
||||
import ${CommonResultClassName};
|
||||
import ${BeanUtils};
|
||||
import static ${CommonResultClassName}.success;
|
||||
|
||||
import ${ExcelUtilsClassName};
|
||||
|
||||
import ${ApiAccessLogClassName};
|
||||
import static ${OperateTypeEnumClassName}.*;
|
||||
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
#end
|
||||
import ${basePackage}.module.${table.moduleName}.service.${table.businessName}.${table.className}Service;
|
||||
|
||||
/**
|
||||
* ${sceneEnum.name} - ${table.classComment}
|
||||
*/
|
||||
@RestController
|
||||
##二级的 businessName 暂时不算在 HTTP 路径上,可以根据需要写
|
||||
@RequestMapping("/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
@Validated
|
||||
public class ${sceneEnum.prefixClass}${table.className}Controller {
|
||||
|
||||
@Resource
|
||||
private ${table.className}Service ${classNameVar}Service;
|
||||
|
||||
/**
|
||||
* 创建${table.classComment}
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")
|
||||
#end
|
||||
public CommonResult<${primaryColumn.javaType}> create${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}SaveReqVO createReqVO) {
|
||||
return success(${classNameVar}Service.create${simpleClassName}(createReqVO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新${table.classComment}
|
||||
*/
|
||||
@PutMapping("/update")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
|
||||
#end
|
||||
public CommonResult<Boolean> update${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO) {
|
||||
${classNameVar}Service.update${simpleClassName}(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除${table.classComment}
|
||||
*/
|
||||
@DeleteMapping("/delete")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
|
||||
#end
|
||||
public CommonResult<Boolean> delete${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
|
||||
${classNameVar}Service.delete${simpleClassName}(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得${table.classComment}
|
||||
*/
|
||||
@GetMapping("/get")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<${sceneEnum.prefixClass}${table.className}RespVO> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
|
||||
${table.className}DO ${classNameVar} = ${classNameVar}Service.get${simpleClassName}(id);
|
||||
return success(BeanUtils.toBean(${classNameVar}, ${sceneEnum.prefixClass}${table.className}RespVO.class));
|
||||
}
|
||||
|
||||
#if ( $table.templateType != 2 )
|
||||
|
||||
/**
|
||||
* 获得${table.classComment}分页
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<PageResult<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}Page(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO) {
|
||||
PageResult<${table.className}DO> pageResult = ${classNameVar}Service.get${simpleClassName}Page(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, ${sceneEnum.prefixClass}${table.className}RespVO.class));
|
||||
}
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#else
|
||||
/**
|
||||
* 获得${table.classComment}列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<List<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}List(@Valid ${sceneEnum.prefixClass}${table.className}ListReqVO listReqVO) {
|
||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(listReqVO);
|
||||
return success(BeanUtils.toBean(list, ${sceneEnum.prefixClass}${table.className}RespVO.class));
|
||||
}
|
||||
|
||||
#end
|
||||
/**
|
||||
* 导出${table.classComment} Excel
|
||||
*/
|
||||
@GetMapping("/export-excel")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")
|
||||
#end
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
#if ( $table.templateType != 2 )
|
||||
public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}Page(pageReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "${table.classComment}.xls", "数据", ${sceneEnum.prefixClass}${table.className}RespVO.class,
|
||||
BeanUtils.toBean(list, ${sceneEnum.prefixClass}${table.className}RespVO.class));
|
||||
}
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#else
|
||||
public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}ListReqVO listReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(listReqVO);
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "${table.classComment}.xls", "数据", ${table.className}RespVO.class,
|
||||
BeanUtils.toBean(list, ${table.className}RespVO.class));
|
||||
}
|
||||
#end
|
||||
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
/**
|
||||
* 获得${subTable.classComment}分页
|
||||
*/
|
||||
@GetMapping("/${subSimpleClassName_strikeCase}/page")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<PageResult<${subTable.className}DO>> get${subSimpleClassName}Page(PageParam pageReqVO,
|
||||
@RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return success(${classNameVar}Service.get${subSimpleClassName}Page(pageReqVO, ${subJoinColumn.javaField}));
|
||||
}
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
/**
|
||||
* 获得${subTable.classComment}列表
|
||||
*/
|
||||
@GetMapping("/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<List<${subTable.className}DO>> get${subSimpleClassName}ListBy${SubJoinColumnName}(@RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return success(${classNameVar}Service.get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}));
|
||||
}
|
||||
|
||||
#else
|
||||
/**
|
||||
* 获得${subTable.classComment}
|
||||
*/
|
||||
@GetMapping("/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<${subTable.className}DO> get${subSimpleClassName}By${SubJoinColumnName}(@RequestParam("${subJoinColumn.javaField}") ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return success(${classNameVar}Service.get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}));
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
/**
|
||||
* 创建${subTable.classComment}
|
||||
*/
|
||||
@PostMapping("/${subSimpleClassName_strikeCase}/create")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")
|
||||
#end
|
||||
public CommonResult<${subPrimaryColumn.javaType}> create${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) {
|
||||
return success(${classNameVar}Service.create${subSimpleClassName}(${subClassNameVar}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新${subTable.classComment}
|
||||
*/
|
||||
@PutMapping("/${subSimpleClassName_strikeCase}/update")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
|
||||
#end
|
||||
public CommonResult<Boolean> update${subSimpleClassName}(@Valid @RequestBody ${subTable.className}DO ${subClassNameVar}) {
|
||||
${classNameVar}Service.update${subSimpleClassName}(${subClassNameVar});
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除${subTable.classComment}
|
||||
*/
|
||||
@DeleteMapping("/${subSimpleClassName_strikeCase}/delete")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
|
||||
#end
|
||||
public CommonResult<Boolean> delete${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) {
|
||||
${classNameVar}Service.delete${subSimpleClassName}(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得${subTable.classComment}
|
||||
*/
|
||||
@GetMapping("/${subSimpleClassName_strikeCase}/get")
|
||||
#if ($sceneEnum.scene == 1)
|
||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
||||
#end
|
||||
public CommonResult<${subTable.className}DO> get${subSimpleClassName}(@RequestParam("id") ${subPrimaryColumn.javaType} id) {
|
||||
return success(${classNameVar}Service.get${subSimpleClassName}(id));
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
|
||||
import ${PageParamClassName};
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 LocalDateTime 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation} && ${column.javaType} == "LocalDateTime")
|
||||
import java.time.LocalDateTime;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 字段模板
|
||||
#macro(columnTpl $prefix $prefixStr)
|
||||
/**
|
||||
* ${prefixStr}${column.columnComment}"#if ("$!column.example" != "
|
||||
*/, example = "${column.example}"#end)
|
||||
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
|
||||
#end
|
||||
|
||||
/**
|
||||
* ${sceneEnum.name} - ${table.classComment}列表 Request VO
|
||||
*/
|
||||
@Data
|
||||
public class ${sceneEnum.prefixClass}${table.className}ListReqVO {
|
||||
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})##查询操作
|
||||
#if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候
|
||||
/**
|
||||
* ${column.columnComment}"#if ("$!column.example" != "
|
||||
*/, example = "${column.example}"#end)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private ${column.javaType}[] ${column.javaField};
|
||||
#else##情况二,非 Between 的时间
|
||||
#columnTpl('', '')
|
||||
#end
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
|
||||
import ${PageParamClassName};
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 LocalDateTime 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperationCondition} && ${column.javaType} == "LocalDateTime")
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 字段模板
|
||||
#macro(columnTpl $prefix $prefixStr)
|
||||
/**
|
||||
* ${prefixStr}${column.columnComment}"#if ("$!column.example" != "
|
||||
*/, example = "${column.example}"#end)
|
||||
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
|
||||
#end
|
||||
|
||||
/**
|
||||
* ${sceneEnum.name} - ${table.classComment}分页 Request VO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ${sceneEnum.prefixClass}${table.className}PageReqVO extends PageParam {
|
||||
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})##查询操作
|
||||
#if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候
|
||||
/**
|
||||
* ${column.columnComment}"#if ("$!column.example" != "
|
||||
*/, example = "${column.example}"#end)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private ${column.javaType}[] ${column.javaField};
|
||||
#else##情况二,非 Between 的时间
|
||||
#columnTpl('', '')
|
||||
#end
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
## 处理 BigDecimal 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 LocalDateTime 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperationResult} && ${column.javaType} == "LocalDateTime")
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 Excel 导出
|
||||
import com.alibaba.excel.annotation.*;
|
||||
#foreach ($column in $columns)
|
||||
#if ("$!column.dictType" != "")## 有设置数据字典
|
||||
import ${DictFormatClassName};
|
||||
import ${DictConvertClassName};
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
|
||||
/**
|
||||
* ${sceneEnum.name} - ${table.classComment} Response VO
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class ${sceneEnum.prefixClass}${table.className}RespVO {
|
||||
|
||||
## 逐个处理字段
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperationResult})
|
||||
## 1. 处理 Swagger 注解
|
||||
/**
|
||||
* ${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != "
|
||||
*/, example = "${column.example}"#end)
|
||||
## 2. 处理 Excel 导出
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
@ExcelProperty(value = "${column.columnComment}", converter = DictConvert.class)
|
||||
@DictFormat("${column.dictType}") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||
#else
|
||||
@ExcelProperty("${column.columnComment}")
|
||||
#end
|
||||
## 3. 处理字段定义
|
||||
private ${column.javaType} ${column.javaField};
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import ${jakartaPackage}.validation.constraints.*;
|
||||
## 处理 BigDecimal 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 处理 LocalDateTime 字段的引入
|
||||
#foreach ($column in $columns)
|
||||
#if ((${column.createOperation} || ${column.updateOperation}) && ${column.javaType} == "LocalDateTime")
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
#break
|
||||
#end
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
#end
|
||||
|
||||
/**
|
||||
* ${sceneEnum.name} - ${table.classComment}新增/修改 Request VO
|
||||
*/
|
||||
@Data
|
||||
public class ${sceneEnum.prefixClass}${table.className}SaveReqVO {
|
||||
|
||||
## 逐个处理字段
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.createOperation} || ${column.updateOperation})
|
||||
## 1. 处理 Swagger 注解
|
||||
/**
|
||||
* ${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != "
|
||||
*/, example = "${column.example}"#end)
|
||||
## 2. 处理 Validator 参数校验
|
||||
#if (!${column.nullable} && !${column.primaryKey})
|
||||
#if (${column.javaType} == 'String')
|
||||
@NotEmpty(message = "${column.columnComment}不能为空")
|
||||
#else
|
||||
@NotNull(message = "${column.columnComment}不能为空")
|
||||
#end
|
||||
#end
|
||||
## 3. 处理字段定义
|
||||
private ${column.javaType} ${column.javaField};
|
||||
|
||||
#end
|
||||
#end
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#if ( $subTable.subJoinMany)
|
||||
/**
|
||||
* ${subTable.classComment}列表
|
||||
*/
|
||||
private List<${subTable.className}DO> ${subClassNameVars.get($index)}s;
|
||||
|
||||
#else
|
||||
/**
|
||||
* ${subTable.classComment}
|
||||
*/
|
||||
private ${subTable.className}DO ${subClassNameVars.get($index)};
|
||||
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName};
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#end
|
||||
#if (${column.javaType} == "LocalDateTime")
|
||||
import java.time.LocalDateTime;
|
||||
#end
|
||||
#end
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import ${BaseDOClassName};
|
||||
|
||||
/**
|
||||
* ${table.classComment} DO
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@TableName("${table.tableName.toLowerCase()}")
|
||||
@KeySequence("${table.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ${table.className}DO extends BaseDO {
|
||||
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
public static final Long ${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT = 0L;
|
||||
|
||||
#end
|
||||
#foreach ($column in $columns)
|
||||
#if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段
|
||||
/**
|
||||
* ${column.columnComment}
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
*
|
||||
* 枚举 {@link TODO ${column.dictType} 对应的类}
|
||||
#end
|
||||
*/
|
||||
#if (${column.primaryKey})##处理主键
|
||||
@TableId#if (${column.javaType} == 'String')(type = IdType.INPUT)#end
|
||||
#end
|
||||
private ${column.javaType} ${column.javaField};
|
||||
#end
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
package ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName};
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
#foreach ($column in $subColumns)
|
||||
#if (${column.javaType} == "BigDecimal")
|
||||
import java.math.BigDecimal;
|
||||
#end
|
||||
#if (${column.javaType} == "LocalDateTime")
|
||||
import java.time.LocalDateTime;
|
||||
#end
|
||||
#end
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import ${BaseDOClassName};
|
||||
|
||||
/**
|
||||
* ${subTable.classComment} DO
|
||||
*
|
||||
* @author ${subTable.author}
|
||||
*/
|
||||
@TableName("${subTable.tableName.toLowerCase()}")
|
||||
@KeySequence("${subTable.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ${subTable.className}DO extends BaseDO {
|
||||
|
||||
#foreach ($column in $subColumns)
|
||||
#if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段
|
||||
/**
|
||||
* ${column.columnComment}
|
||||
#if ("$!column.dictType" != "")##处理枚举值
|
||||
*
|
||||
* 枚举 {@link TODO ${column.dictType} 对应的类}
|
||||
#end
|
||||
*/
|
||||
#if (${column.primaryKey})##处理主键
|
||||
@TableId#if (${column.javaType} == 'String')(type = IdType.INPUT)#end
|
||||
#end
|
||||
private ${column.javaType} ${column.javaField};
|
||||
#end
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName};
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ${PageResultClassName};
|
||||
import ${QueryWrapperClassName};
|
||||
import ${BaseMapperClassName};
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
|
||||
## 字段模板
|
||||
#macro(listCondition)
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})
|
||||
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
|
||||
#if (${column.listOperationCondition} == "=")##情况一,= 的时候
|
||||
.eqIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "!=")##情况二,!= 的时候
|
||||
.neIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == ">")##情况三,> 的时候
|
||||
.gtIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == ">=")##情况四,>= 的时候
|
||||
.geIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "<")##情况五,< 的时候
|
||||
.ltIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "<=")##情况五,<= 的时候
|
||||
.leIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "LIKE")##情况七,Like 的时候
|
||||
.likeIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#if (${column.listOperationCondition} == "BETWEEN")##情况八,Between 的时候
|
||||
.betweenIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
/**
|
||||
* ${table.classComment} Mapper
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@Mapper
|
||||
public interface ${table.className}Mapper extends BaseMapperX<${table.className}DO> {
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
default PageResult<${table.className}DO> selectPage(${sceneEnum.prefixClass}${table.className}PageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<${table.className}DO>()
|
||||
#listCondition()
|
||||
.orderByDesc(${table.className}DO::getId));## 大多数情况下,id 倒序
|
||||
|
||||
}
|
||||
#else
|
||||
default List<${table.className}DO> selectList(${sceneEnum.prefixClass}${table.className}ListReqVO reqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<${table.className}DO>()
|
||||
#listCondition()
|
||||
.orderByDesc(${table.className}DO::getId));## 大多数情况下,id 倒序
|
||||
|
||||
}
|
||||
#end
|
||||
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
|
||||
default ${table.className}DO selectBy${TreeParentJavaField}And${TreeNameJavaField}(Long ${treeParentColumn.javaField}, String ${treeNameColumn.javaField}) {
|
||||
return selectOne(${table.className}DO::get${TreeParentJavaField}, ${treeParentColumn.javaField}, ${table.className}DO::get${TreeNameJavaField}, ${treeNameColumn.javaField});
|
||||
}
|
||||
|
||||
default Long selectCountBy${TreeParentJavaField}(${treeParentColumn.javaType} ${treeParentColumn.javaField}) {
|
||||
return selectCount(${table.className}DO::get${TreeParentJavaField}, ${treeParentColumn.javaField});
|
||||
}
|
||||
|
||||
#end
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
</mapper>
|
||||
@@ -1,57 +0,0 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subJoinColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
package ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName};
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ${PageResultClassName};
|
||||
import ${PageParamClassName};
|
||||
import ${QueryWrapperClassName};
|
||||
import ${BaseMapperClassName};
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* ${subTable.classComment} Mapper
|
||||
*
|
||||
* @author ${subTable.author}
|
||||
*/
|
||||
@Mapper
|
||||
public interface ${subTable.className}Mapper extends BaseMapperX<${subTable.className}DO> {
|
||||
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
default PageResult<${subTable.className}DO> selectPage(PageParam reqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<${subTable.className}DO>()
|
||||
.eq(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField})
|
||||
.orderByDesc(${subTable.className}DO::getId));## 大多数情况下,id 倒序
|
||||
|
||||
}
|
||||
## 主表与子表是一对一时
|
||||
#if (!$subTable.subJoinMany)
|
||||
default ${subTable.className}DO selectBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return selectOne(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
|
||||
}
|
||||
#end
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany)
|
||||
default List<${subTable.className}DO> selectListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return selectList(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#else
|
||||
default ${subTable.className}DO selectBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return selectOne(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
default int deleteBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return delete(${subTable.className}DO::get${SubJoinColumnName}, ${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// TODO 待办:请将下面的错误码复制到 yudao-module-${table.moduleName}-api 模块的 ErrorCodeConstants 类中。注意,请给“TODO 补充编号”设置一个错误码编号!!!
|
||||
// ========== ${table.classComment} TODO 补充编号 ==========
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS = new ErrorCode(TODO 补充编号, "${table.classComment}不存在");
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_EXITS_CHILDREN = new ErrorCode(TODO 补充编号, "存在存在子${table.classComment},无法删除");
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_PARENT_NOT_EXITS = new ErrorCode(TODO 补充编号,"父级${table.classComment}不存在");
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_PARENT_ERROR = new ErrorCode(TODO 补充编号, "不能设置自己为父${table.classComment}");
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE = new ErrorCode(TODO 补充编号, "已经存在该${treeNameColumn.columnComment}的${table.classComment}");
|
||||
ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_PARENT_IS_CHILD = new ErrorCode(TODO 补充编号, "不能设置自己的子${table.className}为父${table.className}");
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 )## 特殊:ERP 情况
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($simpleClassNameUnderlineCase = $simpleClassNameUnderlineCases.get($index))
|
||||
ErrorCode ${simpleClassNameUnderlineCase.toUpperCase()}_NOT_EXISTS = new ErrorCode(TODO 补充编号, "${subTable.classComment}不存在");
|
||||
#if ( !$subTable.subJoinMany )
|
||||
ErrorCode ${simpleClassNameUnderlineCase.toUpperCase()}_EXISTS = new ErrorCode(TODO 补充编号, "${subTable.classComment}已存在");
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
@@ -1,147 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
|
||||
|
||||
import java.util.*;
|
||||
import ${jakartaPackage}.validation.*;
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
#end
|
||||
import ${PageResultClassName};
|
||||
import ${PageParamClassName};
|
||||
|
||||
/**
|
||||
* ${table.classComment} Service 接口
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
public interface ${table.className}Service {
|
||||
|
||||
/**
|
||||
* 创建${table.classComment}
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
${primaryColumn.javaType} create${simpleClassName}(@Valid ${sceneEnum.prefixClass}${table.className}SaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新${table.classComment}
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void update${simpleClassName}(@Valid ${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除${table.classComment}
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void delete${simpleClassName}(${primaryColumn.javaType} id);
|
||||
|
||||
/**
|
||||
* 获得${table.classComment}
|
||||
*
|
||||
* @param id 编号
|
||||
* @return ${table.classComment}
|
||||
*/
|
||||
${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id);
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
/**
|
||||
* 获得${table.classComment}分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return ${table.classComment}分页
|
||||
*/
|
||||
PageResult<${table.className}DO> get${simpleClassName}Page(${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO);
|
||||
#else
|
||||
/**
|
||||
* 获得${table.classComment}列表
|
||||
*
|
||||
* @param listReqVO 查询条件
|
||||
* @return ${table.classComment}列表
|
||||
*/
|
||||
List<${table.className}DO> get${simpleClassName}List(${sceneEnum.prefixClass}${table.className}ListReqVO listReqVO);
|
||||
#end
|
||||
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
/**
|
||||
* 获得${subTable.classComment}分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
|
||||
* @return ${subTable.classComment}分页
|
||||
*/
|
||||
PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField});
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
/**
|
||||
* 获得${subTable.classComment}列表
|
||||
*
|
||||
* @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
|
||||
* @return ${subTable.classComment}列表
|
||||
*/
|
||||
List<${subTable.className}DO> get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField});
|
||||
|
||||
#else
|
||||
/**
|
||||
* 获得${subTable.classComment}
|
||||
*
|
||||
* @param ${subJoinColumn.javaField} ${subJoinColumn.columnComment}
|
||||
* @return ${subTable.classComment}
|
||||
*/
|
||||
${subTable.className}DO get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField});
|
||||
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
/**
|
||||
* 创建${subTable.classComment}
|
||||
*
|
||||
* @param ${subClassNameVar} 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
${subPrimaryColumn.javaType} create${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar});
|
||||
|
||||
/**
|
||||
* 更新${subTable.classComment}
|
||||
*
|
||||
* @param ${subClassNameVar} 更新信息
|
||||
*/
|
||||
void update${subSimpleClassName}(@Valid ${subTable.className}DO ${subClassNameVar});
|
||||
|
||||
/**
|
||||
* 删除${subTable.classComment}
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void delete${subSimpleClassName}(${subPrimaryColumn.javaType} id);
|
||||
|
||||
/**
|
||||
* 获得${subTable.classComment}
|
||||
*
|
||||
* @param id 编号
|
||||
* @return ${subTable.classComment}
|
||||
*/
|
||||
${subTable.className}DO get${subSimpleClassName}(${subPrimaryColumn.javaType} id);
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,351 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ${jakartaPackage}.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.dataobject.${subTable.businessName}.${subTable.className}DO;
|
||||
#end
|
||||
import ${PageResultClassName};
|
||||
import ${PageParamClassName};
|
||||
import ${BeanUtils};
|
||||
|
||||
import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
import ${basePackage}.module.${subTable.moduleName}.dal.mysql.${subTable.businessName}.${subTable.className}Mapper;
|
||||
#end
|
||||
|
||||
import static ${ServiceExceptionUtilClassName}.exception;
|
||||
import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* ${table.classComment} Service 实现类
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ${table.className}ServiceImpl implements ${table.className}Service {
|
||||
|
||||
@Resource
|
||||
private ${table.className}Mapper ${classNameVar}Mapper;
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
@Resource
|
||||
private ${subTable.className}Mapper ${subClassNameVars.get($index)}Mapper;
|
||||
#end
|
||||
|
||||
@Override
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
#end
|
||||
public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}SaveReqVO createReqVO) {
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
|
||||
// 校验${treeParentColumn.columnComment}的有效性
|
||||
validateParent${simpleClassName}(null, createReqVO.get${TreeParentJavaField}());
|
||||
// 校验${treeNameColumn.columnComment}的唯一性
|
||||
validate${simpleClassName}${TreeNameJavaField}Unique(null, createReqVO.get${TreeParentJavaField}(), createReqVO.get${TreeNameJavaField}());
|
||||
|
||||
#end
|
||||
// 插入
|
||||
${table.className}DO ${classNameVar} = BeanUtils.toBean(createReqVO, ${table.className}DO.class);
|
||||
${classNameVar}Mapper.insert(${classNameVar});
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
|
||||
// 插入子表
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#if ( $subTable.subJoinMany)
|
||||
create${subSimpleClassName}List(${classNameVar}.getId(), createReqVO.get${subSimpleClassNames.get($index)}s());
|
||||
#else
|
||||
create${subSimpleClassName}(${classNameVar}.getId(), createReqVO.get${subSimpleClassNames.get($index)}());
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
// 返回
|
||||
return ${classNameVar}.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11 )
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
#end
|
||||
public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validate${simpleClassName}Exists(updateReqVO.getId());
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
|
||||
// 校验${treeParentColumn.columnComment}的有效性
|
||||
validateParent${simpleClassName}(updateReqVO.getId(), updateReqVO.get${TreeParentJavaField}());
|
||||
// 校验${treeNameColumn.columnComment}的唯一性
|
||||
validate${simpleClassName}${TreeNameJavaField}Unique(updateReqVO.getId(), updateReqVO.get${TreeParentJavaField}(), updateReqVO.get${TreeNameJavaField}());
|
||||
|
||||
#end
|
||||
// 更新
|
||||
${table.className}DO updateObj = BeanUtils.toBean(updateReqVO, ${table.className}DO.class);
|
||||
${classNameVar}Mapper.updateById(updateObj);
|
||||
## 特殊:主子表专属逻辑(非 ERP 模式)
|
||||
#if ( $subTables && $subTables.size() > 0 && $table.templateType != 11)
|
||||
|
||||
// 更新子表
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#if ( $subTable.subJoinMany)
|
||||
update${subSimpleClassName}List(updateReqVO.getId(), updateReqVO.get${subSimpleClassNames.get($index)}s());
|
||||
#else
|
||||
update${subSimpleClassName}(updateReqVO.getId(), updateReqVO.get${subSimpleClassNames.get($index)}());
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
@Override
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $subTables && $subTables.size() > 0)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
#end
|
||||
public void delete${simpleClassName}(${primaryColumn.javaType} id) {
|
||||
// 校验存在
|
||||
validate${simpleClassName}Exists(id);
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($ParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
// 校验是否有子${table.classComment}
|
||||
if (${classNameVar}Mapper.selectCountBy${ParentJavaField}(id) > 0) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_EXITS_CHILDREN);
|
||||
}
|
||||
#end
|
||||
// 删除
|
||||
${classNameVar}Mapper.deleteById(id);
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $subTables && $subTables.size() > 0)
|
||||
|
||||
// 删除子表
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
delete${subSimpleClassName}By${SubJoinColumnName}(id);
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
private void validate${simpleClassName}Exists(${primaryColumn.javaType} id) {
|
||||
if (${classNameVar}Mapper.selectById(id) == null) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
#set ($TreeParentJavaField = $treeParentColumn.javaField.substring(0,1).toUpperCase() + ${treeParentColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($TreeNameJavaField = $treeNameColumn.javaField.substring(0,1).toUpperCase() + ${treeNameColumn.javaField.substring(1)})##首字母大写
|
||||
private void validateParent${simpleClassName}(Long id, Long ${treeParentColumn.javaField}) {
|
||||
if (${treeParentColumn.javaField} == null || ${simpleClassName}DO.${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT.equals(${treeParentColumn.javaField})) {
|
||||
return;
|
||||
}
|
||||
// 1. 不能设置自己为父${table.classComment}
|
||||
if (Objects.equals(id, ${treeParentColumn.javaField})) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_ERROR);
|
||||
}
|
||||
// 2. 父${table.classComment}不存在
|
||||
${simpleClassName}DO parent${simpleClassName} = ${classNameVar}Mapper.selectById(${treeParentColumn.javaField});
|
||||
if (parent${simpleClassName} == null) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_NOT_EXITS);
|
||||
}
|
||||
// 3. 递归校验父${table.classComment},如果父${table.classComment}是自己的子${table.classComment},则报错,避免形成环路
|
||||
if (id == null) { // id 为空,说明新增,不需要考虑环路
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < Short.MAX_VALUE; i++) {
|
||||
// 3.1 校验环路
|
||||
${treeParentColumn.javaField} = parent${simpleClassName}.get${TreeParentJavaField}();
|
||||
if (Objects.equals(id, ${treeParentColumn.javaField})) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_PARENT_IS_CHILD);
|
||||
}
|
||||
// 3.2 继续递归下一级父${table.classComment}
|
||||
if (${treeParentColumn.javaField} == null || ${simpleClassName}DO.${treeParentColumn_javaField_underlineCase.toUpperCase()}_ROOT.equals(${treeParentColumn.javaField})) {
|
||||
break;
|
||||
}
|
||||
parent${simpleClassName} = ${classNameVar}Mapper.selectById(${treeParentColumn.javaField});
|
||||
if (parent${simpleClassName} == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validate${simpleClassName}${TreeNameJavaField}Unique(Long id, Long ${treeParentColumn.javaField}, String ${treeNameColumn.javaField}) {
|
||||
${simpleClassName}DO ${classNameVar} = ${classNameVar}Mapper.selectBy${TreeParentJavaField}And${TreeNameJavaField}(${treeParentColumn.javaField}, ${treeNameColumn.javaField});
|
||||
if (${classNameVar} == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的${table.classComment}
|
||||
if (id == null) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE);
|
||||
}
|
||||
if (!Objects.equals(${classNameVar}.getId(), id)) {
|
||||
throw exception(${simpleClassName_underlineCase.toUpperCase()}_${treeNameColumn_javaField_underlineCase.toUpperCase()}_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
#end
|
||||
@Override
|
||||
public ${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id) {
|
||||
return ${classNameVar}Mapper.selectById(id);
|
||||
}
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
@Override
|
||||
public PageResult<${table.className}DO> get${simpleClassName}Page(${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO) {
|
||||
return ${classNameVar}Mapper.selectPage(pageReqVO);
|
||||
}
|
||||
#else
|
||||
@Override
|
||||
public List<${table.className}DO> get${simpleClassName}List(${sceneEnum.prefixClass}${table.className}ListReqVO listReqVO) {
|
||||
return ${classNameVar}Mapper.selectList(listReqVO);
|
||||
}
|
||||
#end
|
||||
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($simpleClassNameUnderlineCase = $simpleClassNameUnderlineCases.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
@Override
|
||||
public PageResult<${subTable.className}DO> get${subSimpleClassName}Page(PageParam pageReqVO, ${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return ${subClassNameVars.get($index)}Mapper.selectPage(pageReqVO, ${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
@Override
|
||||
public List<${subTable.className}DO> get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return ${subClassNameVars.get($index)}Mapper.selectListBy${SubJoinColumnName}(${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#else
|
||||
@Override
|
||||
public ${subTable.className}DO get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
return ${subClassNameVars.get($index)}Mapper.selectBy${SubJoinColumnName}(${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
## 情况一:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
@Override
|
||||
public ${subPrimaryColumn.javaType} create${subSimpleClassName}(${subTable.className}DO ${subClassNameVar}) {
|
||||
## 特殊:一对一时,需要保证只有一条,不能重复插入
|
||||
#if ( !$subTable.subJoinMany)
|
||||
// 校验是否已经存在
|
||||
if (${subClassNameVars.get($index)}Mapper.selectBy${SubJoinColumnName}(${subClassNameVar}.get${SubJoinColumnName}()) != null) {
|
||||
throw exception(${simpleClassNameUnderlineCase.toUpperCase()}_EXISTS);
|
||||
}
|
||||
// 插入
|
||||
#end
|
||||
${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
|
||||
return ${subClassNameVar}.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update${subSimpleClassName}(${subTable.className}DO ${subClassNameVar}) {
|
||||
// 校验存在
|
||||
validate${subSimpleClassName}Exists(${subClassNameVar}.getId());
|
||||
// 更新
|
||||
${subClassNameVar}.setUpdater(null).setUpdateTime(null); // 解决更新情况下:updateTime 不更新
|
||||
${subClassNameVars.get($index)}Mapper.updateById(${subClassNameVar});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete${subSimpleClassName}(${subPrimaryColumn.javaType} id) {
|
||||
// 校验存在
|
||||
validate${subSimpleClassName}Exists(id);
|
||||
// 删除
|
||||
${subClassNameVars.get($index)}Mapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ${subTable.className}DO get${subSimpleClassName}(${subPrimaryColumn.javaType} id) {
|
||||
return ${subClassNameVars.get($index)}Mapper.selectById(id);
|
||||
}
|
||||
|
||||
private void validate${subSimpleClassName}Exists(${subPrimaryColumn.javaType} id) {
|
||||
if (${subClassNameVar}Mapper.selectById(id) == null) {
|
||||
throw exception(${simpleClassNameUnderlineCase.toUpperCase()}_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
## 情况二:非 MASTER_ERP 时,支持批量的新增、修改操作
|
||||
#else
|
||||
#if ( $subTable.subJoinMany)
|
||||
private void create${subSimpleClassName}List(${primaryColumn.javaType} ${subJoinColumn.javaField}, List<${subTable.className}DO> list) {
|
||||
list.forEach(o -> o.set$SubJoinColumnName(${subJoinColumn.javaField}));
|
||||
${subClassNameVars.get($index)}Mapper.insertBatch(list);
|
||||
}
|
||||
|
||||
private void update${subSimpleClassName}List(${primaryColumn.javaType} ${subJoinColumn.javaField}, List<${subTable.className}DO> list) {
|
||||
delete${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField});
|
||||
list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新
|
||||
create${subSimpleClassName}List(${subJoinColumn.javaField}, list);
|
||||
}
|
||||
|
||||
#else
|
||||
private void create${subSimpleClassName}(${primaryColumn.javaType} ${subJoinColumn.javaField}, ${subTable.className}DO ${subClassNameVar}) {
|
||||
if (${subClassNameVar} == null) {
|
||||
return;
|
||||
}
|
||||
${subClassNameVar}.set$SubJoinColumnName(${subJoinColumn.javaField});
|
||||
${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
|
||||
}
|
||||
|
||||
private void update${subSimpleClassName}(${primaryColumn.javaType} ${subJoinColumn.javaField}, ${subTable.className}DO ${subClassNameVar}) {
|
||||
if (${subClassNameVar} == null) {
|
||||
return;
|
||||
}
|
||||
${subClassNameVar}.set$SubJoinColumnName(${subJoinColumn.javaField});
|
||||
${subClassNameVar}.setUpdater(null).setUpdateTime(null); // 解决更新情况下:updateTime 不更新
|
||||
${subClassNameVars.get($index)}Mapper.insertOrUpdate(${subClassNameVar});
|
||||
}
|
||||
|
||||
#end
|
||||
#end
|
||||
private void delete${subSimpleClassName}By${SubJoinColumnName}(${primaryColumn.javaType} ${subJoinColumn.javaField}) {
|
||||
${subClassNameVars.get($index)}Mapper.deleteBy${SubJoinColumnName}(${subJoinColumn.javaField});
|
||||
}
|
||||
|
||||
#end
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import ${jakartaPackage}.annotation.Resource;
|
||||
|
||||
import ${baseFrameworkPackage}.test.core.ut.BaseDbUnitTest;
|
||||
|
||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||
import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
|
||||
import ${PageResultClassName};
|
||||
|
||||
import ${jakartaPackage}.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*;
|
||||
import static ${baseFrameworkPackage}.test.core.util.AssertUtils.*;
|
||||
import static ${baseFrameworkPackage}.test.core.util.RandomUtils.*;
|
||||
import static ${LocalDateTimeUtilsClassName}.*;
|
||||
import static ${ObjectUtilsClassName}.*;
|
||||
import static ${DateUtilsClassName}.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
## 字段模板
|
||||
#macro(getPageCondition $VO)
|
||||
// mock 数据
|
||||
${table.className}DO db${simpleClassName} = randomPojo(${table.className}DO.class, o -> { // 等会查询到
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})
|
||||
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
|
||||
o.set$JavaField(null);
|
||||
#end
|
||||
#end
|
||||
});
|
||||
${classNameVar}Mapper.insert(db${simpleClassName});
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})
|
||||
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
|
||||
// 测试 ${column.javaField} 不匹配
|
||||
${classNameVar}Mapper.insert(cloneIgnoreId(db${simpleClassName}, o -> o.set$JavaField(null)));
|
||||
#end
|
||||
#end
|
||||
// 准备参数
|
||||
${sceneEnum.prefixClass}${table.className}${VO} reqVO = new ${sceneEnum.prefixClass}${table.className}${VO}();
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.listOperation})
|
||||
#set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
|
||||
#if (${column.listOperationCondition} == "BETWEEN")## BETWEEN 的情况
|
||||
reqVO.set${JavaField}(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
#else
|
||||
reqVO.set$JavaField(null);
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
/**
|
||||
* {@link ${table.className}ServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author ${table.author}
|
||||
*/
|
||||
@Import(${table.className}ServiceImpl.class)
|
||||
public class ${table.className}ServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private ${table.className}ServiceImpl ${classNameVar}Service;
|
||||
|
||||
@Resource
|
||||
private ${table.className}Mapper ${classNameVar}Mapper;
|
||||
|
||||
@Test
|
||||
public void testCreate${simpleClassName}_success() {
|
||||
// 准备参数
|
||||
${sceneEnum.prefixClass}${table.className}SaveReqVO createReqVO = randomPojo(${sceneEnum.prefixClass}${table.className}SaveReqVO.class).setId(null);
|
||||
|
||||
// 调用
|
||||
${primaryColumn.javaType} ${classNameVar}Id = ${classNameVar}Service.create${simpleClassName}(createReqVO);
|
||||
// 断言
|
||||
assertNotNull(${classNameVar}Id);
|
||||
// 校验记录的属性是否正确
|
||||
${table.className}DO ${classNameVar} = ${classNameVar}Mapper.selectById(${classNameVar}Id);
|
||||
assertPojoEquals(createReqVO, ${classNameVar}, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate${simpleClassName}_success() {
|
||||
// mock 数据
|
||||
${table.className}DO db${simpleClassName} = randomPojo(${table.className}DO.class);
|
||||
${classNameVar}Mapper.insert(db${simpleClassName});// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO = randomPojo(${sceneEnum.prefixClass}${table.className}SaveReqVO.class, o -> {
|
||||
o.setId(db${simpleClassName}.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
${classNameVar}Service.update${simpleClassName}(updateReqVO);
|
||||
// 校验是否更新正确
|
||||
${table.className}DO ${classNameVar} = ${classNameVar}Mapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(updateReqVO, ${classNameVar});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate${simpleClassName}_notExists() {
|
||||
// 准备参数
|
||||
${sceneEnum.prefixClass}${table.className}SaveReqVO updateReqVO = randomPojo(${sceneEnum.prefixClass}${table.className}SaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> ${classNameVar}Service.update${simpleClassName}(updateReqVO), ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete${simpleClassName}_success() {
|
||||
// mock 数据
|
||||
${table.className}DO db${simpleClassName} = randomPojo(${table.className}DO.class);
|
||||
${classNameVar}Mapper.insert(db${simpleClassName});// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
${primaryColumn.javaType} id = db${simpleClassName}.getId();
|
||||
|
||||
// 调用
|
||||
${classNameVar}Service.delete${simpleClassName}(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(${classNameVar}Mapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete${simpleClassName}_notExists() {
|
||||
// 准备参数
|
||||
${primaryColumn.javaType} id = random${primaryColumn.javaType}Id();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> ${classNameVar}Service.delete${simpleClassName}(id), ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS);
|
||||
}
|
||||
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGet${simpleClassName}Page() {
|
||||
#getPageCondition("PageReqVO")
|
||||
|
||||
// 调用
|
||||
PageResult<${table.className}DO> pageResult = ${classNameVar}Service.get${simpleClassName}Page(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(db${simpleClassName}, pageResult.getList().get(0));
|
||||
}
|
||||
#else
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGet${simpleClassName}List() {
|
||||
#getPageCondition("ListReqVO")
|
||||
|
||||
// 调用
|
||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(db${simpleClassName}, list.get(0));
|
||||
}
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
-- 将该建表 SQL 语句,添加到 yudao-module-${table.moduleName}-biz 模块的 test/resources/sql/create_tables.sql 文件里
|
||||
CREATE TABLE IF NOT EXISTS "${table.tableName.toLowerCase()}" (
|
||||
#foreach ($column in $columns)
|
||||
#if (${column.javaType} == 'Long')
|
||||
#set ($dataType='bigint')
|
||||
#elseif (${column.javaType} == 'Integer')
|
||||
#set ($dataType='int')
|
||||
#elseif (${column.javaType} == 'Boolean')
|
||||
#set ($dataType='bit')
|
||||
#elseif (${column.javaType} == 'Date')
|
||||
#set ($dataType='datetime')
|
||||
#else
|
||||
#set ($dataType='varchar')
|
||||
#end
|
||||
#if (${column.primaryKey})##处理主键
|
||||
"${column.javaField}"#if (${column.javaType} == 'String') ${dataType} NOT NULL#else ${dataType} NOT NULL GENERATED BY DEFAULT AS IDENTITY#end,
|
||||
#else
|
||||
#if (${column.columnName} == 'create_time')
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
#elseif (${column.columnName} == 'update_time')
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
#elseif (${column.columnName} == 'creator' || ${column.columnName} == 'updater')
|
||||
"${column.columnName}" ${dataType} DEFAULT '',
|
||||
#elseif (${column.columnName} == 'deleted')
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
#elseif (${column.columnName} == 'tenant_id')
|
||||
"tenant_id" bigint NOT NULL DEFAULT 0,
|
||||
#else
|
||||
"${column.columnName.toLowerCase()}" ${dataType}#if (${column.nullable} == false) NOT NULL#end,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
PRIMARY KEY ("${primaryColumn.columnName.toLowerCase()}")
|
||||
) COMMENT '${table.tableComment}';
|
||||
|
||||
-- 将该删表 SQL 语句,添加到 yudao-module-${table.moduleName}-biz 模块的 test/resources/sql/clean.sql 文件里
|
||||
DELETE FROM "${table.tableName}";
|
||||
@@ -1,28 +0,0 @@
|
||||
-- 菜单 SQL
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status, component_name
|
||||
)
|
||||
VALUES (
|
||||
'${table.classComment}管理', '', 2, 0, ${table.parentMenuId},
|
||||
'${simpleClassName_strikeCase}', '', '${table.moduleName}/${table.businessName}/index', 0, '${table.className}'
|
||||
);
|
||||
|
||||
-- 按钮父菜单ID
|
||||
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
|
||||
SELECT @parentId := LAST_INSERT_ID();
|
||||
|
||||
-- 按钮 SQL
|
||||
#set ($functionNames = ['查询', '创建', '更新', '删除', '导出'])
|
||||
#set ($functionOps = ['query', 'create', 'update', 'delete', 'export'])
|
||||
#foreach ($functionName in $functionNames)
|
||||
#set ($index = $foreach.count - 1)
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status
|
||||
)
|
||||
VALUES (
|
||||
'${table.classComment}${functionName}', '${permissionPrefix}:${functionOps.get($index)}', 3, $foreach.count, @parentId,
|
||||
'', '', '', 0
|
||||
);
|
||||
#end
|
||||
@@ -1,141 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
// 创建${table.classComment}
|
||||
export function create${simpleClassName}(data) {
|
||||
return request({
|
||||
url: '${baseURL}/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新${table.classComment}
|
||||
export function update${simpleClassName}(data) {
|
||||
return request({
|
||||
url: '${baseURL}/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除${table.classComment}
|
||||
export function delete${simpleClassName}(id) {
|
||||
return request({
|
||||
url: '${baseURL}/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得${table.classComment}
|
||||
export function get${simpleClassName}(id) {
|
||||
return request({
|
||||
url: '${baseURL}/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
#if ( $table.templateType != 2 )
|
||||
// 获得${table.classComment}分页
|
||||
export function get${simpleClassName}Page(params) {
|
||||
return request({
|
||||
url: '${baseURL}/page',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
#else
|
||||
// 获得${table.classComment}列表
|
||||
export function get${simpleClassName}List(params) {
|
||||
return request({
|
||||
url: '${baseURL}/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
#end
|
||||
// 导出${table.classComment} Excel
|
||||
export function export${simpleClassName}Excel(params) {
|
||||
return request({
|
||||
url: '${baseURL}/export-excel',
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ($table.templateType == 11)
|
||||
// 获得${subTable.classComment}分页
|
||||
export function get${subSimpleClassName}Page(params) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/page',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ($subTable.subJoinMany)
|
||||
// 获得${subTable.classComment}列表
|
||||
export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=' + ${subJoinColumn.javaField},
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
#else
|
||||
// 获得${subTable.classComment}
|
||||
export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=' + ${subJoinColumn.javaField},
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ($table.templateType == 11)
|
||||
// 新增${subTable.classComment}
|
||||
export function create${subSimpleClassName}(data) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 修改${subTable.classComment}
|
||||
export function update${subSimpleClassName}(data) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 删除${subTable.classComment}
|
||||
export function delete${subSimpleClassName}(id) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
// 获得${subTable.classComment}
|
||||
export function get${subSimpleClassName}(id) {
|
||||
return request({
|
||||
url: '${baseURL}/${subSimpleClassName_strikeCase}/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
#end
|
||||
#end
|
||||
@@ -1,205 +0,0 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
#set ($hasImageUploadColumn = true)
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<ImageUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
#set ($hasFileUploadColumn = true)
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<FileUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
#set ($hasEditorColumn = true)
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<editor v-model="formData.${javaField}" :min-height="192"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||
#else##没数据字典
|
||||
<el-checkbox>请选择字典生成</el-checkbox>
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
#if ($hasImageUploadColumn)
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
import Editor from '@/components/Editor';
|
||||
#end
|
||||
export default {
|
||||
name: "${subSimpleClassName}Form",
|
||||
components: {
|
||||
#if ($hasImageUploadColumn)
|
||||
ImageUpload,
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
FileUpload,
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
Editor,
|
||||
#end
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 弹出层标题
|
||||
dialogTitle: "",
|
||||
// 是否显示弹出层
|
||||
dialogVisible: false,
|
||||
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
formLoading: false,
|
||||
// 表单参数
|
||||
formData: {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
},
|
||||
// 表单校验
|
||||
formRules: {
|
||||
#foreach ($column in $subColumns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
|
||||
#end
|
||||
#end
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/** 打开弹窗 */
|
||||
async open(id, ${subJoinColumn.javaField}) {
|
||||
this.dialogVisible = true;
|
||||
this.reset();
|
||||
this.formData.${subJoinColumn.javaField} = ${subJoinColumn.javaField};
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
this.formLoading = true;
|
||||
try {
|
||||
const res = await ${simpleClassName}Api.get${subSimpleClassName}(id);
|
||||
this.formData = res.data;
|
||||
this.dialogTitle = "修改${subTable.classComment}";
|
||||
} finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
}
|
||||
this.dialogTitle = "新增${subTable.classComment}";
|
||||
},
|
||||
/** 提交按钮 */
|
||||
async submitForm() {
|
||||
await this.#[[$]]#refs["formRef"].validate();
|
||||
this.formLoading = true;
|
||||
try {
|
||||
const data = this.formData;
|
||||
// 修改的提交
|
||||
if (data.${primaryColumn.javaField}) {
|
||||
await ${simpleClassName}Api.update${subSimpleClassName}(data);
|
||||
this.#[[$modal]]#.msgSuccess("修改成功");
|
||||
this.dialogVisible = false;
|
||||
this.#[[$]]#emit('success');
|
||||
return;
|
||||
}
|
||||
// 添加的提交
|
||||
await ${simpleClassName}Api.create${subSimpleClassName}(data);
|
||||
this.#[[$modal]]#.msgSuccess("新增成功");
|
||||
this.dialogVisible = false;
|
||||
this.#[[$]]#emit('success');
|
||||
}finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
},
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.formData = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
};
|
||||
this.resetForm("formRef");
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,2 +0,0 @@
|
||||
## 主表的 normal 和 inner 使用相同的 form 表单
|
||||
#parse("codegen/vue/views/components/form_sub_normal.vue.vm")
|
||||
@@ -1,347 +0,0 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
<template>
|
||||
<div class="app-container">
|
||||
#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
v-loading="formLoading"
|
||||
label-width="0px"
|
||||
:inline-message="true"
|
||||
>
|
||||
<el-table :data="formData" class="-mt-10px">
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-input v-model="row.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
#set ($hasImageUploadColumn = true)
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<ImageUpload v-model="row.${javaField}"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
#set ($hasFileUploadColumn = true)
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<FileUpload v-model="row.${javaField}"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
#set ($hasEditorColumn = true)
|
||||
<el-table-column label="${comment}" min-width="400">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<Editor v-model="row.${javaField}" :min-height="192"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-select v-model="row.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-checkbox-group v-model="row.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||
#else##没数据字典
|
||||
<el-checkbox>请选择字典生成</el-checkbox>
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-radio-group v-model="row.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-date-picker clearable v-model="row.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template v-slot="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||
<template v-slot="{ $index }">
|
||||
<el-link @click="handleDelete($index)">—</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
<el-row justify="center" class="mt-3">
|
||||
<el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>
|
||||
</el-row>
|
||||
#else## 情况二:一对一,form
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
#set ($hasImageUploadColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<ImageUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
#set ($hasFileUploadColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<FileUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
#set ($hasEditorColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<Editor v-model="formData.${javaField}" :min-height="192"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||
#else##没数据字典
|
||||
<el-checkbox>请选择字典生成</el-checkbox>
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
#end
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
#if ($hasImageUploadColumn)
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
import Editor from '@/components/Editor';
|
||||
#end
|
||||
export default {
|
||||
name: "${subSimpleClassName}Form",
|
||||
components: {
|
||||
#if ($hasImageUploadColumn)
|
||||
ImageUpload,
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
FileUpload,
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
Editor,
|
||||
#end
|
||||
},
|
||||
props:[
|
||||
'${subJoinColumn.javaField}'
|
||||
],// ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
data() {
|
||||
return {
|
||||
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
formLoading: false,
|
||||
// 表单参数
|
||||
formData: [],
|
||||
// 表单校验
|
||||
formRules: {
|
||||
#foreach ($column in $subColumns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
|
||||
#end
|
||||
#end
|
||||
},
|
||||
};
|
||||
},
|
||||
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
${subJoinColumn.javaField}:{
|
||||
handler(val) {
|
||||
// 1. 重置表单
|
||||
#if ( $subTable.subJoinMany )
|
||||
this.formData = []
|
||||
#else
|
||||
this.formData = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
#end
|
||||
// 2. val 非空,则加载数据
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.formLoading = true;
|
||||
// 这里还是需要获取一下 this 的不然取不到 formData
|
||||
const that = this;
|
||||
#if ( $subTable.subJoinMany )
|
||||
${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val).then(function (res){
|
||||
that.formData = res.data;
|
||||
})
|
||||
#else
|
||||
${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val).then(function (res){
|
||||
const data = res.data;
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
that.formData = data;
|
||||
})
|
||||
#end
|
||||
} finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
#if ( $subTable.subJoinMany )
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
const row = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
row.${subJoinColumn.javaField} = this.${subJoinColumn.javaField};
|
||||
this.formData.push(row);
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(index) {
|
||||
this.formData.splice(index, 1);
|
||||
},
|
||||
#end
|
||||
/** 表单校验 */
|
||||
validate(){
|
||||
return this.#[[$]]#refs["formRef"].validate();
|
||||
},
|
||||
/** 表单值 */
|
||||
getData(){
|
||||
return this.formData;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,165 +0,0 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
<template>
|
||||
<div class="app-container">
|
||||
#if ($table.templateType == 11)
|
||||
<!-- 操作工具栏 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||
v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
#end
|
||||
## 列表
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.javaType == "LocalDateTime")## 时间类型
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
|
||||
<template v-slot="scope">
|
||||
<span>{{ parseTime(scope.row.${javaField}) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template v-slot="scope">
|
||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template v-slot="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.${primaryColumn.javaField})"
|
||||
v-hasPermi="['${permissionPrefix}:update']">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||
v-hasPermi="['${permissionPrefix}:delete']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
#if ($table.templateType == 11)
|
||||
<!-- 分页组件 -->
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"/>
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<${subSimpleClassName}Form ref="formRef" @success="getList" />
|
||||
#end
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
#if ($table.templateType == 11)
|
||||
import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue';
|
||||
#end
|
||||
export default {
|
||||
name: "${subSimpleClassName}List",
|
||||
#if ($table.templateType == 11)
|
||||
components: {
|
||||
${subSimpleClassName}Form
|
||||
},
|
||||
#end
|
||||
props:[
|
||||
'${subJoinColumn.javaField}'
|
||||
],// ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 列表的数据
|
||||
list: [],
|
||||
#if ($table.templateType == 11)
|
||||
// 列表的总页数
|
||||
total: 0,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
${subJoinColumn.javaField}: undefined
|
||||
}
|
||||
#end
|
||||
};
|
||||
},
|
||||
#if ($table.templateType != 11)
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
#end
|
||||
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
${subJoinColumn.javaField}:{
|
||||
handler(val) {
|
||||
this.queryParams.${subJoinColumn.javaField} = val;
|
||||
if (val){
|
||||
this.handleQuery();
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 查询列表 */
|
||||
async getList() {
|
||||
try {
|
||||
this.loading = true;
|
||||
#if ($table.templateType == 11)
|
||||
const res = await ${simpleClassName}Api.get${subSimpleClassName}Page(this.queryParams);
|
||||
this.list = res.data.list;
|
||||
this.total = res.data.total;
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
const res = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(this.${subJoinColumn.javaField});
|
||||
this.list = res.data;
|
||||
#else
|
||||
const res = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(this.${subJoinColumn.javaField});
|
||||
const data = res.data;
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
this.list.push(data);
|
||||
#end
|
||||
#end
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNo = 1;
|
||||
this.getList();
|
||||
},
|
||||
#if ($table.templateType == 11)
|
||||
/** 添加/修改操作 */
|
||||
openForm(id) {
|
||||
if (!this.${subJoinColumn.javaField}) {
|
||||
this.#[[$modal]]#.msgError('请选择一个${table.classComment}');
|
||||
return;
|
||||
}
|
||||
this.#[[$]]#refs["formRef"].open(id, this.${subJoinColumn.javaField});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
async handleDelete(row) {
|
||||
const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
|
||||
await this.#[[$modal]]#.confirm('是否确认删除${table.classComment}编号为"' + ${primaryColumn.javaField} + '"的数据项?');
|
||||
try {
|
||||
await ${simpleClassName}Api.delete${subSimpleClassName}(${primaryColumn.javaField});
|
||||
await this.getList();
|
||||
this.#[[$modal]]#.msgSuccess("删除成功");
|
||||
} catch {}
|
||||
},
|
||||
#end
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,4 +0,0 @@
|
||||
## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
|
||||
## 1)inner 使用 list 不分页,erp 使用 page 分页
|
||||
## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
|
||||
#parse("codegen/vue/views/components/list_sub_erp.vue.vm")
|
||||
@@ -1,320 +0,0 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||
#foreach($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<TreeSelect
|
||||
v-model="formData.${javaField}"
|
||||
:options="${classNameVar}Tree"
|
||||
:normalizer="normalizer"
|
||||
placeholder="请选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
#set ($hasImageUploadColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<ImageUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
#set ($hasFileUploadColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<FileUpload v-model="formData.${javaField}"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
#set ($hasEditorColumn = true)
|
||||
<el-form-item label="${comment}">
|
||||
<Editor v-model="formData.${javaField}" :min-height="192"/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||
#else##没数据字典
|
||||
<el-checkbox>请选择字典生成</el-checkbox>
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio label="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
<!-- 子表的表单 -->
|
||||
<el-tabs v-model="subTabsName">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
#end
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
#if ($hasImageUploadColumn)
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
import Editor from '@/components/Editor';
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
import TreeSelect from "@riophae/vue-treeselect";
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
|
||||
#end
|
||||
#end
|
||||
export default {
|
||||
name: "${simpleClassName}Form",
|
||||
components: {
|
||||
#if ($hasImageUploadColumn)
|
||||
ImageUpload,
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
FileUpload,
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
Editor,
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
TreeSelect,
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
${subSimpleClassName}Form,
|
||||
#end
|
||||
#end
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 弹出层标题
|
||||
dialogTitle: "",
|
||||
// 是否显示弹出层
|
||||
dialogVisible: false,
|
||||
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
formLoading: false,
|
||||
// 表单参数
|
||||
formData: {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
},
|
||||
// 表单校验
|
||||
formRules: {
|
||||
#foreach ($column in $columns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||
#end
|
||||
#end
|
||||
},
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
${classNameVar}Tree: [], // 树形结构
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
/** 子表的表单 */
|
||||
subTabsName: '$subClassNameVars.get(0)'
|
||||
#end
|
||||
#end
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/** 打开弹窗 */
|
||||
async open(id) {
|
||||
this.dialogVisible = true;
|
||||
this.reset();
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
this.formLoading = true;
|
||||
try {
|
||||
const res = await ${simpleClassName}Api.get${simpleClassName}(id);
|
||||
this.formData = res.data;
|
||||
this.title = "修改${table.classComment}";
|
||||
} finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
}
|
||||
this.title = "新增${table.classComment}";
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
await this.get${simpleClassName}Tree();
|
||||
#end
|
||||
},
|
||||
/** 提交按钮 */
|
||||
async submitForm() {
|
||||
// 校验主表
|
||||
await this.$refs["formRef"].validate();
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
// 校验子表
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
try {
|
||||
## 代码生成后会替换为正确的 refs
|
||||
await this.refs['${subClassNameVar}FormRef'].validate();
|
||||
} catch (e) {
|
||||
this.subTabsName = '${subClassNameVar}';
|
||||
return;
|
||||
}
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
this.formLoading = true;
|
||||
try {
|
||||
const data = this.formData;
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
// 拼接子表的数据
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = this.refs['${subClassNameVar}FormRef'].getData();
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
// 修改的提交
|
||||
if (data.${primaryColumn.javaField}) {
|
||||
await ${simpleClassName}Api.update${simpleClassName}(data);
|
||||
this.#[[$modal]]#.msgSuccess("修改成功");
|
||||
this.dialogVisible = false;
|
||||
this.#[[$]]#emit('success');
|
||||
return;
|
||||
}
|
||||
// 添加的提交
|
||||
await ${simpleClassName}Api.create${simpleClassName}(data);
|
||||
this.#[[$modal]]#.msgSuccess("新增成功");
|
||||
this.dialogVisible = false;
|
||||
this.#[[$]]#emit('success');
|
||||
} finally {
|
||||
this.formLoading = false;
|
||||
}
|
||||
},
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
/** 获得${table.classComment}树 */
|
||||
async get${simpleClassName}Tree() {
|
||||
this.${classNameVar}Tree = [];
|
||||
const res = await ${simpleClassName}Api.get${simpleClassName}List();
|
||||
const root = { id: 0, name: '顶级${table.classComment}', children: [] };
|
||||
root.children = this.handleTree(res.data, 'id', '${treeParentColumn.javaField}')
|
||||
this.${classNameVar}Tree.push(root)
|
||||
},
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
/** 转换${table.classComment}数据结构 */
|
||||
normalizer(node) {
|
||||
if (node.children && !node.children.length) {
|
||||
delete node.children;
|
||||
}
|
||||
#if ($treeNameColumn.javaField == "name")
|
||||
return {
|
||||
id: node.id,
|
||||
label: node.name,
|
||||
children: node.children
|
||||
};
|
||||
#else
|
||||
return {
|
||||
id: node.id,
|
||||
label: node['$treeNameColumn.javaField'],
|
||||
children: node.children
|
||||
};
|
||||
#end
|
||||
},
|
||||
#end
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.formData = {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
};
|
||||
this.resetForm("formRef");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,340 +0,0 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($column.htmlType == "input")
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="queryParams.${javaField}" placeholder="请输入${comment}" clearable @keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="queryParams.${javaField}" placeholder="请选择${comment}" clearable size="small">
|
||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
#else## 未设置 dictType 数据字典的情况
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")
|
||||
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker clearable v-model="queryParams.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${comment}" />
|
||||
</el-form-item>
|
||||
#else## 范围
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker v-model="queryParams.${javaField}" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
||||
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 操作工具栏 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||
v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
||||
v-hasPermi="['${permissionPrefix}:export']">导出</el-button>
|
||||
</el-col>
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">
|
||||
展开/折叠
|
||||
</el-button>
|
||||
</el-col>
|
||||
#end
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:highlight-current-row="true"
|
||||
:show-overflow-tooltip="true"
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
## 特殊:树表专属逻辑
|
||||
#elseif ( $table.templateType == 2 )
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
v-if="refreshTable"
|
||||
row-key="id"
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||
>
|
||||
#else
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
|
||||
<!-- 子表的列表 -->
|
||||
<el-table-column type="expand">
|
||||
<template #default="scope">
|
||||
<el-tabs value="$subClassNameVars.get(0)">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
|
||||
<template v-slot="scope">
|
||||
<span>{{ parseTime(scope.row.${javaField}) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif("" != $column.dictType)## 数据字典
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template v-slot="scope">
|
||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template v-slot="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.${primaryColumn.javaField})"
|
||||
v-hasPermi="['${permissionPrefix}:update']">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||
v-hasPermi="['${permissionPrefix}:delete']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
## 特殊:树表专属逻辑(树不需要分页)
|
||||
#if ( $table.templateType != 2 )
|
||||
<!-- 分页组件 -->
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"/>
|
||||
#end
|
||||
<!-- 对话框(添加 / 修改) -->
|
||||
<${simpleClassName}Form ref="formRef" @success="getList" />
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||
<!-- 子表的列表 -->
|
||||
<el-tabs v-model="subTabsName">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}List v-if="currentRow.id" :${subJoinColumn_strikeCase}="currentRow.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
#end
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||
import ${simpleClassName}Form from './${simpleClassName}Form.vue';
|
||||
#if ($hasImageUploadColumn)
|
||||
import ImageUpload from '@/components/ImageUpload';
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
import Editor from '@/components/Editor';
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType != 10 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue';
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
export default {
|
||||
name: "${simpleClassName}",
|
||||
components: {
|
||||
${simpleClassName}Form,
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType != 10 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
${subSimpleClassName}List,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#if ($hasImageUploadColumn)
|
||||
ImageUpload,
|
||||
#end
|
||||
#if ($hasFileUploadColumn)
|
||||
FileUpload,
|
||||
#end
|
||||
#if ($hasEditorColumn)
|
||||
Editor,
|
||||
#end
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 导出遮罩层
|
||||
exportLoading: false,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
// 总条数
|
||||
total: 0,
|
||||
#end
|
||||
// ${table.classComment}列表
|
||||
list: [],
|
||||
// 是否展开,默认全部展开
|
||||
isExpandAll: true,
|
||||
// 重新渲染表格状态
|
||||
refreshTable: true,
|
||||
// 选中行
|
||||
currentRow: {},
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
#end
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#if ($column.listOperationCondition != 'BETWEEN')
|
||||
$column.javaField: null,
|
||||
#end
|
||||
#if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||
$column.javaField: [],
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
},
|
||||
## 特殊:主子表专属逻辑-erp
|
||||
#if ( $table.templateType == 11)
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
/** 子表的列表 */
|
||||
subTabsName: '$subClassNameVars.get(0)'
|
||||
#end
|
||||
#end
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询列表 */
|
||||
async getList() {
|
||||
try {
|
||||
this.loading = true;
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType == 2 )
|
||||
const res = await ${simpleClassName}Api.get${simpleClassName}List(this.queryParams);
|
||||
this.list = this.handleTree(res.data, 'id', '${treeParentColumn.javaField}');
|
||||
#else
|
||||
const res = await ${simpleClassName}Api.get${simpleClassName}Page(this.queryParams);
|
||||
this.list = res.data.list;
|
||||
this.total = res.data.total;
|
||||
#end
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNo = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 添加/修改操作 */
|
||||
openForm(id) {
|
||||
this.#[[$]]#refs["formRef"].open(id);
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
async handleDelete(row) {
|
||||
const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
|
||||
await this.#[[$modal]]#.confirm('是否确认删除${table.classComment}编号为"' + ${primaryColumn.javaField} + '"的数据项?')
|
||||
try {
|
||||
await ${simpleClassName}Api.delete${simpleClassName}(${primaryColumn.javaField});
|
||||
await this.getList();
|
||||
this.#[[$modal]]#.msgSuccess("删除成功");
|
||||
} catch {}
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
async handleExport() {
|
||||
await this.#[[$modal]]#.confirm('是否确认导出所有${table.classComment}数据项?');
|
||||
try {
|
||||
this.exportLoading = true;
|
||||
const data = await ${simpleClassName}Api.export${simpleClassName}Excel(this.queryParams);
|
||||
this.#[[$]]#download.excel(data, '${table.classComment}.xls');
|
||||
} catch {
|
||||
} finally {
|
||||
this.exportLoading = false;
|
||||
}
|
||||
},
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 )
|
||||
/** 选中行操作 */
|
||||
handleCurrentChange(row) {
|
||||
this.currentRow = row;
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
/** 子表的列表 */
|
||||
this.subTabsName = '$subClassNameVars.get(0)';
|
||||
#end
|
||||
},
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
/** 展开/折叠操作 */
|
||||
toggleExpandAll() {
|
||||
this.refreshTable = false
|
||||
this.isExpandAll = !this.isExpandAll
|
||||
this.$nextTick(function () {
|
||||
this.refreshTable = true
|
||||
})
|
||||
}
|
||||
#end
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,115 +0,0 @@
|
||||
import request from '@/config/axios'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
// ${table.classComment} VO
|
||||
export interface ${simpleClassName}VO {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "short" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||
${column.javaField}: number // ${column.columnComment}
|
||||
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")
|
||||
${column.javaField}: Date // ${column.columnComment}
|
||||
#else
|
||||
${column.javaField}: ${column.javaType.toLowerCase()} // ${column.columnComment}
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
// ${table.classComment} API
|
||||
export const ${simpleClassName}Api = {
|
||||
#if ( $table.templateType != 2 )
|
||||
// 查询${table.classComment}分页
|
||||
get${simpleClassName}Page: async (params: any) => {
|
||||
return await request.get({ url: `${baseURL}/page`, params })
|
||||
},
|
||||
#else
|
||||
// 查询${table.classComment}列表
|
||||
get${simpleClassName}List: async (params) => {
|
||||
return await request.get({ url: `${baseURL}/list`, params })
|
||||
},
|
||||
#end
|
||||
|
||||
// 查询${table.classComment}详情
|
||||
get${simpleClassName}: async (id: number) => {
|
||||
return await request.get({ url: `${baseURL}/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增${table.classComment}
|
||||
create${simpleClassName}: async (data: ${simpleClassName}VO) => {
|
||||
return await request.post({ url: `${baseURL}/create`, data })
|
||||
},
|
||||
|
||||
// 修改${table.classComment}
|
||||
update${simpleClassName}: async (data: ${simpleClassName}VO) => {
|
||||
return await request.put({ url: `${baseURL}/update`, data })
|
||||
},
|
||||
|
||||
// 删除${table.classComment}
|
||||
delete${simpleClassName}: async (id: number) => {
|
||||
return await request.delete({ url: `${baseURL}/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出${table.classComment} Excel
|
||||
export${simpleClassName}: async (params) => {
|
||||
return await request.download({ url: `${baseURL}/export-excel`, params })
|
||||
},
|
||||
## 特殊:主子表专属逻辑
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
|
||||
// ==================== 子表($subTable.classComment) ====================
|
||||
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||
#if ( $table.templateType == 11 )
|
||||
|
||||
// 获得${subTable.classComment}分页
|
||||
get${subSimpleClassName}Page: async (params) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/page`, params })
|
||||
},
|
||||
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
|
||||
// 获得${subTable.classComment}列表
|
||||
get${subSimpleClassName}ListBy${SubJoinColumnName}: async (${subJoinColumn.javaField}) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
|
||||
},
|
||||
#else
|
||||
|
||||
// 获得${subTable.classComment}
|
||||
get${subSimpleClassName}By${SubJoinColumnName}: async (${subJoinColumn.javaField}) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField} })
|
||||
},
|
||||
#end
|
||||
#end
|
||||
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||
#if ( $table.templateType == 11 )
|
||||
// 新增${subTable.classComment}
|
||||
create${subSimpleClassName}: async (data) => {
|
||||
return await request.post({ url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, data })
|
||||
},
|
||||
|
||||
// 修改${subTable.classComment}
|
||||
update${subSimpleClassName}: async (data) => {
|
||||
return await request.put({ url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, data })
|
||||
},
|
||||
|
||||
// 删除${subTable.classComment}
|
||||
delete${subSimpleClassName}: async (id: number) => {
|
||||
return await request.delete({ url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 获得${subTable.classComment}
|
||||
get${subSimpleClassName}: async (id: number) => {
|
||||
return await request.get({ url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id })
|
||||
},
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadImg v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadFile v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<Editor v-model="formData.${javaField}" height="150px" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-checkbox label="请选择字典生成" />
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="formData.${javaField}"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRules = reactive({
|
||||
#foreach ($column in $subColumns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number, ${subJoinColumn.javaField}: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
formData.value.${subJoinColumn.javaField} = ${subJoinColumn.javaField}
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await ${simpleClassName}Api.get${subSimpleClassName}(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value
|
||||
if (formType.value === 'create') {
|
||||
await ${simpleClassName}Api.create${subSimpleClassName}(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await ${simpleClassName}Api.update${subSimpleClassName}(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
@@ -1,2 +0,0 @@
|
||||
## 主表的 normal 和 inner 使用相同的 form 表单
|
||||
#parse("codegen/vue3/views/components/form_sub_normal.vue.vm")
|
||||
@@ -1,360 +0,0 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
<template>
|
||||
#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
v-loading="formLoading"
|
||||
label-width="0px"
|
||||
:inline-message="true"
|
||||
>
|
||||
<el-table :data="formData" class="-mt-10px">
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-input v-model="row.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<UploadImg v-model="row.${javaField}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<UploadFile v-model="row.${javaField}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
<el-table-column label="${comment}" min-width="400">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<Editor v-model="row.${javaField}" height="150px" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-select v-model="row.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-checkbox-group v-model="row.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-checkbox label="请选择字典生成" />
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-radio-group v-model="row.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-table-column label="${comment}" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-date-picker
|
||||
v-model="row.${javaField}"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-table-column label="${comment}" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||
<el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||
<template #default="{ $index }">
|
||||
<el-button @click="handleDelete($index)" link>—</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
<el-row justify="center" class="mt-3">
|
||||
<el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>
|
||||
</el-row>
|
||||
#else## 情况二:一对一,form
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadImg v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadFile v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<Editor v-model="formData.${javaField}" height="150px" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-checkbox label="请选择字典生成" />
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="formData.${javaField}"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
#end
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
|
||||
const props = defineProps<{
|
||||
${subJoinColumn.javaField}: undefined // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
}>()
|
||||
const formLoading = ref(false) // 表单的加载中
|
||||
const formData = ref([])
|
||||
const formRules = reactive({
|
||||
#foreach ($column in $subColumns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
() => props.${subJoinColumn.javaField},
|
||||
async (val) => {
|
||||
// 1. 重置表单
|
||||
#if ( $subTable.subJoinMany )
|
||||
formData.value = []
|
||||
#else
|
||||
formData.value = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
#end
|
||||
// 2. val 非空,则加载数据
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
formLoading.value = true
|
||||
#if ( $subTable.subJoinMany )
|
||||
formData.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val)
|
||||
#else
|
||||
const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val)
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
formData.value = data
|
||||
#end
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
#if ( $subTable.subJoinMany )
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
const row = {
|
||||
#foreach ($column in $subColumns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
row.${subJoinColumn.javaField} = props.${subJoinColumn.javaField}
|
||||
formData.value.push(row)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (index) => {
|
||||
formData.value.splice(index, 1)
|
||||
}
|
||||
#end
|
||||
|
||||
/** 表单校验 */
|
||||
const validate = () => {
|
||||
return formRef.value.validate()
|
||||
}
|
||||
|
||||
/** 表单值 */
|
||||
const getData = () => {
|
||||
return formData.value
|
||||
}
|
||||
|
||||
defineExpose({ validate, getData })
|
||||
</script>
|
||||
@@ -1,184 +0,0 @@
|
||||
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||
<template>
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
#if ($table.templateType == 11)
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['${permissionPrefix}:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
#end
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
#foreach($column in $subColumns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||
#elseif ($column.javaType == "LocalDateTime")## 时间类型
|
||||
<el-table-column
|
||||
label="${comment}"
|
||||
align="center"
|
||||
prop="${javaField}"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#if ($table.templateType == 11)
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['${permissionPrefix}:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['${permissionPrefix}:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
</el-table>
|
||||
#if ($table.templateType == 11)
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
#end
|
||||
</ContentWrap>
|
||||
#if ($table.templateType == 11)
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<${subSimpleClassName}Form ref="formRef" @success="getList" />
|
||||
#end
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import { ${simpleClassName}Api } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
#if ($table.templateType == 11)
|
||||
import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue'
|
||||
#end
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const props = defineProps<{
|
||||
${subJoinColumn.javaField}?: number // ${subJoinColumn.columnComment}(主表的关联字段)
|
||||
}>()
|
||||
const loading = ref(false) // 列表的加载中
|
||||
const list = ref([]) // 列表的数据
|
||||
#if ($table.templateType == 11)
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
${subJoinColumn.javaField}: undefined as unknown
|
||||
})
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
() => props.${subJoinColumn.javaField},
|
||||
(val: number) => {
|
||||
if (!val) {
|
||||
return
|
||||
}
|
||||
queryParams.${subJoinColumn.javaField} = val
|
||||
handleQuery()
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
#end
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
#if ($table.templateType == 11)
|
||||
const data = await ${simpleClassName}Api.get${subSimpleClassName}Page(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
#else
|
||||
#if ( $subTable.subJoinMany )
|
||||
list.value = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(props.${subJoinColumn.javaField})
|
||||
#else
|
||||
const data = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(props.${subJoinColumn.javaField})
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
list.value.push(data)
|
||||
#end
|
||||
#end
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
#if ($table.templateType == 11)
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
if (!props.${subJoinColumn.javaField}) {
|
||||
message.error('请选择一个${table.classComment}')
|
||||
return
|
||||
}
|
||||
formRef.value.open(type, id, props.${subJoinColumn.javaField})
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await ${simpleClassName}Api.delete${subSimpleClassName}(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
#end
|
||||
#if ($table.templateType != 11)
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
#end
|
||||
</script>
|
||||
@@ -1,4 +0,0 @@
|
||||
## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
|
||||
## 1)inner 使用 list 不分页,erp 使用 page 分页
|
||||
## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
|
||||
#parse("codegen/vue3/views/components/list_sub_erp.vue.vm")
|
||||
@@ -1,300 +0,0 @@
|
||||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
#foreach($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-tree-select
|
||||
v-model="formData.${javaField}"
|
||||
:data="${classNameVar}Tree"
|
||||
#if ($treeNameColumn.javaField == "name")
|
||||
:props="defaultProps"
|
||||
#else
|
||||
:props="{...defaultProps, label: '$treeNameColumn.javaField'}"
|
||||
#end
|
||||
check-strictly
|
||||
default-expand-all
|
||||
placeholder="请选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadImg v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<UploadFile v-model="formData.${javaField}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<Editor v-model="formData.${javaField}" height="150px" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-checkbox-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-checkbox
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else##没数据字典
|
||||
<el-checkbox label="请选择字典生成" />
|
||||
#end
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-radio-group v-model="formData.${javaField}">
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
<el-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
#else##没数据字典
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
#end
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="formData.${javaField}"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择${comment}"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")## 文本框
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</el-form>
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
<!-- 子表的表单 -->
|
||||
<el-tabs v-model="subTabsName">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
#end
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
|
||||
#end
|
||||
#end
|
||||
|
||||
/** ${table.classComment} 表单 */
|
||||
defineOptions({ name: '${simpleClassName}Form' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRules = reactive({
|
||||
#foreach ($column in $columns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
#set($comment=$column.columnComment)
|
||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
const ${classNameVar}Tree = ref() // 树形结构
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
|
||||
/** 子表的表单 */
|
||||
const subTabsName = ref('$subClassNameVars.get(0)')
|
||||
#foreach ($subClassNameVar in $subClassNameVars)
|
||||
const ${subClassNameVar}FormRef = ref()
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await ${simpleClassName}Api.get${simpleClassName}(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
await get${simpleClassName}Tree()
|
||||
#end
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
// 校验子表单
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
try {
|
||||
await ${subClassNameVar}FormRef.value.validate()
|
||||
} catch (e) {
|
||||
subTabsName.value = '${subClassNameVar}'
|
||||
return
|
||||
}
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as ${simpleClassName}VO
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||
#if ( $subTables && $subTables.size() > 0 )
|
||||
// 拼接子表的数据
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = ${subClassNameVar}FormRef.value.getData()
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
if (formType.value === 'create') {
|
||||
await ${simpleClassName}Api.create${simpleClassName}(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await ${simpleClassName}Api.update${simpleClassName}(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.createOperation || $column.updateOperation)
|
||||
#if ($column.htmlType == "checkbox")
|
||||
$column.javaField: [],
|
||||
#else
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
|
||||
/** 获得${table.classComment}树 */
|
||||
const get${simpleClassName}Tree = async () => {
|
||||
${classNameVar}Tree.value = []
|
||||
const data = await ${simpleClassName}Api.get${simpleClassName}List()
|
||||
const root: Tree = { id: 0, name: '顶级${table.classComment}', children: [] }
|
||||
root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')
|
||||
${classNameVar}Tree.value.push(root)
|
||||
}
|
||||
#end
|
||||
</script>
|
||||
@@ -1,374 +0,0 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "getIntDictOptions")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "getStrDictOptions")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "getBoolDictOptions")
|
||||
#end
|
||||
#if ($column.htmlType == "input")
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-input
|
||||
v-model="queryParams.${javaField}"
|
||||
placeholder="请输入${comment}"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-select
|
||||
v-model="queryParams.${javaField}"
|
||||
placeholder="请选择${comment}"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||
<el-option
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
#else## 未设置 dictType 数据字典的情况
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")
|
||||
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="queryParams.${javaField}"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="date"
|
||||
placeholder="选择${comment}"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
#else## 范围
|
||||
<el-form-item label="${comment}" prop="${javaField}">
|
||||
<el-date-picker
|
||||
v-model="queryParams.${javaField}"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['${permissionPrefix}:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['${permissionPrefix}:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
<el-button type="danger" plain @click="toggleExpandAll">
|
||||
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
|
||||
</el-button>
|
||||
#end
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
highlight-current-row
|
||||
@current-change="handleCurrentChange"
|
||||
>
|
||||
## 特殊:树表专属逻辑
|
||||
#elseif ( $table.templateType == 2 )
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
row-key="id"
|
||||
:default-expand-all="isExpandAll"
|
||||
v-if="refreshTable"
|
||||
>
|
||||
#else
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
#end
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
|
||||
<!-- 子表的列表 -->
|
||||
<el-table-column type="expand">
|
||||
<template #default="scope">
|
||||
<el-tabs model-value="$subClassNameVars.get(0)">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||
<el-table-column
|
||||
label="${comment}"
|
||||
align="center"
|
||||
prop="${javaField}"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['${permissionPrefix}:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['${permissionPrefix}:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<${simpleClassName}Form ref="formRef" @success="getList" />
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||
<!-- 子表的列表 -->
|
||||
<ContentWrap>
|
||||
<el-tabs model-value="$subClassNameVars.get(0)">
|
||||
#foreach ($subTable in $subTables)
|
||||
#set ($index = $foreach.count - 1)
|
||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="currentRow.id" />
|
||||
</el-tab-pane>
|
||||
#end
|
||||
</el-tabs>
|
||||
</ContentWrap>
|
||||
#end
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
import { handleTree } from '@/utils/tree'
|
||||
#end
|
||||
import download from '@/utils/download'
|
||||
import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
import ${simpleClassName}Form from './${simpleClassName}Form.vue'
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType != 10 )
|
||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||
import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue'
|
||||
#end
|
||||
#end
|
||||
|
||||
/** ${table.classComment} 列表 */
|
||||
defineOptions({ name: '${table.className}' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
const total = ref(0) // 列表的总页数
|
||||
#end
|
||||
const queryParams = reactive({
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType != 2 )
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
#end
|
||||
#foreach ($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#if ($column.listOperationCondition != 'BETWEEN')
|
||||
$column.javaField: undefined,
|
||||
#end
|
||||
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||
$column.javaField: [],
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||
#if ( $table.templateType == 2 )
|
||||
const data = await ${simpleClassName}Api.get${simpleClassName}List(queryParams)
|
||||
list.value = handleTree(data, 'id', '${treeParentColumn.javaField}')
|
||||
#else
|
||||
const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
#end
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await ${simpleClassName}Api.delete${simpleClassName}(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)
|
||||
download.excel(data, '${table.classComment}.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
## 特殊:主子表专属逻辑
|
||||
#if ( $table.templateType == 11 )
|
||||
|
||||
/** 选中行操作 */
|
||||
const currentRow = ref({}) // 选中行
|
||||
const handleCurrentChange = (row) => {
|
||||
currentRow.value = row
|
||||
}
|
||||
#end
|
||||
## 特殊:树表专属逻辑
|
||||
#if ( $table.templateType == 2 )
|
||||
|
||||
/** 展开/折叠操作 */
|
||||
const isExpandAll = ref(true) // 是否展开,默认全部展开
|
||||
const refreshTable = ref(true) // 重新渲染表格状态
|
||||
const toggleExpandAll = async () => {
|
||||
refreshTable.value = false
|
||||
isExpandAll.value = !isExpandAll.value
|
||||
await nextTick()
|
||||
refreshTable.value = true
|
||||
}
|
||||
#end
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
@@ -1,32 +0,0 @@
|
||||
import { defHttp } from '@/utils/http/axios'
|
||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||
|
||||
// 查询${table.classComment}列表
|
||||
export function get${simpleClassName}Page(params) {
|
||||
return defHttp.get({ url: '${baseURL}/page', params })
|
||||
}
|
||||
|
||||
// 查询${table.classComment}详情
|
||||
export function get${simpleClassName}(id: number) {
|
||||
return defHttp.get({ url: `${baseURL}/get?id=${id}` })
|
||||
}
|
||||
|
||||
// 新增${table.classComment}
|
||||
export function create${simpleClassName}(data) {
|
||||
return defHttp.post({ url: '${baseURL}/create', data })
|
||||
}
|
||||
|
||||
// 修改${table.classComment}
|
||||
export function update${simpleClassName}(data) {
|
||||
return defHttp.put({ url: '${baseURL}/update', data })
|
||||
}
|
||||
|
||||
// 删除${table.classComment}
|
||||
export function delete${simpleClassName}(id: number) {
|
||||
return defHttp.delete({ url: `${baseURL}/delete?id=${id}` })
|
||||
}
|
||||
|
||||
// 导出${table.classComment} Excel
|
||||
export function export${simpleClassName}(params) {
|
||||
return defHttp.download({ url: '${baseURL}/export-excel', params }, '${table.classComment}.xls')
|
||||
}
|
||||
@@ -1,260 +0,0 @@
|
||||
import type {BasicColumn, FormSchema} from '@/components/Table'
|
||||
import {useRender} from '@/components/Table'
|
||||
import {DICT_TYPE, getDictOptions} from '@/utils/dict'
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperationResult)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||
{
|
||||
title: '${comment}',
|
||||
dataIndex: '${javaField}',
|
||||
width: 180,
|
||||
customRender: ({ text }) => {
|
||||
return useRender.renderDate(text)
|
||||
},
|
||||
},
|
||||
#elseif("" != $column.dictType)## 数据字典
|
||||
{
|
||||
title: '${comment}',
|
||||
dataIndex: '${javaField}',
|
||||
width: 180,
|
||||
customRender: ({ text }) => {
|
||||
return useRender.renderDict(text, DICT_TYPE.$dictType.toUpperCase())
|
||||
},
|
||||
},
|
||||
#else
|
||||
{
|
||||
title: '${comment}',
|
||||
dataIndex: '${javaField}',
|
||||
width: 160,
|
||||
},
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
]
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($dictType=$column.dictType)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment=$column.columnComment)
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "number")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "string")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "boolean")
|
||||
#end
|
||||
{
|
||||
label: '${comment}',
|
||||
field: '${javaField}',
|
||||
#if ($column.htmlType == "input")
|
||||
component: 'Input',
|
||||
#elseif ($column.htmlType == "select")
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else## 未设置 dictType 数据字典的情况
|
||||
options: [],
|
||||
#end
|
||||
},
|
||||
#elseif ($column.htmlType == "radio")
|
||||
component: 'RadioButtonGroup',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else## 未设置 dictType 数据字典的情况
|
||||
options: [],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "datetime")
|
||||
component: 'RangePicker',
|
||||
#end
|
||||
colProps: { span: 8 },
|
||||
},
|
||||
#end
|
||||
#end
|
||||
]
|
||||
|
||||
export const createFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '编号',
|
||||
field: 'id',
|
||||
show: false,
|
||||
component: 'Input',
|
||||
},
|
||||
#foreach($column in $columns)
|
||||
#if ($column.createOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "number")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "string")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "boolean")
|
||||
#end
|
||||
#if (!$column.primaryKey)## 忽略主键,不用在表单里
|
||||
{
|
||||
label: '${comment}',
|
||||
field: '${javaField}',
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
required: true,
|
||||
#end
|
||||
#if ($column.htmlType == "input")
|
||||
component: 'Input',
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
component: 'FileUpload',
|
||||
componentProps: {
|
||||
fileType: 'image',
|
||||
maxCount: 1,
|
||||
},
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
component: 'FileUpload',
|
||||
componentProps: {
|
||||
fileType: 'file',
|
||||
maxCount: 1,
|
||||
},
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
component: 'Editor',
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
component: 'Checkbox',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
component: 'RadioButtonGroup',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
format: 'YYYY-MM-DD HH:mm:ss',
|
||||
valueFormat: 'x',
|
||||
},
|
||||
#elseif($column.htmlType == "textarea")## 文本域
|
||||
component: 'InputTextArea',
|
||||
#end
|
||||
},
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
]
|
||||
|
||||
export const updateFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '编号',
|
||||
field: 'id',
|
||||
show: false,
|
||||
component: 'Input',
|
||||
},
|
||||
#foreach($column in $columns)
|
||||
#if ($column.updateOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||
#set ($dictMethod = "number")
|
||||
#elseif ($javaType == "String")
|
||||
#set ($dictMethod = "string")
|
||||
#elseif ($javaType == "Boolean")
|
||||
#set ($dictMethod = "boolean")
|
||||
#end
|
||||
#if (!$column.primaryKey)## 忽略主键,不用在表单里
|
||||
{
|
||||
label: '${comment}',
|
||||
field: '${javaField}',
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||
required: true,
|
||||
#end
|
||||
#if ($column.htmlType == "input")
|
||||
component: 'Input',
|
||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||
component: 'FileUpload',
|
||||
componentProps: {
|
||||
fileType: 'image',
|
||||
maxCount: 1,
|
||||
},
|
||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||
component: 'FileUpload',
|
||||
componentProps: {
|
||||
fileType: 'file',
|
||||
maxCount: 1,
|
||||
},
|
||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||
component: 'Editor',
|
||||
#elseif($column.htmlType == "select")## 下拉框
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "checkbox")## 多选框
|
||||
component: 'Checkbox',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "radio")## 单选框
|
||||
component: 'RadioButtonGroup',
|
||||
componentProps: {
|
||||
#if ("" != $dictType)## 有数据字典
|
||||
options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), '$dictMethod'),
|
||||
#else##没数据字典
|
||||
options:[],
|
||||
#end
|
||||
},
|
||||
#elseif($column.htmlType == "datetime")## 时间框
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
format: 'YYYY-MM-DD HH:mm:ss',
|
||||
valueFormat: 'x',
|
||||
},
|
||||
#elseif($column.htmlType == "textarea")## 文本域
|
||||
component: 'InputTextArea',
|
||||
#end
|
||||
},
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
]
|
||||
@@ -1,58 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue'
|
||||
import { createFormSchema, updateFormSchema } from './${classNameVar}.data'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useMessage } from '@/hooks/web/useMessage'
|
||||
import { BasicForm, useForm } from '@/components/Form'
|
||||
import { BasicModal, useModalInner } from '@/components/Modal'
|
||||
import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
|
||||
defineOptions({ name: '${table.className}Modal' })
|
||||
|
||||
const emit = defineEmits(['success', 'register'])
|
||||
|
||||
const { t } = useI18n()
|
||||
const { createMessage } = useMessage()
|
||||
const isUpdate = ref(true)
|
||||
|
||||
const [registerForm, { setFieldsValue, resetFields, resetSchema, validate }] = useForm({
|
||||
labelWidth: 120,
|
||||
baseColProps: { span: 24 },
|
||||
schemas: createFormSchema,
|
||||
showActionButtonGroup: false,
|
||||
actionColOptions: { span: 23 },
|
||||
})
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
resetFields()
|
||||
setModalProps({ confirmLoading: false })
|
||||
isUpdate.value = !!data?.isUpdate
|
||||
if (unref(isUpdate)) {
|
||||
resetSchema(updateFormSchema)
|
||||
const res = await get${simpleClassName}(data.record.id)
|
||||
setFieldsValue({ ...res })
|
||||
}
|
||||
})
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate()
|
||||
setModalProps({ confirmLoading: true })
|
||||
if (unref(isUpdate))
|
||||
await update${simpleClassName}(values)
|
||||
else
|
||||
await create${simpleClassName}(values)
|
||||
|
||||
closeModal()
|
||||
emit('success')
|
||||
createMessage.success(t('common.saveSuccessText'))
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" :title="isUpdate ? t('action.edit') : t('action.create')" @register="registerModal" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
@@ -1,92 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import ${simpleClassName}Modal from './${simpleClassName}Modal.vue'
|
||||
import { columns, searchFormSchema } from './${classNameVar}.data'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useMessage } from '@/hooks/web/useMessage'
|
||||
import { useModal } from '@/components/Modal'
|
||||
import { IconEnum } from '@/enums/appEnum'
|
||||
import { BasicTable, TableAction, useTable } from '@/components/Table'
|
||||
import { delete${simpleClassName}, export${simpleClassName}, get${simpleClassName}Page } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
|
||||
defineOptions({ name: '${table.className}' })
|
||||
|
||||
const { t } = useI18n()
|
||||
const { createConfirm, createMessage } = useMessage()
|
||||
const [registerModal, { openModal }] = useModal()
|
||||
|
||||
const [registerTable, { getForm, reload }] = useTable({
|
||||
title: '${table.classComment}列表',
|
||||
api: get${simpleClassName}Page,
|
||||
columns,
|
||||
formConfig: { labelWidth: 120, schemas: searchFormSchema },
|
||||
useSearchForm: true,
|
||||
showTableSetting: true,
|
||||
actionColumn: {
|
||||
width: 140,
|
||||
title: t('common.action'),
|
||||
dataIndex: 'action',
|
||||
fixed: 'right',
|
||||
},
|
||||
})
|
||||
|
||||
function handleCreate() {
|
||||
openModal(true, { isUpdate: false })
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, { record, isUpdate: true })
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
createConfirm({
|
||||
title: t('common.exportTitle'),
|
||||
iconType: 'warning',
|
||||
content: t('common.exportMessage'),
|
||||
async onOk() {
|
||||
await export${simpleClassName}(getForm().getFieldsValue())
|
||||
createMessage.success(t('common.exportSuccessText'))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
await delete${simpleClassName}(record.id)
|
||||
createMessage.success(t('common.delSuccessText'))
|
||||
reload()
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #toolbar>
|
||||
<a-button type="primary" v-auth="['${permissionPrefix}:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
|
||||
{{ t('action.create') }}
|
||||
</a-button>
|
||||
<a-button v-auth="['${permissionPrefix}:export']" :preIcon="IconEnum.EXPORT" @click="handleExport">
|
||||
{{ t('action.export') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: '${permissionPrefix}:update', onClick: handleEdit.bind(null, record) },
|
||||
{
|
||||
icon: IconEnum.DELETE,
|
||||
danger: true,
|
||||
label: t('action.delete'),
|
||||
auth: '${permissionPrefix}:delete',
|
||||
popConfirm: {
|
||||
title: t('common.delMessage'),
|
||||
placement: 'left',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<${simpleClassName}Modal @register="registerModal" @success="reload()" />
|
||||
</div>
|
||||
</template>
|
||||
20
tashow-module/tashow-module-pay/Dockerfile
Normal file
20
tashow-module/tashow-module-pay/Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
||||
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
|
||||
## 感谢复旦核博士的建议!灰子哥,牛皮!
|
||||
FROM eclipse-temurin:21-jre
|
||||
|
||||
|
||||
## 创建目录,并使用它作为工作目录
|
||||
RUN mkdir -p /yudao-module-pay-biz
|
||||
WORKDIR /yudao-module-pay-biz
|
||||
## 将后端项目的 Jar 文件,复制到镜像中
|
||||
COPY ./target/yudao-module-pay-biz.jar app.jar
|
||||
|
||||
## 设置 TZ 时区
|
||||
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
|
||||
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m"
|
||||
|
||||
## 暴露后端项目的 48080 端口
|
||||
EXPOSE 48085
|
||||
|
||||
## 启动后端项目
|
||||
CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar
|
||||
97
tashow-module/tashow-module-pay/pom.xml
Normal file
97
tashow-module/tashow-module-pay/pom.xml
Normal file
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-module</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>tashow-module-pay</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
pay 模块,我们放支付业务,提供业务的支付能力。
|
||||
例如说:商户、应用、支付、退款等等
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Cloud 基础 -->
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-framework-env</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖服务 -->
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-pay-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-framework-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-data-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RPC 远程调用相关 -->
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-framework-rpc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 注册中心相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Config 配置中心相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>com.tashow.cloud</groupId>
|
||||
<artifactId>tashow-data-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.tashow.cloud.pay;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* 项目的启动类
|
||||
*
|
||||
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class PayServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
|
||||
SpringApplication.run(PayServerApplication.class, args);
|
||||
|
||||
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.tashow.cloud.pay.api.order;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
|
||||
import com.tashow.cloud.pay.convert.order.PayOrderConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.order.PayOrderDO;
|
||||
import com.tashow.cloud.pay.service.order.PayOrderService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class PayOrderApiImpl implements PayOrderApi {
|
||||
|
||||
@Resource
|
||||
private PayOrderService payOrderService;
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> createOrder(PayOrderCreateReqDTO reqDTO) {
|
||||
return success(payOrderService.createOrder(reqDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<PayOrderRespDTO> getOrder(Long id) {
|
||||
PayOrderDO order = payOrderService.getOrder(id);
|
||||
return success(PayOrderConvert.INSTANCE.convert2(order));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updatePayOrderPrice(Long id, Integer payPrice) {
|
||||
payOrderService.updatePayOrderPrice(id, payPrice);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.tashow.cloud.pay.api.refund;
|
||||
|
||||
import com.tashow.cloud.common.pojo.CommonResult;
|
||||
import com.tashow.cloud.pay.convert.refund.PayRefundConvert;
|
||||
import com.tashow.cloud.pay.service.refund.PayRefundService;
|
||||
import com.tashow.cloud.payapi.api.refund.PayRefundApi;
|
||||
import com.tashow.cloud.sdk.payment.dto.refund.PayRefundRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static com.tashow.cloud.common.pojo.CommonResult.success;
|
||||
|
||||
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class PayRefundApiImpl implements PayRefundApi {
|
||||
|
||||
@Resource
|
||||
private PayRefundService payRefundService;
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> createRefund(PayRefundCreateReqDTO reqDTO) {
|
||||
return success(payRefundService.createPayRefund(reqDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<PayRefundRespDTO> getRefund(Long id) {
|
||||
return success(PayRefundConvert.INSTANCE.convert02(payRefundService.getRefund(id)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.tashow.cloud.pay.api.transfer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO;
|
||||
import com.tashow.cloud.pay.dal.dataobject.transfer.PayTransferDO;
|
||||
import com.tashow.cloud.pay.service.transfer.PayTransferService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 转账单 API 实现类
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class PayTransferApiImpl implements PayTransferApi {
|
||||
|
||||
@Resource
|
||||
private PayTransferService payTransferService;
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> createTransfer(PayTransferCreateReqDTO reqDTO) {
|
||||
return success(payTransferService.createTransfer(reqDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<PayTransferRespDTO> getTransfer(Long id) {
|
||||
PayTransferDO transfer = payTransferService.getTransfer(id);
|
||||
return success(BeanUtils.toBean(transfer, PayTransferRespDTO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.tashow.cloud.pay.api.wallet;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO;
|
||||
import com.tashow.cloud.pay.dal.dataobject.wallet.PayWalletDO;
|
||||
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
|
||||
import com.tashow.cloud.pay.service.wallet.PayWalletService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.*;
|
||||
|
||||
/**
|
||||
* 钱包 API 实现类
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class PayWalletApiImpl implements PayWalletApi {
|
||||
|
||||
@Resource
|
||||
private PayWalletService payWalletService;
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> addWalletBalance(PayWalletAddBalanceReqDTO reqDTO) {
|
||||
// 创建或获取钱包
|
||||
PayWalletDO wallet = payWalletService.getOrCreateWallet(reqDTO.getUserId(), reqDTO.getUserType());
|
||||
Assert.notNull(wallet, "钱包({}/{})不存在", reqDTO.getUserId(), reqDTO.getUserType());
|
||||
|
||||
// 增加余额
|
||||
PayWalletBizTypeEnum bizType = PayWalletBizTypeEnum.valueOf(reqDTO.getBizType());
|
||||
payWalletService.addWalletBalance(wallet.getId(), reqDTO.getBizId(), bizType, reqDTO.getPrice());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.tashow.cloud.pay.controller.admin.app;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.pay.controller.admin.app.vo.*;
|
||||
import com.tashow.cloud.pay.controller.admin.app.vo.*;
|
||||
import com.tashow.cloud.payapi.controller.admin.app.vo.*;
|
||||
import com.tashow.cloud.pay.convert.app.PayAppConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.app.PayAppDO;
|
||||
import com.tashow.cloud.pay.dal.dataobject.channel.PayChannelDO;
|
||||
import com.tashow.cloud.pay.service.app.PayAppService;
|
||||
import com.tashow.cloud.pay.service.channel.PayChannelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Slf4j
|
||||
@Tag(name = "管理后台 - 支付应用信息")
|
||||
@RestController
|
||||
@RequestMapping("/pay/app")
|
||||
@Validated
|
||||
public class PayAppController {
|
||||
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
@Resource
|
||||
private PayChannelService channelService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建支付应用信息")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:create')")
|
||||
public CommonResult<Long> createApp(@Valid @RequestBody PayAppCreateReqVO createReqVO) {
|
||||
return success(appService.createApp(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新支付应用信息")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:update')")
|
||||
public CommonResult<Boolean> updateApp(@Valid @RequestBody PayAppUpdateReqVO updateReqVO) {
|
||||
appService.updateApp(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@Operation(summary = "更新支付应用状态")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:update')")
|
||||
public CommonResult<Boolean> updateAppStatus(@Valid @RequestBody PayAppUpdateStatusReqVO updateReqVO) {
|
||||
appService.updateAppStatus(updateReqVO.getId(), updateReqVO.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除支付应用信息")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:delete')")
|
||||
public CommonResult<Boolean> deleteApp(@RequestParam("id") Long id) {
|
||||
appService.deleteApp(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得支付应用信息")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:query')")
|
||||
public CommonResult<PayAppRespVO> getApp(@RequestParam("id") Long id) {
|
||||
PayAppDO app = appService.getApp(id);
|
||||
return success(PayAppConvert.INSTANCE.convert(app));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得支付应用信息分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:query')")
|
||||
public CommonResult<PageResult<PayAppPageItemRespVO>> getAppPage(@Valid PayAppPageReqVO pageVO) {
|
||||
// 得到应用分页列表
|
||||
PageResult<PayAppDO> pageResult = appService.getAppPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty());
|
||||
}
|
||||
|
||||
// 得到所有的应用编号,查出所有的渠道,并移除未启用的渠道
|
||||
List<PayChannelDO> channels = channelService.getChannelListByAppIds(
|
||||
convertList(pageResult.getList(), PayAppDO::getId));
|
||||
channels.removeIf(channel -> !CommonStatusEnum.ENABLE.getStatus().equals(channel.getStatus()));
|
||||
|
||||
// 拼接后返回
|
||||
return success(PayAppConvert.INSTANCE.convertPage(pageResult, channels));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得应用列表")
|
||||
@PreAuthorize("@ss.hasPermission('pay:merchant:query')")
|
||||
public CommonResult<List<PayAppRespVO>> getAppList() {
|
||||
List<PayAppDO> appListDO = appService.getAppList();
|
||||
return success(PayAppConvert.INSTANCE.convertList(appListDO));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.tashow.cloud.pay.controller.admin.app.vo;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayAppBaseVO {
|
||||
|
||||
@Schema(description = "应用标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
|
||||
@NotEmpty(message = "应用标识不能为空")
|
||||
private String appKey;
|
||||
|
||||
@Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "小豆")
|
||||
@NotNull(message = "应用名不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@NotNull(message = "开启状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "我是一个测试应用")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "支付结果的回调地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/pay-callback")
|
||||
@NotNull(message = "支付结果的回调地址不能为空")
|
||||
@URL(message = "支付结果的回调地址必须为 URL 格式")
|
||||
private String orderNotifyUrl;
|
||||
|
||||
@Schema(description = "退款结果的回调地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/refund-callback")
|
||||
@NotNull(message = "退款结果的回调地址不能为空")
|
||||
@URL(message = "退款结果的回调地址必须为 URL 格式")
|
||||
private String refundNotifyUrl;
|
||||
|
||||
@Schema(description = "转账结果的回调地址", example = "http://127.0.0.1:48080/transfer-callback")
|
||||
@URL(message = "转账结果的回调地址必须为 URL 格式")
|
||||
private String transferNotifyUrl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tashow.cloud.pay.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 支付应用信息创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppCreateReqVO extends PayAppBaseVO {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.tashow.cloud.pay.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - 支付应用信息分页查询 Response VO,相比于支付信息,还会多出应用渠道的开关信息")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppPageItemRespVO extends PayAppBaseVO {
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "已配置的支付渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "[alipay_pc, alipay_wap]")
|
||||
private Set<String> channelCodes;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.tashow.cloud.pay.controller.admin.app.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 支付应用信息分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "应用名", example = "小豆")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "应用标识", example = "yudao")
|
||||
private String appKey;
|
||||
|
||||
@Schema(description = "开启状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tashow.cloud.pay.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 支付应用信息 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppRespVO extends PayAppBaseVO {
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "应用标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
|
||||
private String appKey;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.tashow.cloud.pay.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 支付应用信息更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppUpdateReqVO extends PayAppBaseVO {
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.tashow.cloud.pay.controller.admin.app.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 应用更新状态 Request VO")
|
||||
@Data
|
||||
public class PayAppUpdateStatusReqVO {
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "状态,见 SysCommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.tashow.cloud.pay.controller.admin.channel;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import com.tashow.cloud.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.channel.vo.PayChannelRespVO;
|
||||
import com.tashow.cloud.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
||||
import com.tashow.cloud.pay.convert.channel.PayChannelConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.channel.PayChannelDO;
|
||||
import com.tashow.cloud.pay.service.channel.PayChannelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 支付渠道")
|
||||
@RestController
|
||||
@RequestMapping("/pay/channel")
|
||||
@Validated
|
||||
public class PayChannelController {
|
||||
|
||||
@Resource
|
||||
private PayChannelService channelService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建支付渠道 ")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:create')")
|
||||
public CommonResult<Long> createChannel(@Valid @RequestBody PayChannelCreateReqVO createReqVO) {
|
||||
return success(channelService.createChannel(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新支付渠道 ")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:update')")
|
||||
public CommonResult<Boolean> updateChannel(@Valid @RequestBody PayChannelUpdateReqVO updateReqVO) {
|
||||
channelService.updateChannel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除支付渠道 ")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:delete')")
|
||||
public CommonResult<Boolean> deleteChannel(@RequestParam("id") Long id) {
|
||||
channelService.deleteChannel(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得支付渠道")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
||||
public CommonResult<PayChannelRespVO> getChannel(@RequestParam(value = "id", required = false) Long id,
|
||||
@RequestParam(value = "appId", required = false) Long appId,
|
||||
@RequestParam(value = "code", required = false) String code) {
|
||||
PayChannelDO channel = null;
|
||||
if (id != null) {
|
||||
channel = channelService.getChannel(id);
|
||||
} else if (appId != null && code != null) {
|
||||
channel = channelService.getChannelByAppIdAndCode(appId, code);
|
||||
}
|
||||
return success(PayChannelConvert.INSTANCE.convert(channel));
|
||||
}
|
||||
|
||||
@GetMapping("/get-enable-code-list")
|
||||
@Operation(summary = "获得指定应用的开启的支付渠道编码列表")
|
||||
@Parameter(name = "appId", description = "应用编号", required = true, example = "1")
|
||||
public CommonResult<Set<String>> getEnableChannelCodeList(@RequestParam("appId") Long appId) {
|
||||
List<PayChannelDO> channels = channelService.getEnableChannelList(appId);
|
||||
return success(convertSet(channels, PayChannelDO::getCode));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.tashow.cloud.pay.controller.admin.channel.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 支付渠道 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayChannelBaseVO {
|
||||
|
||||
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "开启状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "我是小备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "渠道费率,单位:百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@NotNull(message = "渠道费率,单位:百分比不能为空")
|
||||
private Double feeRate;
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long appId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.tashow.cloud.pay.controller.admin.channel.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 支付渠道 创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelCreateReqVO extends PayChannelBaseVO {
|
||||
|
||||
@Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc")
|
||||
@NotNull(message = "渠道编码不能为空")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "渠道配置的 json 字符串")
|
||||
@NotBlank(message = "渠道配置不能为空")
|
||||
private String config;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.tashow.cloud.pay.controller.admin.channel.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 支付渠道 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelRespVO extends PayChannelBaseVO {
|
||||
|
||||
@Schema(description = "商户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "配置", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String config;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.tashow.cloud.pay.controller.admin.channel.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 支付渠道 更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelUpdateReqVO extends PayChannelBaseVO {
|
||||
|
||||
@Schema(description = "商户编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "商户编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "渠道配置的json字符串")
|
||||
@NotBlank(message = "渠道配置不能为空")
|
||||
private String config;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.tashow.cloud.pay.controller.admin.demo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO;
|
||||
import com.tashow.cloud.pay.controller.admin.demo.vo.order.PayDemoOrderCreateReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.demo.vo.order.PayDemoOrderRespVO;
|
||||
import com.tashow.cloud.pay.convert.demo.PayDemoOrderConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.demo.PayDemoOrderDO;
|
||||
import com.tashow.cloud.pay.service.demo.PayDemoOrderService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.validation.Valid;
|
||||
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.common.util.servlet.ServletUtils.getClientIP;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - 示例订单")
|
||||
@RestController
|
||||
@RequestMapping("/pay/demo-order")
|
||||
@Validated
|
||||
public class PayDemoOrderController {
|
||||
|
||||
@Resource
|
||||
private PayDemoOrderService payDemoOrderService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建示例订单")
|
||||
public CommonResult<Long> createDemoOrder(@Valid @RequestBody PayDemoOrderCreateReqVO createReqVO) {
|
||||
return success(payDemoOrderService.createDemoOrder(getLoginUserId(), createReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得示例订单分页")
|
||||
public CommonResult<PageResult<PayDemoOrderRespVO>> getDemoOrderPage(@Valid PageParam pageVO) {
|
||||
PageResult<PayDemoOrderDO> pageResult = payDemoOrderService.getDemoOrderPage(pageVO);
|
||||
return success(PayDemoOrderConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@PostMapping("/update-paid")
|
||||
@Operation(summary = "更新示例订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
||||
@PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现
|
||||
public CommonResult<Boolean> updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
|
||||
payDemoOrderService.updateDemoOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
|
||||
notifyReqDTO.getPayOrderId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/refund")
|
||||
@Operation(summary = "发起示例订单的退款")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> refundDemoOrder(@RequestParam("id") Long id) {
|
||||
payDemoOrderService.refundDemoOrder(id, getClientIP());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/update-refunded")
|
||||
@Operation(summary = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
||||
@PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现
|
||||
public CommonResult<Boolean> updateDemoOrderRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) {
|
||||
payDemoOrderService.updateDemoOrderRefunded(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
|
||||
notifyReqDTO.getPayRefundId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.tashow.cloud.pay.controller.admin.demo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayTransferNotifyReqDTO;
|
||||
import com.tashow.cloud.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.demo.vo.transfer.PayDemoTransferRespVO;
|
||||
import com.tashow.cloud.pay.convert.demo.PayDemoTransferConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.demo.PayDemoTransferDO;
|
||||
import com.tashow.cloud.pay.service.demo.PayDemoTransferService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 示例转账单")
|
||||
@RestController
|
||||
@RequestMapping("/pay/demo-transfer")
|
||||
@Validated
|
||||
public class PayDemoTransferController {
|
||||
@Resource
|
||||
private PayDemoTransferService demoTransferService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建示例转账订单")
|
||||
public CommonResult<Long> createDemoTransfer(@Valid @RequestBody PayDemoTransferCreateReqVO createReqVO) {
|
||||
return success(demoTransferService.createDemoTransfer(createReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得示例转账订单分页")
|
||||
public CommonResult<PageResult<PayDemoTransferRespVO>> getDemoTransferPage(@Valid PageParam pageVO) {
|
||||
PageResult<PayDemoTransferDO> pageResult = demoTransferService.getDemoTransferPage(pageVO);
|
||||
return success(PayDemoTransferConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@PostMapping("/update-status")
|
||||
@Operation(summary = "更新示例转账订单的转账状态") // 由 pay-module 转账服务,进行回调
|
||||
@PermitAll // 无需登录,安全由 PayDemoTransferService 内部校验实现
|
||||
public CommonResult<Boolean> updateDemoTransferStatus(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) {
|
||||
demoTransferService.updateDemoTransferStatus(Long.valueOf(notifyReqDTO.getMerchantTransferId()),
|
||||
notifyReqDTO.getPayTransferId());
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.tashow.cloud.pay.controller.admin.demo.vo.order;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 示例订单创建 Request VO")
|
||||
@Data
|
||||
public class PayDemoOrderCreateReqVO {
|
||||
|
||||
@Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17682")
|
||||
@NotNull(message = "商品编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.tashow.cloud.pay.controller.admin.demo.vo.order;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 示例订单 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayDemoOrderRespVO {
|
||||
|
||||
@Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23199")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17682")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商家备注", example = "李四")
|
||||
private String spuName;
|
||||
|
||||
@Schema(description = "价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "30381")
|
||||
private Integer price;
|
||||
|
||||
@Schema(description = "是否已支付", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean payStatus;
|
||||
|
||||
@Schema(description = "支付订单编号", example = "16863")
|
||||
private Long payOrderId;
|
||||
|
||||
@Schema(description = "订单支付时间")
|
||||
private LocalDateTime payTime;
|
||||
|
||||
@Schema(description = "支付渠道", example = "alipay_qr")
|
||||
private String payChannelCode;
|
||||
|
||||
@Schema(description = "支付退款编号", example = "23366")
|
||||
private Long payRefundId;
|
||||
|
||||
@Schema(description = "退款金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "14039")
|
||||
private Integer refundPrice;
|
||||
|
||||
@Schema(description = "退款时间")
|
||||
private LocalDateTime refundTime;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.tashow.cloud.pay.controller.admin.demo.vo.transfer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Validator;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum.Alipay;
|
||||
import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum.WxPay;
|
||||
|
||||
/**
|
||||
* @author jason
|
||||
*/
|
||||
@Schema(description = "管理后台 - 示例转账单创建 Request VO")
|
||||
@Data
|
||||
public class PayDemoTransferCreateReqVO {
|
||||
|
||||
@Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "转账类型不能为空")
|
||||
@InEnum(PayTransferTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "转账金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
@NotNull(message = "转账金额不能为空")
|
||||
@Min(value = 1, message = "转账金额必须大于零")
|
||||
private Integer price;
|
||||
|
||||
@Schema(description = "收款人姓名", example = "test1")
|
||||
@NotBlank(message = "收款人姓名不能为空", groups = {Alipay.class})
|
||||
private String userName;
|
||||
|
||||
// ========== 支付宝转账相关字段 ==========
|
||||
@Schema(description = "支付宝登录号,支持邮箱和手机号格式", example = "test1@@sandbox.com")
|
||||
@NotBlank(message = "支付宝登录号不能为空", groups = {Alipay.class})
|
||||
private String alipayLogonId;
|
||||
|
||||
// ========== 微信转账相关字段 ==========
|
||||
@Schema(description = "微信 openId", example = "oLefc4g5Gxx")
|
||||
@NotBlank(message = "微信 openId 不能为空", groups = {WxPay.class})
|
||||
private String openid;
|
||||
|
||||
|
||||
// ========== 转账到银行卡和钱包相关字段 待补充 ==========
|
||||
|
||||
public void validate(Validator validator) {
|
||||
PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(type);
|
||||
switch (transferType) {
|
||||
case ALIPAY_BALANCE: {
|
||||
ValidationUtils.validate(validator, this, Alipay.class);
|
||||
break;
|
||||
}
|
||||
case WX_BALANCE: {
|
||||
ValidationUtils.validate(validator, this, WxPay.class);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new UnsupportedOperationException("待实现");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.tashow.cloud.pay.controller.admin.demo.vo.transfer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 示例业务转账订单 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayDemoTransferRespVO {
|
||||
|
||||
@Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "转账金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22338")
|
||||
private Integer price;
|
||||
|
||||
@Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "收款人姓名", example = "test")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "支付宝登录号", example = "32167")
|
||||
private String alipayLogonId;
|
||||
|
||||
@Schema(description = "微信 openId", example = "31139")
|
||||
private String openid;
|
||||
|
||||
@Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer transferStatus;
|
||||
|
||||
@Schema(description = "转账订单编号", example = "23695")
|
||||
private Long payTransferId;
|
||||
|
||||
@Schema(description = "转账支付成功渠道")
|
||||
private String payChannelCode;
|
||||
|
||||
@Schema(description = "转账支付时间")
|
||||
private LocalDateTime transferTime;
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package com.tashow.cloud.pay.controller.admin.notify;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
|
||||
import com.tashow.cloud.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO;
|
||||
import com.tashow.cloud.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.notify.vo.PayNotifyTaskRespVO;
|
||||
import com.tashow.cloud.pay.convert.notify.PayNotifyTaskConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.app.PayAppDO;
|
||||
import com.tashow.cloud.pay.dal.dataobject.notify.PayNotifyLogDO;
|
||||
import com.tashow.cloud.pay.dal.dataobject.notify.PayNotifyTaskDO;
|
||||
import com.tashow.cloud.pay.service.app.PayAppService;
|
||||
import com.tashow.cloud.pay.service.channel.PayChannelService;
|
||||
import com.tashow.cloud.pay.service.notify.PayNotifyService;
|
||||
import com.tashow.cloud.pay.service.order.PayOrderService;
|
||||
import com.tashow.cloud.pay.service.refund.PayRefundService;
|
||||
import com.tashow.cloud.pay.service.transfer.PayTransferService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_FOUND;
|
||||
|
||||
@Tag(name = "管理后台 - 回调通知")
|
||||
@RestController
|
||||
@RequestMapping("/pay/notify")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class PayNotifyController {
|
||||
|
||||
@Resource
|
||||
private PayOrderService orderService;
|
||||
@Resource
|
||||
private PayRefundService refundService;
|
||||
@Resource
|
||||
private PayTransferService payTransferService;
|
||||
@Resource
|
||||
private PayNotifyService notifyService;
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
@Resource
|
||||
private PayChannelService channelService;
|
||||
|
||||
@PostMapping(value = "/order/{channelId}")
|
||||
@Operation(summary = "支付渠道的统一【支付】回调")
|
||||
@PermitAll
|
||||
public String notifyOrder(@PathVariable("channelId") Long channelId,
|
||||
@RequestParam(required = false) Map<String, String> params,
|
||||
@RequestBody(required = false) String body) {
|
||||
log.info("[notifyOrder][channelId({}) 回调数据({}/{})]", channelId, params, body);
|
||||
// 1. 校验支付渠道是否存在
|
||||
PayClient payClient = channelService.getPayClient(channelId);
|
||||
if (payClient == null) {
|
||||
log.error("[notifyOrder][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||
throw exception(CHANNEL_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 2. 解析通知数据
|
||||
PayOrderRespDTO notify = payClient.parseOrderNotify(params, body);
|
||||
orderService.notifyOrder(channelId, notify);
|
||||
return "success";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/refund/{channelId}")
|
||||
@Operation(summary = "支付渠道的统一【退款】回调")
|
||||
@PermitAll
|
||||
public String notifyRefund(@PathVariable("channelId") Long channelId,
|
||||
@RequestParam(required = false) Map<String, String> params,
|
||||
@RequestBody(required = false) String body) {
|
||||
log.info("[notifyRefund][channelId({}) 回调数据({}/{})]", channelId, params, body);
|
||||
// 1. 校验支付渠道是否存在
|
||||
PayClient payClient = channelService.getPayClient(channelId);
|
||||
if (payClient == null) {
|
||||
log.error("[notifyRefund][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||
throw exception(CHANNEL_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 2. 解析通知数据
|
||||
PayRefundRespDTO notify = payClient.parseRefundNotify(params, body);
|
||||
refundService.notifyRefund(channelId, notify);
|
||||
return "success";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/transfer/{channelId}")
|
||||
@Operation(summary = "支付渠道的统一【转账】回调")
|
||||
@PermitAll
|
||||
public String notifyTransfer(@PathVariable("channelId") Long channelId,
|
||||
@RequestParam(required = false) Map<String, String> params,
|
||||
@RequestBody(required = false) String body) {
|
||||
log.info("[notifyTransfer][channelId({}) 回调数据({}/{})]", channelId, params, body);
|
||||
// 1. 校验支付渠道是否存在
|
||||
PayClient payClient = channelService.getPayClient(channelId);
|
||||
if (payClient == null) {
|
||||
log.error("[notifyTransfer][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||
throw exception(CHANNEL_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 2. 解析通知数据
|
||||
PayTransferRespDTO notify = payClient.parseTransferNotify(params, body);
|
||||
payTransferService.notifyTransfer(channelId, notify);
|
||||
return "success";
|
||||
}
|
||||
|
||||
@GetMapping("/get-detail")
|
||||
@Operation(summary = "获得回调通知的明细")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:notify:query')")
|
||||
public CommonResult<PayNotifyTaskDetailRespVO> getNotifyTaskDetail(@RequestParam("id") Long id) {
|
||||
PayNotifyTaskDO task = notifyService.getNotifyTask(id);
|
||||
if (task == null) {
|
||||
return success(null);
|
||||
}
|
||||
// 拼接返回
|
||||
PayAppDO app = appService.getApp(task.getAppId());
|
||||
List<PayNotifyLogDO> logs = notifyService.getNotifyLogList(id);
|
||||
return success(PayNotifyTaskConvert.INSTANCE.convert(task, app, logs));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得回调通知分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:notify:query')")
|
||||
public CommonResult<PageResult<PayNotifyTaskRespVO>> getNotifyTaskPage(@Valid PayNotifyTaskPageReqVO pageVO) {
|
||||
PageResult<PayNotifyTaskDO> pageResult = notifyService.getNotifyTaskPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty());
|
||||
}
|
||||
// 拼接返回
|
||||
Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTaskDO::getAppId));
|
||||
return success(PayNotifyTaskConvert.INSTANCE.convertPage(pageResult, appMap));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.tashow.cloud.pay.controller.admin.notify.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 回调通知 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayNotifyTaskBaseVO {
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10636")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "通知类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Byte type;
|
||||
|
||||
@Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6722")
|
||||
private Long dataId;
|
||||
|
||||
@Schema(description = "通知状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Byte status;
|
||||
|
||||
@Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26697")
|
||||
private String merchantOrderId;
|
||||
|
||||
@Schema(description = "下一次通知时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime nextNotifyTime;
|
||||
|
||||
@Schema(description = "最后一次执行时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime lastExecuteTime;
|
||||
|
||||
@Schema(description = "当前通知次数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Byte notifyTimes;
|
||||
|
||||
@Schema(description = "最大可通知次数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Byte maxNotifyTimes;
|
||||
|
||||
@Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
|
||||
private String notifyUrl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
package com.tashow.cloud.pay.controller.admin.notify.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 回调通知的明细 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayNotifyTaskDetailRespVO extends PayNotifyTaskBaseVO {
|
||||
|
||||
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "应用名称", example = "wx_pay")
|
||||
private String appName;
|
||||
|
||||
@Schema(description = "回调日志列表")
|
||||
private List<Log> logs;
|
||||
|
||||
@Schema(description = "管理后台 - 回调日志")
|
||||
@Data
|
||||
public static class Log {
|
||||
|
||||
@Schema(description = "日志编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8848")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "通知状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Byte status;
|
||||
|
||||
@Schema(description = "当前通知次数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Byte notifyTimes;
|
||||
|
||||
@Schema(description = "HTTP 响应结果", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String response;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.tashow.cloud.pay.controller.admin.notify.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 回调通知分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayNotifyTaskPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "应用编号", example = "10636")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "通知类型", example = "2")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "数据编号", example = "6722")
|
||||
private Long dataId;
|
||||
|
||||
@Schema(description = "通知状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "商户订单编号", example = "26697")
|
||||
private String merchantOrderId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tashow.cloud.pay.controller.admin.notify.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 回调通知 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayNotifyTaskRespVO extends PayNotifyTaskBaseVO {
|
||||
|
||||
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "应用名称", example = "wx_pay")
|
||||
private String appName;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
|
||||
import com.tashow.cloud.pay.controller.admin.order.vo.*;
|
||||
import com.tashow.cloud.payapi.controller.admin.order.vo.*;
|
||||
import com.tashow.cloud.pay.convert.order.PayOrderConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.app.PayAppDO;
|
||||
import com.tashow.cloud.pay.dal.dataobject.order.PayOrderDO;
|
||||
import com.tashow.cloud.pay.dal.dataobject.order.PayOrderExtensionDO;
|
||||
import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
|
||||
import com.tashow.cloud.pay.framework.pay.core.WalletPayClient;
|
||||
import com.tashow.cloud.pay.service.app.PayAppService;
|
||||
import com.tashow.cloud.pay.service.order.PayOrderService;
|
||||
import com.google.common.collect.Maps;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType;
|
||||
|
||||
@Tag(name = "管理后台 - 支付订单")
|
||||
@RestController
|
||||
@RequestMapping("/pay/order")
|
||||
@Validated
|
||||
public class PayOrderController {
|
||||
|
||||
@Resource
|
||||
private PayOrderService orderService;
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得支付订单")
|
||||
@Parameters({
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024"),
|
||||
@Parameter(name = "sync", description = "是否同步", example = "true")
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('pay:order:query')")
|
||||
public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id,
|
||||
@RequestParam(value = "sync", required = false) Boolean sync) {
|
||||
PayOrderDO order = orderService.getOrder(id);
|
||||
// sync 仅在等待支付
|
||||
if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) {
|
||||
orderService.syncOrderQuietly(order.getId());
|
||||
// 重新查询,因为同步后,可能会有变化
|
||||
order = orderService.getOrder(id);
|
||||
}
|
||||
return success(BeanUtils.toBean(order, PayOrderRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-detail")
|
||||
@Operation(summary = "获得支付订单详情")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:order:query')")
|
||||
public CommonResult<PayOrderDetailsRespVO> getOrderDetail(@RequestParam("id") Long id) {
|
||||
PayOrderDO order = orderService.getOrder(id);
|
||||
if (order == null) {
|
||||
return success(null);
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
PayAppDO app = appService.getApp(order.getAppId());
|
||||
PayOrderExtensionDO orderExtension = orderService.getOrderExtension(order.getExtensionId());
|
||||
return success(PayOrderConvert.INSTANCE.convert(order, orderExtension, app));
|
||||
}
|
||||
|
||||
@PostMapping("/submit")
|
||||
@Operation(summary = "提交支付订单")
|
||||
public CommonResult<PayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) {
|
||||
// 1. 钱包支付事,需要额外传 user_id 和 user_type
|
||||
if (Objects.equals(reqVO.getChannelCode(), PayChannelEnum.WALLET.getCode())) {
|
||||
Map<String, String> channelExtras = reqVO.getChannelExtras() == null ?
|
||||
Maps.newHashMapWithExpectedSize(2) : reqVO.getChannelExtras();
|
||||
channelExtras.put(WalletPayClient.USER_ID_KEY, String.valueOf(getLoginUserId()));
|
||||
channelExtras.put(WalletPayClient.USER_TYPE_KEY, String.valueOf(getLoginUserType()));
|
||||
reqVO.setChannelExtras(channelExtras);
|
||||
}
|
||||
|
||||
// 2. 提交支付
|
||||
PayOrderSubmitRespVO respVO = orderService.submitOrder(reqVO, getClientIP());
|
||||
return success(respVO);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得支付订单分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:order:query')")
|
||||
public CommonResult<PageResult<PayOrderPageItemRespVO>> getOrderPage(@Valid PayOrderPageReqVO pageVO) {
|
||||
PageResult<PayOrderDO> pageResult = orderService.getOrderPage(pageVO);
|
||||
if (CollectionUtil.isEmpty(pageResult.getList())) {
|
||||
return success(new PageResult<>(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(pageResult.getList(), PayOrderDO::getAppId));
|
||||
return success(PayOrderConvert.INSTANCE.convertPage(pageResult, appMap));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出支付订单 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('pay:order:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<PayOrderDO> list = orderService.getOrderList(exportReqVO);
|
||||
if (CollectionUtil.isEmpty(list)) {
|
||||
ExcelUtils.write(response, "支付订单.xls", "数据",
|
||||
PayOrderExcelVO.class, new ArrayList<>());
|
||||
return;
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(list, PayOrderDO::getAppId));
|
||||
List<PayOrderExcelVO> excelList = PayOrderConvert.INSTANCE.convertList(list, appMap);
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 支付订单 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Data
|
||||
public class PayOrderBaseVO {
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "渠道编号", example = "2048")
|
||||
private Long channelId;
|
||||
|
||||
@Schema(description = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
|
||||
@NotNull(message = "商户订单编号不能为空")
|
||||
private String merchantOrderId;
|
||||
|
||||
@Schema(description = "商品标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆")
|
||||
@NotNull(message = "商品标题不能为空")
|
||||
private String subject;
|
||||
|
||||
@Schema(description = "商品描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是土豆")
|
||||
@NotNull(message = "商品描述不能为空")
|
||||
private String body;
|
||||
|
||||
@Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/pay/notify")
|
||||
@NotNull(message = "异步通知地址不能为空")
|
||||
private String notifyUrl;
|
||||
|
||||
@Schema(description = "支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@NotNull(message = "支付金额,单位:分不能为空")
|
||||
private Long price;
|
||||
|
||||
@Schema(description = "渠道手续费,单位:百分比", example = "10")
|
||||
private Double channelFeeRate;
|
||||
|
||||
@Schema(description = "渠道手续金额,单位:分", example = "100")
|
||||
private Integer channelFeePrice;
|
||||
|
||||
@Schema(description = "支付状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "支付状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
|
||||
@NotNull(message = "用户 IP不能为空")
|
||||
private String userIp;
|
||||
|
||||
@Schema(description = "订单失效时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "订单失效时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
@Schema(description = "订单支付成功时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@Schema(description = "支付成功的订单拓展单编号", example = "50")
|
||||
private Long extensionId;
|
||||
|
||||
@Schema(description = "支付订单号", example = "2048888")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "退款总金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@NotNull(message = "退款总金额,单位:分不能为空")
|
||||
private Long refundPrice;
|
||||
|
||||
@Schema(description = "渠道用户编号", example = "2048")
|
||||
private String channelUserId;
|
||||
|
||||
@Schema(description = "渠道订单号", example = "4096")
|
||||
private String channelOrderNo;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 支付订单详细信息 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayOrderDetailsRespVO extends PayOrderBaseVO {
|
||||
|
||||
@Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "应用名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||
private String appName;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 支付订单扩展
|
||||
*/
|
||||
private PayOrderExtension extension;
|
||||
|
||||
@Data
|
||||
@Schema(description = "支付订单扩展")
|
||||
public static class PayOrderExtension {
|
||||
|
||||
@Schema(description = "支付订单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "支付异步通知的内容")
|
||||
private String channelNotifyData;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.MoneyConvert;
|
||||
import cn.iocoder.yudao.module.pay.enums.DictTypeConstants;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付订单 Excel VO
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Data
|
||||
public class PayOrderExcelVO {
|
||||
|
||||
@ExcelProperty("编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ExcelProperty(value = "支付金额", converter = MoneyConvert.class)
|
||||
private Integer price;
|
||||
|
||||
@ExcelProperty(value = "退款金额", converter = MoneyConvert.class)
|
||||
private Integer refundPrice;
|
||||
|
||||
@ExcelProperty(value = "手续金额", converter = MoneyConvert.class)
|
||||
private Integer channelFeePrice;
|
||||
|
||||
@ExcelProperty("商户单号")
|
||||
private String merchantOrderId;
|
||||
|
||||
@ExcelProperty(value = "支付单号")
|
||||
private String no;
|
||||
|
||||
@ExcelProperty("渠道单号")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ExcelProperty(value = "支付状态", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.ORDER_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty(value = "渠道编号名称", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.CHANNEL_CODE)
|
||||
private String channelCode;
|
||||
|
||||
@ExcelProperty("订单支付成功时间")
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@ExcelProperty("订单失效时间")
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
@ExcelProperty(value = "应用名称")
|
||||
private String appName;
|
||||
|
||||
@ExcelProperty("商品标题")
|
||||
private String subject;
|
||||
|
||||
@ExcelProperty("商品描述")
|
||||
private String body;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 支付订单 Excel 导出 Request VO,参数和 PayOrderPageReqVO 是一致的")
|
||||
@Data
|
||||
public class PayOrderExportReqVO {
|
||||
|
||||
@Schema(description = "应用编号", example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "商户订单编号", example = "4096")
|
||||
private String merchantOrderId;
|
||||
|
||||
@Schema(description = "渠道编号", example = "1888")
|
||||
private String channelOrderNo;
|
||||
|
||||
@Schema(description = "支付单号", example = "2014888")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "支付状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 支付订单分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayOrderPageItemRespVO extends PayOrderBaseVO {
|
||||
|
||||
@Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "应用名称", example = "wx_pay")
|
||||
private String appName;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 支付订单分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayOrderPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "应用编号", example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "商户订单编号", example = "4096")
|
||||
private String merchantOrderId;
|
||||
|
||||
@Schema(description = "渠道编号", example = "1888")
|
||||
private String channelOrderNo;
|
||||
|
||||
@Schema(description = "支付单号", example = "2014888")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "支付状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 支付订单 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayOrderRespVO extends PayOrderBaseVO {
|
||||
|
||||
@Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 支付订单提交 Request VO")
|
||||
@Data
|
||||
public class PayOrderSubmitReqVO {
|
||||
|
||||
@Schema(description = "支付单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "支付单编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "支付渠道", requiredMode = Schema.RequiredMode.REQUIRED, example = "wx_pub")
|
||||
@NotEmpty(message = "支付渠道不能为空")
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数")
|
||||
private Map<String, String> channelExtras;
|
||||
|
||||
@Schema(description = "展示模式", example = "url") // 参见 {@link PayDisplayModeEnum} 枚举。如果不传递,则每个支付渠道使用默认的方式
|
||||
private String displayMode;
|
||||
|
||||
@Schema(description = "回跳地址")
|
||||
@URL(message = "回跳地址的格式必须是 URL")
|
||||
private String returnUrl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.tashow.cloud.pay.controller.admin.order.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 支付订单提交 Response VO")
|
||||
@Data
|
||||
public class PayOrderSubmitRespVO {
|
||||
|
||||
@Schema(description = "支付状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") // 参见 PayOrderStatusEnum 枚举
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "展示模式", requiredMode = Schema.RequiredMode.REQUIRED, example = "url") // 参见 PayDisplayModeEnum 枚举
|
||||
private String displayMode;
|
||||
@Schema(description = "展示内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String displayContent;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.tashow.cloud.pay.controller.admin.refund;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.*;
|
||||
import com.tashow.cloud.pay.controller.admin.refund.vo.*;
|
||||
import com.tashow.cloud.payapi.controller.admin.refund.vo.*;
|
||||
import com.tashow.cloud.pay.convert.refund.PayRefundConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.app.PayAppDO;
|
||||
import com.tashow.cloud.pay.dal.dataobject.refund.PayRefundDO;
|
||||
import com.tashow.cloud.pay.service.app.PayAppService;
|
||||
import com.tashow.cloud.pay.service.refund.PayRefundService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - 退款订单")
|
||||
@RestController
|
||||
@RequestMapping("/pay/refund")
|
||||
@Validated
|
||||
public class PayRefundController {
|
||||
|
||||
@Resource
|
||||
private PayRefundService refundService;
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得退款订单")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:refund:query')")
|
||||
public CommonResult<PayRefundDetailsRespVO> getRefund(@RequestParam("id") Long id) {
|
||||
PayRefundDO refund = refundService.getRefund(id);
|
||||
if (refund == null) {
|
||||
return success(new PayRefundDetailsRespVO());
|
||||
}
|
||||
|
||||
// 拼接数据
|
||||
PayAppDO app = appService.getApp(refund.getAppId());
|
||||
return success(PayRefundConvert.INSTANCE.convert(refund, app));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得退款订单分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:refund:query')")
|
||||
public CommonResult<PageResult<PayRefundPageItemRespVO>> getRefundPage(@Valid PayRefundPageReqVO pageVO) {
|
||||
PageResult<PayRefundDO> pageResult = refundService.getRefundPage(pageVO);
|
||||
if (CollectionUtil.isEmpty(pageResult.getList())) {
|
||||
return success(new PageResult<>(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 处理应用ID数据
|
||||
Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(pageResult.getList(), PayRefundDO::getAppId));
|
||||
return success(PayRefundConvert.INSTANCE.convertPage(pageResult, appMap));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出退款订单 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('pay:refund:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<PayRefundDO> list = refundService.getRefundList(exportReqVO);
|
||||
if (CollectionUtil.isEmpty(list)) {
|
||||
ExcelUtils.write(response, "退款订单.xls", "数据",
|
||||
PayRefundExcelVO.class, new ArrayList<>());
|
||||
return;
|
||||
}
|
||||
|
||||
// 拼接返回
|
||||
Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(list, PayRefundDO::getAppId));
|
||||
List<PayRefundExcelVO> excelList = PayRefundConvert.INSTANCE.convertList(list, appMap);
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "退款订单.xls", "数据", PayRefundExcelVO.class, excelList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.tashow.cloud.pay.controller.admin.refund.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 退款订单 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayRefundBaseVO {
|
||||
|
||||
@Schema(description = "外部退款号", requiredMode = Schema.RequiredMode.REQUIRED, example = "110")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "渠道编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||
private Long channelId;
|
||||
|
||||
@Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long orderId;
|
||||
|
||||
// ========== 商户相关字段 ==========
|
||||
|
||||
@Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "225")
|
||||
private String merchantOrderId;
|
||||
|
||||
@Schema(description = "商户退款订单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "512")
|
||||
private String merchantRefundId;
|
||||
|
||||
@Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String notifyUrl;
|
||||
|
||||
// ========== 退款相关字段 ==========
|
||||
|
||||
@Schema(description = "退款状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "支付金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
private Long payPrice;
|
||||
|
||||
@Schema(description = "退款金额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "200")
|
||||
private Long refundPrice;
|
||||
|
||||
@Schema(description = "退款原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "我要退了")
|
||||
private String reason;
|
||||
|
||||
@Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
|
||||
private String userIp;
|
||||
|
||||
// ========== 渠道相关字段 ==========
|
||||
|
||||
@Schema(description = "渠道订单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "233")
|
||||
private String channelOrderNo;
|
||||
|
||||
@Schema(description = "渠道退款单号", example = "2022")
|
||||
private String channelRefundNo;
|
||||
|
||||
@Schema(description = "退款成功时间")
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@Schema(description = "调用渠道的错误码")
|
||||
private String channelErrorCode;
|
||||
|
||||
@Schema(description = "调用渠道的错误提示")
|
||||
private String channelErrorMsg;
|
||||
|
||||
@Schema(description = "支付渠道的额外参数")
|
||||
private String channelNotifyData;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.tashow.cloud.pay.controller.admin.refund.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 退款订单详情 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayRefundDetailsRespVO extends PayRefundBaseVO {
|
||||
|
||||
@Schema(description = "支付退款编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "应用名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是芋艿")
|
||||
private String appName;
|
||||
|
||||
@Schema(description = "支付订单", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Order order;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 支付订单")
|
||||
@Data
|
||||
public static class Order {
|
||||
|
||||
@Schema(description = "商品标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆")
|
||||
private String subject;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.tashow.cloud.pay.controller.admin.refund.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.MoneyConvert;
|
||||
import cn.iocoder.yudao.module.pay.enums.DictTypeConstants;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 退款订单 Excel VO
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Data
|
||||
public class PayRefundExcelVO {
|
||||
|
||||
@ExcelProperty("支付退款编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ExcelProperty(value = "支付金额", converter = MoneyConvert.class)
|
||||
private Integer payPrice;
|
||||
|
||||
@ExcelProperty(value = "退款金额", converter = MoneyConvert.class)
|
||||
private Integer refundPrice;
|
||||
|
||||
@ExcelProperty("商户退款单号")
|
||||
private String merchantRefundId;
|
||||
@ExcelProperty("退款单号")
|
||||
private String no;
|
||||
@ExcelProperty("渠道退款单号")
|
||||
private String channelRefundNo;
|
||||
|
||||
@ExcelProperty("商户支付单号")
|
||||
private String merchantOrderId;
|
||||
@ExcelProperty("渠道支付单号")
|
||||
private String channelOrderNo;
|
||||
|
||||
@ExcelProperty(value = "退款状态", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.REFUND_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty(value = "退款渠道", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.CHANNEL_CODE)
|
||||
private String channelCode;
|
||||
|
||||
@ExcelProperty("成功时间")
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@ExcelProperty(value = "支付应用")
|
||||
private String appName;
|
||||
|
||||
@ExcelProperty("退款原因")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.tashow.cloud.pay.controller.admin.refund.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 退款订单 Excel 导出 Request VO,参数和 PayRefundPageReqVO 是一致的")
|
||||
@Data
|
||||
public class PayRefundExportReqVO {
|
||||
|
||||
@Schema(description = "应用编号", example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "商户支付单号", example = "10")
|
||||
private String merchantOrderId;
|
||||
|
||||
@Schema(description = "商户退款单号", example = "20")
|
||||
private String merchantRefundId;
|
||||
|
||||
@Schema(description = "渠道支付单号", example = "30")
|
||||
private String channelOrderNo;
|
||||
|
||||
@Schema(description = "渠道退款单号", example = "40")
|
||||
private String channelRefundNo;
|
||||
|
||||
@Schema(description = "退款状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tashow.cloud.pay.controller.admin.refund.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 退款订单分页查询 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayRefundPageItemRespVO extends PayRefundBaseVO {
|
||||
|
||||
@Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "应用名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是芋艿")
|
||||
private String appName;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.tashow.cloud.pay.controller.admin.refund.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 退款订单分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayRefundPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "应用编号", example = "1024")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "商户支付单号", example = "10")
|
||||
private String merchantOrderId;
|
||||
|
||||
@Schema(description = "商户退款单号", example = "20")
|
||||
private String merchantRefundId;
|
||||
|
||||
@Schema(description = "渠道支付单号", example = "30")
|
||||
private String channelOrderNo;
|
||||
|
||||
@Schema(description = "渠道退款单号", example = "40")
|
||||
private String channelRefundNo;
|
||||
|
||||
@Schema(description = "退款状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.tashow.cloud.pay.controller.admin.transfer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.*;
|
||||
import com.tashow.cloud.pay.controller.admin.transfer.vo.*;
|
||||
import com.tashow.cloud.payapi.controller.admin.transfer.vo.*;
|
||||
import com.tashow.cloud.pay.convert.transfer.PayTransferConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.transfer.PayTransferDO;
|
||||
import com.tashow.cloud.pay.service.transfer.PayTransferService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
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.common.util.servlet.ServletUtils.getClientIP;
|
||||
|
||||
@Tag(name = "管理后台 - 转账单")
|
||||
@RestController
|
||||
@RequestMapping("/pay/transfer")
|
||||
@Validated
|
||||
public class PayTransferController {
|
||||
|
||||
@Resource
|
||||
private PayTransferService payTransferService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建转账单,发起转账")
|
||||
@PreAuthorize("@ss.hasPermission('pay:transfer:create')")
|
||||
public CommonResult<PayTransferCreateRespVO> createPayTransfer(@Valid @RequestBody PayTransferCreateReqVO reqVO) {
|
||||
PayTransferDO payTransfer = payTransferService.createTransfer(reqVO, getClientIP());
|
||||
return success(new PayTransferCreateRespVO().setId(payTransfer.getId()).setStatus(payTransfer.getStatus()));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得转账订单")
|
||||
@PreAuthorize("@ss.hasPermission('pay:transfer:query')")
|
||||
public CommonResult<PayTransferRespVO> getTransfer(@RequestParam("id") Long id) {
|
||||
return success(PayTransferConvert.INSTANCE.convert(payTransferService.getTransfer(id)));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得转账订单分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:transfer:query')")
|
||||
public CommonResult<PageResult<PayTransferPageItemRespVO>> getTransferPage(@Valid PayTransferPageReqVO pageVO) {
|
||||
PageResult<PayTransferDO> pageResult = payTransferService.getTransferPage(pageVO);
|
||||
return success(PayTransferConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.tashow.cloud.pay.controller.admin.transfer.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||
import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Validator;
|
||||
import jakarta.validation.constraints.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum.*;
|
||||
|
||||
@Schema(description = "管理后台 - 发起转账 Request VO")
|
||||
@Data
|
||||
public class PayTransferCreateReqVO {
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "商户转账单编号不能为空")
|
||||
private String merchantTransferId;
|
||||
|
||||
@Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "转账类型不能为空")
|
||||
@InEnum(PayTransferTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "转账渠道", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc")
|
||||
@NotEmpty(message = "转账渠道不能为空")
|
||||
private String channelCode;
|
||||
|
||||
@Min(value = 1, message = "转账金额必须大于零")
|
||||
@NotNull(message = "转账金额不能为空")
|
||||
private Integer price;
|
||||
|
||||
@Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "示例转账")
|
||||
@NotEmpty(message = "转账标题不能为空")
|
||||
private String subject;
|
||||
|
||||
@Schema(description = "收款人姓名", example = "test1")
|
||||
@NotBlank(message = "收款人姓名不能为空", groups = {Alipay.class})
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "支付宝登录号", example = "test1@sandbox.com")
|
||||
@NotBlank(message = "支付宝登录号不能为空", groups = {Alipay.class})
|
||||
private String alipayLogonId;
|
||||
|
||||
@Schema(description = "微信 openId", example = "oLefc4g5Gxx")
|
||||
@NotBlank(message = "微信 openId 不能为空", groups = {WxPay.class})
|
||||
private String openid;
|
||||
|
||||
@Schema(description = "转账渠道的额外参数")
|
||||
private Map<String, String> channelExtras;
|
||||
|
||||
public void validate(Validator validator) {
|
||||
PayTransferTypeEnum transferType = typeOf(type);
|
||||
switch (transferType) {
|
||||
case ALIPAY_BALANCE: {
|
||||
ValidationUtils.validate(validator, this, Alipay.class);
|
||||
break;
|
||||
}
|
||||
case WX_BALANCE: {
|
||||
ValidationUtils.validate(validator, this, WxPay.class);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new UnsupportedOperationException("待实现");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AssertTrue(message = "转账类型和转账渠道不匹配")
|
||||
public boolean isValidChannelCode() {
|
||||
PayTransferTypeEnum transferType = typeOf(type);
|
||||
switch (transferType) {
|
||||
case ALIPAY_BALANCE: {
|
||||
return PayChannelEnum.isAlipay(channelCode);
|
||||
}
|
||||
case WX_BALANCE:
|
||||
case BANK_CARD:
|
||||
case WALLET_BALANCE: {
|
||||
throw exception(NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.tashow.cloud.pay.controller.admin.transfer.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 发起转账 Response VO")
|
||||
@Data
|
||||
public class PayTransferCreateRespVO {
|
||||
|
||||
@Schema(description = "转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") // 参见 PayTransferStatusEnum 枚举
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.tashow.cloud.pay.controller.admin.transfer.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author jason
|
||||
*/
|
||||
@Schema(description = "管理后台 - 转账单分页项 Response VO")
|
||||
@Data
|
||||
public class PayTransferPageItemRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2931")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "转账单号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String no;
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12831")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "转账渠道编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24833")
|
||||
private Long channelId;
|
||||
|
||||
@Schema(description = "转账渠道编码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17481")
|
||||
private String merchantTransferId;
|
||||
|
||||
@Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "转账成功时间")
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@Schema(description = "转账金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "964")
|
||||
private Integer price;
|
||||
|
||||
@Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String subject;
|
||||
|
||||
@Schema(description = "收款人姓名", example = "王五")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "支付宝登录号", example = "29245")
|
||||
private String alipayLogonId;
|
||||
|
||||
@Schema(description = "微信 openId", example = "26589")
|
||||
private String openid;
|
||||
|
||||
@Schema(description = "渠道转账单号")
|
||||
private String channelTransferNo;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.tashow.cloud.pay.controller.admin.transfer.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 转账单分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayTransferPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "转账单号")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "应用编号", example = "12831")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "渠道编码", example = "wx_app")
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "商户转账单编号", example = "17481")
|
||||
private String merchantTransferId;
|
||||
|
||||
@Schema(description = "类型", example = "2")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "转账状态", example = "2")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "收款人姓名", example = "王五")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "渠道转账单号")
|
||||
private String channelTransferNo;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.tashow.cloud.pay.controller.admin.transfer.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 转账单 Response VO")
|
||||
@Data
|
||||
public class PayTransferRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2931")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "转账单号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String no;
|
||||
|
||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12831")
|
||||
private Long appId;
|
||||
|
||||
@Schema(description = "转账渠道编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24833")
|
||||
private Long channelId;
|
||||
|
||||
@Schema(description = "转账渠道编码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String channelCode;
|
||||
|
||||
@Schema(description = "商户转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17481")
|
||||
private String merchantTransferId;
|
||||
|
||||
@Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "转账成功时间")
|
||||
private LocalDateTime successTime;
|
||||
|
||||
@Schema(description = "转账金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "964")
|
||||
private Integer price;
|
||||
|
||||
@Schema(description = "转账标题", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String subject;
|
||||
|
||||
@Schema(description = "收款人姓名", example = "王五")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "支付宝登录号", example = "29245")
|
||||
private String alipayLogonId;
|
||||
|
||||
@Schema(description = "微信 openId", example = "26589")
|
||||
private String openid;
|
||||
|
||||
@Schema(description = "异步通知商户地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
|
||||
private String notifyUrl;
|
||||
|
||||
@Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String userIp;
|
||||
|
||||
@Schema(description = "渠道的额外参数")
|
||||
private Map<String, String> channelExtras;
|
||||
|
||||
@Schema(description = "渠道转账单号")
|
||||
private String channelTransferNo;
|
||||
|
||||
@Schema(description = "调用渠道的错误码")
|
||||
private String channelErrorCode;
|
||||
|
||||
@Schema(description = "调用渠道的错误提示")
|
||||
private String channelErrorMsg;
|
||||
|
||||
@Schema(description = "渠道的同步/异步通知的内容")
|
||||
private String channelNotifyData;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.tashow.cloud.pay.controller.admin.wallet;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.wallet.PayWalletUpdateBalanceReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.wallet.PayWalletUserReqVO;
|
||||
import com.tashow.cloud.pay.convert.wallet.PayWalletConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.wallet.PayWalletDO;
|
||||
import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
|
||||
import com.tashow.cloud.pay.service.wallet.PayWalletService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.enums.UserTypeEnum.MEMBER;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.WALLET_NOT_FOUND;
|
||||
|
||||
@Tag(name = "管理后台 - 用户钱包")
|
||||
@RestController
|
||||
@RequestMapping("/pay/wallet")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class PayWalletController {
|
||||
|
||||
@Resource
|
||||
private PayWalletService payWalletService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet:query')")
|
||||
@Operation(summary = "获得用户钱包明细")
|
||||
public CommonResult<PayWalletRespVO> getWallet(PayWalletUserReqVO reqVO) {
|
||||
PayWalletDO wallet = payWalletService.getOrCreateWallet(reqVO.getUserId(), MEMBER.getValue());
|
||||
return success(PayWalletConvert.INSTANCE.convert02(wallet));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得会员钱包分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet:query')")
|
||||
public CommonResult<PageResult<PayWalletRespVO>> getWalletPage(@Valid PayWalletPageReqVO pageVO) {
|
||||
PageResult<PayWalletDO> pageResult = payWalletService.getWalletPage(pageVO);
|
||||
return success(PayWalletConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@PutMapping("/update-balance")
|
||||
@Operation(summary = "更新会员用户余额")
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet:update-balance')")
|
||||
public CommonResult<Boolean> updateWalletBalance(@Valid @RequestBody PayWalletUpdateBalanceReqVO updateReqVO) {
|
||||
// 获得用户钱包
|
||||
PayWalletDO wallet = payWalletService.getOrCreateWallet(updateReqVO.getUserId(), MEMBER.getValue());
|
||||
if (wallet == null) {
|
||||
log.error("[updateWalletBalance],updateReqVO({}) 用户钱包不存在.", updateReqVO);
|
||||
throw exception(WALLET_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 更新钱包余额
|
||||
payWalletService.addWalletBalance(wallet.getId(), String.valueOf(updateReqVO.getUserId()),
|
||||
PayWalletBizTypeEnum.UPDATE_BALANCE, updateReqVO.getBalance());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.tashow.cloud.pay.controller.admin.wallet;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO;
|
||||
import com.tashow.cloud.pay.service.wallet.PayWalletRechargeService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.common.util.servlet.ServletUtils.getClientIP;
|
||||
|
||||
@Tag(name = "管理后台 - 钱包充值")
|
||||
@RestController
|
||||
@RequestMapping("/pay/wallet-recharge")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class PayWalletRechargeController {
|
||||
|
||||
@Resource
|
||||
private PayWalletRechargeService walletRechargeService;
|
||||
|
||||
@PostMapping("/update-paid")
|
||||
@Operation(summary = "更新钱包充值为已充值") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
||||
@PermitAll // 无需登录, 内部校验实现
|
||||
public CommonResult<Boolean> updateWalletRechargerPaid(@Valid @RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
|
||||
walletRechargeService.updateWalletRechargerPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
|
||||
notifyReqDTO.getPayOrderId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// TODO @jason:发起退款,要 post 操作哈;
|
||||
@GetMapping("/refund")
|
||||
@Operation(summary = "发起钱包充值退款")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> refundWalletRecharge(@RequestParam("id") Long id) {
|
||||
walletRechargeService.refundWalletRecharge(id, getClientIP());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/update-refunded")
|
||||
@Operation(summary = "更新钱包充值为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
||||
@PermitAll // 无需登录, 内部校验实现
|
||||
public CommonResult<Boolean> updateWalletRechargeRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) {
|
||||
walletRechargeService.updateWalletRechargeRefunded(
|
||||
Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayRefundId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.tashow.cloud.pay.controller.admin.wallet;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.rechargepackage.WalletRechargePackageCreateReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.rechargepackage.WalletRechargePackagePageReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.rechargepackage.WalletRechargePackageRespVO;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.rechargepackage.WalletRechargePackageUpdateReqVO;
|
||||
import com.tashow.cloud.pay.convert.wallet.PayWalletRechargePackageConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.wallet.PayWalletRechargePackageDO;
|
||||
import com.tashow.cloud.pay.service.wallet.PayWalletRechargePackageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
|
||||
@Tag(name = "管理后台 - 钱包充值套餐")
|
||||
@RestController
|
||||
@RequestMapping("/pay/wallet-recharge-package")
|
||||
@Validated
|
||||
public class PayWalletRechargePackageController {
|
||||
|
||||
@Resource
|
||||
private PayWalletRechargePackageService walletRechargePackageService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建钱包充值套餐")
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet-recharge-package:create')")
|
||||
public CommonResult<Long> createWalletRechargePackage(@Valid @RequestBody WalletRechargePackageCreateReqVO createReqVO) {
|
||||
return success(walletRechargePackageService.createWalletRechargePackage(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新钱包充值套餐")
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet-recharge-package:update')")
|
||||
public CommonResult<Boolean> updateWalletRechargePackage(@Valid @RequestBody WalletRechargePackageUpdateReqVO updateReqVO) {
|
||||
walletRechargePackageService.updateWalletRechargePackage(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除钱包充值套餐")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet-recharge-package:delete')")
|
||||
public CommonResult<Boolean> deleteWalletRechargePackage(@RequestParam("id") Long id) {
|
||||
walletRechargePackageService.deleteWalletRechargePackage(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得钱包充值套餐")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet-recharge-package:query')")
|
||||
public CommonResult<WalletRechargePackageRespVO> getWalletRechargePackage(@RequestParam("id") Long id) {
|
||||
PayWalletRechargePackageDO walletRechargePackage = walletRechargePackageService.getWalletRechargePackage(id);
|
||||
return success(PayWalletRechargePackageConvert.INSTANCE.convert(walletRechargePackage));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得钱包充值套餐分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet-recharge-package:query')")
|
||||
public CommonResult<PageResult<WalletRechargePackageRespVO>> getWalletRechargePackagePage(@Valid WalletRechargePackagePageReqVO pageVO) {
|
||||
PageResult<PayWalletRechargePackageDO> pageResult = walletRechargePackageService.getWalletRechargePackagePage(pageVO);
|
||||
return success(PayWalletRechargePackageConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.tashow.cloud.pay.controller.admin.wallet;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.transaction.PayWalletTransactionPageReqVO;
|
||||
import com.tashow.cloud.pay.controller.admin.wallet.vo.transaction.PayWalletTransactionRespVO;
|
||||
import com.tashow.cloud.pay.convert.wallet.PayWalletTransactionConvert;
|
||||
import com.tashow.cloud.pay.dal.dataobject.wallet.PayWalletTransactionDO;
|
||||
import com.tashow.cloud.pay.service.wallet.PayWalletTransactionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 钱包余额明细")
|
||||
@RestController
|
||||
@RequestMapping("/pay/wallet-transaction")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class PayWalletTransactionController {
|
||||
|
||||
@Resource
|
||||
private PayWalletTransactionService payWalletTransactionService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得钱包流水分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:wallet:query')")
|
||||
public CommonResult<PageResult<PayWalletTransactionRespVO>> getWalletTransactionPage(
|
||||
@Valid PayWalletTransactionPageReqVO pageReqVO) {
|
||||
PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(pageReqVO);
|
||||
return success(PayWalletTransactionConvert.INSTANCE.convertPage2(result));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.tashow.cloud.pay.controller.admin.wallet.vo.rechargepackage;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 充值套餐 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class WalletRechargePackageBaseVO {
|
||||
|
||||
@Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
@NotNull(message = "套餐名不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "支付金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "16454")
|
||||
@NotNull(message = "支付金额不能为空")
|
||||
private Integer payPrice;
|
||||
|
||||
@Schema(description = "赠送金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "20887")
|
||||
@NotNull(message = "赠送金额不能为空")
|
||||
private Integer bonusPrice;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Byte status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tashow.cloud.pay.controller.admin.wallet.vo.rechargepackage;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 充值套餐创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class WalletRechargePackageCreateReqVO extends WalletRechargePackageBaseVO {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.tashow.cloud.pay.controller.admin.wallet.vo.rechargepackage;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 充值套餐分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class WalletRechargePackagePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "套餐名", example = "李四")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "状态", example = "2")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user