chore: init read-star monorepo

This commit is contained in:
2026-01-16 13:06:44 +08:00
commit 1e510efe8e
508 changed files with 44803 additions and 0 deletions

20
apps/admin/src/typings/api/auth.d.ts vendored Normal file
View File

@ -0,0 +1,20 @@
declare namespace Api {
/**
* namespace Auth
*
* backend api module: "auth"
*/
namespace Auth {
interface LoginToken {
token: string
refreshToken: string
}
interface UserInfo {
userId: string
userName: string
roles: string[]
buttons: string[]
}
}
}

50
apps/admin/src/typings/api/common.d.ts vendored Normal file
View File

@ -0,0 +1,50 @@
/**
* Namespace Api
*
* All backend api type
*/
declare namespace Api {
namespace Common {
/** common params of paginating */
interface PaginatingCommonParams {
/** current page number */
current: number
/** page size */
size: number
/** total count */
total: number
}
/** common params of paginating query list data */
interface PaginatingQueryRecord<T = any> extends PaginatingCommonParams {
records: T[]
}
/** common search params of table */
type CommonSearchParams = Pick<Common.PaginatingCommonParams, 'current' | 'size'>
/**
* enable status
*
* - "1": enabled
* - "2": disabled
*/
type EnableStatus = '1' | '2'
/** common record */
type CommonRecord<T = any> = {
/** record id */
id: number
/** record creator */
createBy: string
/** record create time */
createTime: string
/** record updater */
updateBy: string
/** record update time */
updateTime: string
/** record status */
status: EnableStatus | null
} & T
}
}

19
apps/admin/src/typings/api/route.d.ts vendored Normal file
View File

@ -0,0 +1,19 @@
declare namespace Api {
/**
* namespace Route
*
* backend api module: "route"
*/
namespace Route {
type ElegantConstRoute = import('@elegant-router/types').ElegantConstRoute
interface MenuRoute extends ElegantConstRoute {
id: string
}
interface UserRoute {
routes: MenuRoute[]
home: import('@elegant-router/types').LastLevelRouteKey
}
}
}

653
apps/admin/src/typings/app.d.ts vendored Normal file
View File

