mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-23 23:39:47 +08:00
feat: 新增api代码生成模板
This commit is contained in:
34
docs/java/SysMenuServiceImpl.java
Normal file
34
docs/java/SysMenuServiceImpl.java
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 查询系统菜单列表
|
||||
*
|
||||
* @param menu 菜单信息
|
||||
* @return 菜单列表
|
||||
*/
|
||||
@Override
|
||||
public List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId) {
|
||||
List<SysMenuVo> menuList;
|
||||
// 管理员显示所有菜单信息
|
||||
if (LoginHelper.isSuperAdmin(userId)) {
|
||||
menuList = baseMapper.selectVoList(new LambdaQueryWrapper<SysMenu>()
|
||||
.like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
|
||||
.eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
|
||||
.eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
|
||||
.eq(StringUtils.isNotBlank(menu.getMenuType()), SysMenu::getMenuType, menu.getMenuType())
|
||||
.eq(ObjectUtil.isNotNull(menu.getParentId()), SysMenu::getParentId, menu.getParentId())
|
||||
.orderByAsc(SysMenu::getParentId)
|
||||
.orderByAsc(SysMenu::getOrderNum));
|
||||
} else {
|
||||
QueryWrapper<SysMenu> wrapper = Wrappers.query();
|
||||
wrapper.inSql("r.role_id", "select role_id from sys_user_role where user_id = " + userId)
|
||||
.like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
|
||||
.eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
|
||||
.eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
|
||||
.eq(StringUtils.isNotBlank(menu.getMenuType()), "m.menu_type", menu.getMenuType())
|
||||
.eq(ObjectUtil.isNotNull(menu.getParentId()), "m.parent_id", menu.getParentId())
|
||||
.orderByAsc("m.parent_id")
|
||||
.orderByAsc("m.order_num");
|
||||
List<SysMenu> list = baseMapper.selectMenuListByUserId(wrapper);
|
||||
menuList = MapstructUtils.convert(list, SysMenuVo.class);
|
||||
}
|
||||
return menuList;
|
||||
}
|
94
docs/java/VelocityUtils.java
Normal file
94
docs/java/VelocityUtils.java
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* 获取模板信息
|
||||
*
|
||||
* @return 模板列表
|
||||
*/
|
||||
public static List<String> getTemplateList(String tplCategory) {
|
||||
List<String> templates = new ArrayList<>();
|
||||
templates.add("vm/java/domain.java.vm");
|
||||
templates.add("vm/java/vo.java.vm");
|
||||
templates.add("vm/java/bo.java.vm");
|
||||
templates.add("vm/java/mapper.java.vm");
|
||||
templates.add("vm/java/service.java.vm");
|
||||
templates.add("vm/java/serviceImpl.java.vm");
|
||||
templates.add("vm/java/controller.java.vm");
|
||||
templates.add("vm/xml/mapper.xml.vm");
|
||||
if (DataBaseHelper.isOracle()) {
|
||||
templates.add("vm/sql/oracle/sql.vm");
|
||||
} else if (DataBaseHelper.isPostgerSql()) {
|
||||
templates.add("vm/sql/postgres/sql.vm");
|
||||
} else if (DataBaseHelper.isSqlServer()) {
|
||||
templates.add("vm/sql/sqlserver/sql.vm");
|
||||
} else {
|
||||
templates.add("vm/sql/sql.vm");
|
||||
}
|
||||
templates.add("vm/ts/api.ts.vm");
|
||||
templates.add("vm/ts/types.ts.vm");
|
||||
templates.add("vm/soybean/typings/soy.api.d.ts.vm");
|
||||
templates.add("vm/soybean/api/soy.api.ts.vm");
|
||||
if (GenConstants.TPL_CRUD.equals(tplCategory)) {
|
||||
templates.add("vm/vue/index.vue.vm");
|
||||
templates.add("vm/soybean/soy.index.vue.vm");
|
||||
} else if (GenConstants.TPL_TREE.equals(tplCategory)) {
|
||||
templates.add("vm/vue/index-tree.vue.vm");
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名
|
||||
*/
|
||||
public static String getFileName(String template, GenTable genTable) {
|
||||
// 文件名称
|
||||
String fileName = "";
|
||||
// 包路径
|
||||
String packageName = genTable.getPackageName();
|
||||
// 模块名
|
||||
String moduleName = genTable.getModuleName();
|
||||
// 大写类名
|
||||
String className = genTable.getClassName();
|
||||
// 业务名称
|
||||
String businessName = genTable.getBusinessName();
|
||||
|
||||
String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
|
||||
String mybatisPath = MYBATIS_PATH + "/" + moduleName;
|
||||
String vuePath = "vue";
|
||||
|
||||
if (template.contains("domain.java.vm")) {
|
||||
fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
|
||||
}
|
||||
if (template.contains("vo.java.vm")) {
|
||||
fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className);
|
||||
}
|
||||
if (template.contains("bo.java.vm")) {
|
||||
fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className);
|
||||
}
|
||||
if (template.contains("soy.index.vue.vm")) {
|
||||
fileName = StringUtils.format("soybean/views/{}/{}/index.vue", moduleName, businessName);
|
||||
} else if (template.contains("soy.api.d.ts.vm")) {
|
||||
fileName = StringUtils.format("soybean/typings/api/{}.d.ts", moduleName);
|
||||
} else if (template.contains("soy.api.ts.vm")) {
|
||||
fileName = StringUtils.format("soybean/api/{}/{}.ts", moduleName, businessName);
|
||||
} else if (template.contains("mapper.java.vm")) {
|
||||
fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
|
||||
} else if (template.contains("service.java.vm")) {
|
||||
fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
|
||||
} else if (template.contains("serviceImpl.java.vm")) {
|
||||
fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
|
||||
} else if (template.contains("controller.java.vm")) {
|
||||
fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className);
|
||||
} else if (template.contains("mapper.xml.vm")) {
|
||||
fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className);
|
||||
} else if (template.contains("sql.vm")) {
|
||||
fileName = businessName + "Menu.sql";
|
||||
} else if (template.contains("api.ts.vm")) {
|
||||
fileName = StringUtils.format("{}/api/{}/{}/index.ts", vuePath, moduleName, businessName);
|
||||
} else if (template.contains("types.ts.vm")) {
|
||||
fileName = StringUtils.format("{}/api/{}/{}/types.ts", vuePath, moduleName, businessName);
|
||||
} else if (template.contains("index.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
|
||||
} else if (template.contains("index-tree.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
|
||||
}
|
||||
return fileName;
|
||||
}
|
36
docs/template/api/soy.api.ts.vm
vendored
Normal file
36
docs/template/api/soy.api.ts.vm
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
import { request } from '@/service/request';
|
||||
|
||||
/** 获取${functionName}列表 */
|
||||
export function fetchGet${BusinessName}List(params?: Api.System.${BusinessName}SearchParams) {
|
||||
return request<Api.${ModuleName}.${BusinessName}List>({
|
||||
url: '/${moduleName}/${businessName}/list',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/** 新增${functionName} */
|
||||
export function fetchCreate${BusinessName}(data: Api.${ModuleName}.${BusinessName}OperateParams) {
|
||||
return request<boolean>({
|
||||
url: '/${moduleName}/${businessName}',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/** 修改${functionName} */
|
||||
export function fetchUpdate${BusinessName}(data: Api.${ModuleName}.${BusinessName}OperateParams) {
|
||||
return request<boolean>({
|
||||
url: '/${moduleName}/${businessName}',
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量删除${functionName} */
|
||||
export function fetchDelete${BusinessName}(${pkColumn.javaField}s: CommonType.IdType[]) {
|
||||
return request<boolean>({
|
||||
url: `/${moduleName}/${businessName}/${${pkColumn.javaField}s.join(',')}`,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
150
docs/template/soy.index.vue.vm
vendored
Normal file
150
docs/template/soy.index.vue.vm
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
<script setup lang="tsx">
|
||||
import { NButton, NPopconfirm } from 'naive-ui';
|
||||
import { fetchGet${BusinessName}List, fetchDelete${BusinessName}, fetchBatchDelete${BusinessName} } from '@/service/api';
|
||||
import { $t } from '@/locales';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import ${BusinessName}OperateDrawer from './modules/${businessName}-operate-drawer.vue';
|
||||
import ${BusinessName}Search from './modules/${businessName}-search.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const {
|
||||
columns,
|
||||
columnChecks,
|
||||
data,
|
||||
getData,
|
||||
getDataByPage,
|
||||
loading,
|
||||
mobilePagination,
|
||||
searchParams,
|
||||
resetSearchParams
|
||||
} = useTable({
|
||||
apiFn: fetchGet${BusinessName}List,
|
||||
apiParams: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
// if you want to use the searchParams in Form, you need to define the following properties, and the value is null
|
||||
// the value can not be undefined, otherwise the property in Form will not be reactive
|
||||
#foreach ($column in $columns)
|
||||
#if($column.query)
|
||||
$column.javaField: null#if($foreach.hasNext),#end
|
||||
#end
|
||||
#end
|
||||
},
|
||||
columns: () => [
|
||||
{
|
||||
type: 'selection',
|
||||
align: 'center',
|
||||
width: 48
|
||||
},
|
||||
{
|
||||
key: 'index',
|
||||
title: $t('common.index'),
|
||||
align: 'center',
|
||||
width: 64
|
||||
},
|
||||
#foreach ($column in $columns)
|
||||
#if($column.list)
|
||||
{
|
||||
key: '$column.javaField',
|
||||
title: '$column.columnComment',
|
||||
align: 'center',
|
||||
minWidth: 120
|
||||
},
|
||||
#end
|
||||
#end
|
||||
{
|
||||
key: 'operate',
|
||||
title: $t('common.operate'),
|
||||
align: 'center',
|
||||
width: 130,
|
||||
render: row => (
|
||||
<div class="flex-center gap-8px">
|
||||
<NButton type="primary" ghost size="small" onClick={() => edit(row.id)}>
|
||||
{$t('common.edit')}
|
||||
</NButton>
|
||||
<NPopconfirm onPositiveClick={() => handleDelete(row.id)}>
|
||||
{{
|
||||
default: () => $t('common.confirmDelete'),
|
||||
trigger: () => (
|
||||
<NButton type="error" ghost size="small">
|
||||
{$t('common.delete')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const {
|
||||
drawerVisible,
|
||||
operateType,
|
||||
editingData,
|
||||
handleAdd,
|
||||
handleEdit,
|
||||
checkedRowKeys,
|
||||
onBatchDeleted,
|
||||
onDeleted
|
||||
} = useTableOperate(data, getData);
|
||||
|
||||
async function handleBatchDelete() {
|
||||
// request
|
||||
const { error } = await fetchDelete${BusinessName}(checkedRowKeys.value)
|
||||
if (error) return;
|
||||
onBatchDeleted();
|
||||
}
|
||||
|
||||
async function handleDelete(id: number) {
|
||||
// request
|
||||
const { error } = await fetchBatchDelete${BusinessName}([id])
|
||||
if (error) return;
|
||||
onDeleted();
|
||||
}
|
||||
|
||||
async function edit(id: number) {
|
||||
handleEdit('#foreach($column in $columns)#if($column.isPk == '1')$column.javaField#end#end', id);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<${BusinessName}Search v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="${functionName}" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
:disabled-delete="checkedRowKeys.length === 0"
|
||||
:loading="loading"
|
||||
@add="handleAdd"
|
||||
@delete="handleBatchDelete"
|
||||
@refresh="getData"
|
||||
/>
|
||||
</template>
|
||||
<NDataTable
|
||||
v-model:checked-row-keys="checkedRowKeys"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
size="small"
|
||||
:flex-height="!appStore.isMobile"
|
||||
:scroll-x="962"
|
||||
:loading="loading"
|
||||
remote
|
||||
:row-key="row => row.id"
|
||||
:pagination="mobilePagination"
|
||||
class="sm:h-full"
|
||||
/>
|
||||
<${BusinessName}OperateDrawer
|
||||
v-model:visible="drawerVisible"
|
||||
:operate-type="operateType"
|
||||
:row-data="editingData"
|
||||
@submitted="getDataByPage"
|
||||
/>
|
||||
</NCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
39
docs/template/typings/soy.api.d.ts.vm
vendored
Normal file
39
docs/template/typings/soy.api.d.ts.vm
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
#set($ModuleName=$moduleName.substring(0, 1).toUpperCase() + $moduleName.substring(1))
|
||||
/**
|
||||
* namespace ${ModuleName}
|
||||
*
|
||||
* backend api module: "${ModuleName}"
|
||||
*/
|
||||
namespace ${ModuleName} {
|
||||
/** ${businessName} */
|
||||
type ${BusinessName} = Common.CommonRecord<{
|
||||
#foreach($column in $columns)#if($column.insert || $column.edit)
|
||||
/** $column.columnComment */
|
||||
$column.javaField:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) CommonType.IdType; #elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number; #elseif($column.javaType == 'Boolean') boolean; #else string; #end
|
||||
#end#end
|
||||
}>;
|
||||
|
||||
/** ${businessName} search params */
|
||||
type ${BusinessName}SearchParams = CommonType.RecordNullable<
|
||||
Pick<
|
||||
Api.${ModuleName}.${BusinessName},
|
||||
#foreach($column in $columns)
|
||||
#if($column.query)
|
||||
#set($dictType=$column.dictType)
|
||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||
#if($parentheseIndex != -1)
|
||||
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||
#else
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#if($foreach.hasNext) |#end '${column.javaField}'
|
||||
#end
|
||||
#end
|
||||
> &
|
||||
Common.CommonSearchParams
|
||||
>;
|
||||
|
||||
/** ${businessName} list */
|
||||
type ${BusinessName}List = Common.PaginatingQueryRecord<${BusinessName}>;
|
||||
}
|
Reference in New Issue
Block a user