Compare commits
No commits in common. "0d9b6589c73444404b36a39271ac75808d467ef9" and "5644602b3a8edd0a99737feb613e1cce33fc6a1b" have entirely different histories.
0d9b6589c7
...
5644602b3a
17
auto-imports.d.ts
vendored
17
auto-imports.d.ts
vendored
@ -9,10 +9,6 @@ declare global {
|
|||||||
const EffectScope: typeof import('vue')['EffectScope']
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
const addChildMenu: typeof import('./src/api/menu')['addChildMenu']
|
const addChildMenu: typeof import('./src/api/menu')['addChildMenu']
|
||||||
const addParentMenu: typeof import('./src/api/menu')['addParentMenu']
|
const addParentMenu: typeof import('./src/api/menu')['addParentMenu']
|
||||||
const addChildDict: typeof import('./src/api/dictApi')['addChildDict']
|
|
||||||
const addChildMenu: typeof import('./src/api/menu')['addChildMenu']
|
|
||||||
const addParentDict: typeof import('./src/api/dictApi')['addParentDict']
|
|
||||||
const addParentMenu: typeof import('./src/api/menu')['addParentMenu']
|
|
||||||
const computed: typeof import('vue')['computed']
|
const computed: typeof import('vue')['computed']
|
||||||
const createApp: typeof import('vue')['createApp']
|
const createApp: typeof import('vue')['createApp']
|
||||||
const customRef: typeof import('vue')['customRef']
|
const customRef: typeof import('vue')['customRef']
|
||||||
@ -21,24 +17,13 @@ declare global {
|
|||||||
const deleteMenu: typeof import('./src/api/menu')['deleteMenu']
|
const deleteMenu: typeof import('./src/api/menu')['deleteMenu']
|
||||||
const deleteUser: typeof import('./src/api/roleApi')['deleteUser']
|
const deleteUser: typeof import('./src/api/roleApi')['deleteUser']
|
||||||
const editParentMenu: typeof import('./src/api/menu')['editParentMenu']
|
const editParentMenu: typeof import('./src/api/menu')['editParentMenu']
|
||||||
const deleteChildDict: typeof import('./src/api/dictApi')['deleteChildDict']
|
|
||||||
const deleteMenu: typeof import('./src/api/menu')['deleteMenu']
|
|
||||||
const deleteParentDict: typeof import('./src/api/dictApi')['deleteParentDict']
|
|
||||||
const deleteUser: typeof import('./src/api/roleApi')['deleteUser']
|
|
||||||
const editParentMenu: typeof import('./src/api/menu')['editParentMenu']
|
|
||||||
const effectScope: typeof import('vue')['effectScope']
|
const effectScope: typeof import('vue')['effectScope']
|
||||||
const eidtChildMenu: typeof import('./src/api/menu')['eidtChildMenu']
|
const eidtChildMenu: typeof import('./src/api/menu')['eidtChildMenu']
|
||||||
const enable: typeof import('./src/api/roleApi')['enable']
|
const enable: typeof import('./src/api/roleApi')['enable']
|
||||||
const enableRole: typeof import('./src/api/roleApi')['enableRole']
|
const enableRole: typeof import('./src/api/roleApi')['enableRole']
|
||||||
const getAllMenu: typeof import('./src/api/menu')['getAllMenu']
|
const getAllMenu: typeof import('./src/api/menu')['getAllMenu']
|
||||||
const eidtChildMenu: typeof import('./src/api/menu')['eidtChildMenu']
|
|
||||||
const enable: typeof import('./src/api/roleApi')['enable']
|
|
||||||
const enableRole: typeof import('./src/api/roleApi')['enableRole']
|
|
||||||
const getAllMenu: typeof import('./src/api/menu')['getAllMenu']
|
|
||||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||||
const getDict: typeof import('./src/api/dictApi')['getDict']
|
|
||||||
const getParentDict: typeof import('./src/api/dictApi')['getParentDict']
|
|
||||||
const getRoleList: typeof import('./src/api/roleApi')['getRoleList']
|
const getRoleList: typeof import('./src/api/roleApi')['getRoleList']
|
||||||
const getUserInfo: typeof import('./src/api/userApi')['getUserInfo']
|
const getUserInfo: typeof import('./src/api/userApi')['getUserInfo']
|
||||||
const getUserList: typeof import('./src/api/roleApi')['getUserList']
|
const getUserList: typeof import('./src/api/roleApi')['getUserList']
|
||||||
@ -83,8 +68,6 @@ declare global {
|
|||||||
const toValue: typeof import('vue')['toValue']
|
const toValue: typeof import('vue')['toValue']
|
||||||
const triggerRef: typeof import('vue')['triggerRef']
|
const triggerRef: typeof import('vue')['triggerRef']
|
||||||
const unref: typeof import('vue')['unref']
|
const unref: typeof import('vue')['unref']
|
||||||
const updateChildDict: typeof import('./src/api/dictApi')['updateChildDict']
|
|
||||||
const updateParentDict: typeof import('./src/api/dictApi')['updateParentDict']
|
|
||||||
const useAttrs: typeof import('vue')['useAttrs']
|
const useAttrs: typeof import('vue')['useAttrs']
|
||||||
const useCssModule: typeof import('vue')['useCssModule']
|
const useCssModule: typeof import('vue')['useCssModule']
|
||||||
const useCssVars: typeof import('vue')['useCssVars']
|
const useCssVars: typeof import('vue')['useCssVars']
|
||||||
|
|||||||
5642
package-lock.json
generated
5642
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,109 +0,0 @@
|
|||||||
import http from "@/utils/request";
|
|
||||||
|
|
||||||
const dictUrl = "/api/v1/AdminDictionary"
|
|
||||||
|
|
||||||
interface DictRowQuery {
|
|
||||||
parentId?: string
|
|
||||||
parentValue?: string
|
|
||||||
label: string
|
|
||||||
labelEn?: string
|
|
||||||
remark?: string
|
|
||||||
value: string
|
|
||||||
tag?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DictRowReturn {
|
|
||||||
uuid: string
|
|
||||||
parentId: string
|
|
||||||
parentValue: string
|
|
||||||
label: string
|
|
||||||
labelEn: string
|
|
||||||
remark: string
|
|
||||||
value: string
|
|
||||||
tag: string
|
|
||||||
createTime: string
|
|
||||||
createUserId: string
|
|
||||||
};
|
|
||||||
const DictParentURL = "/api/Dict/parents";
|
|
||||||
const DictChildURL = "/api/Dict/children";
|
|
||||||
|
|
||||||
// 获取父级字典
|
|
||||||
export function getParentDict(label: string): Promise<DictRowReturn[]> {
|
|
||||||
return http({
|
|
||||||
url: DictParentURL,
|
|
||||||
method: 'GET',
|
|
||||||
params: label
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 新增父级字典
|
|
||||||
export function addParentDict(data: { label: string, value: string }) {
|
|
||||||
return http({
|
|
||||||
url: DictParentURL,
|
|
||||||
method: 'POST',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 更新父级字典
|
|
||||||
export function updateParentDict(uuid: string, data: { label: string }) {
|
|
||||||
return http({
|
|
||||||
url: `${DictParentURL}/${uuid}`,
|
|
||||||
method: 'PUT',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 删除父级字典
|
|
||||||
export function deleteParentDict(uuid: string) {
|
|
||||||
return http({
|
|
||||||
url: `${DictParentURL}/${uuid}`,
|
|
||||||
method: 'DELETE',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 新增子级字典
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param data 必需parentId, parentValue, label, value
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function addChildDict(data: DictRowQuery) {
|
|
||||||
console.log("addChildDict", data);
|
|
||||||
return http({
|
|
||||||
url: DictChildURL,
|
|
||||||
method: 'POST',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 获取子级字典
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param value 为父级value
|
|
||||||
* @param tag 用逗号连接选择的tags数组
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getDict(value: string, tag: string): Promise<DictRowReturn[]> {
|
|
||||||
return http({
|
|
||||||
url: DictChildURL,
|
|
||||||
method: 'GET',
|
|
||||||
params: { value, tag }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 更新子级字典
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param data 必需label, value
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function updateChildDict(uuid: string, data: DictRowQuery) {
|
|
||||||
console.log("updateChildDict", data);
|
|
||||||
return http({
|
|
||||||
url: `${DictChildURL}/${uuid}`,
|
|
||||||
method: 'PUT',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 删除子级字典
|
|
||||||
export function deleteChildDict(uuid: string) {
|
|
||||||
return http({
|
|
||||||
url: `${DictChildURL}/${uuid}`,
|
|
||||||
method: 'DELETE',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,508 +0,0 @@
|
|||||||
<template>
|
|
||||||
<main class="dict-main">
|
|
||||||
<!-- 上面有一排操作按钮:input框查询 查询按钮,新增 -->
|
|
||||||
<!-- 字典表格,含有字段:字典id,字典名称,字典值,字典标签,操作列(编辑 删除) -->
|
|
||||||
<div v-if="tableTitle === ''" class="dict-main__empty">
|
|
||||||
<LsEmpty type="no-data" v-model:title="emptyStateTitle" v-model:description="emptyStateDescription" />
|
|
||||||
</div>
|
|
||||||
<div v-if="tableTitle !== ''" class="dict-main__content">
|
|
||||||
<div class="dict-main__header">
|
|
||||||
<h1>{{ tableTitle }}</h1>
|
|
||||||
</div>
|
|
||||||
<div class="dict-main__search">
|
|
||||||
<n-input autosize v-model:value="mainSearch" placeholder="查询字典名称(中/英)" clearable
|
|
||||||
@keyup.enter="handleFindDatas" class="dict-main__search-input">
|
|
||||||
</n-input>
|
|
||||||
<n-button type="primary" @click="handleFindDatas" :focusable="false" class="dict-main__search-btn">
|
|
||||||
<template #icon>
|
|
||||||
<n-icon :component="SearchOutline" />
|
|
||||||
</template>
|
|
||||||
查询
|
|
||||||
</n-button>
|
|
||||||
<n-button type="primary" @click="hanldeAddData" :focusable="false" class="dict-main__add-btn">
|
|
||||||
<template #icon>
|
|
||||||
<n-icon :component="AddOutline" />
|
|
||||||
</template>
|
|
||||||
新增
|
|
||||||
</n-button>
|
|
||||||
</div>
|
|
||||||
<div class="dict-main__table" ref="tableMainRef">
|
|
||||||
<n-data-table v-if="height" :loading="loading" :columns="columns" :data="currentData"
|
|
||||||
:table-layout="'fixed'" :max-height="`${height}px`" class="dict-main__table-content" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<n-modal v-model:show="showDataModal" title="新增字典数据" preset="dialog" :mask-closable="false">
|
|
||||||
<n-form ref="formRef" :model="formData" :rules="formRules">
|
|
||||||
<n-form-item label="字典中文名称" path="label">
|
|
||||||
<n-input v-model:value="formData.label" placeholder="输入字典中文名称" clearable />
|
|
||||||
</n-form-item>
|
|
||||||
|
|
||||||
<n-form-item label="字典英文名称" path="labelEn">
|
|
||||||
<n-input v-model:value="formData.labelEn" placeholder="输入字典英文名称" clearable />
|
|
||||||
</n-form-item>
|
|
||||||
|
|
||||||
<n-form-item label="字典描述" path="remark">
|
|
||||||
<n-input v-model:value="formData.remark" placeholder="输入字典描述" type="textarea"
|
|
||||||
:autosize="{ minRows: 2, maxRows: 4 }" />
|
|
||||||
</n-form-item>
|
|
||||||
|
|
||||||
<n-form-item label="字典值" path="value">
|
|
||||||
<n-input v-model:value="formData.value" placeholder="输入字典值" clearable />
|
|
||||||
</n-form-item>
|
|
||||||
|
|
||||||
<n-form-item label="新增标签" path="tags">
|
|
||||||
<n-dynamic-tags v-model:value="formData.tags" :render-tag="renderTag" />
|
|
||||||
</n-form-item>
|
|
||||||
</n-form>
|
|
||||||
<template #action>
|
|
||||||
<n-space justify="end">
|
|
||||||
<n-button @click="showDataModal = false">取消</n-button>
|
|
||||||
<n-button type="primary" @click="handleFormSubmit">提交</n-button>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
|
||||||
</n-modal>
|
|
||||||
|
|
||||||
<n-modal v-model:show="showDeleteModal" title="删除字典数据" preset="dialog" :mask-closable="false" content="确认删除该项字典数据?"
|
|
||||||
negative-text="取消" positive-text="确认" @negative-click="showDeleteModal = false"
|
|
||||||
@positive-click="hanldeDeleteSubmit">
|
|
||||||
|
|
||||||
</n-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { getDict } from '@/api/dictApi';
|
|
||||||
import LsEmpty from '@/components/Ls-UI/LsEmpty.vue';
|
|
||||||
import { deepClone } from '@/utils';
|
|
||||||
import { AddOutline, PencilOutline, SearchOutline, TrashOutline } from '@vicons/ionicons5';
|
|
||||||
import { DataTableColumns, FormInst, NButton, NIcon, NSpace, NTag, NTime, useMessage } from 'naive-ui';
|
|
||||||
|
|
||||||
const parentProps = defineProps<{
|
|
||||||
uuid: string
|
|
||||||
value: string
|
|
||||||
label: string
|
|
||||||
}>();
|
|
||||||
|
|
||||||
watch(parentProps, async (newValue) => {
|
|
||||||
console.log(newValue);
|
|
||||||
|
|
||||||
loading.value = true;
|
|
||||||
tableTitle.value = newValue.label;
|
|
||||||
if (!height.value) {
|
|
||||||
nextTick(() => {
|
|
||||||
if (tableMainRef.value) {
|
|
||||||
height.value = tableMainRef.value.clientHeight;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (tableTitle.value !== '') {
|
|
||||||
try {
|
|
||||||
await getDatas();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('数据获取失败:', error);
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
interface DictRow {
|
|
||||||
uuid?: string
|
|
||||||
parentId?: string
|
|
||||||
parentValue?: string
|
|
||||||
label: string
|
|
||||||
labelEn?: string
|
|
||||||
remark?: string
|
|
||||||
value: string
|
|
||||||
tags?: string[]
|
|
||||||
createTime?: string
|
|
||||||
createUserId?: string
|
|
||||||
};
|
|
||||||
|
|
||||||
const getColumns = ({
|
|
||||||
mod: modifyRowData, del: deleteRowData
|
|
||||||
}: {
|
|
||||||
mod: (row: DictRow) => void,
|
|
||||||
del: (row: DictRow) => void
|
|
||||||
}): DataTableColumns<DictRow> => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
title: '字典中文',
|
|
||||||
key: 'label',
|
|
||||||
width: 75,
|
|
||||||
ellipsis: { tooltip: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '字典英文',
|
|
||||||
key: 'labelEn',
|
|
||||||
width: 75,
|
|
||||||
ellipsis: { tooltip: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '备注',
|
|
||||||
key: 'remark',
|
|
||||||
width: 125,
|
|
||||||
ellipsis: { tooltip: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '字典值',
|
|
||||||
key: 'value',
|
|
||||||
width: 75,
|
|
||||||
ellipsis: { tooltip: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '标签',
|
|
||||||
key: 'tags',
|
|
||||||
width: 125,
|
|
||||||
render(row: DictRow) {
|
|
||||||
const tags = row.tags.map((tagKey) => {
|
|
||||||
return h(
|
|
||||||
NTag,
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
marginRight: '6px',
|
|
||||||
color: '#3D8EFF',
|
|
||||||
},
|
|
||||||
type: 'info',
|
|
||||||
bordered: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
default: () => tagKey
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
return tags
|
|
||||||
},
|
|
||||||
ellipsis: { tooltip: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '创建时间',
|
|
||||||
key: 'createTime',
|
|
||||||
width: 75,
|
|
||||||
render(row: DictRow) {
|
|
||||||
const timeStr = row.createTime;
|
|
||||||
if (!timeStr) return '无效日期';
|
|
||||||
|
|
||||||
const timestamp = Date.parse(timeStr);
|
|
||||||
if (isNaN(timestamp)) {
|
|
||||||
return '无效日期';
|
|
||||||
}
|
|
||||||
|
|
||||||
return h(
|
|
||||||
NTime,
|
|
||||||
{
|
|
||||||
format: 'yyyy-MM-dd hh:mm:ss',
|
|
||||||
time: timestamp
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '创建用户编号',
|
|
||||||
key: 'createUserId',
|
|
||||||
width: 75,
|
|
||||||
fixed: 'right',
|
|
||||||
ellipsis: { tooltip: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
key: 'actions',
|
|
||||||
width: 75,
|
|
||||||
align: 'center',
|
|
||||||
render(row: DictRow) {
|
|
||||||
return h(
|
|
||||||
NSpace,
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
default: () => [
|
|
||||||
h(
|
|
||||||
NButton,
|
|
||||||
{
|
|
||||||
size: 'small',
|
|
||||||
quaternary: true,
|
|
||||||
type: 'info',
|
|
||||||
focusable: false,
|
|
||||||
onClick: () => modifyRowData(row)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: () => h(NIcon, { color: 'blue' }, { default: () => h(PencilOutline) })
|
|
||||||
}
|
|
||||||
),
|
|
||||||
h(
|
|
||||||
NButton,
|
|
||||||
{
|
|
||||||
size: 'small',
|
|
||||||
quaternary: true,
|
|
||||||
type: 'error',
|
|
||||||
focusable: false,
|
|
||||||
onClick: () => deleteRowData(row)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: () => h(NIcon, { color: 'red' }, { default: () => h(TrashOutline) })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
const getDatas = async () => {
|
|
||||||
try {
|
|
||||||
console.log("父级字典:", parentProps);
|
|
||||||
const result = await getDict(parentProps.value, null);
|
|
||||||
tableData.value = result.map(item => {
|
|
||||||
const { tag, ...rest } = item;
|
|
||||||
return {
|
|
||||||
tags: tag ? tag.split(",") : [],
|
|
||||||
...rest,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
currentData.value = tableData.value
|
|
||||||
} catch (error) {
|
|
||||||
console.log('获取失败', error);
|
|
||||||
message.error('获取数据失败');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFindDatas = () => {
|
|
||||||
currentData.value = tableData.value.filter(item => (item.label.includes(mainSearch.value) || item.labelEn.includes(mainSearch.value)) && item.value === parentProps.value)
|
|
||||||
};
|
|
||||||
|
|
||||||
const message = useMessage();
|
|
||||||
|
|
||||||
const formRef = ref<FormInst | null>(null);
|
|
||||||
const currentMode = ref<'Add' | 'Modify'>('Add');
|
|
||||||
const showDataModal = ref(false);
|
|
||||||
|
|
||||||
const formData = ref<DictRow>();
|
|
||||||
const formRules = {
|
|
||||||
label: {
|
|
||||||
required: true,
|
|
||||||
message: '请输入字典中文名称',
|
|
||||||
trigger: 'input'
|
|
||||||
},
|
|
||||||
labelEn: {
|
|
||||||
required: false,
|
|
||||||
message: '请输入字典英文名称',
|
|
||||||
trigger: 'input'
|
|
||||||
},
|
|
||||||
remark: {
|
|
||||||
required: false,
|
|
||||||
message: '请输入字典描述',
|
|
||||||
trigger: 'input'
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
required: true,
|
|
||||||
message: '请输入字典值',
|
|
||||||
trigger: 'input'
|
|
||||||
},
|
|
||||||
tags: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增与修改相关逻辑
|
|
||||||
const hanldeAddData = () => {
|
|
||||||
console.log("新增");
|
|
||||||
formData.value = ({
|
|
||||||
label: '',
|
|
||||||
labelEn: '',
|
|
||||||
remark: '',
|
|
||||||
value: '',
|
|
||||||
tags: [],
|
|
||||||
});
|
|
||||||
currentMode.value = 'Add';
|
|
||||||
showDataModal.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const modifyChildUuid = ref('');
|
|
||||||
|
|
||||||
const hanldeModifyData = (row: DictRow) => {
|
|
||||||
console.log("修改:", row);
|
|
||||||
const { uuid, parentId, parentValue, createTime, createUserId, ...rest } = row;
|
|
||||||
modifyChildUuid.value = uuid;
|
|
||||||
formData.value = deepClone(rest);
|
|
||||||
console.log(formData.value.tags);
|
|
||||||
currentMode.value = 'Modify';
|
|
||||||
showDataModal.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 表单内标签逻辑
|
|
||||||
const renderTag = (tag: string, index: number) => {
|
|
||||||
return h(
|
|
||||||
NTag,
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
marginRight: '6px',
|
|
||||||
color: '#3D8EFF',
|
|
||||||
},
|
|
||||||
type: 'info',
|
|
||||||
bordered: false,
|
|
||||||
closable: true,
|
|
||||||
onClose: () => {
|
|
||||||
formData.value.tags.splice(index, 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
default: () => tag
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 表单提交
|
|
||||||
const handleFormSubmit = async (e: MouseEvent) => {
|
|
||||||
e.preventDefault()
|
|
||||||
formRef.value?.validate(async (errors) => {
|
|
||||||
if (!errors) {
|
|
||||||
try {
|
|
||||||
const { tags, ...rest } = formData.value;
|
|
||||||
if (currentMode.value === 'Add') {
|
|
||||||
const result = await addChildDict({ parentId: parentProps.uuid, parentValue: parentProps.value, tag: tags.join(","), ...rest });
|
|
||||||
console.log(result);
|
|
||||||
message.success('新增成功');
|
|
||||||
}
|
|
||||||
else if (currentMode.value === 'Modify') {
|
|
||||||
const result = await updateChildDict(modifyChildUuid.value, { tag: tags.join(","), ...rest });
|
|
||||||
console.log(result);
|
|
||||||
message.success('修改成功');
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await getDatas();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('数据获取失败:', error);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log('提交失败', error);
|
|
||||||
message.error('提交失败');
|
|
||||||
} finally {
|
|
||||||
modifyChildUuid.value = '';
|
|
||||||
showDataModal.value = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('表单信息不完整', errors);
|
|
||||||
message.error('表单信息不完整');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除相关逻辑
|
|
||||||
const showDeleteModal = ref(false);
|
|
||||||
const deleteData = ref<DictRow | null>(null);
|
|
||||||
|
|
||||||
const handleDeleteDatas = (row: DictRow) => {
|
|
||||||
console.log("删除:", row);
|
|
||||||
deleteData.value = row;
|
|
||||||
showDeleteModal.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const hanldeDeleteSubmit = async () => {
|
|
||||||
console.log('submit delete ', deleteData);
|
|
||||||
try {
|
|
||||||
await deleteChildDict(deleteData.value.uuid);
|
|
||||||
message.success('删除成功');
|
|
||||||
try {
|
|
||||||
await getDatas();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('数据获取失败:', error);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log('删除失败', error);
|
|
||||||
message.error('删除失败');
|
|
||||||
} finally {
|
|
||||||
showDataModal.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 空状态展示用标题与描述
|
|
||||||
const emptyStateTitle = ref('');
|
|
||||||
const emptyStateDescription = ref('');
|
|
||||||
// 搜索绑定字段
|
|
||||||
const mainSearch = ref('');
|
|
||||||
// 页面标题、表格列名、总数据、表格展示数据、表格是否加载
|
|
||||||
const tableTitle = ref('');
|
|
||||||
const columns = ref(getColumns({ mod: hanldeModifyData, del: handleDeleteDatas }));
|
|
||||||
const tableData = ref<DictRow[]>([]);
|
|
||||||
const currentData = ref<DictRow[]>([]);
|
|
||||||
const loading = ref(true);
|
|
||||||
// 用于控制表格最大高度参数
|
|
||||||
const tableMainRef = ref<HTMLElement | null>(null);
|
|
||||||
const height = ref(null);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.dict-main {
|
|
||||||
flex: 1;
|
|
||||||
padding: $normolGap;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
||||||
|
|
||||||
&__empty {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__content {
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: $bigGap;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding-bottom: $smallGap;
|
|
||||||
border-bottom: 1px solid $dashLineColor;
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 600;
|
|
||||||
color: $titleTextColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__search {
|
|
||||||
display: flex;
|
|
||||||
gap: $smallGap;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.n-input {
|
|
||||||
flex: 1;
|
|
||||||
max-width: 500px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__table {
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
border: 1px solid $dashLineColor;
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.n-data-table {
|
|
||||||
:deep(.n-data-table-th) {
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.n-data-table-td) {
|
|
||||||
padding: 12px $smallGap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,417 +0,0 @@
|
|||||||
<template>
|
|
||||||
<nav class="dict-nav">
|
|
||||||
<div class="dict-nav__search">
|
|
||||||
<n-input style="min-width: 100%" v-model:value="navSearch" placeholder="查询父级字典" clearable
|
|
||||||
@keyup.enter="handleFindParent(navSearch)">
|
|
||||||
<template #prefix>
|
|
||||||
<n-icon :component="SearchOutline" />
|
|
||||||
</template>
|
|
||||||
</n-input>
|
|
||||||
</div>
|
|
||||||
<div class="dict-nav__aciton">
|
|
||||||
<n-button block type="default" @click="handleAddParent" :focusable="false">
|
|
||||||
<template #icon>
|
|
||||||
<n-icon>
|
|
||||||
<AddOutline />
|
|
||||||
</n-icon>
|
|
||||||
</template>
|
|
||||||
新增父级字典
|
|
||||||
</n-button>
|
|
||||||
</div>
|
|
||||||
<n-space vertical>
|
|
||||||
<n-list bordered hoverable class="dict-nav__list">
|
|
||||||
<n-list-item v-for="(item, index) in parentDictDatas" :key="index" @click="handleUpdateParent(item)"
|
|
||||||
class="dict-nav__item">
|
|
||||||
<n-icon :component="BookOutline" size="20" class="dict-nav__item-icon" />
|
|
||||||
<span class="dict-nav__item-label">{{ item.label }}</span>
|
|
||||||
<div class="dict-nav__item-actions">
|
|
||||||
<n-button text class="dict-nav__action-btn dict-nav__action-btn--modify"
|
|
||||||
@click="e => handleModifyParent(e, item)">
|
|
||||||
<n-icon :component="PencilOutline" size="18" />
|
|
||||||
</n-button>
|
|
||||||
<n-button text class="dict-nav__action-btn dict-nav__action-btn--delete"
|
|
||||||
@click="e => handleDeleteParent(e, item)">
|
|
||||||
<n-icon :component="TrashOutline" size="18" />
|
|
||||||
</n-button>
|
|
||||||
</div>
|
|
||||||
</n-list-item>
|
|
||||||
</n-list>
|
|
||||||
</n-space>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<n-modal v-model:show="showDataModal" title="新增父级字典" preset="dialog" :mask-closable="false">
|
|
||||||
<n-form ref="formRef" :model="formData" :rules="formRules">
|
|
||||||
<n-form-item label="父级字典名称" path="label">
|
|
||||||
<n-input v-model:value="formData.label" placeholder="输入父级字典名称" />
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="父级字典值" path="value" v-if="currentMode === 'Add'">
|
|
||||||
<n-input v-model:value="formData.value" placeholder="输入父级字典值" />
|
|
||||||
</n-form-item>
|
|
||||||
</n-form>
|
|
||||||
<template #action>
|
|
||||||
<n-space justify="end">
|
|
||||||
<n-button @click="showDataModal = false">取消</n-button>
|
|
||||||
<n-button type="primary" @click="handleFormSubmit">提交</n-button>
|
|
||||||
</n-space>
|
|
||||||
</template>
|
|
||||||
</n-modal>
|
|
||||||
|
|
||||||
<n-modal v-model:show="showDeleteModal" title="删除父级字典数据" preset="dialog" :mask-closable="false"
|
|
||||||
content="确认删除该项字典数据?" negative-text="取消" positive-text="确认" @negative-click="showDeleteModal = false"
|
|
||||||
@positive-click="handleDeleteSubmit">
|
|
||||||
|
|
||||||
</n-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { getParentDict } from '@/api/dictApi';
|
|
||||||
import { AddOutline, BookOutline, PencilOutline, SearchOutline, TrashOutline } from '@vicons/ionicons5';
|
|
||||||
import { FormInst, NButton, NIcon, useMessage } from 'naive-ui';
|
|
||||||
|
|
||||||
const parentProps = defineProps<{
|
|
||||||
parentUuid: string
|
|
||||||
parentValue: string
|
|
||||||
parentTitle: string
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'update:parentUuid', value: string): void
|
|
||||||
(e: 'update:parentValue', value: string): void
|
|
||||||
(e: 'update:parentTitle', value: string): void
|
|
||||||
}>();
|
|
||||||
|
|
||||||
interface DictRow {
|
|
||||||
uuid?: string
|
|
||||||
parentId?: string
|
|
||||||
parentValue?: string
|
|
||||||
label: string
|
|
||||||
labelEn?: string
|
|
||||||
remark?: string
|
|
||||||
value: string
|
|
||||||
tags?: string[]
|
|
||||||
createTime?: string
|
|
||||||
createUserId?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const parentDictDatas = ref<DictRow[]>([]);
|
|
||||||
|
|
||||||
// 查找父级字典相关逻辑
|
|
||||||
const handleFindParent = async (label: string) => {
|
|
||||||
console.log('查找父级字典: ', label)
|
|
||||||
try {
|
|
||||||
const result = await getParentDict(label);
|
|
||||||
console.log("getParentDict: ", result);;
|
|
||||||
parentDictDatas.value = result;
|
|
||||||
console.log(parentDictDatas);
|
|
||||||
} catch (error) {
|
|
||||||
console.log('获取失败', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化
|
|
||||||
const init = async () => {
|
|
||||||
handleFindParent('');
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
init();
|
|
||||||
})
|
|
||||||
|
|
||||||
// 按钮触发更新
|
|
||||||
const handleUpdateParent = (dict: DictRow) => {
|
|
||||||
console.log("点击更新!", dict);
|
|
||||||
emit('update:parentUuid', dict.uuid);
|
|
||||||
emit('update:parentValue', dict.value);
|
|
||||||
emit('update:parentTitle', dict.label);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const message = useMessage();
|
|
||||||
|
|
||||||
// 新增与编辑相关数据与逻辑
|
|
||||||
interface FormData {
|
|
||||||
label: string;
|
|
||||||
value?: string;
|
|
||||||
}
|
|
||||||
const formData = ref<FormData>({
|
|
||||||
label: '',
|
|
||||||
value: ''
|
|
||||||
})
|
|
||||||
const formRules = {
|
|
||||||
label: {
|
|
||||||
required: true,
|
|
||||||
message: '请输入父级字典名称',
|
|
||||||
trigger: 'input'
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
required: true,
|
|
||||||
message: '请输入父级字典值',
|
|
||||||
trigger: 'input'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const formRef = ref<FormInst | null>(null);
|
|
||||||
const currentMode = ref<'Add' | 'Modify'>('Add');
|
|
||||||
const showDataModal = ref(false);
|
|
||||||
|
|
||||||
const handleAddParent = () => {
|
|
||||||
formData.value = {
|
|
||||||
label: '',
|
|
||||||
value: ''
|
|
||||||
};
|
|
||||||
currentMode.value = 'Add';
|
|
||||||
showDataModal.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const modifyParentUuid = ref('');
|
|
||||||
|
|
||||||
const handleModifyParent = (e: MouseEvent, data: DictRow) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
formData.value = { label: data.label };
|
|
||||||
currentMode.value = 'Modify';
|
|
||||||
modifyParentUuid.value = data.uuid;
|
|
||||||
console.log('修改', data);
|
|
||||||
showDataModal.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFormSubmit = async (e: MouseEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
console.log('当前模式:', currentMode.value);
|
|
||||||
formRef.value?.validate(async (errors) => {
|
|
||||||
if (!errors) {
|
|
||||||
console.log('提交', formData.value);
|
|
||||||
try {
|
|
||||||
if (currentMode.value === 'Add' && formData.value.value) {
|
|
||||||
const result = await addParentDict({ label: formData.value.label, value: formData.value.value });
|
|
||||||
console.log(result);
|
|
||||||
message.success('新增成功');
|
|
||||||
} else if (currentMode.value === 'Modify') {
|
|
||||||
const result = await updateParentDict(modifyParentUuid.value, formData.value);
|
|
||||||
console.log(result);
|
|
||||||
message.success('修改成功');
|
|
||||||
}
|
|
||||||
handleFindParent(navSearch.value);
|
|
||||||
} catch (error) {
|
|
||||||
console.log('提交失败', error);
|
|
||||||
message.error('提交失败');
|
|
||||||
} finally {
|
|
||||||
modifyParentUuid.value = '';
|
|
||||||
showDataModal.value = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('表单信息不完整', errors);
|
|
||||||
message.error('表单信息不完整');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除相关逻辑
|
|
||||||
const showDeleteModal = ref(false);
|
|
||||||
const deleteData = ref<DictRow | null>(null);
|
|
||||||
|
|
||||||
const handleDeleteParent = (e: MouseEvent, data: DictRow) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
console.log('删除', data);
|
|
||||||
deleteData.value = data;
|
|
||||||
showDeleteModal.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleDeleteSubmit = async () => {
|
|
||||||
console.log('submit delete ', deleteData);
|
|
||||||
try {
|
|
||||||
await deleteParentDict(deleteData.value.uuid);
|
|
||||||
if (deleteData.value.uuid === parentProps.parentUuid) {
|
|
||||||
emit('update:parentUuid', '');
|
|
||||||
emit('update:parentValue', '');
|
|
||||||
emit('update:parentTitle', '');
|
|
||||||
}
|
|
||||||
message.success('删除成功');
|
|
||||||
handleFindParent(navSearch.value);
|
|
||||||
} catch (error) {
|
|
||||||
console.log('删除失败', error);
|
|
||||||
message.error('删除失败');
|
|
||||||
} finally {
|
|
||||||
showDataModal.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const navSearch = ref('');
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.dict-nav {
|
|
||||||
width: 280px;
|
|
||||||
min-width: 280px;
|
|
||||||
height: 100%;
|
|
||||||
padding: $normolGap;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: $bigGap;
|
|
||||||
background-color: #fff;
|
|
||||||
border-right: 1px solid $dashLineColor;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
|
|
||||||
&__search {
|
|
||||||
.n-input {
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
:deep(.n-input__border) {
|
|
||||||
border-color: $dashLineColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.n-input__state-border) {
|
|
||||||
border-color: $primaryColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__action {
|
|
||||||
.dict-nav__add-btn {
|
|
||||||
background-color: $primaryColor;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $primaryColorHover;
|
|
||||||
box-shadow: 0 2px 8px rgba($primaryColor, 0.3);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: $primaryColorPressed;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__list {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid $dashLineColor;
|
|
||||||
|
|
||||||
.n-list {
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
|
|
||||||
.n-list-item {
|
|
||||||
padding: 0;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
|
|
||||||
&:not(:last-child) {
|
|
||||||
border-bottom: 1px solid $dashLineColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&-content {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
padding: $smallGap $normolGap;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-icon {
|
|
||||||
margin-right: $smallGap;
|
|
||||||
color: $primaryColor;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-label {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
padding-right: $bigGap;
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-actions {
|
|
||||||
position: absolute;
|
|
||||||
right: $smallGap;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
display: flex;
|
|
||||||
gap: $miniGap;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba($primaryColor, 0.05);
|
|
||||||
|
|
||||||
.dict-nav__item-label {
|
|
||||||
padding-right: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dict-nav__item-actions {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--active {
|
|
||||||
background-color: rgba($primaryColor, 0.1);
|
|
||||||
border-left: 3px solid $primaryColor;
|
|
||||||
|
|
||||||
.dict-nav__item-label {
|
|
||||||
font-weight: 600;
|
|
||||||
color: $primaryColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dict-nav__item-icon {
|
|
||||||
color: $primaryColorSuppl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__action-btn {
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: rgba(#fff, 0.8);
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
|
|
||||||
.n-icon {
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--modify {
|
|
||||||
color: #666;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba($primaryColor, 0.15);
|
|
||||||
color: $primaryColor;
|
|
||||||
|
|
||||||
.n-icon {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--delete {
|
|
||||||
color: #999;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(#ff4d4f, 0.15);
|
|
||||||
color: #ff4d4f;
|
|
||||||
|
|
||||||
.n-icon {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,25 +1,24 @@
|
|||||||
<!-- 用户字典 -->
|
<!-- 用户字典 -->
|
||||||
<template>
|
<template>
|
||||||
<!-- 左右布局,左侧为占15%的nav,右侧为占据75%的main -->
|
<!-- 左右布局,左侧为占25%的nav,右侧为占据75%的main -->
|
||||||
<div class="main__container white-bg table dict-container">
|
<div class="main__container white-bg table">
|
||||||
<DictNav v-model:parentUuid="currentUuid" v-model:parentValue="currentKey" v-model:parentTitle="currentTitle" />
|
<!-- 侧边字典属性结构 -->
|
||||||
<DictMain :uuid="currentUuid" :value="currentKey" :label="currentTitle" />
|
<nav class="dict-nav">
|
||||||
|
<!-- 要求可以搜索 -->
|
||||||
|
<n-input v-model:value="search"></n-input>
|
||||||
|
<!-- 树结构 右侧要能够删除 -->
|
||||||
|
<n-tree></n-tree>
|
||||||
|
</nav>
|
||||||
|
<main class="dict-nav">
|
||||||
|
<!-- 上面有一排操作按钮:input框查询 查询按钮,新增 -->
|
||||||
|
<!-- 字典表格,含有字段:字典id,字典名称,字典值,字典标签,操作列(编辑 删除) -->
|
||||||
|
<n-table></n-table>
|
||||||
|
</main>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import DictMain from './components/DictMain.vue';
|
const search = ref('');
|
||||||
import DictNav from './components/DictNav.vue';
|
|
||||||
|
|
||||||
const currentUuid = ref('')
|
|
||||||
const currentKey = ref('')
|
|
||||||
const currentTitle = ref('')
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped lang='scss'></style>
|
||||||
<style scoped lang='scss'>
|
|
||||||
.dict-container {
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Loading…
x
Reference in New Issue
Block a user