mirror of
https://gitee.com/smallc/blade-tool.git
synced 2026-08-24 20:31:16 +08:00
✨ 代码生成器前端模板升级 TS + Composition API 产出,增强实体租户与主键序列化判定
This commit is contained in:
parent
e518473599
commit
3d93b3d587
|
|
@ -60,7 +60,7 @@ public class CodeGenerator {
|
|||
/**
|
||||
* 基础业务字段
|
||||
*/
|
||||
public static String[] SUPER_ENTITY_COLUMNS = {"create_time", "create_user", "update_time", "update_user", "status", "is_deleted"};
|
||||
public static String[] SUPER_ENTITY_COLUMNS = {"create_time", "create_user", "create_dept", "update_time", "update_user", "status", "is_deleted"};
|
||||
/**
|
||||
* 是否包含包装器
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,11 +15,13 @@
|
|||
*/
|
||||
package org.springblade.develop.support;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
|
||||
import com.baomidou.mybatisplus.generator.config.OutputFile;
|
||||
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
|
||||
import com.baomidou.mybatisplus.generator.config.builder.Entity;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.DateType;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
|
|
@ -148,25 +150,33 @@ public class BladeCodeGenerator {
|
|||
customFile.put("wrapper.java", "/templates/api/wrapper.java.vm");
|
||||
}
|
||||
if (Func.isNotBlank(packageWebDir)) {
|
||||
customFile.put("api.js", "/templates/saber/api.js.vm");
|
||||
customFile.put("api.ts", "/templates/saber/api.ts.vm");
|
||||
customFile.put("crud.vue", "/templates/saber/crud.vue.vm");
|
||||
}
|
||||
|
||||
// 无基础业务字段时实体不再继承 BaseEntity,服务层须同步降级为 MyBatis-Plus 原生接口(3.5.17 起位于 spring 包)
|
||||
String superServiceClass = hasSuperEntity ? "org.springblade.core.mp.base.BaseService" : "com.baomidou.mybatisplus.spring.service.IService";
|
||||
String superServiceImplClass = hasSuperEntity ? "org.springblade.core.mp.base.BaseServiceImpl" : "com.baomidou.mybatisplus.spring.service.impl.ServiceImpl";
|
||||
|
||||
FastAutoGenerator.create(url, username, password)
|
||||
.globalConfig(builder -> builder.author(props.getProperty("author")).dateType(DateType.TIME_PACK).enableSwagger().outputDir(getOutputDir()).disableOpenDir())
|
||||
.packageConfig(builder -> builder.parent(packageName).controller("controller").entity("pojo.entity").service("service").serviceImpl("service.impl").mapper("mapper").xml("mapper"))
|
||||
.strategyConfig(builder -> builder.addTablePrefix(tablePrefix).addInclude(includeTables).addExclude(excludeTables)
|
||||
.entityBuilder().naming(NamingStrategy.underline_to_camel).columnNaming(NamingStrategy.underline_to_camel).enableLombok().superClass("org.springblade.core.mp.base.BaseEntity").addSuperEntityColumns(superEntityColumns).enableFileOverride()
|
||||
.javaTemplate("/templates/api/entity.java.vm")
|
||||
.serviceBuilder().superServiceClass("org.springblade.core.mp.base.BaseService").superServiceImplClass("org.springblade.core.mp.base.BaseServiceImpl").formatServiceFileName("I%sService").formatServiceImplFileName("%sServiceImpl").enableFileOverride()
|
||||
.serviceTemplate("/templates/api/service.java.vm")
|
||||
.serviceImplTemplate("/templates/api/serviceImpl.java.vm")
|
||||
.mapperBuilder().mapperAnnotation(Mapper.class).enableBaseResultMap().enableBaseColumnList().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper").enableFileOverride()
|
||||
.mapperTemplate("/templates/api/mapper.java.vm")
|
||||
.mapperXmlTemplate("/templates/api/mapper.xml.vm")
|
||||
.controllerBuilder().superClass("org.springblade.core.boot.ctrl.BladeController").formatFileName("%sController").enableRestStyle().enableHyphenStyle().enableFileOverride()
|
||||
.template("/templates/api/controller.java.vm")
|
||||
)
|
||||
.strategyConfig(builder -> {
|
||||
Entity.Builder entityBuilder = builder.addTablePrefix(tablePrefix).addInclude(includeTables).addExclude(excludeTables)
|
||||
.entityBuilder().naming(NamingStrategy.underline_to_camel).columnNaming(NamingStrategy.underline_to_camel).enableLombok().idType(IdType.ASSIGN_ID).enableFileOverride()
|
||||
.javaTemplate("/templates/api/entity.java.vm");
|
||||
if (hasSuperEntity) {
|
||||
entityBuilder.superClass("org.springblade.core.mp.base.BaseEntity").addSuperEntityColumns(superEntityColumns);
|
||||
}
|
||||
entityBuilder.serviceBuilder().superServiceClass(superServiceClass).superServiceImplClass(superServiceImplClass).formatServiceFileName("I%sService").formatServiceImplFileName("%sServiceImpl").enableFileOverride()
|
||||
.serviceTemplate("/templates/api/service.java.vm")
|
||||
.serviceImplTemplate("/templates/api/serviceImpl.java.vm")
|
||||
.mapperBuilder().mapperAnnotation(Mapper.class).enableBaseResultMap().enableBaseColumnList().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper").enableFileOverride()
|
||||
.mapperTemplate("/templates/api/mapper.java.vm")
|
||||
.mapperXmlTemplate("/templates/api/mapper.xml.vm")
|
||||
.controllerBuilder().superClass("org.springblade.core.boot.ctrl.BladeController").formatFileName("%sController").enableRestStyle().enableHyphenStyle().enableFileOverride()
|
||||
.template("/templates/api/controller.java.vm");
|
||||
})
|
||||
.injectionConfig(builder -> builder.beforeOutputFile(
|
||||
(tableInfo, objectMap) -> System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size())
|
||||
).customMap(customMap).customFile(customFile)
|
||||
|
|
@ -202,8 +212,8 @@ public class BladeCodeGenerator {
|
|||
outputPath = getOutputDir() + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "wrapper" + StringPool.SLASH + entityName + "Wrapper" + StringPool.DOT_JAVA;
|
||||
}
|
||||
|
||||
if (StringUtil.equals(key, "api.js")) {
|
||||
outputPath = getOutputWebDir() + StringPool.SLASH + "api" + StringPool.SLASH + servicePackage.toLowerCase() + StringPool.SLASH + entityNameLower + ".js";
|
||||
if (StringUtil.equals(key, "api.ts")) {
|
||||
outputPath = getOutputWebDir() + StringPool.SLASH + "api" + StringPool.SLASH + servicePackage.toLowerCase() + StringPool.SLASH + entityNameLower + ".ts";
|
||||
}
|
||||
|
||||
if (StringUtil.equals(key, "crud.vue")) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* Copyright (c) 2018-2099, Chill Zhuang 庄骞 (bladejava@qq.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
|
@ -15,35 +15,30 @@
|
|||
*/
|
||||
package $!{package.Controller};
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
#if($!{superControllerClassPackage})
|
||||
import $!{superControllerClassPackage};
|
||||
#end
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.swagger.annotation.ApiOrder;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
#if($!{superEntityClass})
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
#end
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import $!{package.Entity}.$!{entity};
|
||||
#set($voPackage=$package.Entity.replace("entity","vo"))
|
||||
import $!{voPackage}.$!{entity}VO;
|
||||
#set($wrapperPackage=$package.Entity.replace("pojo.entity","wrapper"))
|
||||
#if($!{hasWrapper})
|
||||
#set($wrapperPackage=$package.Entity.replace("pojo.entity","wrapper"))
|
||||
import $!{wrapperPackage}.$!{entity}Wrapper;
|
||||
#end
|
||||
import $!{package.Service}.$!{table.serviceName};
|
||||
#if($!{superControllerClassPackage})
|
||||
import $!{superControllerClassPackage};
|
||||
#end
|
||||
#if(!$!{superEntityClass})
|
||||
#end
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 控制器
|
||||
|
|
@ -84,7 +79,6 @@ public class $!{table.controllerName} {
|
|||
IPage<$!{entity}> pages = $!{table.entityPath}Service.page(Condition.getPage(query), Condition.getQueryWrapper($!{table.entityPath}));
|
||||
return R.data($!{entity}Wrapper.build().pageVO(pages));
|
||||
}
|
||||
|
||||
#else
|
||||
/**
|
||||
* 详情
|
||||
|
|
@ -144,8 +138,7 @@ public class $!{table.controllerName} {
|
|||
return R.status($!{table.entityPath}Service.saveOrUpdate($!{table.entityPath}));
|
||||
}
|
||||
|
||||
#if($!{superEntityClass})
|
||||
|
||||
#if($!{superEntityClass})
|
||||
/**
|
||||
* 删除 $!{table.comment}
|
||||
*/
|
||||
|
|
@ -155,8 +148,7 @@ public class $!{table.controllerName} {
|
|||
return R.status($!{table.entityPath}Service.deleteLogic(Func.toLongList(ids)));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#else
|
||||
/**
|
||||
* 删除 $!{table.comment}
|
||||
*/
|
||||
|
|
@ -166,6 +158,5 @@ public class $!{table.controllerName} {
|
|||
return R.status($!{table.entityPath}Service.removeByIds(Func.toLongList(ids)));
|
||||
}
|
||||
|
||||
#end
|
||||
|
||||
#end
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,21 @@
|
|||
#set($hasTenant = false)
|
||||
#set($hasKeyField = false)
|
||||
#set($hasLongKey = false)
|
||||
#foreach($field in $!{table.fields})
|
||||
#if($!{field.name} == $!{tenantColumn})
|
||||
#set($hasTenant = true)
|
||||
#end
|
||||
#if($!{field.keyFlag})
|
||||
#set($hasKeyField = true)
|
||||
#end
|
||||
#if($!{field.keyFlag} && $!{field.propertyType} == "Long")
|
||||
#set($hasLongKey = true)
|
||||
#end
|
||||
#end
|
||||
#set($useTenantEntity = false)
|
||||
#if($hasTenant && "$!superEntityClass" == "BaseEntity")
|
||||
#set($useTenantEntity = true)
|
||||
#end
|
||||
/**
|
||||
* Copyright (c) 2018-2099, Chill Zhuang 庄骞 (bladejava@qq.com).
|
||||
* <p>
|
||||
|
|
@ -16,8 +34,20 @@
|
|||
package $!{package.Entity};
|
||||
|
||||
#foreach($pkg in $!{table.importPackages})
|
||||
#if($useTenantEntity && $!{pkg} == "org.springblade.core.mp.base.BaseEntity")
|
||||
import org.springblade.core.mp.base.TenantEntity;
|
||||
#elseif($!{pkg} == "java.io.Serializable" && $!{superEntityClass} && !$!{activeRecord})
|
||||
## 继承父类时不直接实现 Serializable,跳过强制注入的导入
|
||||
#elseif(!$hasKeyField && ($!{pkg} == "com.baomidou.mybatisplus.annotation.IdType" || $!{pkg} == "com.baomidou.mybatisplus.annotation.TableId"))
|
||||
## 主键列归入公共字段时实体内不产出主键注解,跳过全局 idType 注入的导入
|
||||
#else
|
||||
import $!{pkg};
|
||||
#end
|
||||
#end
|
||||
#if($hasLongKey)
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
#end
|
||||
#if($!{entityLombokModel})
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
|
@ -46,7 +76,7 @@ import java.io.Serial;
|
|||
@Schema(description = #if ("$!{table.comment}"=="")"$!{entity}对象"#else"$!{table.comment}"#end)
|
||||
#end
|
||||
#if($!{superEntityClass})
|
||||
public class $!{entity} extends $!{superEntityClass}#if($!{activeRecord})<$!{entity}>#end {
|
||||
public class $!{entity} extends #if($useTenantEntity)TenantEntity#{else}$!{superEntityClass}#end#if($!{activeRecord})<$!{entity}>#end {
|
||||
#elseif($!{activeRecord})
|
||||
@Accessors(chain = true)
|
||||
public class $!{entity} extends Model<$!{entity}> {
|
||||
|
|
@ -59,7 +89,7 @@ public class $!{entity} implements Serializable {
|
|||
|
||||
## ---------- BEGIN 字段循环遍历 ----------
|
||||
#foreach($field in $!{table.fields})
|
||||
#if($!{field.name}!=$!{tenantColumn})
|
||||
#if($!{field.name} != $!{tenantColumn} || !$useTenantEntity)
|
||||
#if($!{field.keyFlag})
|
||||
#set($keyPropertyName=$!{field.propertyName})
|
||||
#end
|
||||
|
|
@ -80,6 +110,9 @@ public class $!{entity} implements Serializable {
|
|||
#elseif($!{field.convert})
|
||||
@TableId("$!{field.name}")
|
||||
#end
|
||||
#if($!{field.propertyType} == "Long")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
#end
|
||||
## 普通字段
|
||||
#elseif($!{field.fill})
|
||||
## ----- 存在字段填充设置 -----
|
||||
|
|
|
|||
|
|
@ -15,11 +15,12 @@
|
|||
*/
|
||||
package $!{package.Mapper};
|
||||
|
||||
import $!{superMapperClassPackage};
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import $!{package.Entity}.$!{entity};
|
||||
#set($voPackage=$package.Entity.replace("entity","vo"))
|
||||
import $!{voPackage}.$!{entity}VO;
|
||||
import $!{superMapperClassPackage};
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,3 +1,13 @@
|
|||
#set($hasTenant = false)
|
||||
#foreach($field in $!{table.fields})
|
||||
#if($!{field.name} == $!{tenantColumn})
|
||||
#set($hasTenant = true)
|
||||
#end
|
||||
#end
|
||||
#set($useTenantEntity = false)
|
||||
#if($hasTenant && "$!superEntityClass" == "BaseEntity")
|
||||
#set($useTenantEntity = true)
|
||||
#end
|
||||
<?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="$!{package.Mapper}.$!{table.mapperName}">
|
||||
|
|
@ -19,7 +29,7 @@
|
|||
<result column="$!{field.name}" property="$!{field.propertyName}"/>
|
||||
#end
|
||||
#foreach($field in $!{table.fields})
|
||||
#if(!$!{field.keyFlag} && $!{field.name} != $!{tenantColumn})##生成普通字段
|
||||
#if(!$!{field.keyFlag} && ($!{field.name} != $!{tenantColumn} || !$useTenantEntity))##生成普通字段
|
||||
<result column="$!{field.name}" property="$!{field.propertyName}"/>
|
||||
#end
|
||||
#end
|
||||
|
|
@ -28,7 +38,11 @@
|
|||
#end
|
||||
|
||||
<select id="select$!{entity}Page" resultMap="$!{table.entityPath}ResultMap">
|
||||
#if($!{superEntityClass})
|
||||
select * from $!{table.name} where is_deleted = 0
|
||||
#else
|
||||
select * from $!{table.name}
|
||||
#end
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@
|
|||
*/
|
||||
package $!{package.Service};
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import $!{superServiceClassPackage};
|
||||
import $!{package.Entity}.$!{entity};
|
||||
#set($voPackage=$package.Entity.replace("entity","vo"))
|
||||
import $!{voPackage}.$!{entity}VO;
|
||||
import $!{superServiceClassPackage};
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 服务类
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@
|
|||
*/
|
||||
package $!{package.ServiceImpl};
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import $!{superServiceImplClassPackage};
|
||||
import $!{package.Entity}.$!{entity};
|
||||
#set($voPackage=$package.Entity.replace("entity","vo"))
|
||||
import $!{voPackage}.$!{entity}VO;
|
||||
import $!{package.Mapper}.$!{table.mapperName};
|
||||
import $!{package.Service}.$!{table.serviceName};
|
||||
import $!{superServiceImplClassPackage};
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 服务实现类
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
#set($wrapperPackage=$package.Entity.replace("pojo.entity","wrapper"))
|
||||
package $!{wrapperPackage};
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import $!{package.Entity}.$!{entity};
|
||||
|
|
@ -29,11 +28,11 @@ import $!{voPackage}.$!{entity}VO;
|
|||
* @author $!{author}
|
||||
* @since $!{date}
|
||||
*/
|
||||
public class $!{entity}Wrapper extends BaseEntityWrapper<$!{entity}, $!{entity}VO> {
|
||||
public class $!{entity}Wrapper extends BaseEntityWrapper<$!{entity}, $!{entity}VO> {
|
||||
|
||||
public static $!{entity}Wrapper build() {
|
||||
return new $!{entity}Wrapper();
|
||||
}
|
||||
return new $!{entity}Wrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public $!{entity}VO entityVO($!{entity} $!{table.entityPath}) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,23 @@
|
|||
#set($hasTenant = false)
|
||||
#foreach($field in $!{table.fields})
|
||||
#if($!{field.name} == $!{tenantColumn})
|
||||
#set($hasTenant = true)
|
||||
#end
|
||||
#end
|
||||
#set($useTenantEntity = false)
|
||||
#if($hasTenant && "$!superEntityClass" == "BaseEntity")
|
||||
#set($useTenantEntity = true)
|
||||
#end
|
||||
<template>
|
||||
<basic-container>
|
||||
<avue-crud :option="option"
|
||||
:table-loading="loading"
|
||||
:data="data"
|
||||
ref="crudRef"
|
||||
v-model="form"
|
||||
v-model:search="search"
|
||||
v-model:page="page"
|
||||
:page="page"
|
||||
:permission="permissionList"
|
||||
:before-open="beforeOpen"
|
||||
v-model="form"
|
||||
ref="crudRef"
|
||||
@row-update="rowUpdate"
|
||||
@row-save="rowSave"
|
||||
@row-del="rowDel"
|
||||
|
|
@ -17,6 +26,7 @@
|
|||
@selection-change="selectionChange"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@refresh-change="refreshChange"
|
||||
@on-load="onLoad">
|
||||
<template #menu-left>
|
||||
<el-button type="danger"
|
||||
|
|
@ -41,8 +51,8 @@ import { validData } from '@/utils/util';
|
|||
interface $!{entity}Entity {
|
||||
id: string;
|
||||
#foreach($field in $!{table.fields})
|
||||
#if($!{field.name}!=$!{tenantColumn})
|
||||
#if($!{field.propertyName} != "id")
|
||||
#if($!{field.name} != $!{tenantColumn} || !$useTenantEntity)
|
||||
#if(!$!{field.keyFlag})
|
||||
#if($!{field.propertyType} == "Integer" || $!{field.propertyType} == "Long" || $!{field.propertyType} == "Short" || $!{field.propertyType} == "Byte" || $!{field.propertyType} == "Double" || $!{field.propertyType} == "Float" || $!{field.propertyType} == "BigDecimal")
|
||||
$!{field.propertyName}?: number;
|
||||
#elseif($!{field.propertyType} == "Boolean")
|
||||
|
|
@ -65,14 +75,13 @@ const permission = computed(() => store.getters.permission);
|
|||
// 表格实例与数据状态
|
||||
const crudRef = ref();
|
||||
const form = ref<$!{entity}Form>({});
|
||||
const search = ref<Partial<$!{entity}Entity>>({});
|
||||
const data = ref<$!{entity}Entity[]>([]);
|
||||
const selectionList = ref<$!{entity}Entity[]>([]);
|
||||
const query = ref<Partial<$!{entity}Entity>>({});
|
||||
const loading = ref(true);
|
||||
|
||||
// 分页参数(整体替换,需用 ref)
|
||||
const page = ref({
|
||||
// 分页参数
|
||||
const page = reactive({
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
total: 0,
|
||||
|
|
@ -85,16 +94,17 @@ const ids = computed(() => selectionList.value.map(ele => ele.id).join(','));
|
|||
const option = reactive({
|
||||
height: 'auto',
|
||||
calcHeight: 210,
|
||||
tip: false,
|
||||
searchShow: true,
|
||||
searchMenuSpan: 6,
|
||||
tip: false,
|
||||
border: true,
|
||||
index: true,
|
||||
viewBtn: true,
|
||||
selection: true,
|
||||
column: [
|
||||
#foreach($field in $!{table.fields})
|
||||
#if($!{field.name}!=$!{tenantColumn})
|
||||
#if($!{field.name} != $!{tenantColumn} || !$useTenantEntity)
|
||||
#if(!$!{field.keyFlag})
|
||||
{
|
||||
label: '$!{field.comment}',
|
||||
prop: '$!{field.propertyName}',
|
||||
|
|
@ -105,6 +115,7 @@ const option = reactive({
|
|||
}],
|
||||
},
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
],
|
||||
});
|
||||
|
|
@ -121,9 +132,9 @@ const permissionList = computed(() => ({
|
|||
const onLoad = (pageData: { currentPage: number; pageSize: number }, params: Partial<$!{entity}Entity> = {}) => {
|
||||
loading.value = true;
|
||||
getList(pageData.currentPage, pageData.pageSize, Object.assign(params, query.value)).then(res => {
|
||||
const list = res.data.data;
|
||||
page.value.total = list.total;
|
||||
data.value = list.records;
|
||||
const listData = res.data.data;
|
||||
page.total = listData.total;
|
||||
data.value = listData.records;
|
||||
loading.value = false;
|
||||
selectionClear();
|
||||
});
|
||||
|
|
@ -132,25 +143,30 @@ const onLoad = (pageData: { currentPage: number; pageSize: number }, params: Par
|
|||
// 条件检索
|
||||
const searchChange = (params: Partial<$!{entity}Entity>, done: () => void) => {
|
||||
query.value = params;
|
||||
page.value.currentPage = 1;
|
||||
onLoad(page.value, params);
|
||||
page.currentPage = 1;
|
||||
onLoad(page, params);
|
||||
done();
|
||||
};
|
||||
|
||||
// 重置检索条件
|
||||
const searchReset = () => {
|
||||
query.value = {};
|
||||
onLoad(page.value);
|
||||
onLoad(page);
|
||||
};
|
||||
|
||||
// 切换页码
|
||||
const currentChange = (currentPage: number) => {
|
||||
page.value.currentPage = currentPage;
|
||||
page.currentPage = currentPage;
|
||||
};
|
||||
|
||||
// 调整每页条数
|
||||
const sizeChange = (pageSize: number) => {
|
||||
page.value.pageSize = pageSize;
|
||||
page.pageSize = pageSize;
|
||||
};
|
||||
|
||||
// 刷新当前列表
|
||||
const refreshChange = () => {
|
||||
onLoad(page, query.value);
|
||||
};
|
||||
|
||||
// 记录当前选中行
|
||||
|
|
@ -168,7 +184,7 @@ const selectionClear = () => {
|
|||
const rowSave = (row: $!{entity}Form, done: () => void, loading: () => void) => {
|
||||
add(row).then(() => {
|
||||
done();
|
||||
onLoad(page.value);
|
||||
onLoad(page);
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '操作成功!',
|
||||
|
|
@ -183,7 +199,7 @@ const rowSave = (row: $!{entity}Form, done: () => void, loading: () => void) =>
|
|||
const rowUpdate = (row: $!{entity}Form, index: number, done: () => void, loading: () => void) => {
|
||||
update(row).then(() => {
|
||||
done();
|
||||
onLoad(page.value);
|
||||
onLoad(page);
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '操作成功!',
|
||||
|
|
@ -205,7 +221,7 @@ const rowDel = (row: $!{entity}Entity) => {
|
|||
return remove(row.id);
|
||||
})
|
||||
.then(() => {
|
||||
onLoad(page.value);
|
||||
onLoad(page);
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '操作成功!',
|
||||
|
|
@ -228,7 +244,7 @@ const handleDelete = () => {
|
|||
return remove(ids.value);
|
||||
})
|
||||
.then(() => {
|
||||
onLoad(page.value);
|
||||
onLoad(page);
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '操作成功!',
|
||||
|
|
@ -237,7 +253,7 @@ const handleDelete = () => {
|
|||
});
|
||||
};
|
||||
|
||||
// 打开弹窗前置处理:编辑与查看回填详情
|
||||
// 打开弹窗前加载编辑/查看详情
|
||||
const beforeOpen = (done: () => void, type: string) => {
|
||||
if (['edit', 'view'].includes(type)) {
|
||||
getDetail(form.value.id).then(res => {
|
||||
|
|
|
|||
|
|
@ -652,7 +652,7 @@ import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
|
|||
|
||||
**⑥ 安全放行(springdoc 路径)**:springdoc UI 与规格端点需匿名可达。框架默认放行清单 `blade-core-secure` 的 `SecureRegistry.defaultExcludePatterns` 已含 `/v3/api-docs/**`、`/swagger-ui/**`、`/swagger-ui.html`(`/swagger-ui/**` 为 UI 静态资源,`/swagger-ui.html` 为跳转入口),下游 servlet 应用继承即可。若应用另有自建放行清单(Boot 单体的 `BladeConfiguration`、Cloud 网关的 `AuthProvider`),须同步补齐这三项,并去掉 `/doc.html`、`/swagger-resources/**` 等 knife4j / springfox 旧路径。
|
||||
|
||||
**⑦ 代码生成器模板**:`blade-starter-develop/src/main/resources/templates/controller.java.vm` 里的 `@ApiOperationSupport` import 与注解一并删除——它是 `.vm` 资源,下游按 `*.java` 批量清理的脚本覆盖不到,须单独处理,否则该生成器产出的 Controller 引用已移除的 knife4j 包、编译不过(排序改用 §9⑧ 的 `@ApiOrder`)。删干净后**还须在模板 `@Tag` 上方补一行无参 `@ApiOrder` + 其 import**(`org.springblade.core.swagger.annotation.ApiOrder`),让生成的 Controller 与手写控制器一致带排序(见下「落地约定」);下游 Boot(`src/{main,test}/resources/templates/`)、Cloud(`blade-ops/blade-develop/src/{main,test}/resources/templates/`)的同名模板副本一并补。
|
||||
**⑦ 代码生成器模板**:`blade-starter-develop/src/main/resources/templates/controller.java.vm` 里的 `@ApiOperationSupport` import 与注解一并删除——它是 `.vm` 资源,下游按 `*.java` 批量清理的脚本覆盖不到,须单独处理,否则该生成器产出的 Controller 引用已移除的 knife4j 包、编译不过(排序改用 §9⑧ 的 `@ApiOrder`)。删干净后**还须在模板 `@Tag` 上方补一行无参 `@ApiOrder` + 其 import**(`org.springblade.core.swagger.annotation.ApiOrder`),让生成的 Controller 与手写控制器一致带排序(见下「落地约定」);下游 Boot(`src/main/resources/templates/`)、Cloud(`blade-ops/blade-develop/src/main/resources/templates/`)的同名模板副本一并补。`src/test/resources/templates/` 下的旧扁平路径 `.vm` 副本自模板重组为 `api/` 子目录后不再被加载,应直接删除,test 侧仅保留 `code.properties` 作为数据源配置覆盖点。
|
||||
|
||||
**⑧ 接口排序:`@ApiOrder`(替代 knife4j 的 `@ApiOperationSupport(order = n)`)**
|
||||
|
||||
|
|
@ -664,7 +664,7 @@ springdoc / OpenAPI 3 无接口排序原生注解,blade-starter-swagger 新增 `
|
|||
|
||||
实现在 `SwaggerAutoConfiguration`:`GlobalOperationCustomizer` 读注解写入 `x-order` 扩展(类级用字节码行号取声明序,反射不保证方法顺序)并记录「tag → 类级序号」;`GlobalOpenApiCustomizer` 按 `x-order` 重排 `paths`、按类级序号重排顶层 `tags`。swagger-ui 仅在两个 sorter 未设时保留 spec 顺序(§9⑤),并须保持 `springdoc.writer-with-order-by-keys` 默认 `false`。
|
||||
|
||||
**落地约定(本次统一)**:三工程**每个带 `@Tag` 的控制器**均在 `@Tag` 上方补一行**无参 `@ApiOrder`**(值取默认 `Integer.MAX_VALUE`),方法体只保留 `@Operation`——效果是分组内接口按**源码声明顺序**展示、各 `@Tag` 分组之间因类级序号相等而回落 tag 名字母序;仅当个别接口要打破源码顺序时,才在该方法上补 `@ApiOrder(n)` 精确覆盖。删 knife4j 排序注解(§3.1 / §4.2)后**只删不补**会让接口在 springdoc UI 下按字母序、丢失原有顺序,故「删旧 + 补 `@ApiOrder`」是同一件事的两半。代码生成器模板 `controller.java.vm`(blade-tool `blade-starter-develop` 源模板 + 下游 Boot/Cloud `blade-develop` 的 main/test 副本,共 5 份)同步在 `@Tag` 上方生成 `@ApiOrder`,新生成的 Controller 开箱即带排序。
|
||||
**落地约定(本次统一)**:三工程**每个带 `@Tag` 的控制器**均在 `@Tag` 上方补一行**无参 `@ApiOrder`**(值取默认 `Integer.MAX_VALUE`),方法体只保留 `@Operation`——效果是分组内接口按**源码声明顺序**展示、各 `@Tag` 分组之间因类级序号相等而回落 tag 名字母序;仅当个别接口要打破源码顺序时,才在该方法上补 `@ApiOrder(n)` 精确覆盖。删 knife4j 排序注解(§3.1 / §4.2)后**只删不补**会让接口在 springdoc UI 下按字母序、丢失原有顺序,故「删旧 + 补 `@ApiOrder`」是同一件事的两半。代码生成器模板 `controller.java.vm`(blade-tool `blade-starter-develop` 源模板 + 下游 Boot/Cloud `blade-develop` 的 main 副本,共 3 份)同步在 `@Tag` 上方生成 `@ApiOrder`,新生成的 Controller 开箱即带排序。
|
||||
|
||||
> 提示:类级 `@ApiOrder(n)` 的 `value` 用作 `@Tag` 分组之间的排序序号(`SwaggerAutoConfiguration#recordTagOrder` 写入、`GlobalOpenApiCustomizer` 据此重排顶层 `tags`);分组内各接口不受此值影响,按源码声明顺序排列。本次全量采用**无参**形式,`value` 恒为默认值、各分组落 tag 名字母序;如需固定分组顺序,给对应控制器标 `@ApiOrder(n)` 即可。
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user