feat(新增): 路由相关修改和菜单图标缺陷修复,代码生成器修复

This commit is contained in:
Bunny 2024-10-03 13:44:39 +08:00
parent 2e53338e8f
commit 8c0d72c3ba
18 changed files with 71 additions and 69 deletions

View File

@ -187,7 +187,7 @@ public class WebGeneratorCode {
public static void writeFiles(String lowercaseName, String lowerHyphen, String originalName, VelocityContext context) throws IOException { public static void writeFiles(String lowercaseName, String lowerHyphen, String originalName, VelocityContext context) throws IOException {
context.put("apiPath", GeneratorCodeUtils.ReplacePathHandle(apiPath) + lowercaseName); context.put("apiPath", GeneratorCodeUtils.ReplacePathHandle(apiPath) + lowercaseName);
context.put("typesPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/types"); context.put("typesPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/types");
context.put("hookPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/hook"); context.put("hookPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/hooks");
context.put("columnsPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/columns"); context.put("columnsPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/columns");
context.put("dialogPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/" + lowerHyphen + "-dialog.vue"); context.put("dialogPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/" + lowerHyphen + "-dialog.vue");
@ -205,7 +205,7 @@ public class WebGeneratorCode {
// 写入hook模板 // 写入hook模板
Template hookTemplate = Velocity.getTemplate("vms/web/hook.vm", "UTF-8"); Template hookTemplate = Velocity.getTemplate("vms/web/hook.vm", "UTF-8");
FileWriter hookTemplateFileWriter = new FileWriter(vuePath + lowercaseName + "\\utils\\hook.ts"); FileWriter hookTemplateFileWriter = new FileWriter(vuePath + lowercaseName + "\\utils\\hooks.ts");
hookTemplate.merge(context, hookTemplateFileWriter); hookTemplate.merge(context, hookTemplateFileWriter);
hookTemplateFileWriter.close(); hookTemplateFileWriter.close();

View File

@ -3,14 +3,15 @@ import { $t } from '@/plugins/i18n';
// 表格列 // 表格列
export const columns: TableColumnList = [ export const columns: TableColumnList = [
{ type: 'index', index: (index: number) => index + 1 },
// { type: 'selection', align: 'left' },
{ label: $t('id'), prop: 'id' }, { label: $t('id'), prop: 'id' },
#foreach($field in $baseFieldList) #foreach($field in $baseFieldList)
// $field.annotation // $field.annotation
{ label: $t('${lowercaseName}_$field.name'), prop: '$field.name' }, { label: $t('${lowercaseName}_$field.name'), prop: '$field.name' },
#end #end
{ label: $t('i18n_typeName'), prop: 'typeName' }, { label: $t('table.updateTime'), prop: 'updateTime', sortable: true },
{ label: $t('table.updateTime'), prop: 'updateTime' }, { label: $t('table.createTime'), prop: 'createTime', sortable: true },
{ label: $t('table.createTime'), prop: 'createTime' },
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser' }, { label: $t('table.createUser'), prop: 'createUser', slot: 'createUser' },
{ label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser' }, { label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser' },
{ label: $t('table.operation'), fixed: 'right', width: 210, slot: 'operation' }, { label: $t('table.operation'), fixed: 'right', width: 210, slot: 'operation' },
@ -20,6 +21,6 @@ export const columns: TableColumnList = [
export const rules = reactive({ export const rules = reactive({
#foreach($field in $baseFieldList) #foreach($field in $baseFieldList)
// $field.annotation // $field.annotation
$field.name: [{ required: true, message: `$leftBrace$t('input')}$leftBrace$t('$lowercaseName_$field.name')}`, trigger: 'blur' }], $field.name: [{ required: true, message: `$leftBrace$t('input')}$leftBrace$t('${lowercaseName}_${field.name}')}`, trigger: 'blur' }],
#end #end
}); });

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { FormInstance } from 'element-plus'; import { FormInstance } from 'element-plus';
import { rules } from '@/views/i18n/i18n-type-setting/utils/columns'; import { rules } from '${hookPath}';
import { FormProps } from '${typesPath}'; import { FormProps } from '${typesPath}';
import { frameSureOptions } from '@/enums'; import { frameSureOptions } from '@/enums';
import Segmented from '@/components/ReSegmented'; import Segmented from '@/components/ReSegmented';

View File

@ -24,7 +24,7 @@ export async function onSearch() {
*/ */
export function onAdd() { export function onAdd() {
addDialog({ addDialog({
title: `$leftBrace $t("add")} $leftBrace$t("${lowercaseName}}")}`, title: `$leftBrace $t("add")} $leftBrace$t("${lowercaseName}")}`,
width: '30%', width: '30%',
props: { props: {
formInline: { formInline: {
@ -58,7 +58,7 @@ export function onAdd() {
*/ */
export function onUpdate(row: any) { export function onUpdate(row: any) {
addDialog({ addDialog({
title: `$leftBrace$t("modify")} $leftBrace$t("${lowercaseName}}")}`, title: `$leftBrace$t("modify")} $leftBrace$t("${lowercaseName}")}`,
width: '30%', width: '30%',
props: { props: {
formInline: { formInline: {

View File

@ -30,14 +30,14 @@
<template> <template>
<div class="main"> <div class="main">
<el-form ref="formRef" :inline="true" :model="i18nTypeStore.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"> <el-form ref="formRef" :inline="true" :model="${lowercaseName}Store.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
#foreach($item in $formList) #foreach($item in $formList)
<el-form-item :label="$t('${lowercaseName}_${item.name}')" prop="${item.name}"> <el-form-item :label="$t('${lowercaseName}_${item.name}')" prop="${item.name}">
<el-input v-model="${lowercaseName}Store.form.${item.name}" :placeholder="`$leftBrace$t('input')} $leftBrace$t('${item.name}')}`" class="!w-[180px]" clearable /> <el-input v-model="${lowercaseName}Store.form.${item.name}" :placeholder="`$leftBrace$t('input')} $leftBrace$t('${item.name}')}`" class="!w-[180px]" clearable />
</el-form-item> </el-form-item>
#end #end
<el-form-item> <el-form-item>
<el-button :icon="useRenderIcon('ri:search-line')" :loading="i18nTypeStore.loading" type="primary" @click="onSearch"> {{ $t('search') }} </el-button> <el-button :icon="useRenderIcon('ri:search-line')" :loading="${lowercaseName}Store.loading" type="primary" @click="onSearch"> {{ $t('search') }} </el-button>
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button> <el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -52,9 +52,9 @@
ref="tableRef" ref="tableRef"
:adaptiveConfig="{ offsetBottom: 45 }" :adaptiveConfig="{ offsetBottom: 45 }"
:columns="dynamicColumns" :columns="dynamicColumns"
:data="i18nTypeStore.datalist" :data="${lowercaseName}Store.datalist"
:header-cell-style="{ background: 'var(--el-fill-color-light)', color: 'var(--el-text-color-primary)' }" :header-cell-style="{ background: 'var(--el-fill-color-light)', color: 'var(--el-text-color-primary)' }"
:loading="i18nTypeStore.loading" :loading="${lowercaseName}Store.loading"
:size="size" :size="size"
adaptive adaptive
align-whole="center" align-whole="center"

View File

@ -35,9 +35,18 @@ export const use${originalName}Store = defineStore('${lowercaseName}Store', {
* * 获取${classTitle} * * 获取${classTitle}
*/ */
async get${originalName}List() { async get${originalName}List() {
const result = await fetchGet${originalName}List(); const data = { ...this.pagination, ...this.form };
if (result.code === 200) { delete data.pageSizes;
this.datalist = result.data; delete data.total;
delete data.background;
const result = await fetchGet${originalName}List(data);
if (result.code === 200) {
this.datalist = result.data.list;
this.pagination.currentPage = result.data.pageNo;
this.pagination.pageSize = result.data.pageSize;
this.pagination.total = result.data.total;
return true; return true;
} }
return false; return false;

View File

@ -61,5 +61,10 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId> <artifactId>spring-boot-starter-mail</artifactId>
</dependency> </dependency>
<!-- 表单验证 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -2,6 +2,7 @@ package cn.bunny.dao.dto.menuIcon;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -15,7 +16,7 @@ import lombok.NoArgsConstructor;
public class MenuIconUpdateDto { public class MenuIconUpdateDto {
@Schema(name = "id", title = "主键") @Schema(name = "id", title = "主键")
@NotBlank(message = "id不能为空") @NotNull(message = "id不能为空")
private Long id; private Long id;
@Schema(name = "iconName", title = "icon 名称") @Schema(name = "iconName", title = "icon 名称")

View File

@ -65,8 +65,7 @@ public class RouterAddDto {
@ApiModelProperty("是否固定标签") @ApiModelProperty("是否固定标签")
private Boolean fixedTag = false; private Boolean fixedTag = false;
@ApiModelProperty("是否显示 返给前端为 showLink") @ApiModelProperty("是否显示")
@JsonProperty("showLink")
private Boolean visible = false; private Boolean visible = false;
@ApiModelProperty("是否显示父级") @ApiModelProperty("是否显示父级")

View File

@ -18,6 +18,7 @@ import lombok.NoArgsConstructor;
public class RouterUpdateDto { public class RouterUpdateDto {
@ApiModelProperty("唯一标识") @ApiModelProperty("唯一标识")
@NotNull(message = "id不能为空")
private Long id; private Long id;
@ApiModelProperty("菜单类型") @ApiModelProperty("菜单类型")
@ -45,34 +46,14 @@ public class RouterUpdateDto {
@ApiModelProperty("等级") @ApiModelProperty("等级")
@JsonProperty("rank") @JsonProperty("rank")
private Integer routerRank = 99; private Integer routerRank;
@ApiModelProperty("重定向")
private String redirect;
@ApiModelProperty("图标") @ApiModelProperty("图标")
private String icon; private String icon;
@ApiModelProperty("进入动画")
private String enterTransition;
@ApiModelProperty("退出动画")
private String leaveTransition;
@ApiModelProperty("frame路径") @ApiModelProperty("frame路径")
private String frameSrc; private String frameSrc;
@ApiModelProperty("是否隐藏标签") @ApiModelProperty("是否显示")
private Boolean hiddenTag = false; private Boolean visible;
@ApiModelProperty("是否固定标签")
private Boolean fixedTag = false;
@ApiModelProperty("是否显示 返给前端为 showLink")
@JsonProperty("showLink")
private Boolean visible = false;
@ApiModelProperty("是否显示父级")
private Boolean showParent = false;
} }

View File

@ -51,7 +51,7 @@ public class Router extends BaseEntity {
@Schema(name = "routerRank", title = "等级") @Schema(name = "routerRank", title = "等级")
private Integer routerRank; private Integer routerRank;
@Schema(name = "visible", title = "是否显示 返给前端为 showLink") @Schema(name = "visible", title = "是否显示")
private Boolean visible; private Boolean visible;
} }

View File

@ -53,7 +53,7 @@ public class RouterManageVo extends BaseVo {
@JsonProperty("rank") @JsonProperty("rank")
private Integer routerRank; private Integer routerRank;
@ApiModelProperty("是否显示 返给前端为 showLink") @ApiModelProperty("是否显示")
private Boolean visible; private Boolean visible;
@ApiModelProperty("子路由") @ApiModelProperty("子路由")

View File

@ -1,6 +1,5 @@
package cn.bunny.dao.vo.router; package cn.bunny.dao.vo.router;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -32,10 +31,6 @@ public class RouterMeta {
@ApiModelProperty(value = "权限列表") @ApiModelProperty(value = "权限列表")
private List<String> auths; private List<String> auths;
@ApiModelProperty("是否显示 返给前端为 showLink")
@JsonProperty("showLink")
private Boolean visible;
@ApiModelProperty("frame路径") @ApiModelProperty("frame路径")
private String frameSrc; private String frameSrc;

View File

@ -14,6 +14,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -44,7 +45,7 @@ public class RouterController {
} }
@Operation(summary = "分页管理菜单列表", description = "分页管理菜单列表") @Operation(summary = "分页管理菜单列表", description = "分页管理菜单列表")
@GetMapping("getMenusByPage/{page}/{limit}") @GetMapping("getMenusList/{page}/{limit}")
public Mono<Result<PageResult<RouterManageVo>>> getMenusByPage( public Mono<Result<PageResult<RouterManageVo>>> getMenusByPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@PathVariable("page") Integer page, @PathVariable("page") Integer page,
@ -58,23 +59,23 @@ public class RouterController {
} }
@Operation(summary = "管理菜单列表", description = "管理菜单列表") @Operation(summary = "管理菜单列表", description = "管理菜单列表")
@GetMapping("getMenus") @GetMapping("getMenusList")
public Mono<Result<List<RouterManageVo>>> getMenu() { public Mono<Result<List<RouterManageVo>>> getMenusList(RouterManageDto dto) {
List<RouterManageVo> voPageResult = routerService.getMenu(); List<RouterManageVo> voPageResult = routerService.getMenusList(dto);
return Mono.just(Result.success(voPageResult)); return Mono.just(Result.success(voPageResult));
} }
@Operation(summary = "添加路由菜单", description = "添加路由菜单") @Operation(summary = "添加路由菜单", description = "添加路由菜单")
@PostMapping("addMenu") @PostMapping("addMenu")
public Mono<Result<String>> addMenu(@RequestBody RouterAddDto dto) { public Mono<Result<String>> addMenu(@Valid @RequestBody RouterAddDto dto) {
routerService.addMenu(dto); routerService.addMenu(dto);
return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS)); return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
} }
@Operation(summary = "更新路由菜单", description = "更新路由菜单") @Operation(summary = "更新路由菜单", description = "更新路由菜单")
@PutMapping("updateMenu") @PutMapping("updateMenu")
public Mono<Result<String>> updateMenu(@RequestBody RouterUpdateDto dto) { public Mono<Result<String>> updateMenu(@Valid @RequestBody RouterUpdateDto dto) {
routerService.updateMenu(dto); routerService.updateMenu(dto);
return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS)); return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS));
} }

View File

@ -9,6 +9,7 @@ import cn.bunny.dao.vo.router.RouterManageVo;
import cn.bunny.dao.vo.router.UserRouterVo; import cn.bunny.dao.vo.router.UserRouterVo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.validation.Valid;
import java.util.List; import java.util.List;
@ -42,21 +43,21 @@ public interface RouterService extends IService<Router> {
* *
* @return 系统菜单表 * @return 系统菜单表
*/ */
List<RouterManageVo> getMenu(); List<RouterManageVo> getMenusList(RouterManageDto dto);
/** /**
* * 添加路由菜单 * * 添加路由菜单
* *
* @param dto 添加菜单表单 * @param dto 添加菜单表单
*/ */
void addMenu(RouterAddDto dto); void addMenu(@Valid RouterAddDto dto);
/** /**
* * 更新路由菜单 * * 更新路由菜单
* *
* @param dto 更新表单 * @param dto 更新表单
*/ */
void updateMenu(RouterUpdateDto dto); void updateMenu(@Valid RouterUpdateDto dto);
/** /**
* * 删除路由菜单 * * 删除路由菜单

View File

@ -16,6 +16,7 @@ import cn.bunny.dao.vo.user.LoginVo;
import cn.bunny.services.factory.RouterServiceFactory; import cn.bunny.services.factory.RouterServiceFactory;
import cn.bunny.services.mapper.RouterMapper; import cn.bunny.services.mapper.RouterMapper;
import cn.bunny.services.service.RouterService; import cn.bunny.services.service.RouterService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -25,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
@ -143,8 +145,12 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
* @return 系统菜单表 * @return 系统菜单表
*/ */
@Override @Override
public List<RouterManageVo> getMenu() { public List<RouterManageVo> getMenusList(RouterManageDto dto) {
return list().stream().map(router -> { LambdaQueryWrapper<Router> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.like(StringUtils.hasText(dto.getTitle()), Router::getTitle, dto.getTitle());
lambdaQueryWrapper.eq(dto.getVisible() != null, Router::getVisible, dto.getVisible());
return list(lambdaQueryWrapper).stream().map(router -> {
RouterManageVo routerManageVo = new RouterManageVo(); RouterManageVo routerManageVo = new RouterManageVo();
BeanUtils.copyProperties(router, routerManageVo); BeanUtils.copyProperties(router, routerManageVo);
return routerManageVo; return routerManageVo;
@ -180,7 +186,7 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
Long id = dto.getId(); Long id = dto.getId();
Router router = getOne(Wrappers.<Router>lambdaQuery().eq(Router::getId, id)); Router router = getOne(Wrappers.<Router>lambdaQuery().eq(Router::getId, id));
if (router == null) { if (router == null) {
throw new BunnyException(ResultCodeEnum.DATA_EXIST); throw new BunnyException(ResultCodeEnum.DATA_NOT_EXIST);
} }
router = new Router(); router = new Router();

View File

@ -74,8 +74,8 @@ mybatis-plus:
global-config: global-config:
db-config: db-config:
logic-delete-field: isDelete logic-delete-field: isDelete
# configuration: configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
logging: logging:
level: level:

View File

@ -68,11 +68,14 @@
<select id="selectListByPage" resultType="cn.bunny.dao.entity.system.Router"> <select id="selectListByPage" resultType="cn.bunny.dao.entity.system.Router">
select * select *
from sys_router from sys_router
<if test="dto.title != null and dto.title != ''"> <where>
title like CONCAT('%',#{dto.title},'%') <if test="dto.title != null and dto.title != ''">
</if> title like CONCAT('%',#{dto.title},'%')
<if test="dto.visible != null"> </if>
visible = #{dto.visible} <if test="dto.visible != null">
</if> visible = #{dto.visible}
</if>
</where>
order by router_rank
</select> </select>
</mapper> </mapper>