@ -0,0 +1,653 @@
/** The global namespace for the app */
declare namespace App {
/** Theme namespace */
namespace Theme {
type ColorPaletteNumber = import('@sa/color').ColorPaletteNumber
/** NaiveUI theme overrides that can be specified in preset */
type NaiveUIThemeOverride = import('naive-ui').GlobalThemeOverrides
/** Theme setting */
interface ThemeSetting {
/** Theme scheme */
themeScheme: UnionKey.ThemeScheme
/** grayscale mode */
grayscale: boolean
/** colour weakness mode */
colourWeakness: boolean
/** Whether to recommend color */
recommendColor: boolean
/** Theme color */
themeColor: string
/** Theme radius */
themeRadius: number
/** Other color */
otherColor: OtherColor
/** Whether info color is followed by the primary color */
isInfoFollowPrimary: boolean
/** Layout */
layout: {
/** Layout mode */
mode: UnionKey.ThemeLayoutMode
/** Scroll mode */
scrollMode: UnionKey.ThemeScrollMode
}
/** Page */
page: {
/** Whether to show the page transition */
animate: boolean
/** Page animate mode */
animateMode: UnionKey.ThemePageAnimateMode
}
/** Header */
header: {
/** Header height */
height: number
/** Header breadcrumb */
breadcrumb: {
/** Whether to show the breadcrumb */
visible: boolean
/** Whether to show the breadcrumb icon */
showIcon: boolean
}
/** Multilingual */
multilingual: {
/** Whether to show the multilingual */
visible: boolean
}
globalSearch: {
/** Whether to show the GlobalSearch */
visible: boolean
}
}
/** Tab */
tab: {
/** Whether to show the tab */
visible: boolean
/**
* Whether to cache the tab
*
* If cache, the tabs will get from the local storage when the page is refreshed
*/
cache: boolean
/** Tab height */
height: number
/** Tab mode */
mode: UnionKey.ThemeTabMode
/** Whether to close tab by middle click */
closeTabByMiddleClick: boolean
}
/** Fixed header and tab */
fixedHeaderAndTab: boolean
/** Sider */
sider: {
/** Inverted sider */
inverted: boolean
/** Sider width */
width: number
/** Collapsed sider width */
collapsedWidth: number
/** Sider width when the layout is 'vertical-mix', 'top-hybrid-sidebar-first', or 'top-hybrid-header-first' */
mixWidth: number
/**
* Collapsed sider width when the layout is 'vertical-mix', 'top-hybrid-sidebar-first', or
* 'top-hybrid-header-first'
*/
mixCollapsedWidth: number
/** Child menu width when the layout is 'vertical-mix', 'top-hybrid-sidebar-first', or 'top-hybrid-header-first' */
mixChildMenuWidth: number
/** Whether to auto select the first submenu */
autoSelectFirstMenu: boolean
}
/** Footer */
footer: {
/** Whether to show the footer */
visible: boolean
/** Whether fixed the footer */
fixed: boolean
/** Footer height */
height: number
/**
* Whether float the footer to the right when the layout is 'top-hybrid-sidebar-first' or
* 'top-hybrid-header-first'
*/
right: boolean
}
/** Watermark */
watermark: {
/** Whether to show the watermark */
visible: boolean
/** Watermark text */
text: string
/** Whether to use user name as watermark text */
enableUserName: boolean
/** Whether to use current time as watermark text */
enableTime: boolean
/** Time format for watermark text */
timeFormat: string
}
/** define some theme settings tokens, will transform to css variables */
tokens: {
light: ThemeSettingToken
dark?: {
[K in keyof ThemeSettingToken]?: Partial<ThemeSettingToken[K]>;
}
}
}
interface OtherColor {
info: string
success: string
warning: string
error: string
}
interface ThemeColor extends OtherColor {
primary: string
}
type ThemeColorKey = keyof ThemeColor
type ThemePaletteColor = {
[key in ThemeColorKey | `${ThemeColorKey}-${ColorPaletteNumber}`]: string;
}
type BaseToken = Record<string, Record<string, string>>
interface ThemeSettingTokenColor {
/** the progress bar color, if not set, will use the primary color */
'nprogress'?: string
'container': string
'layout': string
'inverted': string
'base-text': string
}
interface ThemeSettingTokenBoxShadow {
header: string
sider: string
tab: string
}
interface ThemeSettingToken {
colors: ThemeSettingTokenColor
boxShadow: ThemeSettingTokenBoxShadow
}
type ThemeTokenColor = ThemePaletteColor & ThemeSettingTokenColor
/** Theme token CSS variables */
interface ThemeTokenCSSVars {
colors: ThemeTokenColor & { [key: string]: string }
boxShadow: ThemeSettingTokenBoxShadow & { [key: string]: string }
}
}
/** Global namespace */
namespace Global {
type VNode = import('vue').VNode
type RouteLocationNormalizedLoaded = import('vue-router').RouteLocationNormalizedLoaded
type RouteKey = import('@elegant-router/types').RouteKey
type RouteMap = import('@elegant-router/types').RouteMap
type RoutePath = import('@elegant-router/types').RoutePath
type LastLevelRouteKey = import('@elegant-router/types').LastLevelRouteKey
/** The router push options */
interface RouterPushOptions {
query?: Record<string, string>
params?: Record<string, string>
}
/** The global header props */
interface HeaderProps {
/** Whether to show the logo */
showLogo?: boolean
/** Whether to show the menu toggler */
showMenuToggler?: boolean
/** Whether to show the menu */
showMenu?: boolean
}
/** The global menu */
interface Menu {
/**
* The menu key
*
* Equal to the route key
*/
key: string
/** The menu label */
label: string
/** The menu i18n key */
i18nKey?: I18n.I18nKey | null
/** The route key */
routeKey: RouteKey
/** The route path */
routePath: RoutePath
/** The menu icon */
icon?: () => VNode
/** The menu children */
children?: Menu[]
}
type Breadcrumb = Omit<Menu, 'children'> & {
options?: Breadcrumb[]
}
/** Tab route */
type TabRoute = Pick<RouteLocationNormalizedLoaded, 'name' | 'path' | 'meta'> &
Partial<Pick<RouteLocationNormalizedLoaded, 'fullPath' | 'query' | 'matched'>>
/** The global tab */
interface Tab {
/** The tab id */
id: string
/** The tab label */
label: string
/**
* The new tab label
*
* If set, the tab label will be replaced by this value
*/
newLabel?: string
/**
* The old tab label
*
* when reset the tab label, the tab label will be replaced by this value
*/
oldLabel?: string
/** The tab route key */
routeKey: LastLevelRouteKey
/** The tab route path */
routePath: RouteMap[LastLevelRouteKey]
/** The tab route full path */
fullPath: string
/** The tab fixed index */
fixedIndex?: number | null
/**
* Tab icon
*
* Iconify icon
*/
icon?: string
/**
* Tab local icon
*
* Local icon
*/
localIcon?: string
/** I18n key */
i18nKey?: I18n.I18nKey | null
}
/** Form rule */
type FormRule = import('naive-ui').FormItemRule
/** The global dropdown key */
type DropdownKey = 'closeCurrent' | 'closeOther' | 'closeLeft' | 'closeRight' | 'closeAll' | 'pin' | 'unpin'
}
/**
* I18n namespace
*
* Locales type
*/
namespace I18n {
type RouteKey = import('@elegant-router/types').RouteKey
type LangType = 'en-US' | 'zh-CN'
interface LangOption {
label: string
key: LangType
}
type I18nRouteKey = Exclude<RouteKey, 'root' | 'not-found'>
interface FormMsg {
required: string
invalid: string
}
interface Schema {
system: {
title: string
updateTitle: string
updateContent: string
updateConfirm: string
updateCancel: string
}
common: {
action: string
add: string
addSuccess: string
backToHome: string
batchDelete: string
cancel: string
close: string
check: string
expandColumn: string
columnSetting: string
config: string
confirm: string
delete: string
deleteSuccess: string
confirmDelete: string
edit: string
warning: string
error: string
index: string
keywordSearch: string
logout: string
logoutConfirm: string
lookForward: string
modify: string
modifySuccess: string
noData: string
operate: string
pleaseCheckValue: string
refresh: string
reset: string
search: string
switch: string
tip: string
trigger: string
update: string
updateSuccess: string
userCenter: string
yesOrNo: {
yes: string
no: string
}
}
request: {
logout: string
logoutMsg: string
logoutWithModal: string
logoutWithModalMsg: string
refreshToken: string
tokenExpired: string
}
theme: {
themeDrawerTitle: string
tabs: {
appearance: string
layout: string
general: string
preset: string
}
appearance: {
themeSchema: { title: string } & Record<UnionKey.ThemeScheme, string>
grayscale: string
colourWeakness: string
themeColor: {
title: string
followPrimary: string
} & Record<Theme.ThemeColorKey, string>
recommendColor: string
recommendColorDesc: string
themeRadius: {
title: string
}
preset: {
title: string
apply: string
applySuccess: string
[key: string]:
| {
name: string
desc: string
}
| string
}
}
layout: {
layoutMode: { title: string } & Record<UnionKey.ThemeLayoutMode, string> & {
[K in `${UnionKey.ThemeLayoutMode}_detail`]: string;
}
tab: {
title: string
visible: string
cache: string
cacheTip: string
height: string
mode: { title: string } & Record<UnionKey.ThemeTabMode, string>
closeByMiddleClick: string
closeByMiddleClickTip: string
}
header: {
title: string
height: string
breadcrumb: {
visible: string
showIcon: string
}
}
sider: {
title: string
inverted: string
width: string
collapsedWidth: string
mixWidth: string
mixCollapsedWidth: string
mixChildMenuWidth: string
autoSelectFirstMenu: string
autoSelectFirstMenuTip: string
}
footer: {
title: string
visible: string
fixed: string
height: string
right: string
}
content: {
title: string
scrollMode: { title: string, tip: string } & Record<UnionKey.ThemeScrollMode, string>
page: {
animate: string
mode: { title: string } & Record<UnionKey.ThemePageAnimateMode, string>
}
fixedHeaderAndTab: string
}
}
general: {
title: string
watermark: {
title: string
visible: string
text: string
enableUserName: string
enableTime: string
timeFormat: string
}
multilingual: {
title: string
visible: string
}
globalSearch: {
title: string
visible: string
}
}
configOperation: {
copyConfig: string
copySuccessMsg: string
resetConfig: string
resetSuccessMsg: string
}
}
route: Record<I18nRouteKey, string>
page: {
login: {
common: {
loginOrRegister: string
userNamePlaceholder: string
phonePlaceholder: string
codePlaceholder: string
passwordPlaceholder: string
confirmPasswordPlaceholder: string
codeLogin: string
confirm: string
back: string
validateSuccess: string
loginSuccess: string
welcomeBack: string
}
pwdLogin: {
title: string
rememberMe: string
forgetPassword: string
register: string
otherAccountLogin: string
otherLoginMode: string
superAdmin: string
admin: string
user: string
}
codeLogin: {
title: string
getCode: string
reGetCode: string
sendCodeSuccess: string
imageCodePlaceholder: string
}
register: {
title: string
agreement: string
protocol: string
policy: string
}
resetPwd: {
title: string
}
bindWeChat: {
title: string
}
}
home: {
branchDesc: string
greeting: string
weatherDesc: string
projectCount: string
todo: string
message: string
downloadCount: string
registerCount: string
schedule: string
study: string
work: string
rest: string
entertainment: string
visitCount: string
turnover: string
dealCount: string
projectNews: {
title: string
moreNews: string
desc1: string
desc2: string
desc3: string
desc4: string
desc5: string
}
creativity: string
}
}
form: {
required: string
userName: FormMsg
phone: FormMsg
pwd: FormMsg
confirmPwd: FormMsg
code: FormMsg
email: FormMsg
}
dropdown: Record<Global.DropdownKey, string>
icon: {
themeConfig: string
themeSchema: string
lang: string
fullscreen: string
fullscreenExit: string
reload: string
collapse: string
expand: string
pin: string
unpin: string
}
datatable: {
itemCount: string
}
}
type GetI18nKey<T extends Record<string, unknown>, K extends keyof T = keyof T> = K extends string
? T[K] extends Record<string, unknown>
? `${K}.${GetI18nKey<T[K]>}`
: K
: never
type I18nKey = GetI18nKey<Schema>
type TranslateOptions<Locales extends string> = import('vue-i18n').TranslateOptions<Locales>
interface $T {
(key: I18nKey): string
(key: I18nKey, plural: number, options?: TranslateOptions<LangType>): string
(key: I18nKey, defaultMsg: string, options?: TranslateOptions<I18nKey>): string
(key: I18nKey, list: unknown[], options?: TranslateOptions<I18nKey>): string
(key: I18nKey, list: unknown[], plural: number): string
(key: I18nKey, list: unknown[], defaultMsg: string): string
(key: I18nKey, named: Record<string, unknown>, options?: TranslateOptions<LangType>): string
(key: I18nKey, named: Record<string, unknown>, plural: number): string
(key: I18nKey, named: Record<string, unknown>, defaultMsg: string): string
}
}
/** Service namespace */
namespace Service {
/** Other baseURL key */
type OtherBaseURLKey = 'demo'
interface ServiceConfigItem {
/** The backend service base url */
baseURL: string
/** The proxy pattern of the backend service base url */
proxyPattern: string
}
interface OtherServiceConfigItem extends ServiceConfigItem {
key: OtherBaseURLKey
}
/** The backend service config */
interface ServiceConfig extends ServiceConfigItem {
/** Other backend service config */
other: OtherServiceConfigItem[]
}
interface SimpleServiceConfig extends Pick<ServiceConfigItem, 'baseURL'> {
other: Record<OtherBaseURLKey, string>
}
/** The backend service response data */
interface Response<T = unknown> {
/** The backend service response code */
code: string
/** The backend service response message */
msg: string
/** The backend service response data */
data: T
}
/** The demo backend service response data */
interface DemoResponse<T = unknown> {
/** The backend service response code */
status: string
/** The backend service response message */
message: string
/** The backend service response data */
result: T
}
}
}

