diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index f5bd01365..88aee3633 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -36,15 +36,15 @@
2.3.1
- 2.2.2
+ 2.2.3
1.7.1
8.12.0
2.7.7
0.33.0
- 7.2.9.RELEASE
- 1.0.4
+ 7.2.11.RELEASE
+ 1.0.5
4.8.0
6.7.2
@@ -58,7 +58,7 @@
1.2.83
31.1-jre
5.1.0
- 2.14.0
+ 2.14.2
3.8.0
0.1.55
2.5.0
@@ -68,9 +68,9 @@
3.0.0
4.10.0
8.4.6
- 4.6.2
+ 4.6.3
2.2.1
- 3.1.635
+ 3.1.637
1.4.0
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
index a9b01f28e..64fbf7d79 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
@@ -52,7 +52,7 @@
com.alipay.sdk
alipay-sdk-java
- 4.31.72.ALL
+ 4.34.71.ALL
org.bouncycastle
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
index b7ef5b8bd..376ef3594 100644
--- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
+++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
@@ -48,7 +48,7 @@ public interface BpmTaskConvert {
return null;
}
try {
- T newInstance = target.newInstance();
+ T newInstance = target.getDeclaredConstructor().newInstance();
BeanUtils.copyProperties(source, newInstance);
return newInstance;
} catch (Exception e) {
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
index cec246bfc..132e903d9 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
@@ -91,8 +91,6 @@ public class CodegenEngine {
vue3FilePath("views/${table.moduleName}/${classNameVar}/${classNameVar}.data.ts"))
.put(vue3TemplatePath("api/api.ts"),
vue3FilePath("api/${table.moduleName}/${classNameVar}/index.ts"))
- .put(vue3TemplatePath("api/types.ts"),
- vue3FilePath("api/${table.moduleName}/${classNameVar}/types.ts"))
// SQL
.put("codegen/sql/sql.vm", "sql/sql.sql")
.put("codegen/sql/h2.vm", "sql/h2.sql")
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm
index d1099ecbf..a59849054 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/api.ts.vm
@@ -1,7 +1,48 @@
import request from '@/config/axios'
-import { ${simpleClassName}VO, ${simpleClassName}PageReqVO, ${simpleClassName}ExcelReqVO } from './types'
+export interface ${simpleClassName}VO {
+ #foreach ($column in $columns)
+ #if ($column.createOperation || $column.updateOperation)
+ #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "double")
+ ${column.javaField}: number
+ #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
+ ${column.javaField}: Date
+ #else
+ ${column.javaField}: ${column.javaType.toLowerCase()}
+ #end
+ #end
+ #end
+}
+
+export interface ${simpleClassName}PageReqVO extends PageParam {
+ #foreach ($column in $columns)
+ #if (${column.listOperation})##查询操作
+ #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "double")
+ ${column.javaField}?: number
+ #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
+ ${column.javaField}?: Date[]
+ #else
+ ${column.javaField}?: ${column.javaType.toLowerCase()}
+ #end
+ #end
+ #end
+}
+
+export interface ${simpleClassName}ExcelReqVO {
+ #foreach ($column in $columns)
+ #if (${column.listOperation})##查询操作
+ #if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "double")
+ ${column.javaField}?: number
+ #elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
+ ${column.javaField}?: Date[]
+ #else
+ ${column.javaField}?: ${column.javaType.toLowerCase()}
+ #end
+ #end
+ #end
+}
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
+
// 查询${table.classComment}列表
export const get${simpleClassName}PageApi = async (params: ${simpleClassName}PageReqVO) => {
return await request.get({ url: '${baseURL}/page', params })
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/types.ts.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/types.ts.vm
deleted file mode 100644
index 54ab47e02..000000000
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/api/types.ts.vm
+++ /dev/null
@@ -1,41 +0,0 @@
-export type ${simpleClassName}VO = {
-#foreach ($column in $columns)
-#if ($column.createOperation || $column.updateOperation)
-#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
- ${column.javaField}: number
-#elseif(${column.javaType.toLowerCase()} == "date")
- ${column.javaField}: string
-#else
- ${column.javaField}: ${column.javaType.toLowerCase()}
-#end
-#end
-#end
-}
-
-export type ${simpleClassName}PageReqVO = {
-#foreach ($column in $columns)
-#if (${column.listOperation})##查询操作
-#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
- ${column.javaField}: number
-#elseif(${column.javaType.toLowerCase()} == "date")
- ${column.javaField}: string
-#else
- ${column.javaField}: ${column.javaType.toLowerCase()}
-#end
-#end
-#end
-}
-
-export type ${simpleClassName}ExcelReqVO = {
-#foreach ($column in $columns)
-#if (${column.listOperation})##查询操作
-#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
- ${column.javaField}: number
-#elseif(${column.javaType.toLowerCase()} == "date")
- ${column.javaField}: string
-#else
- ${column.javaField}: ${column.javaType.toLowerCase()}
-#end
-#end
-#end
-}
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/data.ts.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/data.ts.vm
index fa64bc883..c8565521d 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/data.ts.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/data.ts.vm
@@ -1,111 +1,113 @@
import { reactive } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
-import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
import { DICT_TYPE } from '@/utils/dict'
+import { required } from '@/utils/formRules'
+import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
const { t } = useI18n() // 国际化
// 表单校验
export const rules = reactive({
-#foreach ($column in $columns)
-#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
-#set($comment=$column.columnComment)
- $column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == "select")'change'#else'blur'#end }],
-#end
-#end
+ #foreach ($column in $columns)
+ #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
+ #set($comment=$column.columnComment)
+ $column.javaField: [required],
+ #end
+ #end
})
// CrudSchema
-const crudSchemas = reactive([
-#foreach($column in $columns)
- #if ($column.listOperation || $column.listOperationResult || $column.createOperation || $column.updateOperation)
- #set ($dictType = $column.dictType)
- {
- label: '${column.columnComment}',
- field: '${column.javaField}',
- #if ("" != $dictType)## 有数据字典
- dictType: DICT_TYPE.$dictType.toUpperCase(),
- #end
- #if($column.primaryKey)
- type: 'index',
- form: {
- show: false
- },
- detail: {
- show: false
- }
- #else
- #if (!$column.createOperation && !$column.updateOperation)
- form: {
- show: false
- },
- #elseif(!("" != $column.dictType))
- form: {
- show: true,
- #if ($column.htmlType == "datetime")## 时间框
- component: 'DatePicker',
- componentProps: {
- type: 'datetime',
- valueFormat: 'YYYY-MM-DD HH:mm:ss'
- }
- #elseif($column.htmlType == "editor")## 文本编辑器
- component: 'Editor',
- colProps: {
- span: 24
+const crudSchemas = reactive({
+ primaryKey: 'id', // 默认的主键ID
+ primaryTitle: t('common.index'), // 默认显示的值
+ primaryType: 'seq', // 默认为seq,序号模式
+ action: true,
+ actionWidth: '200', // 3个按钮默认200,如有删减对应增减即可
+ columns: [
+ #foreach($column in $columns)
+ #if ($column.listOperation || $column.listOperationResult || $column.createOperation || $column.updateOperation)
+ #set ($dictType = $column.dictType)
+ #if(!$column.primaryKey)
+ {
+ title: '${column.columnComment}',
+ field: '${column.javaField}',
+ #if (!$column.listOperationResult)
+ isTable: false,
+ #end
+ #if ("" != $dictType)## 有数据字典
+ dictType: DICT_TYPE.$dictType.toUpperCase(),
+ #if (${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
+ dictData: 'number',
+ #else
+ dictData: 'string',
+ #end
+ #end
+ #if (!$column.createOperation && !$column.updateOperation)
+ isForm: false,
+ #elseif(!("" != $column.dictType))
+ #if (${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
+ formatter: 'formatDate',
+ form: {
+ component: 'DatePicker',
+ componentProps: {
+ type: 'datetime',
+ valueFormat: 'x'
+ }
+ },
+ #elseif($column.htmlType == "editor")## 文本编辑器
+ form: {
+ component: 'Editor',
+ colProps: {
+ span: 24
+ },
+ componentProps: {
+ valueHtml: ''
+ }
+ },
+ #elseif($column.htmlType == "textarea")## 文本框
+ form: {
+ component: 'Input',
+ componentProps: {
+ type: 'textarea',
+ rows: 4
+ },
+ colProps: {
+ span: 24
+ }
+ },
+ #elseif(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")## 数字类型
+ form: {
+ component: 'InputNumber',
+ value: 0
+ },
+ #elseif($column.htmlType == "imageUpload")## 图片上传
+ form: {
+ component: 'UploadImg',
+ componentProps: {
+ limit: 1
+ }
+ },
+ #elseif($column.htmlType == "fileUpload")## 图片上传
+ form: {
+ component: 'UploadFile'
+ },
+ #end
+ #end
+ #if ($column.listOperation)
+ #if($column.htmlType == "input")
+ isSearch: true,
+ #elseif("" != $dictType)
+ isSearch: true,
+ #elseif($column.htmlType == "datetime")
+ search: {
+ show: true,
+ itemRender: {
+ name: 'XDataTimePicker'
+ }
+ },
+ #end
+ #end
+ #end
},
- componentProps: {
- valueHtml: ''
- }
- #elseif($column.htmlType == "textarea")## 文本框
- component: 'Input',
- componentProps: {
- type: 'textarea',
- rows: 4
- },
- colProps: {
- span: 24
- }
#end
- },
#end
- #if ($column.listOperationResult)
- search: {
- #if($column.htmlType == "input")
- show: true
- #else
- #if($column.htmlType == "datetime")
- show: true,
- component: 'DatePicker',
- componentProps: {
- type: 'datetimerange',
- valueFormat: 'YYYY-MM-DD HH:mm:ss'
- }
- #elseif($column.htmlType == "select" || $column.htmlType == "radio")
- #if ("" == $dictType)## 没有数据字典
- show: true,
- component: 'Select',
- componentProps: {
- option: [{'','请选择字典生成'}]
- }
- #else
- show: true
- #end
- #end
- #end
- }
- #end
- #end
- },
- #end
-#end
- {
- label: t('table.action'),
- field: 'action',
- width: '240px',
- form: {
- show: false
- },
- detail: {
- show: false
- }
- }
-])
-
-export const { allSchemas } = useCrudSchemas(crudSchemas)
\ No newline at end of file
+ ]
+})
+export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
\ No newline at end of file
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm
index 509f1493f..7f4f13418 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm
@@ -1,212 +1,177 @@
-
-
-
-
-
-
-
-
-
-
-
-
-#foreach($column in $columns)
-#if ($column.listOperationResult)
- #set ($dictType=$column.dictType)
- #if ($column.javaType == "LocalDateTime")## 时间类型
-
- {{ dayjs(row.${column.javaField}).format('YYYY-MM-DD HH:mm:ss') }}
-
- #elseif("" != $column.dictType)## 数据字典
-
-
-
- #end
-#end
-#end
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
index 3d135177c..23c88c513 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
@@ -86,11 +86,30 @@ public class MenuServiceImpl implements MenuService {
@Override
@PostConstruct
public synchronized void initLocalCache() {
- // 获取菜单列表,如果有更新
- List menuList = this.loadMenuIfUpdate(maxUpdateTime);
- if (CollUtil.isEmpty(menuList)) {
+ initLocalCacheIfUpdate(null);
+ }
+
+ @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
+ public void schedulePeriodicRefresh() {
+ initLocalCacheIfUpdate(this.maxUpdateTime);
+ }
+
+ /**
+ * 刷新本地缓存
+ *
+ * @param maxUpdateTime 最大更新时间
+ * 1. 如果 maxUpdateTime 为 null,则“强制”刷新缓存
+ * 2. 如果 maxUpdateTime 不为 null,判断自 maxUpdateTime 是否有数据发生变化,有的情况下才刷新缓存
+ */
+ private void initLocalCacheIfUpdate(LocalDateTime maxUpdateTime) {
+ // 如果没有增量的数据变化,则不进行本地缓存的刷新
+ if (maxUpdateTime != null
+ && menuMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
+ log.info("[initLocalCacheIfUpdate][数据未发生变化({}),本地缓存不刷新]", maxUpdateTime);
return;
}
+ List menuList = menuMapper.selectList();
+ log.info("[initLocalCacheIfUpdate][缓存菜单,数量为:{}]", menuList.size());
// 构建缓存
ImmutableMap.Builder menuCacheBuilder = ImmutableMap.builder();
@@ -103,34 +122,9 @@ public class MenuServiceImpl implements MenuService {
});
menuCache = menuCacheBuilder.build();
permissionMenuCache = permMenuCacheBuilder.build();
- maxUpdateTime = CollectionUtils.getMaxValue(menuList, MenuDO::getUpdateTime);
- log.info("[initLocalCache][缓存菜单,数量为:{}]", menuList.size());
- }
- @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
- public void schedulePeriodicRefresh() {
- initLocalCache();
- }
-
- /**
- * 如果菜单发生变化,从数据库中获取最新的全量菜单。
- * 如果未发生变化,则返回空
- *
- * @param maxUpdateTime 当前菜单的最大更新时间
- * @return 菜单列表
- */
- private List loadMenuIfUpdate(LocalDateTime maxUpdateTime) {
- // 第一步,判断是否要更新。
- if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
- log.info("[loadMenuIfUpdate][首次加载全量菜单]");
- } else { // 判断数据库中是否有更新的菜单
- if (menuMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
- return null;
- }
- log.info("[loadMenuIfUpdate][增量加载全量菜单]");
- }
- // 第二步,如果有更新,则从数据库加载所有菜单
- return menuMapper.selectList();
+ // 设置最新的 maxUpdateTime,用于下次的增量判断
+ this.maxUpdateTime = CollectionUtils.getMaxValue(menuList, MenuDO::getUpdateTime);
}
@Override
@@ -224,7 +218,7 @@ public class MenuServiceImpl implements MenuService {
}
// 创建新数组,避免缓存被修改
return menuCache.values().stream().filter(menu -> menuTypes.contains(menu.getType())
- && menusStatuses.contains(menu.getStatus()))
+ && menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList());
}
@@ -236,8 +230,8 @@ public class MenuServiceImpl implements MenuService {
return Collections.emptyList();
}
return menuCache.values().stream().filter(menu -> menuIds.contains(menu.getId())
- && menuTypes.contains(menu.getType())
- && menusStatuses.contains(menu.getStatus()))
+ && menuTypes.contains(menu.getType())
+ && menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList());
}
@@ -277,7 +271,7 @@ public class MenuServiceImpl implements MenuService {
}
// 父菜单必须是目录或者菜单类型
if (!MenuTypeEnum.DIR.getType().equals(menu.getType())
- && !MenuTypeEnum.MENU.getType().equals(menu.getType())) {
+ && !MenuTypeEnum.MENU.getType().equals(menu.getType())) {
throw ServiceExceptionUtil.exception(MENU_PARENT_NOT_DIR_OR_MENU);
}
}