<template>
|
<ElDialog
|
:title="dialogTitle"
|
:model-value="visible"
|
:close-on-click-modal="false"
|
:close-on-press-escape="false"
|
width="820px"
|
align-center
|
@update:model-value="handleVisibleUpdate"
|
@closed="handleClosed"
|
>
|
<ArtForm
|
ref="formRef"
|
v-model="form"
|
:items="formItems"
|
:rules="rules"
|
:span="12"
|
:gutter="20"
|
label-width="100px"
|
:show-reset="false"
|
:show-submit="false"
|
/>
|
|
<template #footer>
|
<span class="dialog-footer">
|
<ElButton @click="handleCancel">{{ t('common.cancel') }}</ElButton>
|
<ElButton type="primary" @click="handleSubmit">{{ t('common.confirm') }}</ElButton>
|
</span>
|
</template>
|
</ElDialog>
|
</template>
|
|
<script setup>
|
import { ElMessageBox } from 'element-plus'
|
import { useI18n } from 'vue-i18n'
|
import ArtForm from '@/components/core/forms/art-form/index.vue'
|
import {
|
buildDictDataDialogModel,
|
createDictDataFormState,
|
getDictDataStatusOptions
|
} from '../dictDataPage.helpers'
|
|
const props = defineProps({
|
visible: { type: Boolean, default: false },
|
dictTypeData: { type: Object, default: () => ({}) },
|
dictData: { type: Object, default: () => ({}) }
|
})
|
|
const emit = defineEmits(['update:visible', 'submit'])
|
const formRef = ref()
|
const form = reactive(createDictDataFormState())
|
const initialSnapshot = ref(createComparableSnapshot())
|
const { t } = useI18n()
|
|
const isEdit = computed(() => Boolean(form.id))
|
const dialogTitle = computed(() => (isEdit.value ? '编辑字典项' : '新增字典项'))
|
|
const rules = computed(() => ({
|
dictTypeId: [{ required: true, message: '缺少字典类型ID', trigger: 'blur' }],
|
dictTypeCode: [{ required: true, message: '缺少字典类型编码', trigger: 'blur' }],
|
value: [{ required: true, message: '请输入字典值', trigger: 'blur' }],
|
label: [{ required: true, message: '请输入字典标签', trigger: 'blur' }]
|
}))
|
|
const formItems = computed(() => [
|
{
|
label: '字典类型ID',
|
key: 'dictTypeId',
|
type: 'input',
|
props: {
|
disabled: true
|
}
|
},
|
{
|
label: '字典编码',
|
key: 'dictTypeCode',
|
type: 'input',
|
props: {
|
disabled: true
|
}
|
},
|
{
|
label: '字典值',
|
key: 'value',
|
type: 'input',
|
props: {
|
clearable: true,
|
placeholder: '请输入字典值'
|
}
|
},
|
{
|
label: '字典标签',
|
key: 'label',
|
type: 'input',
|
props: {
|
clearable: true,
|
placeholder: '请输入字典标签'
|
}
|
},
|
{
|
label: '分组',
|
key: 'group',
|
type: 'input',
|
props: {
|
clearable: true,
|
placeholder: '请输入分组'
|
}
|
},
|
{
|
label: t('table.sort'),
|
key: 'sort',
|
type: 'number',
|
props: {
|
min: 0,
|
controlsPosition: 'right',
|
style: { width: '100%' }
|
}
|
},
|
{
|
label: t('table.status'),
|
key: 'status',
|
type: 'select',
|
props: {
|
clearable: true,
|
placeholder: '请选择状态',
|
options: getDictDataStatusOptions()
|
}
|
},
|
{
|
label: t('table.memo'),
|
key: 'memo',
|
type: 'input',
|
span: 24,
|
props: {
|
type: 'textarea',
|
rows: 3,
|
clearable: true,
|
placeholder: '请输入备注'
|
}
|
}
|
])
|
|
function resetForm() {
|
Object.assign(form, createDictDataFormState(props.dictTypeData))
|
initialSnapshot.value = createComparableSnapshot()
|
formRef.value?.clearValidate?.()
|
}
|
|
function loadFormData() {
|
const nextForm = buildDictDataDialogModel(props.dictData, props.dictTypeData)
|
Object.assign(form, nextForm)
|
initialSnapshot.value = createComparableSnapshot(nextForm)
|
}
|
|
async function handleSubmit() {
|
if (!formRef.value) return
|
try {
|
await formRef.value.validate()
|
emit('submit', { ...form })
|
} catch {
|
return
|
}
|
}
|
|
function closeDialog() {
|
emit('update:visible', false)
|
}
|
|
async function handleCancel() {
|
if (!(await confirmDiscardIfDirty())) {
|
return
|
}
|
closeDialog()
|
}
|
|
function handleVisibleUpdate(nextVisible) {
|
if (!nextVisible) {
|
handleCancel()
|
return
|
}
|
emit('update:visible', true)
|
}
|
|
function handleClosed() {
|
resetForm()
|
}
|
|
watch(
|
() => props.visible,
|
(visible) => {
|
if (visible) {
|
loadFormData()
|
nextTick(() => formRef.value?.clearValidate?.())
|
}
|
},
|
{ immediate: true }
|
)
|
|
watch(
|
() => props.dictData,
|
() => {
|
if (props.visible) {
|
loadFormData()
|
}
|
},
|
{ deep: true }
|
)
|
|
watch(
|
() => props.dictTypeData,
|
() => {
|
if (props.visible) {
|
loadFormData()
|
}
|
},
|
{ deep: true }
|
)
|
|
function createComparableSnapshot(source = form) {
|
return JSON.stringify({
|
...createDictDataFormState(props.dictTypeData),
|
...source
|
})
|
}
|
|
function isDirty() {
|
return createComparableSnapshot() !== initialSnapshot.value
|
}
|
|
async function confirmDiscardIfDirty() {
|
if (!isDirty()) {
|
return true
|
}
|
try {
|
await ElMessageBox.confirm('当前内容尚未保存,确定要关闭吗?', '未保存提示', {
|
confirmButtonText: '放弃修改',
|
cancelButtonText: '继续编辑',
|
type: 'warning'
|
})
|
return true
|
} catch {
|
return false
|
}
|
}
|
</script>
|