25
apps/admin/src/typings/common.d.ts vendored Normal file
View File

@ -0,0 +1,25 @@
/** The common type namespace */
declare namespace CommonType {
/** The strategic pattern */
interface StrategicPattern {
/** The condition */
condition: boolean
/** If the condition is true, then call the action function */
callback: () => void
}
/**
* The option type
*
* @property value: The option value
* @property label: The option label
*/
interface Option<K = string, M = string> { value: K, label: M }
type YesOrNo = 'Y' | 'N'
/** add null to all properties */
type RecordNullable<T> = {
[K in keyof T]?: T[K] | null;
}
}

160
apps/admin/src/typings/components.d.ts vendored Normal file
View File

@ -0,0 +1,160 @@
/* eslint-disable */
// @ts-nocheck
// biome-ignore lint: disable
// oxlint-disable
// ------
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
import { GlobalComponents } from 'vue'
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
AppProvider: typeof import('./../components/common/app-provider.vue')['default']
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
CountTo: typeof import('./../components/custom/count-to.vue')['default']
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
FullScreen: typeof import('./../components/common/full-screen.vue')['default']
IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
IconLocalBanner: typeof import('~icons/local/banner')['default']
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
IconTooltip: typeof import('./../components/common/icon-tooltip.vue')['default']
IconUilSearch: typeof import('~icons/uil/search')['default']
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
NAlert: typeof import('naive-ui')['NAlert']
NBadge: typeof import('naive-ui')['NBadge']
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NColorPicker: typeof import('naive-ui')['NColorPicker']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
NDivider: typeof import('naive-ui')['NDivider']
NDrawer: typeof import('naive-ui')['NDrawer']
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
NDropdown: typeof import('naive-ui')['NDropdown']
NEmpty: typeof import('naive-ui')['NEmpty']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NInput: typeof import('naive-ui')['NInput']
NInputGroup: typeof import('naive-ui')['NInputGroup']
NInputNumber: typeof import('naive-ui')['NInputNumber']
NList: typeof import('naive-ui')['NList']
NListItem: typeof import('naive-ui')['NListItem']
NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NModal: typeof import('naive-ui')['NModal']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NScrollbar: typeof import('naive-ui')['NScrollbar']
NSelect: typeof import('naive-ui')['NSelect']
NSpace: typeof import('naive-ui')['NSpace']
NStatistic: typeof import('naive-ui')['NStatistic']
NSwitch: typeof import('naive-ui')['NSwitch']
NTab: typeof import('naive-ui')['NTab']
NTabs: typeof import('naive-ui')['NTabs']
NThing: typeof import('naive-ui')['NThing']
NTooltip: typeof import('naive-ui')['NTooltip']
NWatermark: typeof import('naive-ui')['NWatermark']
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SoybeanAvatar: typeof import('./../components/custom/soybean-avatar.vue')['default']
SvgIcon: typeof import('./../components/custom/svg-icon.vue')['default']
SystemLogo: typeof import('./../components/common/system-logo.vue')['default']
TableColumnSetting: typeof import('./../components/advanced/table-column-setting.vue')['default']
TableHeaderOperation: typeof import('./../components/advanced/table-header-operation.vue')['default']
ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default']
WaveBg: typeof import('./../components/custom/wave-bg.vue')['default']
}
}
// For TSX support
declare global {
const AppProvider: typeof import('./../components/common/app-provider.vue')['default']
const BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
const ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
const CountTo: typeof import('./../components/custom/count-to.vue')['default']
const DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
const ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
const FullScreen: typeof import('./../components/common/full-screen.vue')['default']
const IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
const IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
const IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
const IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
const IconLocalBanner: typeof import('~icons/local/banner')['default']
const IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
const IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
const IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
const IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
const IconTooltip: typeof import('./../components/common/icon-tooltip.vue')['default']
const IconUilSearch: typeof import('~icons/uil/search')['default']
const LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
const LookForward: typeof import('./../components/custom/look-forward.vue')['default']
const MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
const NAlert: typeof import('naive-ui')['NAlert']
const NBadge: typeof import('naive-ui')['NBadge']
const NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
const NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
const NButton: typeof import('naive-ui')['NButton']
const NCard: typeof import('naive-ui')['NCard']
const NCheckbox: typeof import('naive-ui')['NCheckbox']
const NColorPicker: typeof import('naive-ui')['NColorPicker']
const NDialogProvider: typeof import('naive-ui')['NDialogProvider']
const NDivider: typeof import('naive-ui')['NDivider']
const NDrawer: typeof import('naive-ui')['NDrawer']
const NDrawerContent: typeof import('naive-ui')['NDrawerContent']
const NDropdown: typeof import('naive-ui')['NDropdown']
const NEmpty: typeof import('naive-ui')['NEmpty']
const NForm: typeof import('naive-ui')['NForm']
const NFormItem: typeof import('naive-ui')['NFormItem']
const NGi: typeof import('naive-ui')['NGi']
const NGrid: typeof import('naive-ui')['NGrid']
const NInput: typeof import('naive-ui')['NInput']
const NInputGroup: typeof import('naive-ui')['NInputGroup']
const NInputNumber: typeof import('naive-ui')['NInputNumber']
const NList: typeof import('naive-ui')['NList']
const NListItem: typeof import('naive-ui')['NListItem']
const NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
const NMenu: typeof import('naive-ui')['NMenu']
const NMessageProvider: typeof import('naive-ui')['NMessageProvider']
const NModal: typeof import('naive-ui')['NModal']
const NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
const NScrollbar: typeof import('naive-ui')['NScrollbar']
const NSelect: typeof import('naive-ui')['NSelect']
const NSpace: typeof import('naive-ui')['NSpace']
const NStatistic: typeof import('naive-ui')['NStatistic']
const NSwitch: typeof import('naive-ui')['NSwitch']
const NTab: typeof import('naive-ui')['NTab']
const NTabs: typeof import('naive-ui')['NTabs']
const NThing: typeof import('naive-ui')['NThing']
const NTooltip: typeof import('naive-ui')['NTooltip']
const NWatermark: typeof import('naive-ui')['NWatermark']
const PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
const ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
const RouterLink: typeof import('vue-router')['RouterLink']
const RouterView: typeof import('vue-router')['RouterView']
const SoybeanAvatar: typeof import('./../components/custom/soybean-avatar.vue')['default']
const SvgIcon: typeof import('./../components/custom/svg-icon.vue')['default']
const SystemLogo: typeof import('./../components/common/system-logo.vue')['default']
const TableColumnSetting: typeof import('./../components/advanced/table-column-setting.vue')['default']
const TableHeaderOperation: typeof import('./../components/advanced/table-header-operation.vue')['default']
const ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default']
const WaveBg: typeof import('./../components/custom/wave-bg.vue')['default']
}

