feat: 保存字典值.

This commit is contained in:
lijiahangmax
2023-10-21 02:26:36 +08:00
parent bd02ce1dd0
commit eb2c8eb719
13 changed files with 168 additions and 41 deletions

View File

@@ -9,6 +9,10 @@ package com.orion.ops.framework.common.constant;
*/
public interface ValidConst {
String CHAR_NUMBER_1_32_PATTERN = "^[a-zA-Z0-9]{1,32}$";
String CHAR_NUMBER_1_32_MESSAGE = "只能为 1-32 位的数字或字母";
String CHAR_NUMBER_2_32_PATTERN = "^[a-zA-Z0-9]{2,32}$";
String CHAR_NUMBER_2_32_MESSAGE = "只能为 2-32 位的数字或字母";

View File

@@ -71,15 +71,15 @@ public class DictValueController {
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/list")
@Operation(summary = "查询字典配置值")
public List<DictValueVO> getDictValueList(@RequestParam("key") String key) {
return dictValueService.getDictValueList(key);
public List<DictValueVO> getDictValueList(@RequestParam("keyName") String keyName) {
return dictValueService.getDictValueList(keyName);
}
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/enum")
@Operation(summary = "查询字典配置值枚举")
public Map<String, Map<String, Object>> getDictValueEnum(@RequestParam("key") String key) {
return dictValueService.getDictValueEnum(key);
public Map<String, Map<String, Object>> getDictValueEnum(@RequestParam("keyName") String keyName) {
return dictValueService.getDictValueEnum(keyName);
}
@IgnoreLog(IgnoreLogMode.RET)

View File

@@ -33,7 +33,7 @@ public class DictValueCreateRequest implements Serializable {
@NotBlank
@Size(max = 32)
@Pattern(regexp = ValidConst.CHAR_NUMBER_2_32_PATTERN, message = ValidConst.CHAR_NUMBER_2_32_MESSAGE)
@Pattern(regexp = ValidConst.CHAR_NUMBER_1_32_PATTERN, message = ValidConst.CHAR_NUMBER_1_32_MESSAGE)
@Schema(description = "配置名称")
private String name;

View File

@@ -37,7 +37,7 @@ public class DictValueUpdateRequest implements Serializable {
@NotBlank
@Size(max = 32)
@Pattern(regexp = ValidConst.CHAR_NUMBER_2_32_PATTERN, message = ValidConst.CHAR_NUMBER_2_32_MESSAGE)
@Pattern(regexp = ValidConst.CHAR_NUMBER_1_32_PATTERN, message = ValidConst.CHAR_NUMBER_1_32_MESSAGE)
@Schema(description = "配置名称")
private String name;

View File

@@ -46,18 +46,18 @@ public interface DictValueService {
/**
* 查询全部字典配置值
*
* @param key key
* @param keyName keyName
* @return rows
*/
List<DictValueVO> getDictValueList(String key);
List<DictValueVO> getDictValueList(String keyName);
/**
* 查询全部字典配置值枚举
*
* @param key key
* @param keyName keyName
* @return enum
*/
Map<String, Map<String, Object>> getDictValueEnum(String key);
Map<String, Map<String, Object>> getDictValueEnum(String keyName);
/**
* 分页查询字典配置值

View File

@@ -140,15 +140,15 @@ public class DictValueServiceImpl implements DictValueService {
@Override
@SuppressWarnings("unchecked")
public List<DictValueVO> getDictValueList(String key) {
public List<DictValueVO> getDictValueList(String keyName) {
// 查询缓存
String cacheKey = DictCacheKeyDefine.DICT_VALUE.format(key);
String cacheKey = DictCacheKeyDefine.DICT_VALUE.format(keyName);
List<DictValueCacheDTO> list = RedisMaps.valuesJson(cacheKey, (Class<DictValueCacheDTO>) DictCacheKeyDefine.DICT_VALUE.getType());
if (list.isEmpty()) {
// 查询数据库
list = dictValueDAO.of()
.createWrapper()
.eq(DictValueDO::getKeyName, key)
.eq(DictValueDO::getKeyName, keyName)
.then()
.list(DictValueConvert.MAPPER::toCache);
// 添加默认值 防止穿透
@@ -170,14 +170,14 @@ public class DictValueServiceImpl implements DictValueService {
}
@Override
public Map<String, Map<String, Object>> getDictValueEnum(String key) {
public Map<String, Map<String, Object>> getDictValueEnum(String keyName) {
// 查询配置值
List<DictValueVO> values = this.getDictValueList(key);
List<DictValueVO> values = this.getDictValueList(keyName);
if (values.isEmpty()) {
return Maps.empty();
}
// 查询配置项
Map<String, String> schema = dictKeyService.getDictSchema(key);
Map<String, String> schema = dictKeyService.getDictSchema(keyName);
// 返回
Map<String, Map<String, Object>> result = Maps.newLinkedMap();
for (DictValueVO value : values) {

View File

@@ -5,6 +5,7 @@
:loading="loading"
:disabled="loading"
:filter-option="filterOption"
:allow-create="allowCreate"
placeholder="请选择配置项" />
</template>
@@ -23,6 +24,10 @@
const props = defineProps({
modelValue: Number,
loading: Boolean,
allowCreate: {
type: Boolean,
default: false
}
});
const emits = defineEmits(['update:modelValue', 'change']);
@@ -32,8 +37,21 @@
return props.modelValue;
},
set(e) {
emits('update:modelValue', e);
emits('change', e);
if (typeof e === 'string') {
// 创建的值
emits('update:modelValue', undefined);
emits('change', {
id: undefined,
keyName: e
});
} else {
// 已有的值
emits('update:modelValue', e);
const find = cacheStore.dictKeys.find(s => s.id === e);
if (find) {
emits('change', find);
}
}
}
});
@@ -44,7 +62,6 @@
return {
label: `${s.keyName} - ${s.description || ''}`,
value: s.id,
origin: s,
};
});
};

View File

@@ -16,14 +16,13 @@
</script>
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, PropType } from 'vue';
import { useCacheStore } from '@/store';
import { SelectOptionData } from '@arco-design/web-vue';
import { RoleStatusEnum } from '@/views/user/role/types/enum.types';
const props = defineProps({
// FIXME 拆出来单选多选
modelValue: Array,
modelValue: Object as PropType<Array<number>> | PropType<number>,
loading: Boolean,
multiple: Boolean,
});

View File

@@ -101,7 +101,6 @@
import { definedExtraKeys, innerKeys, ExtraParamType } from '../types/const';
import { ValueTypeEnum } from '../types/enum.types';
import { toOptions } from '@/utils/enum';
import { FieldData } from '@arco-design/web-vue/es/form/interface';
const { visible, setVisible } = useVisible();
const { loading, setLoading } = useLoading();
@@ -113,7 +112,7 @@
return {
id: undefined,
keyName: undefined,
valueType: undefined,
valueType: ValueTypeEnum.STRING.value,
extraSchema: undefined,
description: undefined,
};

View File

@@ -77,6 +77,12 @@
<!-- 操作 -->
<template #handle="{ record }">
<div class="table-handle-wrapper">
<!-- 查看 -->
<a-button type="text"
size="mini"
@click="viewDictKey(record.keyName)">
查看
</a-button>
<!-- 修改 -->
<a-button type="text"
size="mini"
@@ -117,13 +123,15 @@
import { usePagination } from '@/types/table';
import {} from '../types/const';
import { ValueTypeEnum } from '../types/enum.types';
import { toOptions, getEnumValue } from '@/utils/enum';
import { MenuStatusEnum } from '@/views/system/menu/types/enum.types';
import { getEnumValue } from '@/utils/enum';
import { getDictValueEnum } from '@/api/system/dict-value';
import useCopy from '@/hooks/copy';
const tableRenderData = ref<DictKeyQueryResponse[]>([]);
const { loading, setLoading } = useLoading();
const emits = defineEmits(['openAdd', 'openUpdate']);
const { copy } = useCopy();
const pagination = usePagination();
const formModel = reactive<DictKeyQueryRequest>({
@@ -163,6 +171,13 @@
addedCallback, updatedCallback
});
// 查看
const viewDictKey = async (keyName: string) => {
const { data } = await getDictValueEnum(keyName);
// fixme 后续改为 jsonView
await copy(JSON.stringify(data), '复制成功');
};
// 加载数据
const doFetchTableData = async (request: DictKeyQueryRequest) => {
try {

View File

@@ -36,7 +36,7 @@ const columns = [
}, {
title: '操作',
slotName: 'handle',
width: 130,
width: 170,
align: 'center',
fixed: 'right',
},

View File

@@ -22,7 +22,7 @@
:rules="formRules">
<!-- 配置项 -->
<a-form-item field="keyId" label="配置项">
<dict-key-selector v-model="formModel.keyId" />
<dict-key-selector v-model="formModel.keyId" @change="changeKey" />
</a-form-item>
<!-- 配置名称 -->
<a-form-item field="name" label="配置名称">
@@ -42,6 +42,40 @@
placeholder="请输入排序"
hide-button />
</a-form-item>
<!-- 额外配置 -->
<a-form-item v-for="{ name, type } in keyExtraSchemas"
:key="name"
:field="name as string"
:label="name">
<!-- 字符串 -->
<a-input v-if="ValueTypeEnum.STRING.value === type"
v-model="extraValue[name]"
:placeholder="`请输入 ${name}`"
allow-clear />
<!-- 数字 -->
<a-input-number v-else-if="ValueTypeEnum.INTEGER.value === type || ValueTypeEnum.DECIMAL.value === type"
v-model="extraValue[name]"
:placeholder="`请输入 ${name}`"
allow-clear
hide-button />
<!-- 布尔值 -->
<a-switch v-else-if="ValueTypeEnum.BOOLEAN.value === type"
type="round"
v-model="extraValue[name]"
checked-text="TRUE"
unchecked-text="FALSE" />
<!-- 颜色 -->
<template v-else-if="ValueTypeEnum.COLOR.value === type">
<a-input v-model="extraValue[name]"
:placeholder="`请输入 ${name}`"
default-value="#"
allow-clear
hide-button />
<span class="color-block" :style="{
background: extraValue[name] === '#' ? undefined : (extraValue[name] || undefined)
}" />
</template>
</a-form-item>
</a-form>
</a-spin>
</a-modal>
@@ -60,13 +94,16 @@
import formRules from '../types/form.rules';
import { createDictValue, updateDictValue, DictValueUpdateRequest } from '@/api/system/dict-value';
import { Message } from '@arco-design/web-vue';
import {} from '../types/const';
import {} from '../types/enum.types';
import { toOptions } from '@/utils/enum';
import { ExtraParamType, innerKeys } from '../../dict-key/types/const';
import { ValueTypeEnum } from '../../dict-key/types/enum.types';
import {} from '@/utils/enum';
import DictKeySelector from '@/components/system/dict-key/dict-key-selector.vue';
import { DictKeyQueryResponse } from '@/api/system/dict-key';
import { useCacheStore } from '@/store';
const { visible, setVisible } = useVisible();
const { loading, setLoading } = useLoading();
const cacheStore = useCacheStore();
const title = ref<string>();
const isAddHandle = ref<boolean>(true);
@@ -83,6 +120,8 @@
};
};
const keyExtraSchemas = ref<Array<ExtraParamType>>([]);
const extraValue = ref<Record<string, any>>({});
const formRef = ref<any>();
const formModel = ref<DictValueUpdateRequest>({});
@@ -107,10 +146,20 @@
// 渲染表单
const renderForm = (record: any) => {
formModel.value = Object.assign({}, record);
// schema
const find = record.keyId && cacheStore.dictKeys.find((item) => item.id === record.keyId);
keyExtraSchemas.value = (find && find.extraSchema && JSON.parse(find.extraSchema)) || [];
// 额外参数
extraValue.value = (formModel.value.extra && JSON.parse(formModel.value.extra)) || {};
};
defineExpose({ openAdd, openUpdate });
// 切换 key
const changeKey = ({ extraSchema }: DictKeyQueryResponse) => {
keyExtraSchemas.value = (extraSchema && JSON.parse(extraSchema)) || [];
};
// 确定
const handlerOk = async () => {
setLoading(true);
@@ -120,14 +169,34 @@
if (error) {
return false;
}
// 验证额外参数
if (keyExtraSchemas.value.length) {
for (let { name, type } of keyExtraSchemas.value) {
const nameKey = name as string;
const value = extraValue.value[nameKey];
if (value === undefined) {
if (type === ValueTypeEnum.BOOLEAN.value) {
extraValue.value[nameKey] = false;
continue;
}
formRef.value.setFields({
[nameKey]: {
status: 'error',
message: `${name} 不能为空`
}
});
return false;
}
}
}
if (isAddHandle.value) {
// 新增
await createDictValue(formModel.value);
await createDictValue({ ...formModel.value, extra: JSON.stringify(extraValue.value) });
Message.success('创建成功');
emits('added');
} else {
// 修改
await updateDictValue(formModel.value);
await updateDictValue({ ...formModel.value, extra: JSON.stringify(extraValue.value) });
Message.success('修改成功');
emits('updated');
}
@@ -154,5 +223,11 @@
</script>
<style lang="less" scoped>
.color-block {
width: 36px;
height: 30px;
margin-left: 8px;
border-radius: 4px;
background: var(--color-fill-2);
}
</style>

View File

@@ -4,11 +4,13 @@
<a-query-header :model="formModel"
label-align="left"
@submit="fetchTableData"
@reset="fetchTableData"
@reset="resetForm"
@keyup.enter="() => fetchTableData()">
<!-- 配置项 -->
<a-form-item field="keyName" label="配置项" label-col-flex="50px">
<a-input v-model="formModel.keyName" placeholder="请输入配置项" allow-clear />
<a-form-item field="keyId" label="配置项" label-col-flex="50px">
<dict-key-selector v-model="formModel.keyId"
@change="changeKey"
allow-create />
</a-form-item>
<!-- 配置名称 -->
<a-form-item field="name" label="配置名称" label-col-flex="50px">
@@ -100,12 +102,12 @@
@click="emits('openUpdate', record)">
修改
</a-button>
<!-- 回滚 -->
<!-- 历史 -->
<a-button type="text"
size="mini"
v-permission="['infra:dict-value:update']"
@click="emits('openUpdate', record)">
回滚
@click="emits('openHistory', record)">
历史
</a-button>
<!-- 删除 -->
<a-popconfirm content="确认删除这条记录吗?"
@@ -142,11 +144,12 @@
import {} from '../types/enum.types';
import { toOptions, getEnumValue } from '@/utils/enum';
import useCopy from '@/hooks/copy';
import DictKeySelector from '@/components/system/dict-key/dict-key-selector.vue';
const { copy } = useCopy();
const tableRenderData = ref<DictValueQueryResponse[]>([]);
const { loading, setLoading } = useLoading();
const emits = defineEmits(['openAdd', 'openUpdate']);
const emits = defineEmits(['openAdd', 'openUpdate', 'openHistory']);
const pagination = usePagination();
const selectedKeys = ref<number[]>([]);
@@ -210,6 +213,21 @@
addedCallback, updatedCallback
});
// 修改 key
const changeKey = ({ id, keyName }: { id: number, keyName: string }) => {
if (id) {
formModel.keyId = id;
} else {
formModel.keyName = keyName;
}
};
// 清空表单
const resetForm = () => {
formModel.keyName = undefined;
fetchTableData();
};
// 加载数据
const doFetchTableData = async (request: DictValueQueryRequest) => {
try {