feat: 刷新字典缓存.

This commit is contained in:
lijiahang
2023-10-27 19:15:13 +08:00
parent 706492f54a
commit d219b7f88a
70 changed files with 147 additions and 119 deletions

View File

@@ -53,7 +53,7 @@ npm run dev
生成通用 controller entity service dao api convert http vue ts sql junit
代码位置
com.orion.ops.launch.generator.CodeGenerator
com.orion.ops.framework.mybatis.core.generator.CodeGenerator
// 生成的表为 system_role, 业务注释为 '角色', 业务包为 role
Template.create("system_role", "角色", "role")

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator;
package com.orion.ops.framework.mybatis.core.generator;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
@@ -15,10 +15,10 @@ import com.orion.lang.utils.ansi.style.color.AnsiForeground;
import com.orion.lang.utils.ext.yml.YmlExt;
import com.orion.ops.framework.common.utils.Valid;
import com.orion.ops.framework.mybatis.core.domain.BaseDO;
import com.orion.ops.framework.mybatis.core.generator.engine.VelocityTemplateEngine;
import com.orion.ops.framework.mybatis.core.generator.template.Table;
import com.orion.ops.framework.mybatis.core.generator.template.Template;
import com.orion.ops.framework.mybatis.core.mapper.IMapper;
import com.orion.ops.launch.generator.engine.VelocityTemplateEngine;
import com.orion.ops.launch.generator.template.Table;
import com.orion.ops.launch.generator.template.Template;
import org.apache.ibatis.annotations.Mapper;
import java.io.File;
@@ -431,7 +431,8 @@ public class CodeGenerator {
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 后端代码修改完成后请先执行单元测试检测是否正常\n")
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- vue 代码需要注意同一模块的 router 需要自行合并\n")
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- vue 枚举需要自行更改数据类型\n")
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 菜单 sql 执行完成后 需要在菜单页面刷新缓存\n")
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 菜单 sql 执行完成后 需要在系统菜单页面刷新缓存\n")
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 字典 sql 执行完成后 需要在字典配置项页面刷新缓存\n")
.toString();
System.out.print(line);
}

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator.engine;
package com.orion.ops.framework.mybatis.core.generator.engine;
import com.orion.lang.define.collect.MultiLinkedHashMap;
import lombok.AllArgsConstructor;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.orion.ops.launch.generator.engine;
package com.orion.ops.framework.mybatis.core.generator.engine;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.config.ConstVal;
@@ -31,8 +31,8 @@ import com.orion.lang.utils.reflect.BeanMap;
import com.orion.lang.utils.reflect.Fields;
import com.orion.ops.framework.common.constant.Const;
import com.orion.ops.framework.common.constant.OrionOpsProConst;
import com.orion.ops.launch.generator.template.Table;
import com.orion.ops.launch.generator.template.VueEnum;
import com.orion.ops.framework.mybatis.core.generator.template.Table;
import com.orion.ops.framework.mybatis.core.generator.template.VueEnum;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator.template;
package com.orion.ops.framework.mybatis.core.generator.template;
import java.util.concurrent.TimeUnit;

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator.template;
package com.orion.ops.framework.mybatis.core.generator.template;
import com.orion.lang.utils.Enums;
import com.orion.lang.utils.collect.Lists;

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator.template;
package com.orion.ops.framework.mybatis.core.generator.template;
/**
* 后端代码模板
@@ -26,6 +26,7 @@ public class ServerTemplate extends Template {
table.comment = comment;
table.bizPackage = bizPackage;
table.enableUnitTest = true;
table.enableOperatorLog = true;
}
/**
@@ -71,6 +72,17 @@ public class ServerTemplate extends Template {
return this;
}
// fixme
/**
* 生成导出
*
* @return this
*/
public ServerTemplate enableExport() {
table.enableExport = false;
return this;
}
/**
* 不生成单元测试
*
@@ -81,6 +93,17 @@ public class ServerTemplate extends Template {
return this;
}
// fixme
/**
* 不生成操作日志
*
* @return this
*/
public ServerTemplate disableOperatorLog() {
table.enableUnitTest = false;
return this;
}
/**
* 设置 cache
*

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator.template;
package com.orion.ops.framework.mybatis.core.generator.template;
import lombok.Data;
@@ -43,11 +43,21 @@ public class Table {
*/
protected boolean enableUnitTest;
/**
* 是否生成导出
*/
protected boolean enableExport;
/**
* 是否可缓存
*/
protected boolean enableCache;
/**
* 是否生成操作日志
*/
protected boolean enableOperatorLog;
/**
* 缓存的 key
*/

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator.template;
package com.orion.ops.framework.mybatis.core.generator.template;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator.template;
package com.orion.ops.framework.mybatis.core.generator.template;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package com.orion.ops.launch.generator.template;
package com.orion.ops.framework.mybatis.core.generator.template;
/**
* 前端代码模板

View File

@@ -1,68 +0,0 @@
package com.orion.ops.launch.generator;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.orion.lang.define.collect.MultiLinkedHashMap;
import com.orion.lang.utils.Enums;
import com.orion.lang.utils.ansi.AnsiAppender;
import com.orion.lang.utils.ansi.style.AnsiFont;
import com.orion.lang.utils.ansi.style.color.AnsiForeground;
import com.orion.lang.utils.awt.Clipboards;
import com.orion.lang.utils.reflect.Fields;
import com.orion.ops.framework.common.constant.Const;
import com.orion.ops.module.infra.enums.UserStatusEnum;
import java.util.List;
import java.util.function.Function;
/**
* 前端枚举生成器
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/8/25 14:55
*/
public class EnumGenerator {
public static void main(String[] args) {
// 生成前端枚举配置
String gen = gen(UserStatusEnum.class,
UserStatusEnum::getStatus,
UserStatusEnum::name);
System.out.println(gen);
}
public static <E extends Enum<?>> String gen(Class<E> clazz,
Function<E, Object> valueFunction) {
return gen(clazz, valueFunction, Enum::name);
}
@SuppressWarnings("unchecked")
public static <E extends Enum<?>> String gen(Class<E> clazz,
Function<E, Object> valueFunction,
Function<E, Object> labelFunction) {
// 获取枚举
Enum<?>[] constants = clazz.getEnumConstants();
// 获取字段
List<String> fields = Enums.getFields(clazz);
MultiLinkedHashMap<String, String, Object> result = MultiLinkedHashMap.create();
for (Enum<?> e : constants) {
String name = e.name();
result.put(name, Const.VALUE, valueFunction.apply((E) e));
result.put(name, Const.LABEL, labelFunction.apply((E) e));
for (String field : fields) {
result.put(name, field, Fields.getFieldValue(e, field));
}
}
// ts 代码
String tsCode = "/**\n *\n */\nexport const " + clazz.getSimpleName() + " = " + JSON.toJSONString(result, SerializerFeature.PrettyFormat);
// 复制到剪切板
Clipboards.setString(tsCode);
// 提示
String tips = AnsiAppender.create()
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "代码生成完成 - 已复制到剪切板 ^_^")
.toString();
return "\n" + tsCode + "\n\n" + tips;
}
}