View File

@ -0,0 +1,243 @@
/* eslint-disable */
/* prettier-ignore */
// Generated by elegant-router
// Read more: https://github.com/soybeanjs/elegant-router
declare module "@elegant-router/types" {
type ElegantConstRoute = import('@elegant-router/vue').ElegantConstRoute;
/**
* route layout
*/
export type RouteLayout = "base" | "blank";
/**
* route map
*/
export type RouteMap = {
"root": "/";
"not-found": "/:pathMatch(.*)*";
"403": "/403";
"404": "/404";
"500": "/500";
"home": "/home";
"iframe-page": "/iframe-page/:url";
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
"mine": "/mine";
};
/**
* route key
*/
export type RouteKey = keyof RouteMap;
/**
* route path
*/
export type RoutePath = RouteMap[RouteKey];
/**
* custom route key
*/
export type CustomRouteKey = Extract<
RouteKey,
| "root"
| "not-found"
>;
/**
* the generated route key
*/
export type GeneratedRouteKey = Exclude<RouteKey, CustomRouteKey>;
/**
* the first level route key, which contain the layout of the route
*/
export type FirstLevelRouteKey = Extract<
RouteKey,
| "403"
| "404"
| "500"
| "home"
| "iframe-page"
| "login"
| "mine"
>;
/**
* the custom first level route key
*/
export type CustomFirstLevelRouteKey = Extract<
CustomRouteKey,
| "root"
| "not-found"
>;
/**
* the last level route key, which has the page file
*/
export type LastLevelRouteKey = Extract<
RouteKey,
| "403"
| "404"
| "500"
| "iframe-page"
| "login"
| "home"
| "mine"
>;
/**
* the custom last level route key
*/
export type CustomLastLevelRouteKey = Extract<
CustomRouteKey,
| "root"
| "not-found"
>;
/**
* the single level route key
*/
export type SingleLevelRouteKey = FirstLevelRouteKey & LastLevelRouteKey;
/**
* the custom single level route key
*/
export type CustomSingleLevelRouteKey = CustomFirstLevelRouteKey & CustomLastLevelRouteKey;
/**
* the first level route key, but not the single level
*/
export type FirstLevelRouteNotSingleKey = Exclude<FirstLevelRouteKey, SingleLevelRouteKey>;
/**
* the custom first level route key, but not the single level
*/
export type CustomFirstLevelRouteNotSingleKey = Exclude<CustomFirstLevelRouteKey, CustomSingleLevelRouteKey>;
/**
* the center level route key
*/
export type CenterLevelRouteKey = Exclude<GeneratedRouteKey, FirstLevelRouteKey | LastLevelRouteKey>;
/**
* the custom center level route key
*/
export type CustomCenterLevelRouteKey = Exclude<CustomRouteKey, CustomFirstLevelRouteKey | CustomLastLevelRouteKey>;
/**
* the center level route key
*/
type GetChildRouteKey<K extends RouteKey, T extends RouteKey = RouteKey> = T extends `${K}_${infer R}`
? R extends `${string}_${string}`
? never
: T
: never;
/**
* the single level route
*/
type SingleLevelRoute<K extends SingleLevelRouteKey = SingleLevelRouteKey> = K extends string
? Omit<ElegantConstRoute, 'children'> & {
name: K;
path: RouteMap[K];
component: `layout.${RouteLayout}$view.${K}`;
}
: never;
/**
* the last level route
*/
type LastLevelRoute<K extends GeneratedRouteKey> = K extends LastLevelRouteKey
? Omit<ElegantConstRoute, 'children'> & {
name: K;
path: RouteMap[K];
component: `view.${K}`;
}
: never;
/**
* the center level route
*/
type CenterLevelRoute<K extends GeneratedRouteKey> = K extends CenterLevelRouteKey
? Omit<ElegantConstRoute, 'component'> & {
name: K;
path: RouteMap[K];
children: (CenterLevelRoute<GetChildRouteKey<K>> | LastLevelRoute<GetChildRouteKey<K>>)[];
}
: never;
/**
* the multi level route
*/
type MultiLevelRoute<K extends FirstLevelRouteNotSingleKey = FirstLevelRouteNotSingleKey> = K extends string
? ElegantConstRoute & {
name: K;
path: RouteMap[K];
component: `layout.${RouteLayout}`;
children: (CenterLevelRoute<GetChildRouteKey<K>> | LastLevelRoute<GetChildRouteKey<K>>)[];
}
: never;
/**
* the custom first level route
*/
type CustomSingleLevelRoute<K extends CustomFirstLevelRouteKey = CustomFirstLevelRouteKey> = K extends string
? Omit<ElegantConstRoute, 'children'> & {
name: K;
path: RouteMap[K];
component?: `layout.${RouteLayout}$view.${LastLevelRouteKey}`;
}
: never;
/**
* the custom last level route
*/
type CustomLastLevelRoute<K extends CustomRouteKey> = K extends CustomLastLevelRouteKey
? Omit<ElegantConstRoute, 'children'> & {
name: K;
path: RouteMap[K];
component?: `view.${LastLevelRouteKey}`;
}
: never;
/**
* the custom center level route
*/
type CustomCenterLevelRoute<K extends CustomRouteKey> = K extends CustomCenterLevelRouteKey
? Omit<ElegantConstRoute, 'component'> & {
name: K;
path: RouteMap[K];
children: (CustomCenterLevelRoute<GetChildRouteKey<K>> | CustomLastLevelRoute<GetChildRouteKey<K>>)[];
}
: never;
/**
* the custom multi level route
*/
type CustomMultiLevelRoute<K extends CustomFirstLevelRouteNotSingleKey = CustomFirstLevelRouteNotSingleKey> =
K extends string
? ElegantConstRoute & {
name: K;
path: RouteMap[K];
component: `layout.${RouteLayout}`;
children: (CustomCenterLevelRoute<GetChildRouteKey<K>> | CustomLastLevelRoute<GetChildRouteKey<K>>)[];
}
: never;
/**
* the custom route
*/
type CustomRoute = CustomSingleLevelRoute | CustomMultiLevelRoute;
/**
* the generated route
*/
type GeneratedRoute = SingleLevelRoute | MultiLevelRoute;
/**
* the elegant route
*/
type ElegantRoute = GeneratedRoute | CustomRoute;
}

