refactor(dict): 优化字典数据查询逻辑和接口

- 移除不必要的 ISysDictTypeService 依赖,简化 SysDictDataController
- 新增 selectDictDataByTypeRealtime 方法,支持实时查询字典数据,避免缓存问题
- 更新 SysDictDataController 中的字典数据查询逻辑,使用新方法
- 在 SysDictTypeController 中添加按字典类型编码精确查询的接口
- 更新前端组件以支持新的字典查询接口,优化字典选择器的加载逻辑
This commit is contained in:
王文昊
2026-04-28 19:12:50 +08:00
parent dde947516d
commit 5a56094e4f
11 changed files with 541 additions and 100 deletions

View File

@@ -2,6 +2,7 @@
<div style="display: flex; align-items: center;" v-loading="loading">
<!-- 下拉选择器绑定计算属性做双向绑定保留原有样式+清空功能 -->
<el-select
v-if="!toolbarOnly"
v-model="innerValue"
:placeholder="placeholder"
clearable filterable
@@ -20,13 +21,13 @@
<div
v-if="editable"
@click="openDictDialog"
style="cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;"
:style="toolbarOnly ? 'cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; border-radius: 2px;' : 'cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;'"
>
<i class="el-icon-setting"></i>
</div>
<div
v-if="refresh"
v-if="refresh && !toolbarOnly"
@click="handleRefresh"
style="cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;"
>
@@ -37,7 +38,7 @@
<el-dialog
v-if="editable"
:visible.sync="open"
title="字典数据配置"
:title="panelTitle || '字典数据配置'"
width="600px"
append-to-body
>
@@ -145,14 +146,17 @@
</template>
<script>
import { addData, updateData, delData, listData } from '@/api/system/dict/data'
import { listType } from '@/api/system/dict/type'
import { addData, updateData, delData, getDicts } from '@/api/system/dict/data'
export default {
name: 'DictSelectEdit',
props: {
dictType: { type: String, default: '' },
editable: { type: Boolean, default: true },
/** 仅展示字典配置入口(齿轮)与弹窗,不渲染下拉框 — 用于列表页 Tab 旁内联维护字典 */
toolbarOnly: { type: Boolean, default: false },
/** 字典配置弹窗标题 */
panelTitle: { type: String, default: '' },
kisv: { type: Boolean, default: true },
value: { type: String, default: '' },
placeholder: { type: String, default: '请选择' },
@@ -163,18 +167,17 @@ export default {
data() {
return {
dictOptions: [],
dictId: '',
loading: false,
btnLoading: false,
delBtnLoading: '',
open: false,
editRowId: '', // 控制当前编辑行,为空则所有单元格都是文本状态
form: {
dictId: '',
dictLabel: '',
dictValue: '',
dictType: '',
sort: 0
dictSort: 0,
status: '0'
},
dictRules: {
dictLabel: [{ required: true, message: '请输入字典标签', trigger: 'blur' }],
@@ -214,16 +217,16 @@ export default {
watch: {
dictType: {
async handler(newVal) {
if (newVal) {
this.loading = true
try {
const dictId = await this.getDictId(newVal)
await this.getDictOptions(dictId)
} catch (err) {
console.error('加载字典失败:', err)
} finally {
this.loading = false
}
if (!newVal) return
// toolbarOnly仅打开弹窗时加载避免无谓请求下拉模式按 dict_type 加载选项
if (this.toolbarOnly) return
this.loading = true
try {
await this.loadDictRows()
} catch (err) {
console.error('加载字典失败:', err)
} finally {
this.loading = false
}
},
immediate: true
@@ -236,14 +239,11 @@ export default {
}
},
methods: {
async getDictId(type) {
const res = await listType({ dictType: type })
if (res.rows?.length !== 1) {
this.$message.error('字典类型异常,未查询到对应配置')
return Promise.reject('字典类型异常')
}
this.dictId = res.rows[0].dictId
return this.dictId
/** 读字典数据行:优先 getDicts/dict/data/type/{type}),无权限点与系统字典页 list 不一致问题 */
async loadDictRows() {
const res = await getDicts(this.dictType)
this.dictOptions = res.data || []
return this.dictOptions
},
disabledFormat(item) {
if (this.disables) {
@@ -256,27 +256,36 @@ export default {
async handleRefresh() {
this.loading = true
try {
await this.getDictOptions(this.dictId)
await this.loadDictRows()
} catch (err) {
console.error('刷新字典失败:', err)
} finally {
this.loading = false
}
},
async getDictOptions(dictId) {
const res = await listData({ dictType: this.dictType, pageSize: 1000 })
this.dictOptions = res.rows || []
return this.dictOptions
},
openDictDialog() {
async openDictDialog() {
this.open = true
this.resetDictForm()
this.form.dictId = this.dictId
this.form.dictType = this.dictType
this.editRowId = '' // 打开弹窗重置编辑状态
this.editRowId = ''
this.loading = true
try {
await this.loadDictRows()
this.resetDictForm()
} catch (err) {
this.dictOptions = []
console.error('打开字典配置失败:', err)
this.$message.error('字典数据加载失败,请检查字典类型是否正确或稍后重试')
} finally {
this.loading = false
}
},
resetDictForm() {
this.form = { dictId: this.dictId, dictLabel: '', dictValue: '', dictType: this.dictType, sort: 0 }
this.form = {
dictLabel: '',
dictValue: '',
dictType: this.dictType,
dictSort: 0,
status: '0'
}
this.$refs.dictFormRef && this.$refs.dictFormRef.clearValidate()
},
handleKisvTableSync(row) {
@@ -290,7 +299,8 @@ export default {
try {
await addData(this.form)
this.$message.success('字典项新增成功!')
await this.getDictOptions(this.dictId)
await this.loadDictRows()
this.$emit('dict-updated')
this.resetDictForm()
} catch (err) {
this.$message.error('新增失败,请稍后重试')
@@ -309,18 +319,19 @@ export default {
async handleSaveRow(row) {
if (!row.dictLabel || !row.dictValue) {
this.$message.warning('字典标签和字典值不能为空!')
await this.getDictOptions(this.dictId)
await this.loadDictRows()
this.editRowId = '' // 校验失败,也必须还原单元格
return
}
row.sort = 0
if (row.dictSort == null) row.dictSort = 0
this.loading = true
try {
await updateData(row)
this.$message.success('字典项修改成功!')
this.$emit('dict-updated')
} catch (err) {
this.$message.error('修改失败,请稍后重试')
await this.getDictOptions(this.dictId)
await this.loadDictRows()
console.error(err)
} finally {
this.loading = false
@@ -339,7 +350,8 @@ export default {
try {
await delData(row.dictCode)
this.$message.success('删除成功!')
await this.getDictOptions(this.dictId)
await this.loadDictRows()
this.$emit('dict-updated')
} catch (err) {
this.$message.error('删除失败,请稍后重试')
console.error(err)