更新完善字典相关功能

This commit is contained in:
2026-02-18 17:15:33 +08:00
parent 5450777bd7
commit 378b9bd71f
23 changed files with 1657 additions and 572 deletions

View File

@@ -86,7 +86,7 @@
import { ref, computed, watch } from 'vue'
import { message } from 'ant-design-vue'
import systemApi from '@/api/system'
import dictionaryCache from '@/utils/dictionaryCache'
import { useDictionaryStore } from '@/stores/modules/dictionary'
const props = defineProps({
visible: {
@@ -146,9 +146,12 @@ const valueChecked = computed({
}
})
// 初始化字典 store
const dictionaryStore = useDictionaryStore()
// 加载配置分组
const loadGroups = async () => {
const groups = await dictionaryCache.getItemsByCode('config_group')
const groups = await dictionaryStore.getDictionary('config_group')
groupOptions.value = groups.map(item => ({
label: item.label,
value: item.value

View File

@@ -20,7 +20,7 @@
<!-- 状态 -->
<a-form-item label="状态" name="status">
<a-switch v-model:checked="statusChecked" checked-children="启用" un-checked-children="禁用" />
<sc-select v-model:value="form.status" source-type="dictionary" dictionary-code="dictionary_status" placeholder="请选择状态" allow-clear />
</a-form-item>
<!-- 描述 -->
@@ -43,6 +43,7 @@
<script setup>
import { ref, computed, watch } from 'vue'
import { message } from 'ant-design-vue'
import scSelect from '@/components/scSelect/index.vue'
import systemApi from '@/api/system'
// ===== Props =====
@@ -79,18 +80,10 @@ const form = ref({
name: '',
code: '',
description: '',
status: true,
status: null,
sort: 0
})
// ===== 计算属性:状态开关 =====
const statusChecked = computed({
get: () => form.value.status === true,
set: (val) => {
form.value.status = val ? true : false
}
})
// ===== 验证规则 =====
// 编码唯一性验证
const validateCodeUnique = async (rule, value) => {
@@ -131,7 +124,7 @@ const resetForm = () => {
name: '',
code: '',
description: '',
status: true,
status: null,
sort: 0
}
formRef.value?.clearValidate()
@@ -145,7 +138,7 @@ const setData = (data) => {
name: data.name || '',
code: data.code || '',
description: data.description || '',
status: data.status !== undefined ? data.status : true,
status: data.status !== undefined ? data.status : null,
sort: data.sort !== undefined ? data.sort : 0
}
}

View File

@@ -178,7 +178,7 @@ import systemApi from '@/api/system'
import scTable from '@/components/scTable/index.vue'
import DictionaryDialog from './components/DictionaryDialog.vue'
import ItemDialog from './components/ItemDialog.vue'
import dictionaryCache from '@/utils/dictionaryCache'
import { useDictionaryStore } from '@/stores/modules/dictionary'
// ===== 字典列表相关 =====
const dictionaryList = ref([])
@@ -250,6 +250,8 @@ const loadDictionaryList = async () => {
if (res.code === 200) {
dictionaryList.value = res.data || []
filteredDictionaries.value = res.data || []
// 建立字典ID到Code的映射
dictionaryStore.buildIdToCodeMap(res.data || [])
} else {
message.error(res.message || '加载字典列表失败')
}
@@ -388,6 +390,8 @@ const handleDeleteItem = async (record) => {
const res = await systemApi.dictionaryItems.delete.delete(record.id)
if (res.code === 200) {
message.success('删除成功')
// 清除字典缓存
dictionaryStore.clearDictionary(selectedDictionaryId.value)
refreshTable()
// 刷新字典列表以更新项数量
loadDictionaryList()
@@ -420,6 +424,8 @@ const handleBatchDelete = () => {
const res = await systemApi.dictionaryItems.batchDelete.post({ ids })
if (res.code === 200) {
message.success('删除成功')
// 清除字典缓存
dictionaryStore.clearDictionary(selectedDictionaryId.value)
selectedRows.value = []
refreshTable()
loadDictionaryList()
@@ -458,6 +464,8 @@ const handleBatchStatus = () => {
})
if (res.code === 200) {
message.success(`${statusText}成功`)
// 清除字典缓存
dictionaryStore.clearDictionary(selectedDictionaryId.value)
selectedRows.value = []
refreshTable()
} else {
@@ -471,11 +479,14 @@ const handleBatchStatus = () => {
})
}
// 初始化字典 store
const dictionaryStore = useDictionaryStore()
// ===== 方法:字典操作成功回调 =====
const handleDictionarySuccess = () => {
dialog.dictionary = false
// 清理字典缓存
dictionaryCache.clearDictionary()
dictionaryStore.clearCache()
loadDictionaryList()
}
@@ -483,7 +494,7 @@ const handleDictionarySuccess = () => {
const handleItemSuccess = () => {
dialog.item = false
// 清理字典缓存
dictionaryCache.clearDictionary(selectedDictionaryId.value)
dictionaryStore.clearDictionary(selectedDictionaryId.value)
refreshTable()
loadDictionaryList()
}

View File

@@ -71,7 +71,7 @@
<!-- 启用状态 -->
<a-form-item label="启用状态" name="is_active">
<a-switch v-model:checked="isActiveChecked" checked-children="启用" un-checked-children="禁用" />
<sc-select v-model:value="form.is_active" source-type="dictionary" dictionary-code="yes_no" placeholder="请选择状态" allow-clear />
</a-form-item>
<!-- 排序 -->
@@ -93,6 +93,7 @@
<script setup>
import { ref, computed, watch } from 'vue'
import { message } from 'ant-design-vue'
import scSelect from '@/components/scSelect/index.vue'
import systemApi from '@/api/system'
const props = defineProps({
@@ -125,42 +126,13 @@ const form = ref({
expression: '* * * * *',
timezone: 'Asia/Shanghai',
description: '',
is_active: true,
is_active: null,
run_in_background: false,
without_overlapping: false,
only_one: false,
sort: 0
})
// 计算属性:开关
const isActiveChecked = computed({
get: () => form.value.is_active === true,
set: (val) => {
form.value.is_active = val ? true : false
}
})
const runInBackgroundChecked = computed({
get: () => form.value.run_in_background === true,
set: (val) => {
form.value.run_in_background = val ? true : false
}
})
const withoutOverlappingChecked = computed({
get: () => form.value.without_overlapping === true,
set: (val) => {
form.value.without_overlapping = val ? true : false
}
})
const onlyOneChecked = computed({
get: () => form.value.only_one === true,
set: (val) => {
form.value.only_one = val ? true : false
}
})
// Cron 表达式验证函数
const validateCronExpression = (rule, value) => {
if (!value || !value.trim()) {
@@ -304,7 +276,7 @@ const resetForm = () => {
expression: '* * * * *',
timezone: 'Asia/Shanghai',
description: '',
is_active: true,
is_active: null,
run_in_background: false,
without_overlapping: false,
only_one: false,
@@ -324,7 +296,7 @@ const setData = (data) => {
expression: data.expression || '* * * * *',
timezone: data.timezone || 'Asia/Shanghai',
description: data.description || '',
is_active: data.is_active !== undefined ? data.is_active : true,
is_active: data.is_active !== undefined ? data.is_active : null,
run_in_background: data.run_in_background || false,
without_overlapping: data.without_overlapping || false,
only_one: data.only_one || false,