19
apps/admin/src/typings/global.d.ts vendored Normal file
View File

@ -0,0 +1,19 @@
export {}
declare global {
export interface Window {
/** NProgress instance */
NProgress?: import('nprogress').NProgress
/** Loading bar instance */
$loadingBar?: import('naive-ui').LoadingBarProviderInst
/** Dialog instance */
$dialog?: import('naive-ui').DialogProviderInst
/** Message instance */
$message?: import('naive-ui').MessageProviderInst
/** Notification instance */
$notification?: import('naive-ui').NotificationProviderInst
}
/** Build time of the project */
export const BUILD_TIME: string
}

24
apps/admin/src/typings/naive-ui.d.ts vendored Normal file
View File

@ -0,0 +1,24 @@
declare namespace NaiveUI {
type ThemeColor = 'default' | 'error' | 'primary' | 'info' | 'success' | 'warning'
type Align = 'stretch' | 'baseline' | 'start' | 'end' | 'center' | 'flex-end' | 'flex-start'
type DataTableBaseColumn<T> = import('naive-ui').DataTableBaseColumn<T>
type DataTableExpandColumn<T> = import('naive-ui').DataTableExpandColumn<T>
type DataTableSelectionColumn<T> = import('naive-ui').DataTableSelectionColumn<T>
type TableColumnGroup<T> = import('naive-ui/es/data-table/src/interface').TableColumnGroup<T>
type TableColumnCheck = import('@sa/hooks').TableColumnCheck
type SetTableColumnKey<C, T> = Omit<C, 'key'> & { key: keyof T | (string & {}) }
type TableColumnWithKey<T> = SetTableColumnKey<DataTableBaseColumn<T>, T> | SetTableColumnKey<TableColumnGroup<T>, T>
type TableColumn<T> = TableColumnWithKey<T> | DataTableSelectionColumn<T> | DataTableExpandColumn<T>
/**
* the type of table operation
*
* - add: add table item
* - edit: edit table item
*/
type TableOperateType = 'add' | 'edit'
}

