软件研究之JeecgBoot三

标签: 无 分类: 未分类 创建时间:2024-03-14 06:15:24 更新时间:2024-11-23 10:24:26

1.数据字典

使用代码生成工具生成的字典,引用到下来框的时候,总是显示的是数值,而不是选项的内容。

(1)后端注解
后端字段上增加了一个 @Dict 注解,这里要注意,就是我后端数据库用的是 int 类型,这里需要改为 String 类型才可以。

1
2
 @Dict(dicCode = "tszt")
private String tszt;

官方说是用了@Dict注解,会自动翻译一个 tszt_dictText 字段,后来我尝试,不知道是不是我修改其他地方的代码,返回的数据里面,并没有这个 tszt_dictText 字段。

(2) 修改前端
有些文章里面说是用 dataIndex:”tszt_dictText”,但是我修改了之后,还是空白的,于是只能换了一种方式,使用 filterDictTextByCache 方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
import { filterDictTextByCache } from '/@/utils/dict/JDictSelectUtil';

//列表数据
export const columns: BasicColumn[] = [
{
title: '推送状态',
align: 'center',
dataIndex: 'tszt',
customRender: ({ text }) => {
return filterDictTextByCache('tszt', text);
},
},
];

(3)后来我再次的处理这个字典不生效的问题
原来是因为 src/main/java/org/jeecg/common/aspect/DictAspect.java 这个切面中,定义了执行的 @Pointcut,这里没有我自定义的类,所以导致无法调用切面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 定义切点Pointcut
*/
@Pointcut("(@within(org.springframework.web.bind.annotation.RestController) || " +
"@within(org.springframework.stereotype.Controller) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)) " +
"&& execution(public org.jeecg.common.api.vo.Result org.jeecg..*.*(..))")
public void excudeService() {
}

/**
* 后来改成了这个方法
*/
@Pointcut("(@within(org.springframework.web.bind.annotation.RestController) || " +
"@within(org.springframework.stereotype.Controller) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)) " +
"&& (execution(public org.jeecg.common.api.vo.Result *(..)))")
public void excudeService() {
}

(4)还有一点需要注意的是,如果后端数据库中的字段是 int 类型,为了在前端展示下拉框,需要有一个 string 类型的转换才可以。

参考文章:
【1】.jeecg boot 框架学习(4)— 数据字典使用 这里就是处理这个前端为什么不展示的问题,使用了后台的注解的形式。
【2】.前端字典缓存用法 登录的时候一次性加载系统字典前端缓存,减少ajax重复请求
【3】.字典翻译注解@Dict 字典翻译注解@Dict: 用于列表字段字典翻译(比如字段sex存的值是1,会自动生成一个翻译字段 sex_dictText 值是‘男’)
【4】.【Jeecgboot】数据字典的概念及使用方法
【5】.jeecgboot数据字典使用
【6】.JeecgBoot字典配置

2.高级查询

在配置查询的时候,我发现我自己配置的个性化查询,虽然能够进行配置,但是生成的代码并不包含 比如下拉框之类的个性化查询内容。

后来我还是仿照着Form里面的内容,进行了自定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="6">
<a-form-item name="xcqy">
<template #label><span title="巡查区域">巡查区域</span></template>
<j-dict-select-tag v-model:value="queryParam.xcqy" dictCode="xcqy" placeholder="请选择巡查区域" />
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item name="xclx">
<template #label><span title="巡查类型">巡查类型</span></template>
<j-dict-select-tag v-model:value="queryParam.xclx" dictCode="xclx" placeholder="请选择巡查类型" />
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :lg="6">
<a-form-item name="xcrq">
<template #label><span title="巡查日期">巡查日期</span></template>
<a-date-picker valueFormat="YYYY-MM-DD" placeholder="请选择巡查日期" v-model:value="queryParam.xcrq" />
</a-form-item>
</a-col>
</template>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
<a-col :lg="6">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
<a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
</a>
</a-col>
</span>
</a-col>
</a-row>
</a-form>
</div>
参考文章:
【1】.查询配置参数说明
【2】.JSuperQuery 高级查询 使用文档
【3】.自定义查询配置 online查询控件和表单控件默认保持一致的,如果需要自定义查询控件或是修改控件相关配置,可使用此功能【查询配置】。
【4】.查询配置参数说明
【5】.Online自定义查询配置

