fix: perfect dict menu

This commit is contained in:
chansee97 2024-07-07 00:28:41 +08:00
parent 6b40f45ae3
commit 48054e04f9
4 changed files with 36 additions and 160 deletions

View File

@ -1,7 +1,7 @@
{
"name": "nova-admin",
"type": "module",
"version": "0.9.4",
"version": "0.9.5",
"private": true,
"description": "a clean and concise back-end management template based on Vue3, Vite5, Typescript, and Naive UI.",
"author": {

View File

@ -1,148 +0,0 @@
<script setup lang="ts">
import { useBoolean } from '@/hooks'
interface Props {
modalName?: string
dictCode: string
}
const props = withDefaults(defineProps<Props>(), {
modalName: '',
})
const emit = defineEmits<{
open: []
close: []
}>()
const { bool: modalVisible, setTrue: showModal, setFalse: hiddenModal } = useBoolean(false)
const { bool: submitLoading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
const formDefault: Entity.Dict = {
label: '',
code: '',
}
const formModel = ref<Entity.Dict>({ ...formDefault })
type ModalType = 'add' | 'view' | 'edit'
const modalType = shallowRef<ModalType>('add')
const modalTitle = computed(() => {
const titleMap: Record<ModalType, string> = {
add: '添加',
view: '查看',
edit: '编辑',
}
return `${titleMap[modalType.value]}${props.modalName}`
})
async function openModal(type: ModalType = 'add', data?: any) {
emit('open')
modalType.value = type
showModal()
const handlers = {
async add() {
formModel.value = { ...formDefault }
formModel.value.code = props.dictCode
},
async view() {
if (!data)
return
formModel.value = { ...data }
},
async edit() {
if (!data)
return
formModel.value = { ...data }
},
}
await handlers[type]()
}
function closeModal() {
hiddenModal()
endLoading()
emit('close')
}
defineExpose({
openModal,
})
const formRef = ref()
async function submitModal() {
const handlers = {
async add() {
return new Promise((resolve) => {
setTimeout(() => {
window.$message.success('模拟新增成功')
resolve(true)
}, 2000)
})
},
async edit() {
return new Promise((resolve) => {
setTimeout(() => {
window.$message.success('模拟编辑成功')
resolve(true)
}, 2000)
})
},
async view() {
return true
},
}
await formRef.value?.validate()
startLoading()
await handlers[modalType.value]() && closeModal()
}
const rules = {
label: {
required: true,
message: '请输入字典名称',
trigger: 'blur',
},
value: {
required: true,
message: '请输入字典值',
trigger: 'blur',
},
}
</script>
<template>
<n-modal
v-model:show="modalVisible"
:mask-closable="false"
preset="card"
:title="modalTitle"
class="w-700px"
:segmented="{
content: true,
action: true,
}"
>
<n-form ref="formRef" :rules="rules" label-placement="left" :model="formModel" :label-width="100" :disabled="modalType === 'view'">
<n-form-item label="字典名称" path="label">
<n-input v-model:value="formModel.label" />
</n-form-item>
<n-form-item label="字典码" path="code">
<n-input v-model:value="formModel.code" disabled />
</n-form-item>
<n-form-item label="字典值" path="value">
<n-input-number v-model:value="formModel.value" />
</n-form-item>
</n-form>
<template #action>
<n-space justify="center">
<n-button @click="closeModal">
取消
</n-button>
<n-button type="primary" :loading="submitLoading" @click="submitModal">
提交
</n-button>
</n-space>
</template>
</n-modal>
</template>

View File

@ -1,12 +1,16 @@
<script setup lang="ts">
import type { FormRules } from 'naive-ui'
import { useBoolean } from '@/hooks'
interface Props {
modalName?: string
dictCode?: string
isRoot?: boolean
}
const props = withDefaults(defineProps<Props>(), {
modalName: '',
isRoot: false,
})
const emit = defineEmits<{
@ -42,6 +46,11 @@ async function openModal(type: ModalType = 'add', data?: any) {
const handlers = {
async add() {
formModel.value = { ...formDefault }
formModel.value.isRoot = props.isRoot ? 1 : 0
if (props.dictCode) {
formModel.value.code = props.dictCode
}
},
async view() {
if (!data)
@ -95,16 +104,22 @@ async function submitModal() {
await handlers[modalType.value]() && closeModal()
}
const rules = {
const rules: FormRules = {
label: {
required: true,
message: '请输入字典名称',
trigger: 'blur',
trigger: ['input', 'blur'],
},
code: {
required: true,
message: '请输入字典码',
trigger: ['input', 'blur'],
},
value: {
required: true,
message: '请输入字典值',
trigger: 'blur',
type: 'number',
trigger: ['input', 'blur'],
},
}
</script>
@ -126,7 +141,10 @@ const rules = {
<n-input v-model:value="formModel.label" />
</n-form-item>
<n-form-item label="字典码" path="code">
<n-input v-model:value="formModel.code" />
<n-input v-model:value="formModel.code" :disabled="!isRoot" />
</n-form-item>
<n-form-item v-if="!isRoot" label="字典值" path="value">
<n-input-number v-model:value="formModel.value" :min="0" />
</n-form-item>
</n-form>
<template #action>

View File

@ -2,16 +2,16 @@
import type { DataTableColumns } from 'naive-ui'
import { NButton, NFlex, NPopconfirm } from 'naive-ui'
import DictModal from './components/DictModal.vue'
import DictContentModal from './components/DictContentModal.vue'
import { fetchDictList } from '@/service'
import { useBoolean } from '@/hooks'
import { useDictStore } from '@/store'
import CopyText from '@/components/custom/CopyText.vue'
const { bool: dictLoading, setTrue: startDictLoading, setFalse: endDictLoading } = useBoolean(false)
const { bool: contentLoading, setTrue: startContentLoading, setFalse: endContentLoading } = useBoolean(false)
const dictRef = ref<InstanceType<typeof DictModal>>()
const dictContentRef = ref<InstanceType<typeof DictContentModal>>()
const dictContentRef = ref<InstanceType<typeof DictModal>>()
onMounted(() => {
getDictList()
@ -31,10 +31,11 @@ async function getDictList() {
endDictLoading()
}
let lastDictCode: string
const lastDictCode = ref('')
async function getDictContent(code: string) {
startContentLoading()
dictContentData.value = await getDictByNet(code)
lastDictCode.value = code
endContentLoading()
}
@ -46,6 +47,11 @@ const dictColumns: DataTableColumns<Entity.Dict> = [
{
title: '字典码',
key: 'code',
render: (row) => {
return (
<CopyText value={row.code} />
)
},
},
{
title: '操作',
@ -167,7 +173,7 @@ function deleteDict(id: number) {
<div class="flex-1">
<n-card>
<template #header>
<NButton type="primary" @click="dictContentRef!.openModal('add')">
<NButton type="primary" :disabled="!lastDictCode" @click="dictContentRef!.openModal('add')">
<template #icon>
<icon-park-outline-add-one />
</template>
@ -176,7 +182,7 @@ function deleteDict(id: number) {
</template>
<template #header-extra>
<NFlex>
<NButton type="primary" secondary @click="getDictContent(lastDictCode)">
<NButton type="primary" :disabled="!lastDictCode" secondary @click="getDictContent(lastDictCode)">
<template #icon>
<icon-park-outline-refresh />
</template>
@ -191,8 +197,8 @@ function deleteDict(id: number) {
</n-card>
</div>
<DictModal ref="dictRef" modal-name="字典项" />
<DictContentModal ref="dictContentRef" modal-name="字典值" :dict-code="lastDictCode" />
<DictModal ref="dictRef" modal-name="字典项" is-root />
<DictModal ref="dictContentRef" modal-name="字典值" :dict-code="lastDictCode" />
</NFlex>
</template>