feat(product): 新增产品管理模块与字典组件功能
- 新增产品管理相关路由和页面(dashboard、list、requirement、setting) - 实现产品基础信息编辑弹窗组件(base-info-dialog.vue) - 添加运行时字典功能(dict-select、dict-text、dict-tag组件) - 集成字典管理store和API调用 - 规范ID类型定义为string避免精度丢失问题 - 完善国际化资源文件支持中英文对照 - 新增对象上下文业务域入口页导航实现说明 - 添加Vue DevTools浮动入口注释说明 - 统一权限控制支持全局和对象作用域区分 - 规范分页查询参数类型定义与使用方式
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
import { useObjectContextStore } from '@/store/modules/object-context';
|
||||
|
||||
export function useAuth() {
|
||||
const authStore = useAuthStore();
|
||||
const objectContextStore = useObjectContextStore();
|
||||
|
||||
function hasAuth(codes: string | string[]) {
|
||||
if (!authStore.isLogin) {
|
||||
@@ -15,7 +17,14 @@ export function useAuth() {
|
||||
return codes.some(code => authStore.userInfo.buttons.includes(code));
|
||||
}
|
||||
|
||||
function hasObjectAuth(codes: string | string[]) {
|
||||
const targetCodes = typeof codes === 'string' ? [codes] : codes;
|
||||
|
||||
return targetCodes.some(code => objectContextStore.buttonCodes.includes(code));
|
||||
}
|
||||
|
||||
return {
|
||||
hasAuth
|
||||
hasAuth,
|
||||
hasObjectAuth
|
||||
};
|
||||
}
|
||||
|
||||
86
src/hooks/business/dict.ts
Normal file
86
src/hooks/business/dict.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { computed, toValue } from 'vue';
|
||||
import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
type DictCode = string | Ref<string> | ComputedRef<string>;
|
||||
type DictValue = string | number | null | undefined;
|
||||
type DictValueList = Array<DictValue> | null | undefined;
|
||||
type DictFilterOptions = {
|
||||
onlyEnabled?: boolean;
|
||||
};
|
||||
type DictLabelOptions = string | (DictFilterOptions & { fallback?: string });
|
||||
type DictLabelsOptions = string | (DictFilterOptions & { fallback?: string; separator?: string });
|
||||
|
||||
function normalizeLabelOptions(options?: DictLabelOptions) {
|
||||
if (typeof options === 'string') {
|
||||
return {
|
||||
fallback: options,
|
||||
onlyEnabled: false
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
fallback: options?.fallback ?? '--',
|
||||
onlyEnabled: options?.onlyEnabled ?? false
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeLabelsOptions(options?: DictLabelsOptions) {
|
||||
if (typeof options === 'string') {
|
||||
return {
|
||||
fallback: options,
|
||||
separator: ' / ',
|
||||
onlyEnabled: false
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
fallback: options?.fallback ?? '--',
|
||||
separator: options?.separator ?? ' / ',
|
||||
onlyEnabled: options?.onlyEnabled ?? false
|
||||
};
|
||||
}
|
||||
|
||||
export function useDict(dictCode: DictCode | MaybeRefOrGetter<string>) {
|
||||
const dictStore = useDictStore();
|
||||
|
||||
const currentDictCode = computed(() => toValue(dictCode));
|
||||
|
||||
const dictData = computed(() => dictStore.getDictData(currentDictCode.value));
|
||||
const enabledDictData = computed(() => dictStore.getDictData(currentDictCode.value, true));
|
||||
const dictOptions = computed(() => dictStore.getDictOptions(currentDictCode.value));
|
||||
const dictMap = computed(() => new Map(dictData.value.map(item => [item.value, item])));
|
||||
const enabledDictMap = computed(() => new Map(enabledDictData.value.map(item => [item.value, item])));
|
||||
|
||||
function getItem(value?: DictValue, options: DictFilterOptions = {}) {
|
||||
return dictStore.getDictItem(currentDictCode.value, value, options);
|
||||
}
|
||||
|
||||
function getLabel(value?: DictValue, options?: DictLabelOptions) {
|
||||
const normalizedOptions = normalizeLabelOptions(options);
|
||||
|
||||
return dictStore.getDictLabel(currentDictCode.value, value, normalizedOptions);
|
||||
}
|
||||
|
||||
function getLabels(values?: DictValueList, options?: DictLabelsOptions) {
|
||||
const normalizedOptions = normalizeLabelsOptions(options);
|
||||
|
||||
return dictStore.getDictLabels(currentDictCode.value, values, normalizedOptions);
|
||||
}
|
||||
|
||||
function hasValue(value?: DictValue, options: DictFilterOptions = {}) {
|
||||
return dictStore.hasDictValue(currentDictCode.value, value, options);
|
||||
}
|
||||
|
||||
return {
|
||||
dictData,
|
||||
enabledDictData,
|
||||
dictOptions,
|
||||
dictMap,
|
||||
enabledDictMap,
|
||||
getItem,
|
||||
getLabel,
|
||||
getLabels,
|
||||
hasValue
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import type { RouteLocationRaw } from 'vue-router';
|
||||
import type { RouteKey } from '@elegant-router/types';
|
||||
import { router as globalRouter } from '@/router';
|
||||
import { getGlobalRouter } from '@/router/instance';
|
||||
|
||||
/**
|
||||
* Router push
|
||||
@@ -11,6 +11,7 @@ import { router as globalRouter } from '@/router';
|
||||
* @param inSetup Whether is in vue script setup
|
||||
*/
|
||||
export function useRouterPush(inSetup = true) {
|
||||
const globalRouter = getGlobalRouter();
|
||||
const router = inSetup ? useRouter() : globalRouter;
|
||||
const route = globalRouter.currentRoute;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user