Compare commits
5 Commits
8b26aed763
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| dc4b6ac8c5 | |||
| dc32422965 | |||
| bd631f49d0 | |||
| 2c96c788fe | |||
| ae6d08fbe5 |
275
docs/.vitepress/cache/deps/@theme_index.js
vendored
275
docs/.vitepress/cache/deps/@theme_index.js
vendored
@@ -1,275 +0,0 @@
|
||||
import {
|
||||
useMediaQuery
|
||||
} from "./chunk-AAVY4YN3.js";
|
||||
import {
|
||||
computed,
|
||||
ref,
|
||||
shallowRef,
|
||||
watch
|
||||
} from "./chunk-JD3CXNQ6.js";
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/index.js
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/fonts.css";
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/without-fonts.js
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/vars.css";
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/base.css";
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/icons.css";
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/utils.css";
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/components/custom-block.css";
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code.css";
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code-group.css";
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/components/vp-doc.css";
|
||||
import "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/styles/components/vp-sponsor.css";
|
||||
import VPBadge from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
|
||||
import Layout from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/Layout.vue";
|
||||
import { default as default2 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
|
||||
import { default as default3 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPButton.vue";
|
||||
import { default as default4 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue";
|
||||
import { default as default5 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPFeatures.vue";
|
||||
import { default as default6 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPHomeContent.vue";
|
||||
import { default as default7 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue";
|
||||
import { default as default8 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue";
|
||||
import { default as default9 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue";
|
||||
import { default as default10 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPImage.vue";
|
||||
import { default as default11 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPLink.vue";
|
||||
import { default as default12 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearch.vue";
|
||||
import { default as default13 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPSocialLink.vue";
|
||||
import { default as default14 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPSocialLinks.vue";
|
||||
import { default as default15 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue";
|
||||
import { default as default16 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue";
|
||||
import { default as default17 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue";
|
||||
import { default as default18 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue";
|
||||
import { default as default19 } from "C:/repos/flower-rain/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue";
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/local-nav.js
|
||||
import { onContentUpdated } from "vitepress";
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/outline.js
|
||||
import { getScrollOffset } from "vitepress";
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/support/utils.js
|
||||
import { withBase } from "vitepress";
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/data.js
|
||||
import { useData as useData$ } from "vitepress";
|
||||
var useData = useData$;
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/support/utils.js
|
||||
function ensureStartingSlash(path) {
|
||||
return path.startsWith("/") ? path : `/${path}`;
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/support/sidebar.js
|
||||
function getSidebar(_sidebar, path) {
|
||||
if (Array.isArray(_sidebar))
|
||||
return addBase(_sidebar);
|
||||
if (_sidebar == null)
|
||||
return [];
|
||||
path = ensureStartingSlash(path);
|
||||
const dir = Object.keys(_sidebar).sort((a, b) => {
|
||||
return b.split("/").length - a.split("/").length;
|
||||
}).find((dir2) => {
|
||||
return path.startsWith(ensureStartingSlash(dir2));
|
||||
});
|
||||
const sidebar = dir ? _sidebar[dir] : [];
|
||||
return Array.isArray(sidebar) ? addBase(sidebar) : addBase(sidebar.items, sidebar.base);
|
||||
}
|
||||
function getSidebarGroups(sidebar) {
|
||||
const groups = [];
|
||||
let lastGroupIndex = 0;
|
||||
for (const index in sidebar) {
|
||||
const item = sidebar[index];
|
||||
if (item.items) {
|
||||
lastGroupIndex = groups.push(item);
|
||||
continue;
|
||||
}
|
||||
if (!groups[lastGroupIndex]) {
|
||||
groups.push({ items: [] });
|
||||
}
|
||||
groups[lastGroupIndex].items.push(item);
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
function addBase(items, _base) {
|
||||
return [...items].map((_item) => {
|
||||
const item = { ..._item };
|
||||
const base = item.base || _base;
|
||||
if (base && item.link)
|
||||
item.link = base + item.link;
|
||||
if (item.items)
|
||||
item.items = addBase(item.items, base);
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/sidebar.js
|
||||
function useSidebar() {
|
||||
const { frontmatter, page, theme: theme2 } = useData();
|
||||
const is960 = useMediaQuery("(min-width: 960px)");
|
||||
const isOpen = ref(false);
|
||||
const _sidebar = computed(() => {
|
||||
const sidebarConfig = theme2.value.sidebar;
|
||||
const relativePath = page.value.relativePath;
|
||||
return sidebarConfig ? getSidebar(sidebarConfig, relativePath) : [];
|
||||
});
|
||||
const sidebar = ref(_sidebar.value);
|
||||
watch(_sidebar, (next, prev) => {
|
||||
if (JSON.stringify(next) !== JSON.stringify(prev))
|
||||
sidebar.value = _sidebar.value;
|
||||
});
|
||||
const hasSidebar = computed(() => {
|
||||
return frontmatter.value.sidebar !== false && sidebar.value.length > 0 && frontmatter.value.layout !== "home";
|
||||
});
|
||||
const leftAside = computed(() => {
|
||||
if (hasAside)
|
||||
return frontmatter.value.aside == null ? theme2.value.aside === "left" : frontmatter.value.aside === "left";
|
||||
return false;
|
||||
});
|
||||
const hasAside = computed(() => {
|
||||
if (frontmatter.value.layout === "home")
|
||||
return false;
|
||||
if (frontmatter.value.aside != null)
|
||||
return !!frontmatter.value.aside;
|
||||
return theme2.value.aside !== false;
|
||||
});
|
||||
const isSidebarEnabled = computed(() => hasSidebar.value && is960.value);
|
||||
const sidebarGroups = computed(() => {
|
||||
return hasSidebar.value ? getSidebarGroups(sidebar.value) : [];
|
||||
});
|
||||
function open() {
|
||||
isOpen.value = true;
|
||||
}
|
||||
function close() {
|
||||
isOpen.value = false;
|
||||
}
|
||||
function toggle() {
|
||||
isOpen.value ? close() : open();
|
||||
}
|
||||
return {
|
||||
isOpen,
|
||||
sidebar,
|
||||
sidebarGroups,
|
||||
hasSidebar,
|
||||
hasAside,
|
||||
leftAside,
|
||||
isSidebarEnabled,
|
||||
open,
|
||||
close,
|
||||
toggle
|
||||
};
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/outline.js
|
||||
var ignoreRE = /\b(?:VPBadge|header-anchor|footnote-ref|ignore-header)\b/;
|
||||
var resolvedHeaders = [];
|
||||
function getHeaders(range) {
|
||||
const headers = [
|
||||
...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")
|
||||
].filter((el) => el.id && el.hasChildNodes()).map((el) => {
|
||||
const level = Number(el.tagName[1]);
|
||||
return {
|
||||
element: el,
|
||||
title: serializeHeader(el),
|
||||
link: "#" + el.id,
|
||||
level
|
||||
};
|
||||
});
|
||||
return resolveHeaders(headers, range);
|
||||
}
|
||||
function serializeHeader(h) {
|
||||
let ret = "";
|
||||
for (const node of h.childNodes) {
|
||||
if (node.nodeType === 1) {
|
||||
if (ignoreRE.test(node.className))
|
||||
continue;
|
||||
ret += node.textContent;
|
||||
} else if (node.nodeType === 3) {
|
||||
ret += node.textContent;
|
||||
}
|
||||
}
|
||||
return ret.trim();
|
||||
}
|
||||
function resolveHeaders(headers, range) {
|
||||
if (range === false) {
|
||||
return [];
|
||||
}
|
||||
const levelsRange = (typeof range === "object" && !Array.isArray(range) ? range.level : range) || 2;
|
||||
const [high, low] = typeof levelsRange === "number" ? [levelsRange, levelsRange] : levelsRange === "deep" ? [2, 6] : levelsRange;
|
||||
return buildTree(headers, high, low);
|
||||
}
|
||||
function buildTree(data, min, max) {
|
||||
resolvedHeaders.length = 0;
|
||||
const result = [];
|
||||
const stack = [];
|
||||
data.forEach((item) => {
|
||||
const node = { ...item, children: [] };
|
||||
let parent = stack[stack.length - 1];
|
||||
while (parent && parent.level >= node.level) {
|
||||
stack.pop();
|
||||
parent = stack[stack.length - 1];
|
||||
}
|
||||
if (node.element.classList.contains("ignore-header") || parent && "shouldIgnore" in parent) {
|
||||
stack.push({ level: node.level, shouldIgnore: true });
|
||||
return;
|
||||
}
|
||||
if (node.level > max || node.level < min)
|
||||
return;
|
||||
resolvedHeaders.push({ element: node.element, link: node.link });
|
||||
if (parent)
|
||||
parent.children.push(node);
|
||||
else
|
||||
result.push(node);
|
||||
stack.push(node);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/local-nav.js
|
||||
function useLocalNav() {
|
||||
const { theme: theme2, frontmatter } = useData();
|
||||
const headers = shallowRef([]);
|
||||
const hasLocalNav = computed(() => {
|
||||
return headers.value.length > 0;
|
||||
});
|
||||
onContentUpdated(() => {
|
||||
headers.value = getHeaders(frontmatter.value.outline ?? theme2.value.outline);
|
||||
});
|
||||
return {
|
||||
headers,
|
||||
hasLocalNav
|
||||
};
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/without-fonts.js
|
||||
var theme = {
|
||||
Layout,
|
||||
enhanceApp: ({ app }) => {
|
||||
app.component("Badge", VPBadge);
|
||||
}
|
||||
};
|
||||
var without_fonts_default = theme;
|
||||
export {
|
||||
default2 as VPBadge,
|
||||
default3 as VPButton,
|
||||
default4 as VPDocAsideSponsors,
|
||||
default5 as VPFeatures,
|
||||
default6 as VPHomeContent,
|
||||
default7 as VPHomeFeatures,
|
||||
default8 as VPHomeHero,
|
||||
default9 as VPHomeSponsors,
|
||||
default10 as VPImage,
|
||||
default11 as VPLink,
|
||||
default12 as VPNavBarSearch,
|
||||
default13 as VPSocialLink,
|
||||
default14 as VPSocialLinks,
|
||||
default15 as VPSponsors,
|
||||
default16 as VPTeamMembers,
|
||||
default17 as VPTeamPage,
|
||||
default18 as VPTeamPageSection,
|
||||
default19 as VPTeamPageTitle,
|
||||
without_fonts_default as default,
|
||||
useLocalNav,
|
||||
useSidebar
|
||||
};
|
||||
//# sourceMappingURL=@theme_index.js.map
|
||||
40
docs/.vitepress/cache/deps/_metadata.json
vendored
40
docs/.vitepress/cache/deps/_metadata.json
vendored
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"hash": "8c102a36",
|
||||
"configHash": "180cc241",
|
||||
"lockfileHash": "23bc058f",
|
||||
"browserHash": "f63df33a",
|
||||
"optimized": {
|
||||
"vue": {
|
||||
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
|
||||
"file": "vue.js",
|
||||
"fileHash": "3d2f1910",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vitepress > @vue/devtools-api": {
|
||||
"src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
|
||||
"file": "vitepress___@vue_devtools-api.js",
|
||||
"fileHash": "1be5e29d",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vitepress > @vueuse/core": {
|
||||
"src": "../../../../node_modules/vitepress/node_modules/@vueuse/core/index.mjs",
|
||||
"file": "vitepress___@vueuse_core.js",
|
||||
"fileHash": "2e0a6c98",
|
||||
"needsInterop": false
|
||||
},
|
||||
"@theme/index": {
|
||||
"src": "../../../../node_modules/vitepress/dist/client/theme-default/index.js",
|
||||
"file": "@theme_index.js",
|
||||
"fileHash": "7c726b91",
|
||||
"needsInterop": false
|
||||
}
|
||||
},
|
||||
"chunks": {
|
||||
"chunk-AAVY4YN3": {
|
||||
"file": "chunk-AAVY4YN3.js"
|
||||
},
|
||||
"chunk-JD3CXNQ6": {
|
||||
"file": "chunk-JD3CXNQ6.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
3
docs/.vitepress/cache/deps/package.json
vendored
3
docs/.vitepress/cache/deps/package.json
vendored
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,583 +0,0 @@
|
||||
import {
|
||||
DefaultMagicKeysAliasMap,
|
||||
StorageSerializers,
|
||||
TransitionPresets,
|
||||
assert,
|
||||
breakpointsAntDesign,
|
||||
breakpointsBootstrapV5,
|
||||
breakpointsElement,
|
||||
breakpointsMasterCss,
|
||||
breakpointsPrimeFlex,
|
||||
breakpointsQuasar,
|
||||
breakpointsSematic,
|
||||
breakpointsTailwind,
|
||||
breakpointsVuetify,
|
||||
breakpointsVuetifyV2,
|
||||
breakpointsVuetifyV3,
|
||||
bypassFilter,
|
||||
camelize,
|
||||
clamp,
|
||||
cloneFnJSON,
|
||||
computedAsync,
|
||||
computedEager,
|
||||
computedInject,
|
||||
computedWithControl,
|
||||
containsProp,
|
||||
controlledRef,
|
||||
createEventHook,
|
||||
createFetch,
|
||||
createFilterWrapper,
|
||||
createGlobalState,
|
||||
createInjectionState,
|
||||
createRef,
|
||||
createReusableTemplate,
|
||||
createSharedComposable,
|
||||
createSingletonPromise,
|
||||
createTemplatePromise,
|
||||
createUnrefFn,
|
||||
customStorageEventName,
|
||||
debounceFilter,
|
||||
defaultDocument,
|
||||
defaultLocation,
|
||||
defaultNavigator,
|
||||
defaultWindow,
|
||||
executeTransition,
|
||||
extendRef,
|
||||
formatDate,
|
||||
formatTimeAgo,
|
||||
get,
|
||||
getLifeCycleTarget,
|
||||
getSSRHandler,
|
||||
hasOwn,
|
||||
hyphenate,
|
||||
identity,
|
||||
increaseWithUnit,
|
||||
injectLocal,
|
||||
invoke,
|
||||
isClient,
|
||||
isDef,
|
||||
isDefined,
|
||||
isIOS,
|
||||
isObject,
|
||||
isWorker,
|
||||
makeDestructurable,
|
||||
mapGamepadToXbox360Controller,
|
||||
noop,
|
||||
normalizeDate,
|
||||
notNullish,
|
||||
now,
|
||||
objectEntries,
|
||||
objectOmit,
|
||||
objectPick,
|
||||
onClickOutside,
|
||||
onElementRemoval,
|
||||
onKeyDown,
|
||||
onKeyPressed,
|
||||
onKeyStroke,
|
||||
onKeyUp,
|
||||
onLongPress,
|
||||
onStartTyping,
|
||||
pausableFilter,
|
||||
promiseTimeout,
|
||||
provideLocal,
|
||||
provideSSRWidth,
|
||||
pxValue,
|
||||
rand,
|
||||
reactify,
|
||||
reactifyObject,
|
||||
reactiveComputed,
|
||||
reactiveOmit,
|
||||
reactivePick,
|
||||
refAutoReset,
|
||||
refDebounced,
|
||||
refDefault,
|
||||
refThrottled,
|
||||
refWithControl,
|
||||
resolveRef,
|
||||
resolveUnref,
|
||||
set,
|
||||
setSSRHandler,
|
||||
syncRef,
|
||||
syncRefs,
|
||||
templateRef,
|
||||
throttleFilter,
|
||||
timestamp,
|
||||
toArray,
|
||||
toReactive,
|
||||
toRef,
|
||||
toRefs,
|
||||
toValue,
|
||||
tryOnBeforeMount,
|
||||
tryOnBeforeUnmount,
|
||||
tryOnMounted,
|
||||
tryOnScopeDispose,
|
||||
tryOnUnmounted,
|
||||
unrefElement,
|
||||
until,
|
||||
useActiveElement,
|
||||
useAnimate,
|
||||
useArrayDifference,
|
||||
useArrayEvery,
|
||||
useArrayFilter,
|
||||
useArrayFind,
|
||||
useArrayFindIndex,
|
||||
useArrayFindLast,
|
||||
useArrayIncludes,
|
||||
useArrayJoin,
|
||||
useArrayMap,
|
||||
useArrayReduce,
|
||||
useArraySome,
|
||||
useArrayUnique,
|
||||
useAsyncQueue,
|
||||
useAsyncState,
|
||||
useBase64,
|
||||
useBattery,
|
||||
useBluetooth,
|
||||
useBreakpoints,
|
||||
useBroadcastChannel,
|
||||
useBrowserLocation,
|
||||
useCached,
|
||||
useClipboard,
|
||||
useClipboardItems,
|
||||
useCloned,
|
||||
useColorMode,
|
||||
useConfirmDialog,
|
||||
useCountdown,
|
||||
useCounter,
|
||||
useCssVar,
|
||||
useCurrentElement,
|
||||
useCycleList,
|
||||
useDark,
|
||||
useDateFormat,
|
||||
useDebounceFn,
|
||||
useDebouncedRefHistory,
|
||||
useDeviceMotion,
|
||||
useDeviceOrientation,
|
||||
useDevicePixelRatio,
|
||||
useDevicesList,
|
||||
useDisplayMedia,
|
||||
useDocumentVisibility,
|
||||
useDraggable,
|
||||
useDropZone,
|
||||
useElementBounding,
|
||||
useElementByPoint,
|
||||
useElementHover,
|
||||
useElementSize,
|
||||
useElementVisibility,
|
||||
useEventBus,
|
||||
useEventListener,
|
||||
useEventSource,
|
||||
useEyeDropper,
|
||||
useFavicon,
|
||||
useFetch,
|
||||
useFileDialog,
|
||||
useFileSystemAccess,
|
||||
useFocus,
|
||||
useFocusWithin,
|
||||
useFps,
|
||||
useFullscreen,
|
||||
useGamepad,
|
||||
useGeolocation,
|
||||
useIdle,
|
||||
useImage,
|
||||
useInfiniteScroll,
|
||||
useIntersectionObserver,
|
||||
useInterval,
|
||||
useIntervalFn,
|
||||
useKeyModifier,
|
||||
useLastChanged,
|
||||
useLocalStorage,
|
||||
useMagicKeys,
|
||||
useManualRefHistory,
|
||||
useMediaControls,
|
||||
useMediaQuery,
|
||||
useMemoize,
|
||||
useMemory,
|
||||
useMounted,
|
||||
useMouse,
|
||||
useMouseInElement,
|
||||
useMousePressed,
|
||||
useMutationObserver,
|
||||
useNavigatorLanguage,
|
||||
useNetwork,
|
||||
useNow,
|
||||
useObjectUrl,
|
||||
useOffsetPagination,
|
||||
useOnline,
|
||||
usePageLeave,
|
||||
useParallax,
|
||||
useParentElement,
|
||||
usePerformanceObserver,
|
||||
usePermission,
|
||||
usePointer,
|
||||
usePointerLock,
|
||||
usePointerSwipe,
|
||||
usePreferredColorScheme,
|
||||
usePreferredContrast,
|
||||
usePreferredDark,
|
||||
usePreferredLanguages,
|
||||
usePreferredReducedMotion,
|
||||
usePreferredReducedTransparency,
|
||||
usePrevious,
|
||||
useRafFn,
|
||||
useRefHistory,
|
||||
useResizeObserver,
|
||||
useSSRWidth,
|
||||
useScreenOrientation,
|
||||
useScreenSafeArea,
|
||||
useScriptTag,
|
||||
useScroll,
|
||||
useScrollLock,
|
||||
useSessionStorage,
|
||||
useShare,
|
||||
useSorted,
|
||||
useSpeechRecognition,
|
||||
useSpeechSynthesis,
|
||||
useStepper,
|
||||
useStorage,
|
||||
useStorageAsync,
|
||||
useStyleTag,
|
||||
useSupported,
|
||||
useSwipe,
|
||||
useTemplateRefsList,
|
||||
useTextDirection,
|
||||
useTextSelection,
|
||||
useTextareaAutosize,
|
||||
useThrottleFn,
|
||||
useThrottledRefHistory,
|
||||
useTimeAgo,
|
||||
useTimeout,
|
||||
useTimeoutFn,
|
||||
useTimeoutPoll,
|
||||
useTimestamp,
|
||||
useTitle,
|
||||
useToNumber,
|
||||
useToString,
|
||||
useToggle,
|
||||
useTransition,
|
||||
useUrlSearchParams,
|
||||
useUserMedia,
|
||||
useVModel,
|
||||
useVModels,
|
||||
useVibrate,
|
||||
useVirtualList,
|
||||
useWakeLock,
|
||||
useWebNotification,
|
||||
useWebSocket,
|
||||
useWebWorker,
|
||||
useWebWorkerFn,
|
||||
useWindowFocus,
|
||||
useWindowScroll,
|
||||
useWindowSize,
|
||||
watchArray,
|
||||
watchAtMost,
|
||||
watchDebounced,
|
||||
watchDeep,
|
||||
watchIgnorable,
|
||||
watchImmediate,
|
||||
watchOnce,
|
||||
watchPausable,
|
||||
watchThrottled,
|
||||
watchTriggerable,
|
||||
watchWithFilter,
|
||||
whenever
|
||||
} from "./chunk-AAVY4YN3.js";
|
||||
import "./chunk-JD3CXNQ6.js";
|
||||
export {
|
||||
DefaultMagicKeysAliasMap,
|
||||
StorageSerializers,
|
||||
TransitionPresets,
|
||||
assert,
|
||||
computedAsync as asyncComputed,
|
||||
refAutoReset as autoResetRef,
|
||||
breakpointsAntDesign,
|
||||
breakpointsBootstrapV5,
|
||||
breakpointsElement,
|
||||
breakpointsMasterCss,
|
||||
breakpointsPrimeFlex,
|
||||
breakpointsQuasar,
|
||||
breakpointsSematic,
|
||||
breakpointsTailwind,
|
||||
breakpointsVuetify,
|
||||
breakpointsVuetifyV2,
|
||||
breakpointsVuetifyV3,
|
||||
bypassFilter,
|
||||
camelize,
|
||||
clamp,
|
||||
cloneFnJSON,
|
||||
computedAsync,
|
||||
computedEager,
|
||||
computedInject,
|
||||
computedWithControl,
|
||||
containsProp,
|
||||
computedWithControl as controlledComputed,
|
||||
controlledRef,
|
||||
createEventHook,
|
||||
createFetch,
|
||||
createFilterWrapper,
|
||||
createGlobalState,
|
||||
createInjectionState,
|
||||
reactify as createReactiveFn,
|
||||
createRef,
|
||||
createReusableTemplate,
|
||||
createSharedComposable,
|
||||
createSingletonPromise,
|
||||
createTemplatePromise,
|
||||
createUnrefFn,
|
||||
customStorageEventName,
|
||||
debounceFilter,
|
||||
refDebounced as debouncedRef,
|
||||
watchDebounced as debouncedWatch,
|
||||
defaultDocument,
|
||||
defaultLocation,
|
||||
defaultNavigator,
|
||||
defaultWindow,
|
||||
computedEager as eagerComputed,
|
||||
executeTransition,
|
||||
extendRef,
|
||||
formatDate,
|
||||
formatTimeAgo,
|
||||
get,
|
||||
getLifeCycleTarget,
|
||||
getSSRHandler,
|
||||
hasOwn,
|
||||
hyphenate,
|
||||
identity,
|
||||
watchIgnorable as ignorableWatch,
|
||||
increaseWithUnit,
|
||||
injectLocal,
|
||||
invoke,
|
||||
isClient,
|
||||
isDef,
|
||||
isDefined,
|
||||
isIOS,
|
||||
isObject,
|
||||
isWorker,
|
||||
makeDestructurable,
|
||||
mapGamepadToXbox360Controller,
|
||||
noop,
|
||||
normalizeDate,
|
||||
notNullish,
|
||||
now,
|
||||
objectEntries,
|
||||
objectOmit,
|
||||
objectPick,
|
||||
onClickOutside,
|
||||
onElementRemoval,
|
||||
onKeyDown,
|
||||
onKeyPressed,
|
||||
onKeyStroke,
|
||||
onKeyUp,
|
||||
onLongPress,
|
||||
onStartTyping,
|
||||
pausableFilter,
|
||||
watchPausable as pausableWatch,
|
||||
promiseTimeout,
|
||||
provideLocal,
|
||||
provideSSRWidth,
|
||||
pxValue,
|
||||
rand,
|
||||
reactify,
|
||||
reactifyObject,
|
||||
reactiveComputed,
|
||||
reactiveOmit,
|
||||
reactivePick,
|
||||
refAutoReset,
|
||||
refDebounced,
|
||||
refDefault,
|
||||
refThrottled,
|
||||
refWithControl,
|
||||
resolveRef,
|
||||
resolveUnref,
|
||||
set,
|
||||
setSSRHandler,
|
||||
syncRef,
|
||||
syncRefs,
|
||||
templateRef,
|
||||
throttleFilter,
|
||||
refThrottled as throttledRef,
|
||||
watchThrottled as throttledWatch,
|
||||
timestamp,
|
||||
toArray,
|
||||
toReactive,
|
||||
toRef,
|
||||
toRefs,
|
||||
toValue,
|
||||
tryOnBeforeMount,
|
||||
tryOnBeforeUnmount,
|
||||
tryOnMounted,
|
||||
tryOnScopeDispose,
|
||||
tryOnUnmounted,
|
||||
unrefElement,
|
||||
until,
|
||||
useActiveElement,
|
||||
useAnimate,
|
||||
useArrayDifference,
|
||||
useArrayEvery,
|
||||
useArrayFilter,
|
||||
useArrayFind,
|
||||
useArrayFindIndex,
|
||||
useArrayFindLast,
|
||||
useArrayIncludes,
|
||||
useArrayJoin,
|
||||
useArrayMap,
|
||||
useArrayReduce,
|
||||
useArraySome,
|
||||
useArrayUnique,
|
||||
useAsyncQueue,
|
||||
useAsyncState,
|
||||
useBase64,
|
||||
useBattery,
|
||||
useBluetooth,
|
||||
useBreakpoints,
|
||||
useBroadcastChannel,
|
||||
useBrowserLocation,
|
||||
useCached,
|
||||
useClipboard,
|
||||
useClipboardItems,
|
||||
useCloned,
|
||||
useColorMode,
|
||||
useConfirmDialog,
|
||||
useCountdown,
|
||||
useCounter,
|
||||
useCssVar,
|
||||
useCurrentElement,
|
||||
useCycleList,
|
||||
useDark,
|
||||
useDateFormat,
|
||||
refDebounced as useDebounce,
|
||||
useDebounceFn,
|
||||
useDebouncedRefHistory,
|
||||
useDeviceMotion,
|
||||
useDeviceOrientation,
|
||||
useDevicePixelRatio,
|
||||
useDevicesList,
|
||||
useDisplayMedia,
|
||||
useDocumentVisibility,
|
||||
useDraggable,
|
||||
useDropZone,
|
||||
useElementBounding,
|
||||
useElementByPoint,
|
||||
useElementHover,
|
||||
useElementSize,
|
||||
useElementVisibility,
|
||||
useEventBus,
|
||||
useEventListener,
|
||||
useEventSource,
|
||||
useEyeDropper,
|
||||
useFavicon,
|
||||
useFetch,
|
||||
useFileDialog,
|
||||
useFileSystemAccess,
|
||||
useFocus,
|
||||
useFocusWithin,
|
||||
useFps,
|
||||
useFullscreen,
|
||||
useGamepad,
|
||||
useGeolocation,
|
||||
useIdle,
|
||||
useImage,
|
||||
useInfiniteScroll,
|
||||
useIntersectionObserver,
|
||||
useInterval,
|
||||
useIntervalFn,
|
||||
useKeyModifier,
|
||||
useLastChanged,
|
||||
useLocalStorage,
|
||||
useMagicKeys,
|
||||
useManualRefHistory,
|
||||
useMediaControls,
|
||||
useMediaQuery,
|
||||
useMemoize,
|
||||
useMemory,
|
||||
useMounted,
|
||||
useMouse,
|
||||
useMouseInElement,
|
||||
useMousePressed,
|
||||
useMutationObserver,
|
||||
useNavigatorLanguage,
|
||||
useNetwork,
|
||||
useNow,
|
||||
useObjectUrl,
|
||||
useOffsetPagination,
|
||||
useOnline,
|
||||
usePageLeave,
|
||||
useParallax,
|
||||
useParentElement,
|
||||
usePerformanceObserver,
|
||||
usePermission,
|
||||
usePointer,
|
||||
usePointerLock,
|
||||
usePointerSwipe,
|
||||
usePreferredColorScheme,
|
||||
usePreferredContrast,
|
||||
usePreferredDark,
|
||||
usePreferredLanguages,
|
||||
usePreferredReducedMotion,
|
||||
usePreferredReducedTransparency,
|
||||
usePrevious,
|
||||
useRafFn,
|
||||
useRefHistory,
|
||||
useResizeObserver,
|
||||
useSSRWidth,
|
||||
useScreenOrientation,
|
||||
useScreenSafeArea,
|
||||
useScriptTag,
|
||||
useScroll,
|
||||
useScrollLock,
|
||||
useSessionStorage,
|
||||
useShare,
|
||||
useSorted,
|
||||
useSpeechRecognition,
|
||||
useSpeechSynthesis,
|
||||
useStepper,
|
||||
useStorage,
|
||||
useStorageAsync,
|
||||
useStyleTag,
|
||||
useSupported,
|
||||
useSwipe,
|
||||
useTemplateRefsList,
|
||||
useTextDirection,
|
||||
useTextSelection,
|
||||
useTextareaAutosize,
|
||||
refThrottled as useThrottle,
|
||||
useThrottleFn,
|
||||
useThrottledRefHistory,
|
||||
useTimeAgo,
|
||||
useTimeout,
|
||||
useTimeoutFn,
|
||||
useTimeoutPoll,
|
||||
useTimestamp,
|
||||
useTitle,
|
||||
useToNumber,
|
||||
useToString,
|
||||
useToggle,
|
||||
useTransition,
|
||||
useUrlSearchParams,
|
||||
useUserMedia,
|
||||
useVModel,
|
||||
useVModels,
|
||||
useVibrate,
|
||||
useVirtualList,
|
||||
useWakeLock,
|
||||
useWebNotification,
|
||||
useWebSocket,
|
||||
useWebWorker,
|
||||
useWebWorkerFn,
|
||||
useWindowFocus,
|
||||
useWindowScroll,
|
||||
useWindowSize,
|
||||
watchArray,
|
||||
watchAtMost,
|
||||
watchDebounced,
|
||||
watchDeep,
|
||||
watchIgnorable,
|
||||
watchImmediate,
|
||||
watchOnce,
|
||||
watchPausable,
|
||||
watchThrottled,
|
||||
watchTriggerable,
|
||||
watchWithFilter,
|
||||
whenever
|
||||
};
|
||||
//# sourceMappingURL=vitepress___@vueuse_core.js.map
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sourcesContent": [],
|
||||
"mappings": "",
|
||||
"names": []
|
||||
}
|
||||
343
docs/.vitepress/cache/deps/vue.js
vendored
343
docs/.vitepress/cache/deps/vue.js
vendored
@@ -1,343 +0,0 @@
|
||||
import {
|
||||
BaseTransition,
|
||||
BaseTransitionPropsValidators,
|
||||
Comment,
|
||||
DeprecationTypes,
|
||||
EffectScope,
|
||||
ErrorCodes,
|
||||
ErrorTypeStrings,
|
||||
Fragment,
|
||||
KeepAlive,
|
||||
ReactiveEffect,
|
||||
Static,
|
||||
Suspense,
|
||||
Teleport,
|
||||
Text,
|
||||
TrackOpTypes,
|
||||
Transition,
|
||||
TransitionGroup,
|
||||
TriggerOpTypes,
|
||||
VueElement,
|
||||
assertNumber,
|
||||
callWithAsyncErrorHandling,
|
||||
callWithErrorHandling,
|
||||
camelize,
|
||||
capitalize,
|
||||
cloneVNode,
|
||||
compatUtils,
|
||||
compile,
|
||||
computed,
|
||||
createApp,
|
||||
createBaseVNode,
|
||||
createBlock,
|
||||
createCommentVNode,
|
||||
createElementBlock,
|
||||
createHydrationRenderer,
|
||||
createPropsRestProxy,
|
||||
createRenderer,
|
||||
createSSRApp,
|
||||
createSlots,
|
||||
createStaticVNode,
|
||||
createTextVNode,
|
||||
createVNode,
|
||||
customRef,
|
||||
defineAsyncComponent,
|
||||
defineComponent,
|
||||
defineCustomElement,
|
||||
defineEmits,
|
||||
defineExpose,
|
||||
defineModel,
|
||||
defineOptions,
|
||||
defineProps,
|
||||
defineSSRCustomElement,
|
||||
defineSlots,
|
||||
devtools,
|
||||
effect,
|
||||
effectScope,
|
||||
getCurrentInstance,
|
||||
getCurrentScope,
|
||||
getCurrentWatcher,
|
||||
getTransitionRawChildren,
|
||||
guardReactiveProps,
|
||||
h,
|
||||
handleError,
|
||||
hasInjectionContext,
|
||||
hydrate,
|
||||
hydrateOnIdle,
|
||||
hydrateOnInteraction,
|
||||
hydrateOnMediaQuery,
|
||||
hydrateOnVisible,
|
||||
initCustomFormatter,
|
||||
initDirectivesForSSR,
|
||||
inject,
|
||||
isMemoSame,
|
||||
isProxy,
|
||||
isReactive,
|
||||
isReadonly,
|
||||
isRef,
|
||||
isRuntimeOnly,
|
||||
isShallow,
|
||||
isVNode,
|
||||
markRaw,
|
||||
mergeDefaults,
|
||||
mergeModels,
|
||||
mergeProps,
|
||||
nextTick,
|
||||
normalizeClass,
|
||||
normalizeProps,
|
||||
normalizeStyle,
|
||||
onActivated,
|
||||
onBeforeMount,
|
||||
onBeforeUnmount,
|
||||
onBeforeUpdate,
|
||||
onDeactivated,
|
||||
onErrorCaptured,
|
||||
onMounted,
|
||||
onRenderTracked,
|
||||
onRenderTriggered,
|
||||
onScopeDispose,
|
||||
onServerPrefetch,
|
||||
onUnmounted,
|
||||
onUpdated,
|
||||
onWatcherCleanup,
|
||||
openBlock,
|
||||
popScopeId,
|
||||
provide,
|
||||
proxyRefs,
|
||||
pushScopeId,
|
||||
queuePostFlushCb,
|
||||
reactive,
|
||||
readonly,
|
||||
ref,
|
||||
registerRuntimeCompiler,
|
||||
render,
|
||||
renderList,
|
||||
renderSlot,
|
||||
resolveComponent,
|
||||
resolveDirective,
|
||||
resolveDynamicComponent,
|
||||
resolveFilter,
|
||||
resolveTransitionHooks,
|
||||
setBlockTracking,
|
||||
setDevtoolsHook,
|
||||
setTransitionHooks,
|
||||
shallowReactive,
|
||||
shallowReadonly,
|
||||
shallowRef,
|
||||
ssrContextKey,
|
||||
ssrUtils,
|
||||
stop,
|
||||
toDisplayString,
|
||||
toHandlerKey,
|
||||
toHandlers,
|
||||
toRaw,
|
||||
toRef,
|
||||
toRefs,
|
||||
toValue,
|
||||
transformVNodeArgs,
|
||||
triggerRef,
|
||||
unref,
|
||||
useAttrs,
|
||||
useCssModule,
|
||||
useCssVars,
|
||||
useHost,
|
||||
useId,
|
||||
useModel,
|
||||
useSSRContext,
|
||||
useShadowRoot,
|
||||
useSlots,
|
||||
useTemplateRef,
|
||||
useTransitionState,
|
||||
vModelCheckbox,
|
||||
vModelDynamic,
|
||||
vModelRadio,
|
||||
vModelSelect,
|
||||
vModelText,
|
||||
vShow,
|
||||
version,
|
||||
warn,
|
||||
watch,
|
||||
watchEffect,
|
||||
watchPostEffect,
|
||||
watchSyncEffect,
|
||||
withAsyncContext,
|
||||
withCtx,
|
||||
withDefaults,
|
||||
withDirectives,
|
||||
withKeys,
|
||||
withMemo,
|
||||
withModifiers,
|
||||
withScopeId
|
||||
} from "./chunk-JD3CXNQ6.js";
|
||||
export {
|
||||
BaseTransition,
|
||||
BaseTransitionPropsValidators,
|
||||
Comment,
|
||||
DeprecationTypes,
|
||||
EffectScope,
|
||||
ErrorCodes,
|
||||
ErrorTypeStrings,
|
||||
Fragment,
|
||||
KeepAlive,
|
||||
ReactiveEffect,
|
||||
Static,
|
||||
Suspense,
|
||||
Teleport,
|
||||
Text,
|
||||
TrackOpTypes,
|
||||
Transition,
|
||||
TransitionGroup,
|
||||
TriggerOpTypes,
|
||||
VueElement,
|
||||
assertNumber,
|
||||
callWithAsyncErrorHandling,
|
||||
callWithErrorHandling,
|
||||
camelize,
|
||||
capitalize,
|
||||
cloneVNode,
|
||||
compatUtils,
|
||||
compile,
|
||||
computed,
|
||||
createApp,
|
||||
createBlock,
|
||||
createCommentVNode,
|
||||
createElementBlock,
|
||||
createBaseVNode as createElementVNode,
|
||||
createHydrationRenderer,
|
||||
createPropsRestProxy,
|
||||
createRenderer,
|
||||
createSSRApp,
|
||||
createSlots,
|
||||
createStaticVNode,
|
||||
createTextVNode,
|
||||
createVNode,
|
||||
customRef,
|
||||
defineAsyncComponent,
|
||||
defineComponent,
|
||||
defineCustomElement,
|
||||
defineEmits,
|
||||
defineExpose,
|
||||
defineModel,
|
||||
defineOptions,
|
||||
defineProps,
|
||||
defineSSRCustomElement,
|
||||
defineSlots,
|
||||
devtools,
|
||||
effect,
|
||||
effectScope,
|
||||
getCurrentInstance,
|
||||
getCurrentScope,
|
||||
getCurrentWatcher,
|
||||
getTransitionRawChildren,
|
||||
guardReactiveProps,
|
||||
h,
|
||||
handleError,
|
||||
hasInjectionContext,
|
||||
hydrate,
|
||||
hydrateOnIdle,
|
||||
hydrateOnInteraction,
|
||||
hydrateOnMediaQuery,
|
||||
hydrateOnVisible,
|
||||
initCustomFormatter,
|
||||
initDirectivesForSSR,
|
||||
inject,
|
||||
isMemoSame,
|
||||
isProxy,
|
||||
isReactive,
|
||||
isReadonly,
|
||||
isRef,
|
||||
isRuntimeOnly,
|
||||
isShallow,
|
||||
isVNode,
|
||||
markRaw,
|
||||
mergeDefaults,
|
||||
mergeModels,
|
||||
mergeProps,
|
||||
nextTick,
|
||||
normalizeClass,
|
||||
normalizeProps,
|
||||
normalizeStyle,
|
||||
onActivated,
|
||||
onBeforeMount,
|
||||
onBeforeUnmount,
|
||||
onBeforeUpdate,
|
||||
onDeactivated,
|
||||
onErrorCaptured,
|
||||
onMounted,
|
||||
onRenderTracked,
|
||||
onRenderTriggered,
|
||||
onScopeDispose,
|
||||
onServerPrefetch,
|
||||
onUnmounted,
|
||||
onUpdated,
|
||||
onWatcherCleanup,
|
||||
openBlock,
|
||||
popScopeId,
|
||||
provide,
|
||||
proxyRefs,
|
||||
pushScopeId,
|
||||
queuePostFlushCb,
|
||||
reactive,
|
||||
readonly,
|
||||
ref,
|
||||
registerRuntimeCompiler,
|
||||
render,
|
||||
renderList,
|
||||
renderSlot,
|
||||
resolveComponent,
|
||||
resolveDirective,
|
||||
resolveDynamicComponent,
|
||||
resolveFilter,
|
||||
resolveTransitionHooks,
|
||||
setBlockTracking,
|
||||
setDevtoolsHook,
|
||||
setTransitionHooks,
|
||||
shallowReactive,
|
||||
shallowReadonly,
|
||||
shallowRef,
|
||||
ssrContextKey,
|
||||
ssrUtils,
|
||||
stop,
|
||||
toDisplayString,
|
||||
toHandlerKey,
|
||||
toHandlers,
|
||||
toRaw,
|
||||
toRef,
|
||||
toRefs,
|
||||
toValue,
|
||||
transformVNodeArgs,
|
||||
triggerRef,
|
||||
unref,
|
||||
useAttrs,
|
||||
useCssModule,
|
||||
useCssVars,
|
||||
useHost,
|
||||
useId,
|
||||
useModel,
|
||||
useSSRContext,
|
||||
useShadowRoot,
|
||||
useSlots,
|
||||
useTemplateRef,
|
||||
useTransitionState,
|
||||
vModelCheckbox,
|
||||
vModelDynamic,
|
||||
vModelRadio,
|
||||
vModelSelect,
|
||||
vModelText,
|
||||
vShow,
|
||||
version,
|
||||
warn,
|
||||
watch,
|
||||
watchEffect,
|
||||
watchPostEffect,
|
||||
watchSyncEffect,
|
||||
withAsyncContext,
|
||||
withCtx,
|
||||
withDefaults,
|
||||
withDirectives,
|
||||
withKeys,
|
||||
withMemo,
|
||||
withModifiers,
|
||||
withScopeId
|
||||
};
|
||||
//# sourceMappingURL=vue.js.map
|
||||
7
docs/.vitepress/cache/deps/vue.js.map
vendored
7
docs/.vitepress/cache/deps/vue.js.map
vendored
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sourcesContent": [],
|
||||
"mappings": "",
|
||||
"names": []
|
||||
}
|
||||
@@ -38,12 +38,12 @@ export default defineConfig({
|
||||
},
|
||||
{
|
||||
text: "吴禹谷",
|
||||
items: [{ text: "test", link: "/wyg/test" }],
|
||||
items: [{ text: "Sunway User Sys", link: "/wyg/sunway-user-sys" }],
|
||||
},
|
||||
{
|
||||
text: "吴子妍",
|
||||
items: [
|
||||
{ text: "吴子妍", link: "/wzy/wyz" },
|
||||
{ text: "吴子妍", link: "/wzy/wzy" },
|
||||
{ text: "note3-tables", link: "/wzy/note3-tables" },
|
||||
],
|
||||
},
|
||||
@@ -70,6 +70,9 @@ export default defineConfig({
|
||||
|
||||
socialLinks: [
|
||||
{ icon: "gitee", link: "https://gitee.com/gushenfree/flower-rain" },
|
||||
{ icon: "gitea", link: "http://113.46.158.62:3000/gushen/flower-rain" },
|
||||
],
|
||||
},
|
||||
// 在 VitePress 中项目根目录视为 docs 目录
|
||||
outDir: "../output/docs/dist",
|
||||
});
|
||||
|
||||
165
docs/wyg/sunway-user-sys.md
Normal file
165
docs/wyg/sunway-user-sys.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Sunway User Sys 设计方案
|
||||
|
||||
## 1. 文档信息
|
||||
- **文档标题**:基于RBAC的认证服务系统及管理面板产品需求文档
|
||||
- **版本**:1.0
|
||||
- **作者**:Grok 4(xAI)
|
||||
- **创建日期**:2025-12-16
|
||||
- **文档目的**:本文档定义了一个优秀的基于RBAC(Role-Based Access Control)的认证服务系统及其配套管理面板的需求,包括功能设计、系统架构、非功能需求等。旨在为开发团队提供清晰的指导,确保系统安全、高效、可扩展。
|
||||
|
||||
## 2. 项目概述
|
||||
### 2.1 项目背景
|
||||
随着企业应用系统的复杂化,用户认证和权限管理成为核心需求。RBAC模型通过角色(Role)来桥接用户(User)和权限(Permission),简化了权限分配,提高了安全性。本项目旨在开发一个独立的认证服务系统(以下简称“认证服务”),支持多租户、多应用集成。同时,开发一个Web-based的管理面板(以下简称“管理面板”),用于管理员对用户、角色和权限的集中管理。
|
||||
|
||||
### 2.2 项目目标
|
||||
- 提供安全、可靠的认证机制,支持JWT、OAuth2等标准协议。
|
||||
- 实现细粒度的权限控制,支持动态角色分配。
|
||||
- 管理面板提供直观的UI,支持用户自助管理和审计日志。
|
||||
- 系统设计注重可扩展性,支持微服务架构,便于集成到现有系统中。
|
||||
- 确保合规性,符合GDPR、CCPA等数据隐私法规。
|
||||
|
||||
### 2.3 目标用户
|
||||
- **终端用户**:系统使用者,需要认证登录并根据角色访问资源。
|
||||
- **管理员**:负责用户管理、角色配置和权限审计的人员。
|
||||
- **开发者/集成者**:将认证服务集成到其他应用的工程师。
|
||||
|
||||
### 2.4 假设与约束
|
||||
- 假设:系统基于云部署,支持容器化(Docker/Kubernetes)。
|
||||
- 约束:不涉及硬件集成;预算未定,但优先使用开源技术(如Spring Security、Keycloak);开发周期目标为3-6个月。
|
||||
|
||||
## 3. 系统架构设计
|
||||
### 3.1 高层架构
|
||||
系统采用微服务架构,分成两个主要模块:
|
||||
- **认证服务**:后端服务,使用RESTful API,提供认证、授权和令牌管理。技术栈建议:Node.js/Express 或 Java/Spring Boot,数据库使用PostgreSQL(支持JSONB for 权限存储)。
|
||||
- **管理面板**:前端应用,使用React/Vue.js框架,与认证服务通过API交互。部署为单页应用(SPA),支持响应式设计。
|
||||
|
||||
架构图(文本描述):
|
||||
```
|
||||
[客户端应用] <-- JWT/OAuth --> [认证服务 (API Gateway + Auth Server)]
|
||||
|
|
||||
v
|
||||
[管理面板 (Web UI)] <-- Secure API --> [数据库 (Users, Roles, Permissions)]
|
||||
|
|
||||
v
|
||||
[审计日志 & 监控] <-- Integration --> [外部服务 (e.g., Email, Cache)]
|
||||
```
|
||||
|
||||
### 3.2 RBAC模型设计
|
||||
RBAC核心组件:
|
||||
- **用户(User)**:唯一标识(如UUID),包含基本信息(用户名、邮箱、密码哈希)。
|
||||
- **角色(Role)**:用户所属的角色组,如“Admin”、“User”、“Guest”。支持角色继承(e.g., Admin 继承 User 的权限)。
|
||||
- **权限(Permission)**:细粒度操作,如“read:resource”、“write:document”。权限可绑定到角色,支持通配符(e.g., “*:resource”表示所有操作)。
|
||||
- **会话(Session)**:基于JWT的令牌,包含用户ID、角色列表和过期时间。
|
||||
|
||||
扩展设计:
|
||||
- 支持组(Group):用户可属于多个组,组可绑定角色。
|
||||
- 动态权限:通过规则引擎(e.g., OPA - Open Policy Agent)支持上下文-based授权(如基于IP、时间)。
|
||||
- 多租户:每个租户有独立的角色/权限命名空间。
|
||||
|
||||
### 3.3 数据模型(ER图简述)
|
||||
- **User表**:id (PK), username, email, password_hash, status, created_at。
|
||||
- **Role表**:id (PK), name, description, parent_role_id (for 继承)。
|
||||
- **Permission表**:id (PK), name, description。
|
||||
- **User_Role表**:user_id (FK), role_id (FK)。
|
||||
- **Role_Permission表**:role_id (FK), permission_id (FK)。
|
||||
- **Audit_Log表**:id (PK), user_id, action, timestamp, details。
|
||||
|
||||
### 3.4 集成与扩展
|
||||
- 支持OAuth2/OpenID Connect,与Google、GitHub等第三方登录集成。
|
||||
- API网关使用Kong/Nginx,支持速率限制和CORS。
|
||||
- 缓存使用Redis,提升认证性能。
|
||||
- 监控:集成Prometheus/Grafana for metrics。
|
||||
|
||||
## 4. 功能需求
|
||||
### 4.1 认证服务功能
|
||||
1. **用户注册与认证**:
|
||||
- 支持邮箱/手机号注册,验证码验证。
|
||||
- 登录:用户名/密码、OAuth2、社会化登录。
|
||||
- 密码重置:通过邮箱链接。
|
||||
- 多因素认证(MFA):支持TOTP(Google Authenticator)。
|
||||
|
||||
2. **授权与令牌管理**:
|
||||
- 生成JWT令牌,包含claims(user_id, roles, permissions)。
|
||||
- 令牌验证:中间件集成,支持黑名单(revoke token)。
|
||||
- 刷新令牌:使用refresh token延长会话。
|
||||
|
||||
3. **RBAC核心功能**:
|
||||
- 角色创建/编辑/删除。
|
||||
- 权限分配:批量绑定到角色。
|
||||
- 用户角色分配:支持批量操作。
|
||||
- 权限检查:API端点装饰器(e.g., @RequirePermission('read:resource'))。
|
||||
|
||||
4. **审计与日志**:
|
||||
- 记录所有认证/授权事件。
|
||||
- 支持导出日志 for 合规审计。
|
||||
|
||||
### 4.2 管理面板功能
|
||||
1. **仪表盘**:
|
||||
- 显示用户统计、活跃角色、最近日志。
|
||||
|
||||
2. **用户管理**:
|
||||
- CRUD操作:创建、读取、更新、删除用户。
|
||||
- 搜索/过滤:按角色、状态。
|
||||
- 批量导入:CSV/Excel。
|
||||
|
||||
3. **角色与权限管理**:
|
||||
- 角色CRUD:可视化继承树。
|
||||
- 权限CRUD:树状结构显示。
|
||||
- 分配界面:拖拽式绑定用户/角色/权限。
|
||||
|
||||
4. **系统设置**:
|
||||
- 配置MFA、令牌过期时间。
|
||||
- 集成第三方服务(e.g., SMTP for email)。
|
||||
|
||||
5. **安全功能**:
|
||||
- 角色-based面板访问(e.g., 只允许Admin访问)。
|
||||
- 会话超时、CSRF保护。
|
||||
|
||||
### 4.3 API设计
|
||||
- **认证API**:
|
||||
- POST /auth/register:注册用户。
|
||||
- POST /auth/login:登录返回JWT。
|
||||
- GET /auth/validate:验证令牌。
|
||||
|
||||
- **管理API**:
|
||||
- GET /users:列出用户(需Admin权限)。
|
||||
- POST /roles:创建角色。
|
||||
|
||||
所有API使用Swagger/OpenAPI文档化。
|
||||
|
||||
## 5. 非功能需求
|
||||
### 5.1 性能
|
||||
- 响应时间:<200ms for 认证API。
|
||||
- 并发支持:>1000用户/秒(使用负载均衡)。
|
||||
- 扩展性:水平扩展,支持集群部署。
|
||||
|
||||
### 5.2 安全性
|
||||
- 加密:密码使用bcrypt哈希;传输使用HTTPS。
|
||||
- 防护:防SQL注入、XSS、CSRF。
|
||||
- 合规:数据加密 at rest;支持数据删除请求。
|
||||
|
||||
### 5.3 可用性与可靠性
|
||||
- 可用性:99.9% uptime。
|
||||
- 备份:每日数据库备份。
|
||||
- 错误处理:优雅降级,日志记录。
|
||||
|
||||
### 5.4 用户体验
|
||||
- 管理面板:响应式设计,支持多语言(中/英)。
|
||||
- 可访问性:符合WCAG 2.1标准。
|
||||
|
||||
### 5.5 技术要求
|
||||
- 前端:HTML5, CSS3, JavaScript (ES6+)。
|
||||
- 后端:RESTful, JSON格式。
|
||||
- 测试:单元测试覆盖率>80%;集成测试 for API。
|
||||
|
||||
## 6. 风险与缓解
|
||||
- **风险**:安全漏洞。**缓解**:第三方审计,定期渗透测试。
|
||||
- **风险**:集成复杂。**缓解**:提供SDK for 常见框架(e.g., Express middleware)。
|
||||
- **风险**:数据迁移。**缓解**:支持从LDAP/Active Directory导入。
|
||||
|
||||
## 7. 附录
|
||||
- **术语表**:RBAC - Role-Based Access Control;JWT - JSON Web Token。
|
||||
- **参考**:NIST RBAC标准;OWASP安全指南。
|
||||
- **下一步**:基于本PRD,进行详细设计文档(SDD)和原型开发。
|
||||
|
||||
此文档为初始版本,可根据反馈迭代。如果需要更详细的架构图、API规格或代码示例,请提供进一步指示。
|
||||
@@ -1,3 +0,0 @@
|
||||
# wyg
|
||||
|
||||
content
|
||||
Reference in New Issue
Block a user