3.默认字段

我遇到了一个问题,就是当我设置字段的默认值的时候,那么就只能查询这个字段为 默认值的记录了,比如下面 wtsl =0 ,那么列表展示的就只有数据库字段 wtsl 为0 的记录了。

1
2
3
4
@Excel(name = "问题数量", width = 15)
@ApiModelProperty(value = "问题数量")
private Integer wtsl=0;

4.表格设置

1
2
3
4
5
6
7
{
title: '文件路径',
align: 'left',
dataIndex: 'filePath',
ellipsis: false, // 超宽度省略显示
width: 400,
},

5.范围查询

范围查询,需要增加两个查询字段,一个就是 _begin, 一个就是 _end 字段。

1
2
3
4
5
6
7
8
beforeFetch: (params) => {
if (queryParam.scsj) {
let xcrq = queryParam.scsj;
queryParam.scsj_begin = xcrq;
queryParam.scsj_end = moment(xcrq).add(1, 'd').format('yyyy-MM-DD');
}
return Object.assign(params, queryParam);
},
参考文章:
【1】.查询过滤器用法

6.代码精简

我有一个需求,因为jeecgboot太大了,有些功能比如低代码平台,还有一些示例,我也不需要,用不到,所以干脆就直接精简掉好了。

6.1删除数据库表

  • 我先删除了一眼就可以看出来没有用的表,ceshi_note、demo、demo_field_def_val_main、demo_field_def_val_sub、tmp_report_data_1、tmp_report_data_income、test_demo、
    test_enhance_select、test_note、test_order_customer、test_order_main、test_order_product、test_shoptype_tree、test_v3_hello

  • 因为我不打算用低代码平台,于是我把所有的 “onl_” 开头的表都删除了

  • 把所有的 “jimu_” 开头的代码都删除了

  • 把所有的 “jeecg_” 开头的表删除了

  • 如果是单体项目,其实可以删除 “sys_gateway_route” 这个表,同时把页面路径 “系统监控” -> “网关路由” 这个删掉。

  • 如果用不到定时任务,那就删除 “qrtz_” 开头的全部的11个任务调度表

6.2.删除后端代码

  • 删除文件夹:db、jeecg-module-demo(示例代码)、jeecg-server-cloud(微服务模块)、jeecg-system-cloud-api(System模块对外提供的微服务接口)

  • 删除 jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SampleTest.java 测试文件

  • 修改配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    # 修改前
    quartz:
    job-store-type: jdbc
    initialize-schema: embedded
    #定时任务启动开关,true-开 false-关
    auto-startup: true
    #延迟1秒启动定时任务
    startup-delay: 1s
    #启动时更新己存在的Job
    overwrite-existing-jobs: true
    properties:
    org:
    quartz:
    scheduler:
    instanceName: MyScheduler
    instanceId: AUTO
    jobStore:
    class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
    driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    tablePrefix: QRTZ_
    isClustered: true
    misfireThreshold: 12000
    clusterCheckinInterval: 15000
    threadPool:
    class: org.quartz.simpl.SimpleThreadPool
    threadCount: 10
    threadPriority: 5
    threadsInheritContextClassLoaderOfInitializingThread: true

    # 修改后
    quartz:
    job-store-type: memory
    initialize-schema: embedded
    #定时任务启动开关,true-开 false-关
    auto-startup: true
    #延迟1秒启动定时任务
    startup-delay: 1s
    #启动时更新己存在的Job
    overwrite-existing-jobs: true
    properties:
    org:
    quartz:
    scheduler:
    instanceName: MyScheduler
    instanceId: AUTO
    threadPool:
    class: org.quartz.simpl.SimpleThreadPool
    threadCount: 10
    threadPriority: 5
    threadsInheritContextClassLoaderOfInitializingThread: true
  • 删除 积木报表的启动 依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <!-- 积木报表-->
    <dependency>
    <groupId>org.jeecgframework.jimureport</groupId>
    <artifactId>jimureport-spring-boot-starter</artifactId>
    <version>${jimureport-spring-boot-starter.version}</version>
    <exclusions>
    <exclusion>
    <artifactId>autopoi-web</artifactId>
    <groupId>org.jeecgframework</groupId>
    </exclusion>
    <exclusion>
    <artifactId>druid</artifactId>
    <groupId>com.alibaba</groupId>
    </exclusion>
    <exclusion>
    <artifactId>jsqlparser</artifactId>
    <groupId>com.github.jsqlparser</groupId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>org.jeecgframework.jimureport</groupId>
    <artifactId>jimureport-nosql-starter</artifactId>
    <version>1.6.0</version>
    </dependency>
    <!-- 积木仪表盘-->
    <dependency>
    <groupId>org.jeecgframework.jimureport</groupId>
    <artifactId>drag-free</artifactId>
    <version>1.1.2</version>
    </dependency>


    <!-- jeecg-system-biz 中的积木报表 -->
    <dependency>
    <groupId>org.jeecgframework.jimureport</groupId>
    <artifactId>jimureport-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
    <groupId>org.jeecgframework.jimureport</groupId>
    <artifactId>drag-free</artifactId>
    </dependency>
    <!-- 积木报表 mongo redis 支持包
    <dependency>
    <groupId>org.jeecgframework.jimureport</groupId>
    <artifactId>jimureport-nosql-starter</artifactId>
    </dependency>-->
  • 删除 jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/jimureport 配置

