mirror of
https://gitee.com/zhijiantianya/yudao-cloud.git
synced 2025-12-30 09:22:27 +00:00
Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/yudao-cloud
# Conflicts: # yudao-module-mall/yudao-module-promotion-server/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java # yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImpl.java
This commit is contained in:
@@ -23,6 +23,8 @@ public enum CodegenFrontTypeEnum {
|
||||
|
||||
VUE3_VBEN5_EP_SCHEMA(50), // Vue3 VBEN5 + EP + schema 模版
|
||||
VUE3_VBEN5_EP_GENERAL(51), // Vue3 VBEN5 + EP 标准模版
|
||||
|
||||
VUE3_ADMIN_UNIAPP_WOT(60), // Vue3 Admin + Uniapp + WOT 标准模版
|
||||
;
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,6 +72,14 @@ public class FileController {
|
||||
return success(fileService.createFile(createReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文件")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('infra:file:query')")
|
||||
public CommonResult<FileRespVO> getFile(@RequestParam("id") Long id) {
|
||||
return success(BeanUtils.toBean(fileService.getFile(id), FileRespVO.class));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除文件")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
|
||||
@@ -4,12 +4,14 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenTableMapper;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||
@@ -17,7 +19,9 @@ import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
||||
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder;
|
||||
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenEngine;
|
||||
import cn.iocoder.yudao.module.infra.service.db.DataSourceConfigService;
|
||||
import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@@ -45,6 +49,8 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
|
||||
@Resource
|
||||
private DatabaseTableService databaseTableService;
|
||||
@Resource
|
||||
private DataSourceConfigService dataSourceConfigService;
|
||||
|
||||
@Resource
|
||||
private CodegenTableMapper codegenTableMapper;
|
||||
@@ -284,8 +290,11 @@ public class CodegenServiceImpl implements CodegenService {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取数据源对应的数据库类型
|
||||
DataSourceConfigDO dataSourceConfig = dataSourceConfigService.getDataSourceConfig(table.getDataSourceConfigId());
|
||||
DbType dbType = JdbcUtils.getDbType(dataSourceConfig.getUrl());
|
||||
// 执行生成
|
||||
return codegenEngine.execute(table, columns, subTables, subColumnsList);
|
||||
return codegenEngine.execute(dbType, table, columns, subTables, subColumnsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,6 +33,7 @@ import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenVOTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableTable;
|
||||
import com.google.common.collect.Maps;
|
||||
@@ -96,7 +97,7 @@ public class CodegenEngine {
|
||||
.build();
|
||||
|
||||
/**
|
||||
* 后端的配置模版
|
||||
* 前端的配置模版
|
||||
*
|
||||
* key1:UI 模版的类型 {@link CodegenFrontTypeEnum#getType()}
|
||||
* key2:模板在 resources 的地址
|
||||
@@ -137,6 +138,16 @@ public class CodegenEngine {
|
||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("api/api.ts"),
|
||||
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("api/api.ts"),
|
||||
vue3UniappFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/index.vue"),
|
||||
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("components/search-form.vue"),
|
||||
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/components/search-form.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/form/index.vue"),
|
||||
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/form/index.vue"))
|
||||
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/detail/index.vue"),
|
||||
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/detail/index.vue"))
|
||||
// VUE3_VBEN2_ANTD_SCHEMA
|
||||
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/data.ts"),
|
||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${classNameVar}.data.ts"))
|
||||
@@ -300,16 +311,17 @@ public class CodegenEngine {
|
||||
/**
|
||||
* 生成代码
|
||||
*
|
||||
* @param dbType 数据库类型
|
||||
* @param table 表定义
|
||||
* @param columns table 的字段定义数组
|
||||
* @param subTables 子表数组,当且仅当主子表时使用
|
||||
* @param subColumnsList subTables 的字段定义数组
|
||||
* @return 生成的代码,key 是路径,value 是对应代码
|
||||
*/
|
||||
public Map<String, String> execute(CodegenTableDO table, List<CodegenColumnDO> columns,
|
||||
public Map<String, String> execute(DbType dbType, CodegenTableDO table, List<CodegenColumnDO> columns,
|
||||
List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
|
||||
// 1.1 初始化 bindMap 上下文
|
||||
Map<String, Object> bindingMap = initBindingMap(table, columns, subTables, subColumnsList);
|
||||
Map<String, Object> bindingMap = initBindingMap(dbType, table, columns, subTables, subColumnsList);
|
||||
// 1.2 获得模版
|
||||
Map<String, String> templates = getTemplates(table.getFrontType());
|
||||
|
||||
@@ -387,8 +399,8 @@ public class CodegenEngine {
|
||||
* @return 格式化后的代码
|
||||
*/
|
||||
private String prettyCode(String content, String vmPath) {
|
||||
// Vue 界面:去除字段后面多余的 , 逗号,解决前端的 Pretty 代码格式检查的报错(需要排除 vben5)
|
||||
if (!StrUtil.contains(vmPath, "vben5")) {
|
||||
// Vue 界面:去除字段后面多余的 , 逗号,解决前端的 Pretty 代码格式检查的报错(需要排除 vben5、vue3_admin_uniapp)
|
||||
if (!StrUtil.containsAny(vmPath, "vben5", "vue3_admin_uniapp")) {
|
||||
content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
|
||||
}
|
||||
// Vue 界面:去除多的 dateFormatter,只有一个的情况下,说明没使用到
|
||||
@@ -415,10 +427,11 @@ public class CodegenEngine {
|
||||
return content;
|
||||
}
|
||||
|
||||
private Map<String, Object> initBindingMap(CodegenTableDO table, List<CodegenColumnDO> columns,
|
||||
private Map<String, Object> initBindingMap(DbType dbType, CodegenTableDO table, List<CodegenColumnDO> columns,
|
||||
List<CodegenTableDO> subTables, List<List<CodegenColumnDO>> subColumnsList) {
|
||||
// 创建 bindingMap
|
||||
Map<String, Object> bindingMap = new HashMap<>(globalBindingMap);
|
||||
bindingMap.put("dbType", dbType);
|
||||
bindingMap.put("table", table);
|
||||
bindingMap.put("columns", columns);
|
||||
bindingMap.put("primaryColumn", CollectionUtils.findFirst(columns, CodegenColumnDO::getPrimaryKey)); // 主键字段
|
||||
@@ -617,6 +630,15 @@ public class CodegenEngine {
|
||||
"src/" + path;
|
||||
}
|
||||
|
||||
private static String vue3AdminUniappTemplatePath(String path) {
|
||||
return "codegen/vue3_admin_uniapp/" + path + ".vm";
|
||||
}
|
||||
|
||||
private static String vue3UniappFilePath(String path) {
|
||||
return "yudao-ui-${sceneEnum.basePackage}-uniapp/" + // 顶级目录
|
||||
"src/" + path;
|
||||
}
|
||||
|
||||
private static String vue3VbenFilePath(String path) {
|
||||
return "yudao-ui-${sceneEnum.basePackage}-vben/" + // 顶级目录
|
||||
"src/" + path;
|
||||
|
||||
@@ -62,6 +62,7 @@ public interface FileService {
|
||||
* @return 编号
|
||||
*/
|
||||
Long createFile(FileCreateReqVO createReqVO);
|
||||
FileDO getFile(Long id);
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
|
||||
@@ -152,6 +152,11 @@ public class FileServiceImpl implements FileService {
|
||||
return file.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileDO getFile(Long id) {
|
||||
return validateFileExists(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFile(Long id) throws Exception {
|
||||
// 校验存在
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
## 通用变量定义
|
||||
#set ($functionNames = ['查询', '创建', '更新', '删除', '导出'])
|
||||
#set ($functionOps = ['query', 'create', 'update', 'delete', 'export'])
|
||||
##
|
||||
## 宏定义:生成按钮 SQL(通用部分)
|
||||
#macro(insertButtonSql $parentIdVar)
|
||||
#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, ${parentIdVar},
|
||||
'', '', '', 0
|
||||
);
|
||||
#end
|
||||
#end
|
||||
##
|
||||
## ======================= MySQL / OceanBase =======================
|
||||
#if ($dbType.name() == 'MYSQL' || $dbType.name() == 'OCEAN_BASE')
|
||||
-- 菜单 SQL
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
@@ -9,12 +30,9 @@ VALUES (
|
||||
);
|
||||
|
||||
-- 按钮父菜单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(
|
||||
@@ -25,4 +43,139 @@ VALUES (
|
||||
'${table.classComment}${functionName}', '${permissionPrefix}:${functionOps.get($index)}', 3, $foreach.count, @parentId,
|
||||
'', '', '', 0
|
||||
);
|
||||
#end
|
||||
#end
|
||||
##
|
||||
## ======================= Oracle / 达梦 DM =======================
|
||||
#elseif ($dbType.name() == 'ORACLE' || $dbType.name() == 'DM')
|
||||
-- 菜单 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
|
||||
-- 说明:Oracle/达梦 使用序列获取上一个插入的 ID
|
||||
DECLARE
|
||||
v_parent_id NUMBER;
|
||||
BEGIN
|
||||
SELECT system_menu_seq.CURRVAL INTO v_parent_id FROM DUAL;
|
||||
-- 按钮 SQL
|
||||
#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, v_parent_id,
|
||||
'', '', '', 0
|
||||
);
|
||||
#end
|
||||
END;
|
||||
/
|
||||
##
|
||||
## ======================= PostgreSQL / 人大金仓 KingbaseES =======================
|
||||
#elseif ($dbType.name() == 'POSTGRE_SQL' || $dbType.name() == 'KINGBASE_ES')
|
||||
-- 菜单 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
|
||||
-- 说明:PostgreSQL/KingbaseES 使用 lastval() 获取上一个插入的序列值
|
||||
DO $$
|
||||
DECLARE
|
||||
v_parent_id BIGINT;
|
||||
BEGIN
|
||||
v_parent_id := lastval();
|
||||
-- 按钮 SQL
|
||||
#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, v_parent_id,
|
||||
'', '', '', 0
|
||||
);
|
||||
#end
|
||||
END $$;
|
||||
##
|
||||
## ======================= SQL Server =======================
|
||||
#elseif ($dbType.name() == 'SQL_SERVER' || $dbType.name() == 'SQL_SERVER2005')
|
||||
-- 菜单 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
|
||||
-- 说明:SQL Server 使用 SCOPE_IDENTITY() 获取上一个插入的自增 ID
|
||||
DECLARE @parentId BIGINT;
|
||||
SET @parentId = SCOPE_IDENTITY();
|
||||
|
||||
-- 按钮 SQL
|
||||
#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
|
||||
##
|
||||
## ======================= 不支持的数据库类型 =======================
|
||||
#else
|
||||
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
-- 注意:当前数据库类型 ${dbType.name()} 暂不支持自动生成菜单 SQL
|
||||
-- 请参考以下 MySQL 语法,手动修改为您的数据库对应的语法
|
||||
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
-- 菜单 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
|
||||
-- TODO: 请根据您的数据库类型,修改获取上一个插入 ID 的方式
|
||||
-- MySQL: SELECT @parentId := LAST_INSERT_ID();
|
||||
-- Oracle: SELECT system_menu_seq.CURRVAL INTO v_parent_id FROM DUAL;
|
||||
-- PostgreSQL: SELECT lastval() INTO v_parent_id;
|
||||
-- SQL Server: SET @parentId = SCOPE_IDENTITY();
|
||||
SELECT @parentId := LAST_INSERT_ID();
|
||||
|
||||
-- 按钮 SQL
|
||||
#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
|
||||
#end
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<!-- 搜索框入口 -->
|
||||
<view @click="visible = true">
|
||||
<wd-search :placeholder="placeholder" hide-cancel disabled />
|
||||
</view>
|
||||
|
||||
<!-- 搜索弹窗 -->
|
||||
<wd-popup v-model="visible" position="top" @close="visible = false">
|
||||
<view class="yd-search-form-container" :style="{ paddingTop: `#[[${]]#getNavbarHeight()#[[}]]#px` }">
|
||||
#set ($hasDict = 0)
|
||||
#foreach ($column in $columns)
|
||||
#if ($hasDict == 0 && $column.listOperation && $column.dictType && "" != $column.dictType)
|
||||
#set ($hasDict = 1)
|
||||
#end
|
||||
#end
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($listOperationCondition = $column.listOperationCondition)
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")
|
||||
#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")
|
||||
<view class="yd-search-form-item">
|
||||
<view class="yd-search-form-label">
|
||||
${comment}
|
||||
</view>
|
||||
<wd-input
|
||||
v-model="formData.${javaField}"
|
||||
placeholder="请输入${comment}"
|
||||
clearable
|
||||
/>
|
||||
</view>
|
||||
#elseif ($column.htmlType == "datetime" && $listOperationCondition == "BETWEEN")
|
||||
#set ($AttrName = $javaField.substring(0,1).toUpperCase() + ${javaField.substring(1)})
|
||||
<view class="yd-search-form-item">
|
||||
<view class="yd-search-form-label">
|
||||
${comment}
|
||||
</view>
|
||||
<view class="yd-search-form-date-range-container">
|
||||
<view @click="visible${AttrName}[0] = true">
|
||||
<view class="yd-search-form-date-range-picker">
|
||||
{{ formatDate(formData.${javaField}?.[0]) || '开始日期' }}
|
||||
</view>
|
||||
</view>
|
||||
-
|
||||
<view @click="visible${AttrName}[1] = true">
|
||||
<view class="yd-search-form-date-range-picker">
|
||||
{{ formatDate(formData.${javaField}?.[1]) || '结束日期' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<wd-datetime-picker-view v-if="visible${AttrName}[0]" v-model="temp${AttrName}[0]" type="date" />
|
||||
<view v-if="visible${AttrName}[0]" class="yd-search-form-date-range-actions">
|
||||
<wd-button size="small" plain @click="visible${AttrName}[0] = false">
|
||||
取消
|
||||
</wd-button>
|
||||
<wd-button size="small" type="primary" @click="handle${AttrName}0Confirm">
|
||||
确定
|
||||
</wd-button>
|
||||
</view>
|
||||
<wd-datetime-picker-view v-if="visible${AttrName}[1]" v-model="temp${AttrName}[1]" type="date" />
|
||||
<view v-if="visible${AttrName}[1]" class="yd-search-form-date-range-actions">
|
||||
<wd-button size="small" plain @click="visible${AttrName}[1] = false">
|
||||
取消
|
||||
</wd-button>
|
||||
<wd-button size="small" type="primary" @click="handle${AttrName}1Confirm">
|
||||
确定
|
||||
</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
#elseif (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType)
|
||||
<view class="yd-search-form-item">
|
||||
<view class="yd-search-form-label">
|
||||
${comment}
|
||||
</view>
|
||||
<wd-radio-group v-model="formData.${javaField}" shape="button">
|
||||
<wd-radio :value="-1">
|
||||
全部
|
||||
</wd-radio>
|
||||
<wd-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||
:key="dict.value"
|
||||
:value="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</wd-radio>
|
||||
</wd-radio-group>
|
||||
</view>
|
||||
#else
|
||||
<view class="yd-search-form-item">
|
||||
<view class="yd-search-form-label">
|
||||
${comment}
|
||||
</view>
|
||||
<wd-input
|
||||
v-model="formData.${javaField}"
|
||||
placeholder="请输入${comment}"
|
||||
clearable
|
||||
/>
|
||||
</view>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
<view class="yd-search-form-actions">
|
||||
<wd-button class="flex-1" plain @click="handleReset">
|
||||
重置
|
||||
</wd-button>
|
||||
<wd-button class="flex-1" type="primary" @click="handleSearch">
|
||||
搜索
|
||||
</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
#set ($hasDict = 0)
|
||||
#set ($hasGetDictOptions = 0)
|
||||
#set ($hasGetIntDictOptions = 0)
|
||||
#set ($hasGetStrDictOptions = 0)
|
||||
#set ($hasGetBoolDictOptions = 0)
|
||||
#set ($hasDateTimeBetween = 0)
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation && $column.dictType && "" != $column.dictType)
|
||||
#set ($hasDict = 1)
|
||||
#if ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||
#if ($column.javaType == "Integer" || $column.javaType == "Long" || $column.javaType == "Byte" || $column.javaType == "Short")
|
||||
#set ($hasGetIntDictOptions = 1)
|
||||
#elseif ($column.javaType == "String")
|
||||
#set ($hasGetStrDictOptions = 1)
|
||||
#elseif ($column.javaType == "Boolean")
|
||||
#set ($hasGetBoolDictOptions = 1)
|
||||
#else
|
||||
#set ($hasGetDictOptions = 1)
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#if ($hasDateTimeBetween == 0 && $column.listOperation && $column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||
#set ($hasDateTimeBetween = 1)
|
||||
#end
|
||||
#end
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { getNavbarHeight } from '@/utils'
|
||||
#if ($hasDateTimeBetween == 1)
|
||||
import { formatDate, formatDateRange } from '@/utils/date'
|
||||
#end
|
||||
#if ($hasDict == 1)
|
||||
#set ($dictImportNames = "getDictLabel, ")
|
||||
#if ($hasGetDictOptions == 1)
|
||||
#set ($dictImportNames = "${dictImportNames}getDictOptions, ")
|
||||
#end
|
||||
#if ($hasGetIntDictOptions == 1)
|
||||
#set ($dictImportNames = "${dictImportNames}getIntDictOptions, ")
|
||||
#end
|
||||
#if ($hasGetStrDictOptions == 1)
|
||||
#set ($dictImportNames = "${dictImportNames}getStrDictOptions, ")
|
||||
#end
|
||||
#if ($hasGetBoolDictOptions == 1)
|
||||
#set ($dictImportNames = "${dictImportNames}getBoolDictOptions, ")
|
||||
#end
|
||||
#set ($dictImportNames = $dictImportNames.trim())
|
||||
#set ($dictImportNames = $dictImportNames.substring(0, $dictImportNames.length() - 1))
|
||||
import { $dictImportNames } from '@/hooks/useDict'
|
||||
import { DICT_TYPE } from '@/utils/constants'
|
||||
#end
|
||||
|
||||
const emit = defineEmits<{
|
||||
search: [data: Record<string, any>]
|
||||
reset: []
|
||||
}>()
|
||||
|
||||
const visible = ref(false)
|
||||
const formData = reactive({
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($javaType = $column.javaType.toLowerCase())
|
||||
#if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||
${column.javaField}: [undefined, undefined] as [number | undefined, number | undefined],
|
||||
#elseif ($column.dictType && "" != $column.dictType)
|
||||
#if(${javaType} == "string")
|
||||
${column.javaField}: -1 as -1 | string, // -1 表示全部
|
||||
#elseif(${javaType} == "boolean")
|
||||
${column.javaField}: -1 as -1 | boolean, // -1 表示全部
|
||||
#else
|
||||
${column.javaField}: -1, // -1 表示全部
|
||||
#end
|
||||
#elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte")
|
||||
${column.javaField}: undefined as number | undefined,
|
||||
#elseif(${javaType} == "boolean")
|
||||
${column.javaField}: undefined as boolean | undefined,
|
||||
#else
|
||||
${column.javaField}: undefined as string | undefined,
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
|
||||
/** 搜索条件 placeholder 拼接 */
|
||||
const placeholder = computed(() => {
|
||||
const conditions: string[] = []
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType.toLowerCase())
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||
if (formData.${javaField}?.[0] && formData.${javaField}?.[1]) {
|
||||
conditions.push(`${comment}:#[[${]]#formatDate(formData.${javaField}[0])#[[}]]#~#[[${]]#formatDate(formData.${javaField}[1])#[[}]]#`)
|
||||
}
|
||||
#elseif ($dictType && "" != $dictType)
|
||||
if (formData.${javaField} !== -1) {
|
||||
conditions.push(`${comment}:#[[${]]#getDictLabel(DICT_TYPE.${dictType.toUpperCase()}, formData.${javaField})#[[}]]#`)
|
||||
}
|
||||
#else
|
||||
#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte" || ${javaType} == "boolean")
|
||||
if (formData.${javaField} !== undefined) {
|
||||
conditions.push(`${comment}:#[[${]]#formData.${javaField}#[[}]]#`)
|
||||
}
|
||||
#else
|
||||
if (formData.${javaField}) {
|
||||
conditions.push(`${comment}:#[[${]]#formData.${javaField}#[[}]]#`)
|
||||
}
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
return conditions.length > 0 ? conditions.join(' | ') : '搜索${table.classComment}'
|
||||
})
|
||||
|
||||
#if ($hasDateTimeBetween == 1)
|
||||
// 时间范围选择器状态
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation && $column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($AttrName = $javaField.substring(0,1).toUpperCase() + ${javaField.substring(1)})
|
||||
const visible${AttrName} = ref<[boolean, boolean]>([false, false])
|
||||
const temp${AttrName} = ref<[number, number]>([Date.now(), Date.now()])
|
||||
|
||||
/** ${column.columnComment}[0]确认 */
|
||||
function handle${AttrName}0Confirm() {
|
||||
formData.${javaField} = [temp${AttrName}.value[0], formData.${javaField}?.[1]]
|
||||
visible${AttrName}.value[0] = false
|
||||
}
|
||||
|
||||
/** ${column.columnComment}[1]确认 */
|
||||
function handle${AttrName}1Confirm() {
|
||||
formData.${javaField} = [formData.${javaField}?.[0], temp${AttrName}.value[1]]
|
||||
visible${AttrName}.value[1] = false
|
||||
}
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
/** 搜索 */
|
||||
function handleSearch() {
|
||||
visible.value = false
|
||||
emit('search', {
|
||||
...formData,
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#if ($column.dictType && "" != $column.dictType)
|
||||
${column.javaField}: formData.${column.javaField} === -1 ? undefined : formData.${column.javaField},
|
||||
#elseif ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||
${column.javaField}: formatDateRange(formData.${column.javaField}),
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
}
|
||||
|
||||
/** 重置 */
|
||||
function handleReset() {
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperation)
|
||||
#if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||
formData.${column.javaField} = [undefined, undefined]
|
||||
#elseif ($column.dictType && "" != $column.dictType)
|
||||
formData.${column.javaField} = -1
|
||||
#else
|
||||
formData.${column.javaField} = undefined
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
visible.value = false
|
||||
emit('reset')
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<view class="yd-page-container">
|
||||
<!-- 顶部导航栏 -->
|
||||
<wd-navbar
|
||||
title="${table.classComment}详情"
|
||||
left-arrow placeholder safe-area-inset-top fixed
|
||||
@click-left="handleBack"
|
||||
/>
|
||||
|
||||
<!-- 详情内容 -->
|
||||
<view>
|
||||
<wd-cell-group border>
|
||||
#foreach($column in $columns)
|
||||
#if ($column.primaryKey || $column.listOperationResult || $column.createOperation || $column.updateOperation)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($comment = $column.columnComment)
|
||||
#if ($column.dictType && "" != $column.dictType)
|
||||
<wd-cell title="${comment}">
|
||||
<dict-tag :type="DICT_TYPE.${column.dictType.toUpperCase()}" :value="formData?.${javaField}" />
|
||||
</wd-cell>
|
||||
#elseif ($column.javaType == "LocalDateTime")
|
||||
<wd-cell title="${comment}" :value="formatDateTime(formData?.${javaField}) || '-'" />
|
||||
#else
|
||||
<wd-cell title="${comment}" :value="formData?.${javaField} ?? '-'" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</wd-cell-group>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="yd-detail-footer">
|
||||
<view class="yd-detail-footer-actions">
|
||||
<wd-button
|
||||
v-if="hasAccessByCodes(['${permissionPrefix}:update'])"
|
||||
class="flex-1" type="warning" @click="handleEdit"
|
||||
>
|
||||
编辑
|
||||
</wd-button>
|
||||
<wd-button
|
||||
v-if="hasAccessByCodes(['${permissionPrefix}:delete'])"
|
||||
class="flex-1" type="error" :loading="deleting" @click="handleDelete"
|
||||
>
|
||||
删除
|
||||
</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
#set ($hasDict = 0)
|
||||
#foreach($column in $columns)
|
||||
#if ($hasDict == 0 && $column.dictType && "" != $column.dictType)
|
||||
#set ($hasDict = 1)
|
||||
#end
|
||||
#end
|
||||
#set ($hasDateTime = 0)
|
||||
#foreach($column in $columns)
|
||||
#if ($hasDateTime == 0 && $column.javaType == "LocalDateTime")
|
||||
#set ($hasDateTime = 1)
|
||||
#end
|
||||
#end
|
||||
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
import { delete${simpleClassName}, get${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
import { useAccess } from '@/hooks/useAccess'
|
||||
import { navigateBackPlus } from '@/utils'
|
||||
#if ($hasDict == 1)
|
||||
import { DICT_TYPE } from '@/utils/constants'
|
||||
#end
|
||||
#if ($hasDateTime == 1)
|
||||
import { formatDateTime } from '@/utils/date'
|
||||
#end
|
||||
|
||||
const props = defineProps<{
|
||||
id?: number | any
|
||||
}>()
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '',
|
||||
navigationStyle: 'custom',
|
||||
},
|
||||
})
|
||||
|
||||
const { hasAccessByCodes } = useAccess()
|
||||
const toast = useToast()
|
||||
const formData = ref<${simpleClassName}>()
|
||||
const deleting = ref(false)
|
||||
|
||||
/** 返回上一页 */
|
||||
function handleBack() {
|
||||
navigateBackPlus('/pages-${table.moduleName}/${table.businessName}/index')
|
||||
}
|
||||
|
||||
/** 加载${table.classComment}详情 */
|
||||
async function getDetail() {
|
||||
if (!props.id) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
toast.loading('加载中...')
|
||||
formData.value = await get${simpleClassName}(props.id)
|
||||
} finally {
|
||||
toast.close()
|
||||
}
|
||||
}
|
||||
|
||||
/** 编辑${table.classComment} */
|
||||
function handleEdit() {
|
||||
uni.navigateTo({
|
||||
url: `/pages-${table.moduleName}/${table.businessName}/form/index?id=#[[${]]#props.id#[[}]]#`,
|
||||
})
|
||||
}
|
||||
|
||||
/** 删除${table.classComment} */
|
||||
function handleDelete() {
|
||||
if (!props.id) {
|
||||
return
|
||||
}
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要删除该${table.classComment}吗?',
|
||||
success: async (res) => {
|
||||
if (!res.confirm) {
|
||||
return
|
||||
}
|
||||
deleting.value = true
|
||||
try {
|
||||
await delete${simpleClassName}(props.id)
|
||||
toast.success('删除成功')
|
||||
setTimeout(() => {
|
||||
handleBack()
|
||||
}, 500)
|
||||
} finally {
|
||||
deleting.value = false
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(() => {
|
||||
getDetail()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,253 @@
|
||||
<template>
|
||||
<view class="yd-page-container">
|
||||
<!-- 顶部导航栏 -->
|
||||
<wd-navbar
|
||||
:title="getTitle"
|
||||
left-arrow placeholder safe-area-inset-top fixed
|
||||
@click-left="handleBack"
|
||||
/>
|
||||
|
||||
<!-- 表单区域 -->
|
||||
<view>
|
||||
<wd-form ref="formRef" :model="formData" :rules="formRules">
|
||||
<wd-cell-group border>
|
||||
#foreach($column in $columns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.primaryKey)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($javaType = $column.javaType)
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictMethod = "getDictOptions")
|
||||
#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
|
||||
## 优先判断是否有字典,有字典则使用 radio-group
|
||||
#if (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType)
|
||||
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
|
||||
<wd-radio-group v-model="formData.${javaField}" shape="button">
|
||||
<wd-radio
|
||||
v-for="dict in $dictMethod(DICT_TYPE.${dictType.toUpperCase()})"
|
||||
:key="dict.value"
|
||||
:value="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</wd-radio>
|
||||
</wd-radio-group>
|
||||
</wd-cell>
|
||||
## 数字类型(无字典)
|
||||
#elseif (${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer" || ${javaType.toLowerCase()} == "short" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal" || ${javaType.toLowerCase()} == "byte")
|
||||
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
|
||||
<wd-input-number
|
||||
v-model="formData.${javaField}"
|
||||
:min="0"
|
||||
/>
|
||||
</wd-cell>
|
||||
## 布尔类型
|
||||
#elseif (${javaType.toLowerCase()} == "boolean")
|
||||
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
|
||||
<wd-switch v-model="formData.${javaField}" />
|
||||
</wd-cell>
|
||||
## 日期时间类型
|
||||
#elseif (${javaType.toLowerCase()} == "date" || ${javaType.toLowerCase()} == "localdate" || ${javaType.toLowerCase()} == "localdatetime")
|
||||
#set ($pickerType = "date")
|
||||
#if (${javaType.toLowerCase()} == "localdatetime")
|
||||
#set ($pickerType = "datetime")
|
||||
#end
|
||||
<wd-datetime-picker
|
||||
v-model="formData.${javaField}"
|
||||
type="${pickerType}"
|
||||
label="${comment}"
|
||||
label-width="180rpx"
|
||||
prop="${javaField}"
|
||||
/>
|
||||
## 文本域
|
||||
#elseif ($column.htmlType == "textarea")
|
||||
<wd-textarea
|
||||
v-model="formData.${javaField}"
|
||||
label="${comment}"
|
||||
label-width="180rpx"
|
||||
placeholder="请输入${comment}"
|
||||
:maxlength="200"
|
||||
show-word-limit
|
||||
clearable
|
||||
/>
|
||||
## 默认:文本输入
|
||||
#else
|
||||
<wd-input
|
||||
v-model="formData.${javaField}"
|
||||
label="${comment}"
|
||||
label-width="180rpx"
|
||||
prop="${javaField}"
|
||||
clearable
|
||||
placeholder="请输入${comment}"
|
||||
/>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</wd-cell-group>
|
||||
</wd-form>
|
||||
</view>
|
||||
|
||||
<!-- 底部保存按钮 -->
|
||||
<view class="yd-detail-footer">
|
||||
<wd-button
|
||||
type="primary"
|
||||
block
|
||||
:loading="formLoading"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
保存
|
||||
</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
#set ($primaryJavaType = $primaryColumn.javaType.toLowerCase())
|
||||
#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte")
|
||||
#set ($primaryTsType = "number")
|
||||
#else
|
||||
#set ($primaryTsType = "string")
|
||||
#end
|
||||
#set ($hasDict = 0)
|
||||
#set ($hasGetDictOptions = 0)
|
||||
#set ($hasGetIntDictOptions = 0)
|
||||
#set ($hasGetStrDictOptions = 0)
|
||||
#set ($hasGetBoolDictOptions = 0)
|
||||
#foreach ($column in $columns)
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.primaryKey
|
||||
&& ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||
&& $column.dictType && "" != $column.dictType)
|
||||
#set ($hasDict = 1)
|
||||
#if ($column.javaType == "Integer" || $column.javaType == "Long" || $column.javaType == "Byte" || $column.javaType == "Short")
|
||||
#set ($hasGetIntDictOptions = 1)
|
||||
#elseif ($column.javaType == "String")
|
||||
#set ($hasGetStrDictOptions = 1)
|
||||
#elseif ($column.javaType == "Boolean")
|
||||
#set ($hasGetBoolDictOptions = 1)
|
||||
#else
|
||||
#set ($hasGetDictOptions = 1)
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
#if ($hasDict == 1)
|
||||
#set ($dictImportNames = "")
|
||||
#if ($hasGetDictOptions == 1)
|
||||
#set ($dictImportNames = "${dictImportNames}getDictOptions, ")
|
||||
#end
|
||||
#if ($hasGetIntDictOptions == 1)
|
||||
#set ($dictImportNames = "${dictImportNames}getIntDictOptions, ")
|
||||
#end
|
||||
#if ($hasGetStrDictOptions == 1)
|
||||
#set ($dictImportNames = "${dictImportNames}getStrDictOptions, ")
|
||||
#end
|
||||
#if ($hasGetBoolDictOptions == 1)
|
||||
#set ($dictImportNames = "${dictImportNames}getBoolDictOptions, ")
|
||||
#end
|
||||
#set ($dictImportNames = $dictImportNames.trim())
|
||||
#set ($dictImportNames = $dictImportNames.substring(0, $dictImportNames.length() - 1))
|
||||
import { $dictImportNames } from '@/hooks/useDict'
|
||||
#end
|
||||
import { navigateBackPlus } from '@/utils'
|
||||
#if ($hasDict == 1)
|
||||
import { DICT_TYPE } from '@/utils/constants'
|
||||
#end
|
||||
|
||||
const props = defineProps<{
|
||||
id?: ${primaryTsType} | any
|
||||
}>()
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '',
|
||||
navigationStyle: 'custom',
|
||||
},
|
||||
})
|
||||
|
||||
const toast = useToast()
|
||||
const getTitle = computed(() => props.id ? '编辑${table.classComment}' : '新增${table.classComment}')
|
||||
const formLoading = ref(false)
|
||||
const formData = ref<${simpleClassName}>({
|
||||
#foreach($column in $columns)
|
||||
#if (($column.createOperation || $column.updateOperation) || $column.primaryKey)
|
||||
#set ($javaType = $column.javaType.toLowerCase())
|
||||
#set ($javaFieldLower = $column.javaField.toLowerCase())
|
||||
#set ($optional = $column.nullable || $column.primaryKey || $javaFieldLower == "createtime" || $javaFieldLower == "updatetime")
|
||||
#if ($column.primaryKey)
|
||||
${column.javaField}: undefined,
|
||||
#elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte")
|
||||
${column.javaField}: 0,
|
||||
#elseif(${javaType} == "boolean")
|
||||
${column.javaField}: false,
|
||||
#elseif(${javaType} == "date" || ${javaType} == "localdate" || ${javaType} == "localdatetime")
|
||||
${column.javaField}: undefined,
|
||||
#else
|
||||
${column.javaField}: '',
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
})
|
||||
const formRules = {
|
||||
#foreach($column in $columns)
|
||||
#set ($javaFieldLower = $column.javaField.toLowerCase())
|
||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !$column.primaryKey
|
||||
&& $javaFieldLower != "createtime" && $javaFieldLower != "updatetime")
|
||||
${column.javaField}: [{ required: true, message: '${column.columnComment}不能为空' }],
|
||||
#end
|
||||
#end
|
||||
}
|
||||
const formRef = ref()
|
||||
|
||||
/** 返回上一页 */
|
||||
function handleBack() {
|
||||
navigateBackPlus('/pages-${table.moduleName}/${table.businessName}/index')
|
||||
}
|
||||
|
||||
/** 加载${table.classComment}详情 */
|
||||
async function getDetail() {
|
||||
if (!props.id) {
|
||||
return
|
||||
}
|
||||
formData.value = await get${simpleClassName}(props.id)
|
||||
}
|
||||
|
||||
/** 提交表单 */
|
||||
async function handleSubmit() {
|
||||
const { valid } = await formRef.value.validate()
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
|
||||
formLoading.value = true
|
||||
try {
|
||||
if (props.id) {
|
||||
await update${simpleClassName}(formData.value)
|
||||
toast.success('修改成功')
|
||||
} else {
|
||||
await create${simpleClassName}(formData.value)
|
||||
toast.success('新增成功')
|
||||
}
|
||||
setTimeout(() => {
|
||||
handleBack()
|
||||
}, 500)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(() => {
|
||||
getDetail()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,211 @@
|
||||
<template>
|
||||
<view class="yd-page-container">
|
||||
<!-- 顶部导航栏 -->
|
||||
<wd-navbar
|
||||
title="${table.classComment}管理"
|
||||
left-arrow placeholder safe-area-inset-top fixed
|
||||
@click-left="handleBack"
|
||||
/>
|
||||
|
||||
<!-- 搜索组件 -->
|
||||
<SearchForm @search="handleQuery" @reset="handleReset" />
|
||||
|
||||
<!-- ${table.classComment}列表 -->
|
||||
<view class="p-24rpx">
|
||||
<view
|
||||
v-for="item in list"
|
||||
:key="item.${primaryColumn.javaField}"
|
||||
class="mb-24rpx overflow-hidden rounded-12rpx bg-white shadow-sm"
|
||||
@click="handleDetail(item)"
|
||||
>
|
||||
<view class="p-24rpx">
|
||||
#set ($titleField = "")
|
||||
#set ($statusField = "")
|
||||
#set ($statusDictType = "")
|
||||
#foreach($column in $columns)
|
||||
#if ($titleField == "" && !$column.primaryKey && $column.listOperationResult)
|
||||
#set ($titleField = $column.javaField)
|
||||
#set ($titleComment = $column.columnComment)
|
||||
#end
|
||||
#if ($statusField == "" && $column.listOperationResult && $column.dictType && "" != $column.dictType)
|
||||
#set ($statusField = $column.javaField)
|
||||
#set ($statusDictType = $column.dictType)
|
||||
#end
|
||||
#end
|
||||
#if ($titleField == "")
|
||||
#set ($titleField = $primaryColumn.javaField)
|
||||
#end
|
||||
<view class="mb-16rpx flex items-center justify-between">
|
||||
<view class="text-32rpx text-[#333] font-semibold">
|
||||
{{ item.${titleField} }}
|
||||
</view>
|
||||
#if($statusField != "")
|
||||
<dict-tag :type="DICT_TYPE.${statusDictType.toUpperCase()}" :value="item.${statusField}" />
|
||||
#end
|
||||
</view>
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperationResult && !$column.primaryKey && $column.javaField != $titleField && $column.javaField != $statusField)
|
||||
#set ($javaField = $column.javaField)
|
||||
#set ($comment = $column.columnComment)
|
||||
#set ($dictType = $column.dictType)
|
||||
#set ($javaType = $column.javaType)
|
||||
#if ($dictType && "" != $dictType)
|
||||
<view class="mb-12rpx flex items-center text-28rpx text-[#666]">
|
||||
<text class="mr-8rpx text-[#999]">${comment}:</text>
|
||||
<dict-tag :type="DICT_TYPE.${dictType.toUpperCase()}" :value="item.${javaField}" />
|
||||
</view>
|
||||
#elseif ($javaType == "LocalDateTime")
|
||||
<view class="mb-12rpx flex items-center text-28rpx text-[#666]">
|
||||
<text class="mr-8rpx text-[#999]">${comment}:</text>
|
||||
<text class="line-clamp-1">{{ formatDateTime(item.${javaField}) || '-' }}</text>
|
||||
</view>
|
||||
#else
|
||||
<view class="mb-12rpx flex items-center text-28rpx text-[#666]">
|
||||
<text class="mr-8rpx text-[#999]">${comment}:</text>
|
||||
<text class="line-clamp-1">{{ item.${javaField} }}</text>
|
||||
</view>
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="py-100rpx text-center">
|
||||
<wd-status-tip image="content" tip="暂无${table.classComment}数据" />
|
||||
</view>
|
||||
<wd-loadmore
|
||||
v-if="list.length > 0"
|
||||
:state="loadMoreState"
|
||||
@reload="loadMore"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 新增按钮 -->
|
||||
<wd-fab
|
||||
v-if="hasAccessByCodes(['${permissionPrefix}:create'])"
|
||||
position="right-bottom"
|
||||
type="primary"
|
||||
:expandable="false"
|
||||
@click="handleAdd"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
#set ($hasDict = 0)
|
||||
#foreach($column in $columns)
|
||||
#if ($hasDict == 0 && $column.listOperationResult && $column.dictType && "" != $column.dictType)
|
||||
#set ($hasDict = 1)
|
||||
#end
|
||||
#end
|
||||
#set ($hasDateTime = 0)
|
||||
#foreach($column in $columns)
|
||||
#if ($column.listOperationResult)
|
||||
#if ($hasDateTime == 0 && $column.javaType == "LocalDateTime")
|
||||
#set ($hasDateTime = 1)
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
import type { LoadMoreState } from '@/http/types'
|
||||
import { onReachBottom } from '@dcloudio/uni-app'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { get${simpleClassName}Page } from '@/api/${table.moduleName}/${table.businessName}'
|
||||
import { useAccess } from '@/hooks/useAccess'
|
||||
import { navigateBackPlus } from '@/utils'
|
||||
#if ($hasDict == 1)
|
||||
import { DICT_TYPE } from '@/utils/constants'
|
||||
#end
|
||||
#if ($hasDateTime == 1)
|
||||
import { formatDateTime } from '@/utils/date'
|
||||
#end
|
||||
import SearchForm from './components/search-form.vue'
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '',
|
||||
navigationStyle: 'custom',
|
||||
},
|
||||
})
|
||||
|
||||
const { hasAccessByCodes } = useAccess()
|
||||
const total = ref(0)
|
||||
const list = ref<${simpleClassName}[]>([])
|
||||
const loadMoreState = ref<LoadMoreState>('loading')
|
||||
const queryParams = ref({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
})
|
||||
|
||||
/** 返回上一页 */
|
||||
function handleBack() {
|
||||
navigateBackPlus()
|
||||
}
|
||||
|
||||
/** 查询${table.classComment}列表 */
|
||||
async function getList() {
|
||||
loadMoreState.value = 'loading'
|
||||
try {
|
||||
const data = await get${simpleClassName}Page(queryParams.value)
|
||||
list.value = [...list.value, ...data.list]
|
||||
total.value = data.total
|
||||
loadMoreState.value = list.value.length >= total.value ? 'finished' : 'loading'
|
||||
} catch {
|
||||
queryParams.value.pageNo = queryParams.value.pageNo > 1 ? queryParams.value.pageNo - 1 : 1
|
||||
loadMoreState.value = 'error'
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery(data?: Record<string, any>) {
|
||||
queryParams.value = {
|
||||
...data,
|
||||
pageNo: 1,
|
||||
pageSize: queryParams.value.pageSize,
|
||||
}
|
||||
list.value = []
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
function handleReset() {
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 加载更多 */
|
||||
function loadMore() {
|
||||
if (loadMoreState.value === 'finished') {
|
||||
return
|
||||
}
|
||||
queryParams.value.pageNo++
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 新增${table.classComment} */
|
||||
function handleAdd() {
|
||||
uni.navigateTo({
|
||||
url: '/pages-${table.moduleName}/${table.businessName}/form/index',
|
||||
})
|
||||
}
|
||||
|
||||
/** 查看详情 */
|
||||
function handleDetail(item: ${simpleClassName}) {
|
||||
uni.navigateTo({
|
||||
url: `/pages-${table.moduleName}/${table.businessName}/detail/index?id=#[[${]]#item.${primaryColumn.javaField}#[[}]]#`,
|
||||
})
|
||||
}
|
||||
|
||||
/** 触底加载更多 */
|
||||
onReachBottom(() => {
|
||||
loadMore()
|
||||
})
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTa
|
||||
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper;
|
||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenTableMapper;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||
@@ -19,7 +20,9 @@ import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
||||
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder;
|
||||
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenEngine;
|
||||
import cn.iocoder.yudao.module.infra.service.db.DataSourceConfigService;
|
||||
import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -62,6 +65,8 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@MockBean
|
||||
private DatabaseTableService databaseTableService;
|
||||
@MockitoBean
|
||||
private DataSourceConfigService dataSourceConfigService;
|
||||
|
||||
@MockBean
|
||||
private CodegenBuilder codegenBuilder;
|
||||
@@ -453,9 +458,12 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
|
||||
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
|
||||
.setOrdinalPosition(2));
|
||||
codegenColumnMapper.insert(column02);
|
||||
// mock 数据(DataSourceConfigDO)
|
||||
when(dataSourceConfigService.getDataSourceConfig(eq(table.getDataSourceConfigId())))
|
||||
.thenReturn(randomPojo(DataSourceConfigDO.class, o -> o.setUrl("jdbc:mysql://")));
|
||||
// mock 执行生成
|
||||
Map<String, String> codes = MapUtil.of(randomString(), randomString());
|
||||
when(codegenEngine.execute(eq(table), argThat(columns -> {
|
||||
when(codegenEngine.execute(eq(DbType.MYSQL), eq(table), argThat(columns -> {
|
||||
assertEquals(2, columns.size());
|
||||
assertEquals(column01, columns.get(0));
|
||||
assertEquals(column02, columns.get(1));
|
||||
@@ -494,9 +502,12 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
|
||||
// mock 数据(sub CodegenColumnDO)
|
||||
CodegenColumnDO subColumn01 = randomPojo(CodegenColumnDO.class, o -> o.setId(1024L).setTableId(subTable.getId()));
|
||||
codegenColumnMapper.insert(subColumn01);
|
||||
// mock 数据(DataSourceConfigDO)
|
||||
when(dataSourceConfigService.getDataSourceConfig(eq(table.getDataSourceConfigId())))
|
||||
.thenReturn(randomPojo(DataSourceConfigDO.class, o -> o.setUrl("jdbc:mysql://")));
|
||||
// mock 执行生成
|
||||
Map<String, String> codes = MapUtil.of(randomString(), randomString());
|
||||
when(codegenEngine.execute(eq(table), argThat(columns -> {
|
||||
when(codegenEngine.execute(eq(DbType.MYSQL), eq(table), argThat(columns -> {
|
||||
assertEquals(2, columns.size());
|
||||
assertEquals(column01, columns.get(0));
|
||||
assertEquals(column02, columns.get(1));
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -28,7 +29,7 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
|
||||
List<CodegenColumnDO> columns = getColumnList("student");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
Map<String, String> result = codegenEngine.execute(DbType.MYSQL, table, columns, null, null);
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + "/vue2_one");
|
||||
// 断言
|
||||
@@ -44,7 +45,7 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
|
||||
List<CodegenColumnDO> columns = getColumnList("category");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
Map<String, String> result = codegenEngine.execute(DbType.MYSQL, table, columns, null, null);
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + "/vue2_tree");
|
||||
// 断言
|
||||
@@ -88,7 +89,7 @@ public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
|
||||
List<CodegenColumnDO> teacherColumns = getColumnList("teacher");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns,
|
||||
Map<String, String> result = codegenEngine.execute(DbType.MYSQL, table, columns,
|
||||
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + path);
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -28,7 +29,7 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
||||
List<CodegenColumnDO> columns = getColumnList("student");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
Map<String, String> result = codegenEngine.execute(DbType.MYSQL, table, columns, null, null);
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + "/vue3_one");
|
||||
// 断言
|
||||
@@ -44,7 +45,7 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
||||
List<CodegenColumnDO> columns = getColumnList("category");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||
Map<String, String> result = codegenEngine.execute(DbType.MYSQL, table, columns, null, null);
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + "/vue3_tree");
|
||||
// 断言
|
||||
@@ -88,7 +89,7 @@ public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
||||
List<CodegenColumnDO> teacherColumns = getColumnList("teacher");
|
||||
|
||||
// 调用
|
||||
Map<String, String> result = codegenEngine.execute(table, columns,
|
||||
Map<String, String> result = codegenEngine.execute(DbType.MYSQL, table, columns,
|
||||
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
|
||||
// 生成测试文件
|
||||
//writeResult(result, resourcesPath + path);
|
||||
|
||||
Reference in New Issue
Block a user