72
apps/admin/src/typings/router.d.ts vendored Normal file
View File

@ -0,0 +1,72 @@
import 'vue-router'
declare module 'vue-router' {
interface RouteMeta {
/**
* Title of the route
*
* It can be used in document title
*/
title: string
/**
* I18n key of the route
*
* It's used in i18n, if it is set, the title will be ignored
*/
i18nKey?: App.I18n.I18nKey | null
/**
* Roles of the route
*
* Route can be accessed if the current user has at least one of the roles
*
* It only works when the route mode is "static", if the route mode is "dynamic", it will be ignored
*/
roles?: string[]
/** Whether to cache the route */
keepAlive?: boolean | null
/**
* Is constant route
*
* when it is set to true, there will be no login verification and no permission verification to access the route
*/
constant?: boolean | null
/**
* Iconify icon
*
* It can be used in the menu or breadcrumb
*/
icon?: string
/**
* Local icon
*
* In "src/assets/svg-icon", if it is set, the icon will be ignored
*/
localIcon?: string
/** Icon size. width and height are the same. */
iconFontSize?: number
/** Router order */
order?: number | null
/** The outer link of the route */
href?: string | null
/** Whether to hide the route in the menu */
hideInMenu?: boolean | null
/**
* The menu key will be activated when entering the route
*
* The route is not in the menu
*
* @example
* the route is "user_detail", if it is set to "user_list", the menu "user_list" will be activated
*/
activeMenu?: import('@elegant-router/types').RouteKey | null
/**
* By default, the same route path will use one tab, even with different query, if set true, the route with
* different query will use different tabs
*/
multiTab?: boolean | null
/** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */
fixedIndexInTab?: number | null
/** if set query parameters, it will be automatically carried when entering the route */
query?: { key: string, value: string }[] | null
}
}