6.3.删除前端代码

  • 删除demo示例代码 src/views/demo、src/router/routes/modules/demo、src/router/routes/mainOut.ts
    删除了 “src/router/routes/index.ts“ 中的 import { mainOutRoutes } from ‘./mainOut’;

  • 删除微前端依赖qiankun

  • 删除 src/views/report 代码

  • 删除 src/router/routes/modules/dashboard.ts 和 src/router/routes/modules/about.ts、src/router/routes/staticRouter.ts
    删除了之后,需要有一个默认的首页,可以自己重新创建一个首页。src/store/modules/permission.ts 中的 staticRoutesList 也要删除的。

  • 删除 src/layouts/default/tabs/index.vue 中的 aide 组件,src/layouts/default/header/index.vue 组件

  • 修改 src/enums/pageEnum.ts 中的默认的 BASE_HOME 设置

  • 删除 mock/ 文件夹

  • 如果是单体项目,删除 src/views/monitor/route 这个路径,

  • 删除 /src/api/demo

6.4.删除菜单

  • 删除 Online 低代码
  • 删除 主页 及其子菜单
  • 删除 关于 菜单
  • 删除 组件& 功能 及其子菜单
  • 删除 租户管理 及其子菜单
  • 删除 我的租户 及其子菜单
  • 删除 统计报表 及其子菜单
  • 删除 系统管理 -> 网关路由 菜单
参考文章:
【1】.精简版代码制作
【2】.JeecgBoot Vue3前端项目性能优化&按需加载方案
【3】.jeecg-vue 前端精简方案记录
【4】.通过IDEA启动项目 后端项目代码目录
【5】.环境准备 前端项目代码目录

8.自定义首页

jeecg boot 的默认首页是 /dashboard/analysis, 我想把他删掉,修改了后台菜单配置,指向了自定义的首页,然后删除了前端的代码,结果还是会莫名其妙的出现一个 “首页” 菜单。删除了 dashboard/analysis 目录之后,刷新之后,还是会有一个 dashboard/analysis 路由的,这个东西还是费了好大的劲才解决的。我刚开始修改了前端,后来还是不行,只能通过代码进行查看了,找到了 getUserPermissionByToken 这个接口,发现总是返回一个 dashboard/Analysi 路径,估计就是数据库中写好的了。

【尝试方案】
(1)修改前端 src/enums/pageEnum.ts 中的 BASE_HOME 配置
(2)修改后端接口:jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/constant/DefIndexConst.java 中的 DEF_INDEX_COMPONENT 配置
(3)修改后端接口:jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/RoleIndexConfigEnum.java 中的 ROLE_INDEX_CONFIG_ENUM 配置
(4)在 系统管理 -> 用户角色 菜单中,可以为每一个角色设置不同的首页,这样就可以不用多产生一个首页了。

【解决方案】
修改数据库 sys_role_index 表,将 DEF_INDEX_ALL 中的 url(默认:/dashboard/analysis)和 component (默认:dashboard/Analysis) 配置为自定义的内容。注意 在我修改完了数据库之后,我感觉自己重启了应用,结果还是没有修改过来,一直到我多次尝试,缓存消失之后,最后才会走了数据库查询,可能是我的错觉吗?

