chore: 优化字典hooks使用
This commit is contained in:
parent
2b14b84c67
commit
9cbbaff297
@ -9,7 +9,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
immediate: true
|
immediate: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const value = defineModel<string | null>('value', { required: false });
|
const value = defineModel<string | null>('value', { required: false });
|
||||||
|
@ -12,7 +12,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
immediate: true
|
immediate: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const value = defineModel<string | null>('value', { required: true });
|
const value = defineModel<string | null>('value', { required: true });
|
||||||
|
30
src/components/custom/dict-tag.vue
Normal file
30
src/components/custom/dict-tag.vue
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, useAttrs } from 'vue';
|
||||||
|
import type { TagProps } from 'naive-ui';
|
||||||
|
import { useDict } from '@/hooks/business/dict';
|
||||||
|
|
||||||
|
defineOptions({ name: 'DictTag' });
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
value: string;
|
||||||
|
dictCode: string;
|
||||||
|
immediate?: boolean;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const attrs: TagProps = useAttrs();
|
||||||
|
const { transformDictData } = useDict(props.dictCode, props.immediate);
|
||||||
|
const dictData = computed(() => transformDictData(props.value));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NTag v-if="dictData" :class="dictData.cssClass" :type="dictData.listClass" v-bind="attrs">
|
||||||
|
{{ dictData.dictLabel }}
|
||||||
|
</NTag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@ -40,6 +40,11 @@ export function useDict(dictType: string, immediate: boolean = true) {
|
|||||||
options.value = data.value.map(dict => ({ label: dict.dictLabel!, value: dict.dictValue! }));
|
options.value = data.value.map(dict => ({ label: dict.dictLabel!, value: dict.dictValue! }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function transformDictData(dictValue: string): Api.System.DictData | undefined {
|
||||||
|
if (!data.value.length || !dictValue) return undefined;
|
||||||
|
return data.value.find(dict => dict.dictValue === dictValue);
|
||||||
|
}
|
||||||
|
|
||||||
if (immediate) {
|
if (immediate) {
|
||||||
getData().then(() => {
|
getData().then(() => {
|
||||||
getRecord();
|
getRecord();
|
||||||
@ -64,6 +69,7 @@ export function useDict(dictType: string, immediate: boolean = true) {
|
|||||||
options,
|
options,
|
||||||
getData,
|
getData,
|
||||||
getRecord,
|
getRecord,
|
||||||
getOptions
|
getOptions,
|
||||||
|
transformDictData
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
5
src/styles/scss/custom.scss
Normal file
5
src/styles/scss/custom.scss
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.table-search {
|
||||||
|
.n-collapse {
|
||||||
|
--n-title-font-size: 15px !important;
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
@import './scrollbar.scss';
|
@import './scrollbar.scss';
|
||||||
|
@import './custom.scss';
|
||||||
|
2
src/typings/api/system.api.d.ts
vendored
2
src/typings/api/system.api.d.ts
vendored
@ -270,7 +270,7 @@ declare namespace Api {
|
|||||||
/** 是否默认(Y是 N否) */
|
/** 是否默认(Y是 N否) */
|
||||||
isDefault: string;
|
isDefault: string;
|
||||||
/** 表格回显样式 */
|
/** 表格回显样式 */
|
||||||
listClass: string;
|
listClass: NaiveUI.ThemeColor;
|
||||||
/** 备注 */
|
/** 备注 */
|
||||||
remark: string;
|
remark: string;
|
||||||
}>;
|
}>;
|
||||||
|
1
src/typings/components.d.ts
vendored
1
src/typings/components.d.ts
vendored
@ -16,6 +16,7 @@ declare module 'vue' {
|
|||||||
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
|
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
|
||||||
DictRadio: typeof import('./../components/custom/dict-radio.vue')['default']
|
DictRadio: typeof import('./../components/custom/dict-radio.vue')['default']
|
||||||
DictSelect: typeof import('./../components/custom/dict-select.vue')['default']
|
DictSelect: typeof import('./../components/custom/dict-select.vue')['default']
|
||||||
|
DictTag: typeof import('./../components/custom/dict-tag.vue')['default']
|
||||||
ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
|
ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
|
||||||
FullScreen: typeof import('./../components/common/full-screen.vue')['default']
|
FullScreen: typeof import('./../components/common/full-screen.vue')['default']
|
||||||
IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
|
IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
|
||||||
|
@ -4,16 +4,19 @@ import { useBoolean, useLoading } from '@sa/hooks';
|
|||||||
import type { DataTableColumns, TreeInst, TreeOption } from 'naive-ui';
|
import type { DataTableColumns, TreeInst, TreeOption } from 'naive-ui';
|
||||||
import { NButton, NIcon, NInput, NPopconfirm, NTooltip } from 'naive-ui';
|
import { NButton, NIcon, NInput, NPopconfirm, NTooltip } from 'naive-ui';
|
||||||
import { fetchDeleteMenu, fetchGetMenuList } from '@/service/api/system';
|
import { fetchDeleteMenu, fetchGetMenuList } from '@/service/api/system';
|
||||||
import SvgIcon from '@/components/custom/svg-icon.vue';
|
|
||||||
import { useAppStore } from '@/store/modules/app';
|
import { useAppStore } from '@/store/modules/app';
|
||||||
import { menuIsFrameRecord, menuTypeRecord } from '@/constants/business';
|
import { menuIsFrameRecord, menuTypeRecord } from '@/constants/business';
|
||||||
import ButtonIcon from '@/components/custom/button-icon.vue';
|
|
||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import { handleMenuTree } from '@/utils/ruoyi';
|
import { handleMenuTree } from '@/utils/ruoyi';
|
||||||
import StatusTag from '@/components/custom/status-tag.vue';
|
|
||||||
import { useDict } from '@/hooks/business/dict';
|
import { useDict } from '@/hooks/business/dict';
|
||||||
|
import SvgIcon from '@/components/custom/svg-icon.vue';
|
||||||
|
import DictTag from '@/components/custom/dict-tag.vue';
|
||||||
|
import ButtonIcon from '@/components/custom/button-icon.vue';
|
||||||
import MenuOperateDrawer from './modules/menu-operate-drawer.vue';
|
import MenuOperateDrawer from './modules/menu-operate-drawer.vue';
|
||||||
|
|
||||||
|
useDict('sys_show_hide');
|
||||||
|
useDict('sys_normal_disable');
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const editingData = ref<Api.System.Menu>();
|
const editingData = ref<Api.System.Menu>();
|
||||||
const operateType = ref<NaiveUI.TableOperateType>('add');
|
const operateType = ref<NaiveUI.TableOperateType>('add');
|
||||||
@ -207,7 +210,7 @@ const btnColumns: DataTableColumns<Api.System.Menu> = [
|
|||||||
minWidth: 80,
|
minWidth: 80,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render(row) {
|
render(row) {
|
||||||
return <StatusTag size="small" value={row.status} />;
|
return <DictTag size="small" value={row.status} dict-code="sys_normal_disable" />;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -259,8 +262,6 @@ const btnColumns: DataTableColumns<Api.System.Menu> = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const { record: showHideRecord } = useDict('sys_show_hide');
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -367,7 +368,7 @@ const { record: showHideRecord } = useDict('sys_show_hide');
|
|||||||
<NTag size="small" type="primary">{{ menuTypeRecord[currentMenu.menuType!] }}</NTag>
|
<NTag size="small" type="primary">{{ menuTypeRecord[currentMenu.menuType!] }}</NTag>
|
||||||
</NDescriptionsItem>
|
</NDescriptionsItem>
|
||||||
<NDescriptionsItem label="菜单状态">
|
<NDescriptionsItem label="菜单状态">
|
||||||
<StatusTag size="small" :value="currentMenu.status" />
|
<DictTag size="small" :value="currentMenu.status" dict-code="sys_normal_disable" />
|
||||||
</NDescriptionsItem>
|
</NDescriptionsItem>
|
||||||
<NDescriptionsItem label="菜单名称">{{ currentMenu.menuName }}</NDescriptionsItem>
|
<NDescriptionsItem label="菜单名称">{{ currentMenu.menuName }}</NDescriptionsItem>
|
||||||
<NDescriptionsItem v-if="currentMenu.menuType === 'C'" label="组件路径">
|
<NDescriptionsItem v-if="currentMenu.menuType === 'C'" label="组件路径">
|
||||||
@ -391,9 +392,7 @@ const { record: showHideRecord } = useDict('sys_show_hide');
|
|||||||
</NTag>
|
</NTag>
|
||||||
</NDescriptionsItem>
|
</NDescriptionsItem>
|
||||||
<NDescriptionsItem label="显示状态">
|
<NDescriptionsItem label="显示状态">
|
||||||
<NTag v-if="currentMenu.visible" size="small" :type="tagMap[currentMenu.visible]">
|
<DictTag size="small" :value="currentMenu.visible" dict-code="sys_show_hide" />
|
||||||
{{ showHideRecord[currentMenu.visible] }}
|
|
||||||
</NTag>
|
|
||||||
</NDescriptionsItem>
|
</NDescriptionsItem>
|
||||||
<NDescriptionsItem v-if="currentMenu.menuType === 'C'" label="是否缓存">
|
<NDescriptionsItem v-if="currentMenu.menuType === 'C'" label="是否缓存">
|
||||||
<NTag v-if="currentMenu.isCache" size="small" :type="tagMap[currentMenu.isCache]">
|
<NTag v-if="currentMenu.isCache" size="small" :type="tagMap[currentMenu.isCache]">
|
||||||
|
@ -9,7 +9,6 @@ import { menuIconTypeOptions, menuIsFrameOptions, menuTypeOptions } from '@/cons
|
|||||||
import SvgIcon from '@/components/custom/svg-icon.vue';
|
import SvgIcon from '@/components/custom/svg-icon.vue';
|
||||||
import { getLocalMenuIcons } from '@/utils/icon';
|
import { getLocalMenuIcons } from '@/utils/icon';
|
||||||
import { humpToLine, isNotNull } from '@/utils/common';
|
import { humpToLine, isNotNull } from '@/utils/common';
|
||||||
import { useDict } from '@/hooks/business/dict';
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'MenuOperateDrawer'
|
name: 'MenuOperateDrawer'
|
||||||
@ -40,9 +39,6 @@ const visible = defineModel<boolean>('visible', {
|
|||||||
default: false
|
default: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const { options: showHideOptions } = useDict('sys_show_hide', false);
|
|
||||||
const { options: enableStatusOptions } = useDict('sys_normal_disable');
|
|
||||||
|
|
||||||
const iconType = ref<Api.System.IconType>('1');
|
const iconType = ref<Api.System.IconType>('1');
|
||||||
const { formRef, validate, restoreValidation } = useNaiveForm();
|
const { formRef, validate, restoreValidation } = useNaiveForm();
|
||||||
const { createRequiredRule } = useFormRules();
|
const { createRequiredRule } = useFormRules();
|
||||||
@ -411,11 +407,7 @@ const FormTipComponent = defineComponent({
|
|||||||
<span class="pl-3px">显示状态</span>
|
<span class="pl-3px">显示状态</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<NRadioGroup v-model:value="model.visible">
|
<DictRadio v-model:value="model.visible" dict-code="sys_show_hide" />
|
||||||
<NSpace>
|
|
||||||
<NRadio v-for="item in showHideOptions" :key="item.value" :value="item.value" :label="item.label" />
|
|
||||||
</NSpace>
|
|
||||||
</NRadioGroup>
|
|
||||||
</NFormItemGi>
|
</NFormItemGi>
|
||||||
<NFormItemGi :span="12" path="status">
|
<NFormItemGi :span="12" path="status">
|
||||||
<template #label>
|
<template #label>
|
||||||
@ -424,11 +416,7 @@ const FormTipComponent = defineComponent({
|
|||||||
<span class="pl-3px">菜单状态</span>
|
<span class="pl-3px">菜单状态</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<NRadioGroup v-model:value="model.status">
|
<DictRadio v-model:value="model.status" dict-code="sys_normal_disable" />
|
||||||
<NSpace>
|
|
||||||
<NRadio v-for="item in enableStatusOptions" :key="item.value" :value="item.value" :label="item.label" />
|
|
||||||
</NSpace>
|
|
||||||
</NRadioGroup>
|
|
||||||
</NFormItemGi>
|
</NFormItemGi>
|
||||||
<NFormItemGi :span="12" label="显示排序" path="orderNum">
|
<NFormItemGi :span="12" label="显示排序" path="orderNum">
|
||||||
<NInputNumber v-model:value="model.orderNum" placeholder="请输入排序" />
|
<NInputNumber v-model:value="model.orderNum" placeholder="请输入排序" />
|
||||||
|
@ -4,6 +4,8 @@ import { fetchBatchDeleteUser, fetchGetUserList } from '@/service/api/system';
|
|||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import { useAppStore } from '@/store/modules/app';
|
import { useAppStore } from '@/store/modules/app';
|
||||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||||
|
import DictTag from '@/components/custom/dict-tag.vue';
|
||||||
|
import { useDict } from '@/hooks/business/dict';
|
||||||
import UserOperateDrawer from './modules/user-operate-drawer.vue';
|
import UserOperateDrawer from './modules/user-operate-drawer.vue';
|
||||||
import UserSearch from './modules/user-search.vue';
|
import UserSearch from './modules/user-search.vue';
|
||||||
|
|
||||||
@ -11,6 +13,9 @@ defineOptions({
|
|||||||
name: 'UserList'
|
name: 'UserList'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useDict('sys_user_sex');
|
||||||
|
useDict('sys_normal_disable');
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -49,35 +54,42 @@ const {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
width: 64
|
width: 64
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'deptId',
|
|
||||||
title: '部门',
|
|
||||||
align: 'center',
|
|
||||||
minWidth: 120
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'userName',
|
key: 'userName',
|
||||||
title: '用户名称',
|
title: '用户名称',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
minWidth: 120
|
minWidth: 120,
|
||||||
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'nickName',
|
key: 'nickName',
|
||||||
title: '用户昵称',
|
title: '用户昵称',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
minWidth: 120
|
minWidth: 120,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'deptName',
|
||||||
|
title: '部门',
|
||||||
|
align: 'center',
|
||||||
|
minWidth: 120,
|
||||||
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'phonenumber',
|
key: 'phonenumber',
|
||||||
title: '手机号码',
|
title: '手机号码',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
minWidth: 120
|
minWidth: 120,
|
||||||
|
ellipsis: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'status',
|
key: 'status',
|
||||||
title: '帐号状态',
|
title: '状态',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
minWidth: 120
|
minWidth: 80,
|
||||||
|
render(row) {
|
||||||
|
return <DictTag size="small" value={row.status} dict-code="sys_normal_disable" />;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'createTime',
|
key: 'createTime',
|
||||||
@ -85,12 +97,6 @@ const {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
minWidth: 120
|
minWidth: 120
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'remark',
|
|
||||||
title: '备注',
|
|
||||||
align: 'center',
|
|
||||||
minWidth: 120
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'operate',
|
key: 'operate',
|
||||||
title: $t('common.operate'),
|
title: $t('common.operate'),
|
||||||
@ -142,7 +148,7 @@ async function edit(userId: CommonType.IdType) {
|
|||||||
<template>
|
<template>
|
||||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||||
<UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
<UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||||
<NCard title="用户信息列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
<NCard title="用户列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<TableHeaderOperation
|
<TableHeaderOperation
|
||||||
v-model:columns="columnChecks"
|
v-model:columns="columnChecks"
|
||||||
|
@ -155,8 +155,8 @@ watch(visible, () => {
|
|||||||
<NFormItem label="密码" path="password">
|
<NFormItem label="密码" path="password">
|
||||||
<NInput v-model:value="model.password" placeholder="请输入密码" />
|
<NInput v-model:value="model.password" placeholder="请输入密码" />
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NFormItem label="帐号状态" path="status">
|
<NFormItem label="状态" path="status">
|
||||||
<NInput v-model:value="model.status" placeholder="请输入帐号状态" />
|
<DictRadio v-model:value="model.status" dict-code="sys_normal_disable" />
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NFormItem label="备注" path="remark">
|
<NFormItem label="备注" path="remark">
|
||||||
<NInput v-model:value="model.remark" placeholder="请输入备注" />
|
<NInput v-model:value="model.remark" placeholder="请输入备注" />
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import { useNaiveForm } from '@/hooks/common/form';
|
import { useNaiveForm } from '@/hooks/common/form';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'UserSearch'
|
name: 'UserSearch'
|
||||||
});
|
});
|
||||||
@ -36,7 +37,7 @@ async function search() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NCard :bordered="false" size="small" class="card-wrapper">
|
<NCard :bordered="false" size="small" class="table-search card-wrapper">
|
||||||
<NCollapse>
|
<NCollapse>
|
||||||
<NCollapseItem :title="$t('common.search')" name="user-search">
|
<NCollapseItem :title="$t('common.search')" name="user-search">
|
||||||
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
|
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
|
||||||
@ -51,9 +52,14 @@ async function search() {
|
|||||||
<NInput v-model:value="model.phonenumber" placeholder="请输入手机号码" />
|
<NInput v-model:value="model.phonenumber" placeholder="请输入手机号码" />
|
||||||
</NFormItemGi>
|
</NFormItemGi>
|
||||||
<NFormItemGi span="24 s:12 m:6" label="帐号状态" path="status" class="pr-24px">
|
<NFormItemGi span="24 s:12 m:6" label="帐号状态" path="status" class="pr-24px">
|
||||||
<NSelect v-model:value="model.status" placeholder="请选择帐号状态" :options="[]" clearable />
|
<DictSelect
|
||||||
|
v-model:value="model.status"
|
||||||
|
placeholder="请选择帐号状态"
|
||||||
|
dict-code="sys_normal_disable"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
</NFormItemGi>
|
</NFormItemGi>
|
||||||
<NFormItemGi span="24 s:12 m:6" label="创建时间" path="createTime" class="pr-24px">
|
<NFormItemGi span="24 s:12 m:8" label="创建时间" path="createTime" class="pr-24px">
|
||||||
<NDatePicker
|
<NDatePicker
|
||||||
v-model:formatted-value="dateRangeCreateTime"
|
v-model:formatted-value="dateRangeCreateTime"
|
||||||
type="datetimerange"
|
type="datetimerange"
|
||||||
@ -61,7 +67,7 @@ async function search() {
|
|||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</NFormItemGi>
|
</NFormItemGi>
|
||||||
<NFormItemGi span="24" class="pr-24px">
|
<NFormItemGi span="24 s:12 m:16" class="pr-24px">
|
||||||
<NSpace class="w-full" justify="end">
|
<NSpace class="w-full" justify="end">
|
||||||
<NButton @click="reset">
|
<NButton @click="reset">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
|
Loading…
Reference in New Issue
Block a user