43
apps/admin/src/typings/storage.d.ts vendored Normal file
View File

@ -0,0 +1,43 @@
/** The storage namespace */
declare namespace StorageType {
interface Session {
/** The theme color */
themeColor: string
// /**
// * the theme settings
// */
// themeSettings: App.Theme.ThemeSetting;
}
interface Local {
/** The i18n language */
lang: App.I18n.LangType
/** The token */
token: string
/** Fixed sider with mix-menu */
mixSiderFixed: CommonType.YesOrNo
/** The refresh token */
refreshToken: string
/** The theme color */
themeColor: string
/** The dark mode */
darkMode: boolean
/** The theme settings */
themeSettings: App.Theme.ThemeSetting
/**
* The override theme flags
*
* The value is the build time of the project
*/
overrideThemeFlag: string
/** The global tabs */
globalTabs: App.Global.Tab[]
/** The backup theme setting before is mobile */
backupThemeSettingBeforeIsMobile: {
layout: UnionKey.ThemeLayoutMode
siderCollapse: boolean
}
/** The last login user id */
lastLoginUserId: string
}
}

156
apps/admin/src/typings/union-key.d.ts vendored Normal file
View File

@ -0,0 +1,156 @@
/** The union key namespace */
declare namespace UnionKey {
/**
* The login module
*
* - pwd-login: password login
* - code-login: phone code login
* - register: register
* - reset-pwd: reset password
* - bind-wechat: bind wechat
*/
type LoginModule = 'pwd-login' | 'code-login' | 'register' | 'reset-pwd' | 'bind-wechat'
/** Theme scheme */
type ThemeScheme = 'light' | 'dark' | 'auto'
/**
* The layout mode
*
* - vertical: the vertical menu in left
* - horizontal: the horizontal menu in top
* - vertical-mix: two vertical mixed menus in left
* - top-hybrid-sidebar-first: the vertical first level menus in left and horizontal child level menus in top
* - top-hybrid-header-first: the horizontal first level menus in top and vertical child level menus in left
*/
type ThemeLayoutMode =
| 'vertical'
| 'horizontal'
| 'vertical-mix'
| 'vertical-hybrid-header-first'
| 'top-hybrid-sidebar-first'
| 'top-hybrid-header-first'
/**
* The scroll mode when content overflow
*
* - wrapper: the wrapper component's root element overflow
* - content: the content component overflow
*/
type ThemeScrollMode = import('@sa/materials').LayoutScrollMode
/** Page animate mode */
type ThemePageAnimateMode = 'fade' | 'fade-slide' | 'fade-bottom' | 'fade-scale' | 'zoom-fade' | 'zoom-out' | 'none'
/**
* Tab mode
*
* - chrome: chrome style
* - button: button style
*/
type ThemeTabMode = import('@sa/materials').PageTabMode
/** Unocss animate key */
type UnoCssAnimateKey =
| 'pulse'
| 'bounce'
| 'spin'
| 'ping'
| 'bounce-alt'
| 'flash'
| 'pulse-alt'
| 'rubber-band'
| 'shake-x'
| 'shake-y'
| 'head-shake'
| 'swing'
| 'tada'
| 'wobble'
| 'jello'
| 'heart-beat'
| 'hinge'
| 'jack-in-the-box'
| 'light-speed-in-left'
| 'light-speed-in-right'
| 'light-speed-out-left'
| 'light-speed-out-right'
| 'flip'
| 'flip-in-x'
| 'flip-in-y'
| 'flip-out-x'
| 'flip-out-y'
| 'rotate-in'
| 'rotate-in-down-left'
| 'rotate-in-down-right'
| 'rotate-in-up-left'
| 'rotate-in-up-right'
| 'rotate-out'
| 'rotate-out-down-left'
| 'rotate-out-down-right'
| 'rotate-out-up-left'
| 'rotate-out-up-right'
| 'roll-in'
| 'roll-out'
| 'zoom-in'
| 'zoom-in-down'
| 'zoom-in-left'
| 'zoom-in-right'
| 'zoom-in-up'
| 'zoom-out'
| 'zoom-out-down'
| 'zoom-out-left'
| 'zoom-out-right'
| 'zoom-out-up'
| 'bounce-in'
| 'bounce-in-down'
| 'bounce-in-left'
| 'bounce-in-right'
| 'bounce-in-up'
| 'bounce-out'
| 'bounce-out-down'
| 'bounce-out-left'
| 'bounce-out-right'
| 'bounce-out-up'
| 'slide-in-down'
| 'slide-in-left'
| 'slide-in-right'
| 'slide-in-up'
| 'slide-out-down'
| 'slide-out-left'
| 'slide-out-right'
| 'slide-out-up'
| 'fade-in'
| 'fade-in-down'
| 'fade-in-down-big'
| 'fade-in-left'
| 'fade-in-left-big'
| 'fade-in-right'
| 'fade-in-right-big'
| 'fade-in-up'
| 'fade-in-up-big'
| 'fade-in-top-left'
| 'fade-in-top-right'
| 'fade-in-bottom-left'
| 'fade-in-bottom-right'
| 'fade-out'
| 'fade-out-down'
| 'fade-out-down-big'
| 'fade-out-left'
| 'fade-out-left-big'
| 'fade-out-right'
| 'fade-out-right-big'
| 'fade-out-up'
| 'fade-out-up-big'
| 'fade-out-top-left'
| 'fade-out-top-right'
| 'fade-out-bottom-left'
| 'fade-out-bottom-right'
| 'back-in-up'
| 'back-in-down'
| 'back-in-right'
| 'back-in-left'
| 'back-out-up'
| 'back-out-down'
| 'back-out-right'
| 'back-out-left'
}

