refactor: 优化枚举字典处理,增加颜色类型

1.重构 useDict 方法,同时支持枚举和查询字典,对应后端接口增加缓存处理
2.优化 BaseEnum 处理,增加 color 字段可用于设置对应枚举背景颜色(同字典背景颜色)
This commit is contained in:
Charles7c 2023-09-17 18:03:14 +08:00
parent 3a3a5d6b71
commit 1f73aa732d
33 changed files with 234 additions and 191 deletions

View File

@ -30,12 +30,21 @@ import com.baomidou.mybatisplus.annotation.IEnum;
* @author Charles7c * @author Charles7c
* @since 2023/2/5 20:44 * @since 2023/2/5 20:44
*/ */
public interface BaseEnum<V extends Serializable, D extends Serializable> extends IEnum<V> { public interface BaseEnum<V extends Serializable> extends IEnum<V> {
/** /**
* 枚举描述 * 枚举描述
* *
* @return 枚举描述 * @return 枚举描述
*/ */
D getDescription(); String getDescription();
/**
* 颜色
*
* @return 颜色
*/
default String getColor() {
return null;
}
} }

View File

@ -35,7 +35,7 @@ import top.charles7c.cnadmin.common.constant.StringConsts;
* @author Charles7c * @author Charles7c
* @since 2023/2/5 19:29 * @since 2023/2/5 19:29
*/ */
public class ExcelBaseEnumConverter implements Converter<BaseEnum<Integer, String>> { public class ExcelBaseEnumConverter implements Converter<BaseEnum<Integer>> {
@Override @Override
public Class<BaseEnum> supportJavaTypeKey() { public Class<BaseEnum> supportJavaTypeKey() {
@ -60,8 +60,8 @@ public class ExcelBaseEnumConverter implements Converter<BaseEnum<Integer, Strin
* 转换为 Excel 数据写入 Excel * 转换为 Excel 数据写入 Excel
*/ */
@Override @Override
public WriteCellData<String> convertToExcelData(BaseEnum<Integer, String> value, public WriteCellData<String> convertToExcelData(BaseEnum<Integer> value, ExcelContentProperty contentProperty,
ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
if (null == value) { if (null == value) {
return new WriteCellData<>(StringConsts.EMPTY); return new WriteCellData<>(StringConsts.EMPTY);
} }
@ -77,11 +77,11 @@ public class ExcelBaseEnumConverter implements Converter<BaseEnum<Integer, Strin
* 描述 * 描述
* @return 对应枚举 获取不到时为 {@code null} * @return 对应枚举 获取不到时为 {@code null}
*/ */
private BaseEnum<Integer, String> getEnum(Class<?> enumType, String description) { private BaseEnum<Integer> getEnum(Class<?> enumType, String description) {
Object[] enumConstants = enumType.getEnumConstants(); Object[] enumConstants = enumType.getEnumConstants();
for (Object enumConstant : enumConstants) { for (Object enumConstant : enumConstants) {
if (ClassUtil.isAssignable(BaseEnum.class, enumType)) { if (ClassUtil.isAssignable(BaseEnum.class, enumType)) {
BaseEnum<Integer, String> baseEnum = (BaseEnum<Integer, String>)enumConstant; BaseEnum<Integer> baseEnum = (BaseEnum<Integer>)enumConstant;
if (baseEnum.getDescription().equals(description)) { if (baseEnum.getDescription().equals(description)) {
return baseEnum; return baseEnum;
} }

View File

@ -53,6 +53,11 @@ public class CacheConsts {
*/ */
public static final String MENU_KEY_PREFIX = "MENU"; public static final String MENU_KEY_PREFIX = "MENU";
/**
* 字典缓存键前缀
*/
public static final String DICT_KEY_PREFIX = "DICT";
/** /**
* 仪表盘缓存键前缀 * 仪表盘缓存键前缀
*/ */

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.common.constant;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
/**
* UI 相关常量
*
* @author Charles7c
* @since 2023/9/17 14:12
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class UIConsts {
/**
* 主色极致蓝
*/
public static final String COLOR_PRIMARY = "arcoblue";
/**
* 成功色仙野绿
*/
public static final String COLOR_SUCCESS = "green";
/**
* 警告色活力橙
*/
public static final String COLOR_WARNING = "orangered";
/**
* 错误色浪漫红
*/
public static final String COLOR_ERROR = "red";
/**
* 默认色中性灰
*/
public static final String COLOR_DEFAULT = "gray";
}

View File

@ -29,7 +29,7 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum DataScopeEnum implements BaseEnum<Integer, String> { public enum DataScopeEnum implements BaseEnum<Integer> {
/** 全部数据权限 */ /** 全部数据权限 */
ALL(1, "全部数据权限"), ALL(1, "全部数据权限"),
@ -43,8 +43,8 @@ public enum DataScopeEnum implements BaseEnum<Integer, String> {
/** 仅本人数据权限 */ /** 仅本人数据权限 */
SELF(4, "仅本人数据权限"), SELF(4, "仅本人数据权限"),
/** 自定数据权限 */ /** 自定数据权限 */
CUSTOM(5, "自定数据权限"),; CUSTOM(5, "自定数据权限"),;
private final Integer value; private final Integer value;
private final String description; private final String description;

View File

@ -20,6 +20,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import top.charles7c.cnadmin.common.base.BaseEnum; import top.charles7c.cnadmin.common.base.BaseEnum;
import top.charles7c.cnadmin.common.constant.UIConsts;
/** /**
* 数据类型枚举 * 数据类型枚举
@ -29,14 +30,15 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum DataTypeEnum implements BaseEnum<Integer, String> { public enum DataTypeEnum implements BaseEnum<Integer> {
/** 系统内置 */ /** 系统内置 */
SYSTEM(1, "系统内置"), SYSTEM(1, "系统内置", UIConsts.COLOR_ERROR),
/** 自定义 */ /** 自定义 */
CUSTOM(2, "自定义"),; CUSTOM(2, "自定义", UIConsts.COLOR_PRIMARY),;
private final Integer value; private final Integer value;
private final String description; private final String description;
private final String color;
} }

View File

@ -29,7 +29,7 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum DisEnableStatusEnum implements BaseEnum<Integer, String> { public enum DisEnableStatusEnum implements BaseEnum<Integer> {
/** 启用 */ /** 启用 */
ENABLE(1, "启用"), ENABLE(1, "启用"),

View File

@ -29,7 +29,7 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum GenderEnum implements BaseEnum<Integer, String> { public enum GenderEnum implements BaseEnum<Integer> {
/** 未知 */ /** 未知 */
UNKNOWN(0, "未知"), UNKNOWN(0, "未知"),

View File

@ -29,7 +29,7 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum MenuTypeEnum implements BaseEnum<Integer, String> { public enum MenuTypeEnum implements BaseEnum<Integer> {
/** 目录 */ /** 目录 */
DIR(1, "目录"), DIR(1, "目录"),

View File

@ -29,7 +29,7 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum QueryTypeEnum implements BaseEnum<Integer, String> { public enum QueryTypeEnum implements BaseEnum<Integer> {
/** /**
* 等值查询例如WHERE `age` = 18 * 等值查询例如WHERE `age` = 18

View File

@ -20,6 +20,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import top.charles7c.cnadmin.common.base.BaseEnum; import top.charles7c.cnadmin.common.base.BaseEnum;
import top.charles7c.cnadmin.common.constant.UIConsts;
/** /**
* 成功/失败状态枚举 * 成功/失败状态枚举
@ -29,14 +30,15 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum SuccessFailureStatusEnum implements BaseEnum<Integer, String> { public enum SuccessFailureStatusEnum implements BaseEnum<Integer> {
/** 成功 */ /** 成功 */
SUCCESS(1, "成功"), SUCCESS(1, "成功", UIConsts.COLOR_SUCCESS),
/** 失败 */ /** 失败 */
FAILURE(2, "失败"),; FAILURE(2, "失败", UIConsts.COLOR_ERROR),;
private final Integer value; private final Integer value;
private final String description; private final String description;
private final String color;
} }

View File

@ -29,7 +29,7 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum LogStatusEnum implements BaseEnum<Integer, String> { public enum LogStatusEnum implements BaseEnum<Integer> {
/** 成功 */ /** 成功 */
SUCCESS(1, "成功"), SUCCESS(1, "成功"),

View File

@ -20,26 +20,28 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import top.charles7c.cnadmin.common.base.BaseEnum; import top.charles7c.cnadmin.common.base.BaseEnum;
import top.charles7c.cnadmin.common.constant.UIConsts;
/** /**
* 公告类型枚举计划 v1.2.0 增加字典管理用于维护此类信息 * 公告状态枚举
* *
* @author Charles7c * @author Charles7c
* @since 2023/8/20 10:55 * @since 2023/8/20 10:55
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum AnnouncementTypeEnum implements BaseEnum<Integer, String> { public enum AnnouncementStatusEnum implements BaseEnum<Integer> {
/** 活动 */ /** 待发布 */
ACTIVITY(1, "活动"), PENDING_RELEASE(1, "待发布", UIConsts.COLOR_PRIMARY),
/** 消息 */ /** 已发布 */
MESSAGE(2, "消息"), PUBLISHED(2, "已发布", UIConsts.COLOR_SUCCESS),
/** 通知 */ /** 已过期 */
NOTICE(3, "通知"),; EXPIRED(3, "已过期", UIConsts.COLOR_ERROR),;
private final Integer value; private final Integer value;
private final String description; private final String description;
private final String color;
} }

View File

@ -45,9 +45,9 @@ public class AnnouncementQuery implements Serializable {
private String title; private String title;
/** /**
* 类型1活动2消息3通知 * 类型
*/ */
@Schema(description = "类型1活动2消息3通知", example = "1") @Schema(description = "类型", example = "1")
@Query(type = QueryTypeEnum.EQUAL) @Query(type = QueryTypeEnum.EQUAL)
private Integer type; private String type;
} }

View File

@ -23,6 +23,7 @@ import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import top.charles7c.cnadmin.common.base.BaseVO; import top.charles7c.cnadmin.common.base.BaseVO;
import top.charles7c.cnadmin.system.enums.AnnouncementStatusEnum;
/** /**
* 公告信息 * 公告信息
@ -65,15 +66,14 @@ public class AnnouncementVO extends BaseVO {
* *
* @return 公告状态 * @return 公告状态
*/ */
@Schema(description = "状态1待发布2已发布3已过期", example = "1") @Schema(description = "状态1待发布2已发布3已过期", type = "Integer", allowableValues = {"1", "2", "3"}, example = "1")
public Integer getStatus() { public AnnouncementStatusEnum getStatus() {
int status = 2;
if (null != this.effectiveTime && this.effectiveTime.isAfter(LocalDateTime.now())) { if (null != this.effectiveTime && this.effectiveTime.isAfter(LocalDateTime.now())) {
status = 1; return AnnouncementStatusEnum.PENDING_RELEASE;
} }
if (null != this.terminateTime && this.terminateTime.isBefore(LocalDateTime.now())) { if (null != this.terminateTime && this.terminateTime.isBefore(LocalDateTime.now())) {
status = 3; return AnnouncementStatusEnum.EXPIRED;
} }
return status; return AnnouncementStatusEnum.PUBLISHED;
} }
} }

View File

@ -22,8 +22,6 @@ import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import top.charles7c.cnadmin.system.enums.AnnouncementTypeEnum;
/** /**
* 仪表盘-公告信息 * 仪表盘-公告信息
* *
@ -49,8 +47,8 @@ public class DashboardAnnouncementVO implements Serializable {
private String title; private String title;
/** /**
* 类型 * 类型取值于字典 announcement_type
*/ */
@Schema(description = "类型", type = "Integer", allowableValues = {"1", "2", "3"}, example = "1") @Schema(description = "类型(取值于字典 announcement_type", example = "1")
private AnnouncementTypeEnum type; private String type;
} }

View File

@ -20,10 +20,13 @@ import java.util.List;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import top.charles7c.cnadmin.common.base.BaseServiceImpl; import top.charles7c.cnadmin.common.base.BaseServiceImpl;
import top.charles7c.cnadmin.common.constant.CacheConsts;
import top.charles7c.cnadmin.common.model.query.SortQuery; import top.charles7c.cnadmin.common.model.query.SortQuery;
import top.charles7c.cnadmin.common.model.vo.LabelValueVO; import top.charles7c.cnadmin.common.model.vo.LabelValueVO;
import top.charles7c.cnadmin.common.util.validate.CheckUtils; import top.charles7c.cnadmin.common.util.validate.CheckUtils;
@ -43,11 +46,13 @@ import top.charles7c.cnadmin.system.service.DictItemService;
*/ */
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@CacheConfig(cacheNames = CacheConsts.DICT_KEY_PREFIX)
public class DictItemServiceImpl public class DictItemServiceImpl
extends BaseServiceImpl<DictItemMapper, DictItemDO, DictItemVO, DictItemDetailVO, DictItemQuery, DictItemRequest> extends BaseServiceImpl<DictItemMapper, DictItemDO, DictItemVO, DictItemDetailVO, DictItemQuery, DictItemRequest>
implements DictItemService { implements DictItemService {
@Override @Override
@CacheEvict(allEntries = true)
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long add(DictItemRequest request) { public Long add(DictItemRequest request) {
String value = request.getValue(); String value = request.getValue();
@ -56,6 +61,7 @@ public class DictItemServiceImpl
} }
@Override @Override
@CacheEvict(allEntries = true)
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void update(DictItemRequest request, Long id) { public void update(DictItemRequest request, Long id) {
String value = request.getValue(); String value = request.getValue();
@ -80,6 +86,7 @@ public class DictItemServiceImpl
} }
@Override @Override
@CacheEvict(allEntries = true)
public void deleteByDictIds(List<Long> dictIds) { public void deleteByDictIds(List<Long> dictIds) {
baseMapper.lambdaUpdate().in(DictItemDO::getDictId, dictIds).remove(); baseMapper.lambdaUpdate().in(DictItemDO::getDictId, dictIds).remove();
} }

View File

@ -29,7 +29,7 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
*/ */
@Getter @Getter
@RequiredArgsConstructor @RequiredArgsConstructor
public enum FormTypeEnum implements BaseEnum<Integer, String> { public enum FormTypeEnum implements BaseEnum<Integer> {
/** /**
* 文本框 * 文本框

View File

@ -35,10 +35,6 @@ export function listRoleDict(params: RoleParam) {
}); });
} }
export function listEnumDict(enumTypeName: string) {
return axios.get<LabelValueState[]>(`${BASE_URL}/dict/enum/${enumTypeName}`);
}
export function listDict(code: string) { export function listDict(code: string) {
return axios.get<LabelValueState[]>(`${BASE_URL}/dict/${code}`); return axios.get<LabelValueState[]>(`${BASE_URL}/dict/${code}`);
} }

View File

@ -5,32 +5,32 @@ const useDictStore = defineStore('dict', {
state: () => ({ dict: [] as Array<DictState> }), state: () => ({ dict: [] as Array<DictState> }),
actions: { actions: {
// 获取字典 // 获取字典
getDict(_name: string) { getDict(_code: string) {
if (_name == null || _name === '') { if (_code == null || _code === '') {
return null; return null;
} }
for (let i = 0; i < this.dict.length; i += 1) { for (let i = 0; i < this.dict.length; i += 1) {
if (this.dict[i].name === _name) { if (this.dict[i].code === _code) {
return this.dict[i].detail; return this.dict[i].items;
} }
} }
return null; return null;
}, },
// 设置字典 // 设置字典
setDict(_name: string, detail: Array<LabelValueState>) { setDict(_code: string, items: Array<LabelValueState>) {
if (_name !== null && _name !== '') { if (_code !== null && _code !== '') {
this.dict.push({ this.dict.push({
name: _name, code: _code,
detail, items,
}); });
} }
}, },
// 删除字典 // 删除字典
deleteDict(_name: string) { deleteDict(_code: string) {
let bln = false; let bln = false;
try { try {
for (let i = 0; i < this.dict.length; i += 1) { for (let i = 0; i < this.dict.length; i += 1) {
if (this.dict[i].name === _name) { if (this.dict[i].code === _code) {
this.dict.splice(i, 1); this.dict.splice(i, 1);
return true; return true;
} }

View File

@ -5,6 +5,6 @@ export interface LabelValueState {
} }
export interface DictState { export interface DictState {
name: string; code: string;
detail: Array<LabelValueState>; items: Array<LabelValueState>;
} }

View File

@ -1,32 +1,24 @@
import { ref, toRefs } from 'vue'; import { ref, toRefs } from 'vue';
import { listEnumDict, listDict } from '@/api/common'; import { listDict } from '@/api/common';
import { useDictStore } from '@/store'; import { useDictStore } from '@/store';
/** /**
* *
* *
* @param dicts * @param codes
*/ */
export default function useDict( export default function useDict(...codes: Array<string>) {
...dicts: Array<{ name: string; isEnum: boolean }>
) {
const res = ref<any>({}); const res = ref<any>({});
return (() => { return (() => {
dicts.forEach((d) => { codes.forEach((code) => {
const { name } = d; res.value[code] = [];
res.value[name] = []; const dict = useDictStore().getDict(code);
const dict = useDictStore().getDict(name);
if (dict) { if (dict) {
res.value[name] = dict; res.value[code] = dict;
} else if (d.isEnum) {
listEnumDict(name).then((resp) => {
res.value[name] = resp.data;
useDictStore().setDict(name, res.value[name]);
});
} else { } else {
listDict(name).then((resp) => { listDict(code).then((resp) => {
res.value[name] = resp.data; res.value[code] = resp.data;
useDictStore().setDict(name, res.value[name]); useDictStore().setDict(code, res.value[code]);
}); });
} }
}); });

View File

@ -13,7 +13,7 @@
<div> <div>
<a-empty v-if="dataList.length === 0">暂无公告</a-empty> <a-empty v-if="dataList.length === 0">暂无公告</a-empty>
<div v-for="(item, idx) in dataList" :key="idx" class="item"> <div v-for="(item, idx) in dataList" :key="idx" class="item">
<dict-tag :dict="announcement_type" :value="item.type" /> <dict-tag :value="item.type" :dict="announcement_type" />
<span class="item-content"> <span class="item-content">
<a-link @click="toDetail(item.id)">{{ item.title }}</a-link> <a-link @click="toDetail(item.id)">{{ item.title }}</a-link>
</span> </span>
@ -88,10 +88,7 @@
import { DataRecord, get } from '@/api/system/announcement'; import { DataRecord, get } from '@/api/system/announcement';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { announcement_type } = proxy.useDict({ const { announcement_type } = proxy.useDict('announcement_type');
name: 'announcement_type',
isEnum: false,
});
const dataList = ref<DashboardAnnouncementRecord[]>([]); const dataList = ref<DashboardAnnouncementRecord[]>([]);
const dataDetail = ref<DataRecord>({}); const dataDetail = ref<DataRecord>({});

View File

@ -10,7 +10,7 @@
<a-form-item field="status" hide-label> <a-form-item field="status" hide-label>
<a-select <a-select
v-model="queryParams.status" v-model="queryParams.status"
:options="SuccessFailureStatusEnum" :options="success_failure_status_enum"
placeholder="登录状态搜索" placeholder="登录状态搜索"
allow-clear allow-clear
style="width: 150px" style="width: 150px"
@ -91,10 +91,9 @@
} from '@/api/monitor/log'; } from '@/api/monitor/log';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { SuccessFailureStatusEnum } = proxy.useDict({ const { success_failure_status_enum } = proxy.useDict(
name: 'SuccessFailureStatusEnum', 'success_failure_status_enum'
isEnum: true, );
});
const loginLogList = ref<LoginLogRecord[]>([]); const loginLogList = ref<LoginLogRecord[]>([]);
const total = ref(0); const total = ref(0);

View File

@ -19,7 +19,7 @@
<a-form-item field="status" hide-label> <a-form-item field="status" hide-label>
<a-select <a-select
v-model="queryParams.status" v-model="queryParams.status"
:options="SuccessFailureStatusEnum" :options="success_failure_status_enum"
placeholder="操作状态搜索" placeholder="操作状态搜索"
allow-clear allow-clear
style="width: 150px" style="width: 150px"
@ -101,10 +101,9 @@
} from '@/api/monitor/log'; } from '@/api/monitor/log';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { SuccessFailureStatusEnum } = proxy.useDict({ const { success_failure_status_enum } = proxy.useDict(
name: 'SuccessFailureStatusEnum', 'success_failure_status_enum'
isEnum: true, );
});
const operationLogList = ref<OperationLogRecord[]>([]); const operationLogList = ref<OperationLogRecord[]>([]);
const total = ref(0); const total = ref(0);

View File

@ -128,16 +128,15 @@
</a-table-column> </a-table-column>
<a-table-column title="类型" align="center"> <a-table-column title="类型" align="center">
<template #cell="{ record }"> <template #cell="{ record }">
<dict-tag :dict="announcement_type" :value="record.type" /> <dict-tag :value="record.type" :dict="announcement_type" />
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="状态" align="center"> <a-table-column title="状态" align="center">
<template #cell="{ record }"> <template #cell="{ record }">
<a-tag v-if="record.status === 1" color="blue">待发布</a-tag> <dict-tag
<a-tag v-else-if="record.status === 2" color="green" :value="record.status"
>已发布</a-tag :dict="announcement_status_enum"
> />
<a-tag v-else color="red">已过期</a-tag>
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="生效时间"> <a-table-column title="生效时间">
@ -354,10 +353,10 @@
import checkPermission from '@/utils/permission'; import checkPermission from '@/utils/permission';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { announcement_type } = proxy.useDict({ const { announcement_type, announcement_status_enum } = proxy.useDict(
name: 'announcement_type', 'announcement_type',
isEnum: false, 'announcement_status_enum'
}); );
const dataList = ref<DataRecord[]>([]); const dataList = ref<DataRecord[]>([]);
const dataDetail = ref<DataRecord>({ const dataDetail = ref<DataRecord>({

View File

@ -19,7 +19,7 @@
<a-form-item field="status" hide-label> <a-form-item field="status" hide-label>
<a-select <a-select
v-model="queryParams.status" v-model="queryParams.status"
:options="DisEnableStatusEnum" :options="dis_enable_status_enum"
placeholder="状态搜索" placeholder="状态搜索"
allow-clear allow-clear
style="width: 150px" style="width: 150px"
@ -316,10 +316,7 @@
import checkPermission from '@/utils/permission'; import checkPermission from '@/utils/permission';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { DisEnableStatusEnum } = proxy.useDict({ const { dis_enable_status_enum } = proxy.useDict('dis_enable_status_enum');
name: 'DisEnableStatusEnum',
isEnum: true,
});
const dataList = ref<DataRecord[]>([]); const dataList = ref<DataRecord[]>([]);
const dataDetail = ref<DataRecord>({ const dataDetail = ref<DataRecord>({

View File

@ -44,7 +44,7 @@
<template #columns> <template #columns>
<a-table-column title="字典标签" align="center"> <a-table-column title="字典标签" align="center">
<template #cell="{ record }"> <template #cell="{ record }">
<dict-tag :dict="dataList" :value="record.value" /> <dict-tag :value="record.value" :dict="dataList" />
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="字典值" align="center" data-index="value" /> <a-table-column title="字典值" align="center" data-index="value" />
@ -115,20 +115,20 @@
placeholder="请选择或输入背景颜色" placeholder="请选择或输入背景颜色"
allow-clear allow-clear
> >
<template #option="{ record }"> <template #option="{ data }">
<a-tag v-if="record.value === 'primary'" color="arcoblue">{{ <a-tag v-if="data.value === 'primary'" color="arcoblue">{{
record.value data.value
}}</a-tag> }}</a-tag>
<a-tag v-else-if="record.value === 'success'" color="green">{{ <a-tag v-else-if="data.value === 'success'" color="green">{{
record.value data.value
}}</a-tag> }}</a-tag>
<a-tag v-else-if="record.value === 'warning'" color="orangered">{{ <a-tag v-else-if="data.value === 'warning'" color="orangered">{{
record.value data.value
}}</a-tag> }}</a-tag>
<a-tag v-else-if="record.value === 'error'" color="red">{{ <a-tag v-else-if="data.value === 'error'" color="red">{{
record.value data.value
}}</a-tag> }}</a-tag>
<a-tag v-else color="gray">{{ record.value }}</a-tag> <a-tag v-else color="gray">{{ data.value }}</a-tag>
</template> </template>
<template #suffix> <template #suffix>
<color-picker v-model:pureColor="form.color" shape="circle" /> <color-picker v-model:pureColor="form.color" shape="circle" />

View File

@ -19,7 +19,7 @@
<a-form-item field="status" hide-label> <a-form-item field="status" hide-label>
<a-select <a-select
v-model="queryParams.status" v-model="queryParams.status"
:options="DisEnableStatusEnum" :options="dis_enable_status_enum"
placeholder="状态搜索" placeholder="状态搜索"
allow-clear allow-clear
style="width: 150px" style="width: 150px"
@ -355,10 +355,7 @@
import checkPermission from '@/utils/permission'; import checkPermission from '@/utils/permission';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { DisEnableStatusEnum } = proxy.useDict({ const { dis_enable_status_enum } = proxy.useDict('dis_enable_status_enum');
name: 'DisEnableStatusEnum',
isEnum: true,
});
const dataList = ref<DataRecord[]>([]); const dataList = ref<DataRecord[]>([]);
const ids = ref<Array<string>>([]); const ids = ref<Array<string>>([]);

View File

@ -19,7 +19,7 @@
<a-form-item field="status" hide-label> <a-form-item field="status" hide-label>
<a-select <a-select
v-model="queryParams.status" v-model="queryParams.status"
:options="DisEnableStatusEnum" :options="dis_enable_status_enum"
placeholder="状态搜索" placeholder="状态搜索"
allow-clear allow-clear
style="width: 150px" style="width: 150px"
@ -125,13 +125,7 @@
<a-table-column title="角色编码" data-index="code" /> <a-table-column title="角色编码" data-index="code" />
<a-table-column title="数据权限" :width="130"> <a-table-column title="数据权限" :width="130">
<template #cell="{ record }"> <template #cell="{ record }">
<span v-if="record.dataScope === 1">全部数据权限</span> <dict-tag :value="record.dataScope" :dict="data_scope_enum" />
<span v-else-if="record.dataScope === 2"
>本部门及以下数据权限</span
>
<span v-else-if="record.dataScope === 3">本部门数据权限</span>
<span v-else-if="record.dataScope === 4">仅本人数据权限</span>
<span v-else>自定义数据权限</span>
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="角色排序" align="center" data-index="sort" /> <a-table-column title="角色排序" align="center" data-index="sort" />
@ -282,7 +276,7 @@
> >
<a-select <a-select
v-model="form.dataScope" v-model="form.dataScope"
:options="DataScopeEnum" :options="data_scope_enum"
placeholder="请选择数据权限" placeholder="请选择数据权限"
/> />
</a-form-item> </a-form-item>
@ -359,17 +353,10 @@
<a-skeleton-line :rows="1" /> <a-skeleton-line :rows="1" />
</a-skeleton> </a-skeleton>
<span v-else> <span v-else>
<span v-if="dataDetail.dataScope === 1">全部数据权限</span> <dict-tag
<span v-else-if="dataDetail.dataScope === 2" :value="dataDetail.dataScope"
>本部门及以下数据权限</span :dict="data_scope_enum"
> />
<span v-else-if="dataDetail.dataScope === 3"
>本部门数据权限</span
>
<span v-else-if="dataDetail.dataScope === 4"
>仅本人数据权限</span
>
<span v-else>自定义数据权限</span>
</span> </span>
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="创建人"> <a-descriptions-item label="创建人">
@ -448,15 +435,9 @@
import checkPermission from '@/utils/permission'; import checkPermission from '@/utils/permission';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { DataScopeEnum, DisEnableStatusEnum } = proxy.useDict( const { data_scope_enum, dis_enable_status_enum } = proxy.useDict(
{ 'data_scope_enum',
name: 'DataScopeEnum', 'dis_enable_status_enum'
isEnum: true,
},
{
name: 'DisEnableStatusEnum',
isEnum: true,
}
); );
const dataList = ref<DataRecord[]>([]); const dataList = ref<DataRecord[]>([]);

View File

@ -43,7 +43,7 @@
<a-form-item field="status" hide-label> <a-form-item field="status" hide-label>
<a-select <a-select
v-model="queryParams.status" v-model="queryParams.status"
:options="DisEnableStatusEnum" :options="dis_enable_status_enum"
placeholder="状态搜索" placeholder="状态搜索"
allow-clear allow-clear
style="width: 150px" style="width: 150px"
@ -523,10 +523,7 @@
import checkPermission from '@/utils/permission'; import checkPermission from '@/utils/permission';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { DisEnableStatusEnum } = proxy.useDict({ const { dis_enable_status_enum } = proxy.useDict('dis_enable_status_enum');
name: 'DisEnableStatusEnum',
isEnum: true,
});
const dataList = ref<DataRecord[]>([]); const dataList = ref<DataRecord[]>([]);
const dataDetail = ref<DataRecord>({ const dataDetail = ref<DataRecord>({

View File

@ -211,7 +211,7 @@
<a-select <a-select
v-if="record.showInForm || record.showInQuery" v-if="record.showInForm || record.showInQuery"
v-model="record.formType" v-model="record.formType"
:options="FormTypeEnum" :options="form_type_enum"
placeholder="请选择表单类型" placeholder="请选择表单类型"
/> />
<span v-else>无需设置</span> <span v-else>无需设置</span>
@ -222,7 +222,7 @@
<a-select <a-select
v-if="record.showInQuery" v-if="record.showInQuery"
v-model="record.queryType" v-model="record.queryType"
:options="QueryTypeEnum" :options="query_type_Enum"
placeholder="请选择查询方式" placeholder="请选择查询方式"
/> />
<span v-else>无需设置</span> <span v-else>无需设置</span>
@ -301,15 +301,9 @@
} from '@/api/tool/generator'; } from '@/api/tool/generator';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const { FormTypeEnum, QueryTypeEnum } = proxy.useDict( const { form_type_enum, query_type_Enum } = proxy.useDict(
{ 'form_type_enum',
name: 'DisEnableStatusEnum', 'query_type_Enum'
isEnum: true,
},
{
name: 'QueryTypeEnum',
isEnum: true,
}
); );
const tableList = ref<TableRecord[]>([]); const tableList = ref<TableRecord[]>([]);

View File

@ -29,6 +29,7 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -37,9 +38,11 @@ import org.springframework.web.bind.annotation.RestController;
import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import top.charles7c.cnadmin.common.base.BaseEnum; import top.charles7c.cnadmin.common.base.BaseEnum;
import top.charles7c.cnadmin.common.config.properties.ProjectProperties; import top.charles7c.cnadmin.common.config.properties.ProjectProperties;
import top.charles7c.cnadmin.common.constant.CacheConsts;
import top.charles7c.cnadmin.common.model.query.SortQuery; import top.charles7c.cnadmin.common.model.query.SortQuery;
import top.charles7c.cnadmin.common.model.vo.LabelValueVO; import top.charles7c.cnadmin.common.model.vo.LabelValueVO;
import top.charles7c.cnadmin.common.model.vo.R; import top.charles7c.cnadmin.common.model.vo.R;
@ -92,31 +95,43 @@ public class CommonController {
return R.ok(labelValueVOList); return R.ok(labelValueVOList);
} }
@Operation(summary = "查询枚举字典", description = "查询枚举字典列表")
@Parameter(name = "enumTypeName", description = "枚举类型名称", example = "DataScopeEnum", in = ParameterIn.PATH)
@GetMapping("/dict/enum/{enumTypeName}")
public R<List<LabelValueVO>> listEnumDict(@PathVariable String enumTypeName) {
// 扫描所有 BaseEnum 枚举基类的子类
Set<Class<?>> classSet = ClassUtil.scanPackageBySuper(projectProperties.getBasePackage(), BaseEnum.class);
Optional<Class<?>> first =
classSet.stream().filter(c -> c.getSimpleName().equalsIgnoreCase(enumTypeName)).findFirst();
if (!first.isPresent()) {
return R.fail("枚举字典不存在");
}
// 转换枚举为字典列表
Class<?> enumClass = first.get();
Object[] enumConstants = enumClass.getEnumConstants();
List<LabelValueVO> labelValueVOList = Arrays.stream(enumConstants).map(e -> {
BaseEnum<Integer, String> baseEnum = (BaseEnum<Integer, String>)e;
return new LabelValueVO<>(baseEnum.getDescription(), baseEnum.getValue());
}).collect(Collectors.toList());
return R.ok(labelValueVOList);
}
@Operation(summary = "查询字典", description = "查询字典列表") @Operation(summary = "查询字典", description = "查询字典列表")
@Parameter(name = "code", description = "字典编码", example = "announcement_type", in = ParameterIn.PATH) @Parameter(name = "code", description = "字典编码", example = "announcement_type", in = ParameterIn.PATH)
@GetMapping("/dict/{code}") @GetMapping("/dict/{code}")
@Cacheable(key = "#code", cacheNames = CacheConsts.DICT_KEY_PREFIX)
public R<List<LabelValueVO>> listDict(@PathVariable String code) { public R<List<LabelValueVO>> listDict(@PathVariable String code) {
return R.ok(dictItemService.listByDictCode(code)); Optional<Class<?>> enumClass = this.getEnumClassByName(code);
return enumClass.map(this::listEnumDict).orElseGet(() -> R.ok(dictItemService.listByDictCode(code)));
}
/**
* 根据枚举类名查询
*
* @param enumClassName
* 枚举类名
* @return 枚举类型
*/
private Optional<Class<?>> getEnumClassByName(String enumClassName) {
Set<Class<?>> classSet = ClassUtil.scanPackageBySuper(projectProperties.getBasePackage(), BaseEnum.class);
return classSet.stream()
.filter(
c -> StrUtil.equalsAnyIgnoreCase(c.getSimpleName(), enumClassName, StrUtil.toCamelCase(enumClassName)))
.findFirst();
}
/**
* 查询枚举字典
*
* @param enumClass
* 枚举类型
* @return 枚举字典
*/
private R<List<LabelValueVO>> listEnumDict(Class<?> enumClass) {
Object[] enumConstants = enumClass.getEnumConstants();
List<LabelValueVO> labelValueList = Arrays.stream(enumConstants).map(e -> {
BaseEnum<Integer> baseEnum = (BaseEnum<Integer>)e;
return new LabelValueVO<>(baseEnum.getDescription(), baseEnum.getValue(), baseEnum.getColor());
}).collect(Collectors.toList());
return R.ok(labelValueList);
} }
} }