View File

@@ -1,6 +1,7 @@
package com.orion.ops.module.infra.controller;
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.lang.define.wrapper.HttpWrapper;
import com.orion.ops.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.ops.framework.log.core.annotation.IgnoreLog;
import com.orion.ops.framework.log.core.enums.IgnoreLogMode;
@@ -72,6 +73,14 @@ public class DictKeyController {
return dictKeyService.getDictKeyPage(request);
}
@PutMapping("/refresh-cache")
@Operation(summary = "刷新字典缓存")
@PreAuthorize("@ss.hasPermission('infra:dict-key:refresh-cache')")
public HttpWrapper<?> refreshCache() {
dictKeyService.refreshCache();
return HttpWrapper.ok();
}
@OperatorLog(DictKeyOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "删除字典配置项")

View File

@@ -1,5 +1,5 @@
### 初始化角色权限缓存
GET {{baseUrl}}/infra/permission/init-cache
GET {{baseUrl}}/infra/permission/refresh-cache
Authorization: {{token}}

View File

@@ -39,10 +39,10 @@ public class PermissionController {
@Resource
private PermissionService permissionService;
@PutMapping("/init-cache")
@Operation(summary = "初始化角色权限缓存")
@PreAuthorize("@ss.hasPermission('infra:system-menu:init-cache')")
public HttpWrapper<?> initCache() {
@PutMapping("/refresh-cache")
@Operation(summary = "刷新角色权限缓存")
@PreAuthorize("@ss.hasPermission('infra:system-menu:refresh-cache')")
public HttpWrapper<?> refreshCache() {
permissionService.initPermissionCache();
return HttpWrapper.ok();
}

View File

@@ -57,6 +57,11 @@ public interface DictKeyService {
*/
Map<String, String> getDictSchema(String key);
/**
* 刷新字典缓存
*/
void refreshCache();
/**
* 删除字典配置项
*

View File

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.lang.utils.Objects1;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.collect.Lists;
import com.orion.lang.utils.collect.Maps;
import com.orion.ops.framework.biz.operator.log.core.uitls.OperatorLogs;
import com.orion.ops.framework.common.constant.Const;
@@ -166,6 +167,18 @@ public class DictKeyServiceImpl implements DictKeyService {
return result;
}
@Override
public void refreshCache() {
Set<String> schemaKeys = RedisUtils.scanKeys(DictCacheKeyDefine.DICT_SCHEMA.format("*"));
Set<String> valueKeys = RedisUtils.scanKeys(DictCacheKeyDefine.DICT_VALUE.format("*"));
// 需要删除的缓存 key
List<String> list = Lists.of(DictCacheKeyDefine.DICT_KEY.getKey());
list.addAll(schemaKeys);
list.addAll(valueKeys);
// 删除缓存
RedisUtils.delete(list);
}
@Override
public Integer deleteDictKeyById(Long id) {
log.info("DictKeyService-deleteDictKeyById id: {}", id);

View File

@@ -11,7 +11,6 @@ import com.orion.ops.framework.common.constant.Const;
import com.orion.ops.framework.common.constant.ErrorMessage;
import com.orion.ops.framework.common.utils.Valid;
import com.orion.ops.framework.mybatis.core.query.Conditions;
import com.orion.ops.framework.redis.core.utils.RedisMaps;
import com.orion.ops.framework.redis.core.utils.RedisStrings;
import com.orion.ops.module.infra.convert.DictValueConvert;
import com.orion.ops.module.infra.dao.DictKeyDAO;
@@ -79,7 +78,7 @@ public class DictValueServiceImpl implements DictValueService {
Long id = record.getId();
log.info("DictValueService-createDictValue id: {}, effect: {}", id, effect);
// 删除缓存
RedisMaps.delete(DictCacheKeyDefine.DICT_VALUE.format(key));
RedisStrings.delete(DictCacheKeyDefine.DICT_VALUE.format(key));
return id;
}
@@ -103,7 +102,7 @@ public class DictValueServiceImpl implements DictValueService {
int effect = dictValueDAO.updateById(updateRecord);
log.info("DictValueService-updateDictValueById effect: {}", effect);
// 删除缓存
RedisMaps.delete(DictCacheKeyDefine.DICT_VALUE.format(key));
RedisStrings.delete(DictCacheKeyDefine.DICT_VALUE.format(key));
// 记录历史归档
this.checkRecordHistory(updateRecord, record);
return effect;
@@ -130,7 +129,7 @@ public class DictValueServiceImpl implements DictValueService {
int effect = dictValueDAO.updateById(updateRecord);
log.info("DictValueService-rollbackDictValueById effect: {}", effect);
// 删除缓存
RedisMaps.delete(DictCacheKeyDefine.DICT_VALUE.format(record.getKeyName()));
RedisStrings.delete(DictCacheKeyDefine.DICT_VALUE.format(record.getKeyName()));
// 记录历史归档
this.checkRecordHistory(updateRecord, record);
return effect;
@@ -222,7 +221,7 @@ public class DictValueServiceImpl implements DictValueService {
// 删除缓存
String beforeCacheKey = DictCacheKeyDefine.DICT_VALUE.format(beforeKey);
String newCacheKey = DictCacheKeyDefine.DICT_VALUE.format(newKey);
RedisMaps.delete(beforeCacheKey, newCacheKey);
RedisStrings.delete(beforeCacheKey, newCacheKey);
return effect;
}
@@ -296,7 +295,7 @@ public class DictValueServiceImpl implements DictValueService {
.distinct()
.map(DictCacheKeyDefine.DICT_VALUE::format)
.collect(Collectors.toList());
RedisMaps.delete(keyList);
RedisStrings.delete(keyList);
return effect;
}

View File

@@ -69,6 +69,13 @@ export function getDictKeyPage(request: DictKeyQueryRequest) {
return axios.post<DataGrid<DictKeyQueryResponse>>('/infra/dict-key/query', request);
}
/**
* 刷新字典缓存
*/
export function refreshCache() {
return axios.put('/infra/dict-key/refresh-cache');
}
/**
* 删除字典配置项
*/

View File

@@ -88,8 +88,8 @@ export function deleteMenu(id: number) {
}
/**
* 初始化缓存
* 刷新缓存
*/
export function initCache() {
return axios.put('/infra/permission/init-cache');
export function refreshCache() {
return axios.put('/infra/permission/refresh-cache');
}

View File

@@ -65,11 +65,7 @@
}
.modal-form {
.arco-form-item {
&:last-child {
margin-bottom: 0 !important;
}
}
padding: 24px 20px 4px 20px;
}
.card-list-item {

View File

@@ -223,7 +223,7 @@
</script>
<script lang="ts" setup>
import type { PropType } from 'vue';
import type { CSSProperties, PropType } from 'vue';
import type { PaginationProps, ResponsiveValue } from '@arco-design/web-vue';
import type { CardRecord, ColResponsiveValue, HandleVisible, CardFieldConfig, CardPosition } from '@/types/card';
import { compile, computed, h, ref } from 'vue';
@@ -278,7 +278,7 @@
default: '100%'
},
cardClass: String,
cardBodyStyle: Object,
cardBodyStyle: Object as PropType<CSSProperties>,
contextMenu: {
type: Boolean,
default: true

View File

@@ -17,7 +17,7 @@
<script lang="ts" setup>
import type { Theme, Options } from './core';
import type { PropType } from 'vue';
import type { CSSProperties, PropType } from 'vue';
import * as monaco from 'monaco-editor';
import { createDefaultOptions } from './core';
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
@@ -48,7 +48,7 @@
default: 'json',
},
containerClass: String,
containerStyle: Object,
containerStyle: Object as PropType<CSSProperties>,
theme: {
type: [String, Boolean] as PropType<Theme | boolean>,
default: true,

View File

@@ -116,6 +116,10 @@
message
}
});
// 因为输入框已经限制数量 这里只做提示
setTimeout(() => {
formRef.value.clearValidate('tags');
}, 3000);
};
// 确定