后来我发现在查询默认的首页的时候,做过了缓存处理

1
2
3
4
5
6
7
8
9
10
11
@Cacheable(cacheNames = DefIndexConst.CACHE_KEY, key = "'" + DefIndexConst.DEF_INDEX_ALL + "'")
public SysRoleIndex queryDefaultIndex() {
LambdaQueryWrapper<SysRoleIndex> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysRoleIndex::getRoleCode, DefIndexConst.DEF_INDEX_ALL);
SysRoleIndex entity = super.getOne(queryWrapper);
// 保证不为空
if (entity == null) {
entity = this.initDefaultIndex();
}
return entity;
}

修改了后端返回的内容,还有就是跳转的事情。

参考文章:
【1】.自定义首页 新建首页文件,将首页菜单的前端组件配置为自己的文件,注意只能修改前端组件不可修改菜单路径
【2】.自定义首页使用方法 org.jeecg.common.constant.enums.RoleIndexConfigEnum 修改枚举类,配置角色和其对应的首页前端组件地址
【3】.jeecgboot:自定义首页 全局搜索替换前端代码,把首页替换成实时监控。修改后端代码,SysPermissionController.java,把首页都替换成实时监控,不然登录成功后没法跳转到首页,就一直卡在登录那里。
【4】.spring cache 学习 —— @Cacheable 使用详解
【5】.SpringBoot 缓存之 @Cacheable 详细介绍
【6】.spring boot集成redis使用@Cacheable等注解为接口添加缓存

7.关闭顶部菜单

修改 src/settings/projectSetting.ts 文件,将 multiTabsSetting 里面的 show 改为 false ,然后清空浏览器重启。除此之外,前端 src/settings 中还有其他的一些配置内容。

8.问题

(1)Duplicate key (attempted merging values private java.lang.String org.jeecg.modules.system.entity.SysUser.password and private java.lang.String org.jeecg.modules.system.entity.SysUser.salt)
这个问题就是很莫名其妙,就是在打开用户管理这个地方的时候,出现了这个问题,其他的页面都没有问题。至于为什么会出现这个问题,我忘记自己是怎么解决的了。后来我发现,这个实际上并不是 jeecg 里面的问题,问题出在了大疆的代码里面。

【尝试方案】
(1)删除数据库中的相关记录,只留下最后一条记录,好像没有什么用。

【解决方案】
目前的解决方案,就是增加了第三个参数,把后面的值替换掉前面的值:(v1, v2) -> v2,虽然临时解决了这个问题,但是我还是不知道为什么只有这一个接口会出现这样的情况,其他的接口不出现这个情况,到底是为什么呢?

1
2
3
Map<String, Field> fieldMap = Arrays.stream(fields).collect(Collectors.toMap(Field::getName, field -> field));
fieldMap.putAll(Arrays.stream(fields).filter(field -> null != field.getAnnotation(JsonProperty.class))
.collect(Collectors.toMap(field -> field.getAnnotation(JsonProperty.class).value(), field -> field,(v1, v2) -> v2)));
参考文章:
【1】.Duplicate key (attempted merging values x and x) To avoid this error, you need to take one of the duplicate entries for example, to do this you need:
【2】.WebMvcConfigurer中addArgumentResolvers方法的使用 在Springboot中的WebMvcConfigurer接口在Web开发中经常被使用,例如配置拦截器、配置ViewController、配置Cors跨域等。本文主要讲解另一个方法:addArgumentResolvers()在实例中的应用。
【3】.Java8中stream()操作toMap()时Duplicate key问题解决 解决方式就在Java8提供的Collectors.toMap() 方法中,其第三个参数就是当出现 duplicate key的时候的处理方案。
【4】.stream流中toMap()api和Duplicate key问题 1、指定key-value,value是对象中的某个属性值。2、指定key-value,value是对象本身;3、返回其他Map;4、解决重复key问题;
【5】.Java8 Collectors.toMap Duplicate key 报错问题。 这里有源码的部分解析。
【6】.【WEB系列】如何支持下划线驼峰互转的传参与返回
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。