118
apps/admin/src/typings/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1,118 @@
/**
* Namespace Env
*
* It is used to declare the type of the import.meta object
*/
declare namespace Env {
/** The router history mode */
type RouterHistoryMode = 'hash' | 'history' | 'memory'
/** Interface for import.meta */
// eslint-disable-next-line ts/no-shadow
interface ImportMeta extends ImportMetaEnv {
/** The base url of the application */
readonly VITE_BASE_URL: string
/** The title of the application */
readonly VITE_APP_TITLE: string
/** The description of the application */
readonly VITE_APP_DESC: string
/** The router history mode */
readonly VITE_ROUTER_HISTORY_MODE?: RouterHistoryMode
/** The prefix of the iconify icon */
readonly VITE_ICON_PREFIX: 'icon'
/**
* The prefix of the local icon
*
* This prefix is start with the icon prefix
*/
readonly VITE_ICON_LOCAL_PREFIX: 'icon-local'
/** backend service base url */
readonly VITE_SERVICE_BASE_URL: string
/**
* success code of backend service
*
* when the code is received, the request is successful
*/
readonly VITE_SERVICE_SUCCESS_CODE: string
/**
* logout codes of backend service
*
* when the code is received, the user will be logged out and redirected to login page
*
* use "," to separate multiple codes
*/
readonly VITE_SERVICE_LOGOUT_CODES: string
/**
* modal logout codes of backend service
*
* when the code is received, the user will be logged out by displaying a modal
*
* use "," to separate multiple codes
*/
readonly VITE_SERVICE_MODAL_LOGOUT_CODES: string
/**
* token expired codes of backend service
*
* when the code is received, it will refresh the token and resend the request
*
* use "," to separate multiple codes
*/
readonly VITE_SERVICE_EXPIRED_TOKEN_CODES: string
/** when the route mode is static, the defined super role */
readonly VITE_STATIC_SUPER_ROLE: string
/**
* other backend service base url
*
* the value is a json
*/
readonly VITE_OTHER_SERVICE_BASE_URL: string
/**
* Whether to enable the http proxy
*
* Only valid in the development environment
*/
readonly VITE_HTTP_PROXY?: CommonType.YesOrNo
/**
* The auth route mode
*
* - Static: the auth routes is generated in front-end
* - Dynamic: the auth routes is generated in back-end
*/
readonly VITE_AUTH_ROUTE_MODE: 'static' | 'dynamic'
/**
* The home route key
*
* It only has effect when the auth route mode is static, if the route mode is dynamic, the home route key is
* defined in the back-end
*/
readonly VITE_ROUTE_HOME: import('@elegant-router/types').LastLevelRouteKey
/**
* Default menu icon if menu icon is not set
*
* Iconify icon name
*/
readonly VITE_MENU_ICON: string
/** Whether to build with sourcemap */
readonly VITE_SOURCE_MAP?: CommonType.YesOrNo
/**
* Iconify api provider url
*
* If the project is deployed in intranet, you can set the api provider url to the local iconify server
*
* @link https://docs.iconify.design/api/providers.html
*/
readonly VITE_ICONIFY_URL?: string
/** Used to differentiate storage across different domains */
readonly VITE_STORAGE_PREFIX?: string
/** Whether to automatically detect updates after configuring application packaging */
readonly VITE_AUTOMATICALLY_DETECT_UPDATE?: CommonType.YesOrNo
/** show proxy url log in terminal */
readonly VITE_PROXY_LOG?: CommonType.YesOrNo
/** The launch editor */
readonly VITE_DEVTOOLS_LAUNCH_EDITOR?: import('vite-plugin-vue-devtools').VitePluginVueDevToolsOptions['launchEditor']
}
}
interface ImportMeta {
readonly env: Env.ImportMeta
}