View File

@@ -1,6 +1,7 @@
<template>
<a-modal v-model:visible="visible"
body-class="modal-form"
:body-style="{'padding-bottom': '24px'}"
title-align="start"
:title="title"
:top="80"

View File

@@ -38,6 +38,19 @@
<icon-plus />
</template>
</a-button>
<!-- 刷新缓存 -->
<a-popconfirm content="确定要刷新全局字典缓存吗?"
position="left"
type="warning"
@ok="doRefreshCache">
<a-button type="primary" status="warning"
v-permission="['infra:dict-key:refresh-cache']">
刷新缓存
<template #icon>
<icon-sync />
</template>
</a-button>
</a-popconfirm>
</a-space>
</div>
</template>
@@ -124,7 +137,7 @@
<script lang="ts" setup>
import type { DictKeyQueryRequest, DictKeyQueryResponse } from '@/api/system/dict-key';
import { reactive, ref, onMounted } from 'vue';
import { batchDeleteDictKey, deleteDictKey, getDictKeyPage } from '@/api/system/dict-key';
import { batchDeleteDictKey, deleteDictKey, getDictKeyPage, refreshCache } from '@/api/system/dict-key';
import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import columns from '../types/table.columns';
@@ -178,6 +191,18 @@
addedCallback, updatedCallback
});
// 刷新缓存
const doRefreshCache = async () => {
try {
setLoading(true);
await refreshCache();
Message.success('刷新成功 页面缓存刷新后生效');
} catch (e) {
} finally {
setLoading(false);
}
};
// 加载数据
const doFetchTableData = async (request: DictKeyQueryRequest) => {
try {

View File

@@ -29,6 +29,9 @@ export const definedExtraKeys = [
}
];
// 自增排序步长
export const sortStep = 10;
// 内置字段
export const innerKeys = ['value', 'label'];

View File

@@ -92,7 +92,7 @@
import formRules from '../types/form.rules';
import { createDictValue, updateDictValue } from '@/api/system/dict-value';
import { Message } from '@arco-design/web-vue';
import { ValueType } from '../../dict-key/types/const';
import { ValueType, sortStep } from '../../dict-key/types/const';
import DictKeySelector from '@/components/system/dict-key/dict-key-selector.vue';
import { DictKeyQueryResponse } from '@/api/system/dict-key';
import { useCacheStore } from '@/store';
@@ -126,7 +126,7 @@
const openAdd = () => {
title.value = '添加字典配置值';
isAddHandle.value = true;
renderForm({ ...defaultForm(), keyId: formModel.value.keyId, sort: (formModel.value.sort || 0) + 10 });
renderForm({ ...defaultForm(), keyId: formModel.value.keyId, sort: (formModel.value.sort || 0) + sortStep });
setVisible(true);
};

View File

@@ -65,9 +65,9 @@
<a-popconfirm content="确定要刷新全局菜单缓存吗?"
position="left"
type="warning"
@ok="doInitCache">
@ok="doRefreshCache">
<a-button type="primary" status="warning"
v-permission="['infra:system-menu:init-cache']">
v-permission="['infra:system-menu:refresh-cache']">
刷新缓存
<template #icon>
<icon-sync />
@@ -184,7 +184,7 @@
import type { MenuQueryRequest, MenuQueryResponse } from '@/api/system/menu';
import { reactive, ref, onMounted } from 'vue';
import useLoading from '@/hooks/loading';
import { getMenuList, deleteMenu, updateMenuStatus, initCache } from '@/api/system/menu';
import { getMenuList, deleteMenu, updateMenuStatus, refreshCache } from '@/api/system/menu';
import { menuStatusKey, menuVisibleKey, menuTypeKey, MenuType } from '../types/const';
import columns from '../types/table.columns';
import { Message } from '@arco-design/web-vue';
@@ -298,11 +298,11 @@
};
// 刷新缓存
const doInitCache = async () => {
const doRefreshCache = async () => {
try {
setFetchLoading(true);
await initCache();
Message.success('刷新成功');
await refreshCache();
Message.success('刷新成功 页面缓存刷新后生效');
} catch (e) {
} finally {
setFetchLoading(false);

View File

@@ -1,4 +1,4 @@
// 排序步长
// 自增排序步长
export const sortStep = 10;
// 菜单类型 值

View File

@@ -32,7 +32,7 @@ INSERT INTO `system_menu` VALUES (49, 48, '创建用户', 'infra:system-user:cre
INSERT INTO `system_menu` VALUES (50, 48, '修改用户', 'infra:system-user:update', 3, 20, 1, 1, 1, NULL, NULL, NULL, '2023-08-16 10:19:24', '2023-08-16 10:19:24', NULL, NULL, 0);
INSERT INTO `system_menu` VALUES (51, 48, '查询用户', 'infra:system-user:query', 3, 30, 1, 1, 1, NULL, NULL, NULL, '2023-08-16 10:19:24', '2023-08-16 10:19:24', NULL, NULL, 0);
INSERT INTO `system_menu` VALUES (52, 48, '删除用户', 'infra:system-user:delete', 3, 40, 1, 1, 1, NULL, NULL, NULL, '2023-08-16 10:19:24', '2023-08-16 10:19:24', NULL, NULL, 0);
INSERT INTO `system_menu` VALUES (53, 13, '初始化缓存', 'infra:system-menu:init-cache', 3, 10, 1, 1, 1, NULL, NULL, NULL, '2023-08-16 10:29:10', '2023-08-16 10:29:10', '1', '1', 0);
INSERT INTO `system_menu` VALUES (53, 13, '初始化缓存', 'infra:system-menu:refresh-cache', 3, 10, 1, 1, 1, NULL, NULL, NULL, '2023-08-16 10:29:10', '2023-08-16 10:29:10', '1', '1', 0);
INSERT INTO `system_menu` VALUES (60, 48, '修改用户状态', 'infra:system-user:update-status', 3, 10, 1, 1, 1, NULL, NULL, NULL, '2023-08-16 11:49:04', '2023-08-16 11:49:04', '1', '1', 0);
INSERT INTO `system_menu` VALUES (61, 48, '分配用户角色', 'infra:system-user:grant-role', 3, 10, 1, 1, 1, NULL, NULL, NULL, '2023-08-16 11:49:23', '2023-08-16 11:49:23', '1', '1', 0);
INSERT INTO `system_menu` VALUES (62, 48, '重置用户密码', 'infra:system-user:reset-password', 3, 10, 1, 1, 1, NULL, NULL, NULL, '2023-08-16 11:49:50', '2023-08-16 11:49:50', '1', '1', 0);