From e55a822addc2754ba7103ae1eec0f3010d4a40f5 Mon Sep 17 00:00:00 2001 From: shaoyou <57701184+1750911700@users.noreply.github.com> Date: Wed, 16 Jul 2025 15:46:12 +0800 Subject: [PATCH] feat(projects): ceshitijiao --- .env | 44 +++---- .env.prod | 4 +- .env.test | 4 +- build/config/proxy.ts | 12 +- packages/scripts/src/index.ts | 44 +++---- src/locales/langs/en-us.ts | 3 +- src/locales/langs/zh-cn.ts | 3 +- src/router/elegant/imports.ts | 1 + src/router/elegant/routes.ts | 12 +- src/router/elegant/transform.ts | 1 + src/router/guard/route.ts | 47 ++++---- src/service/api/route.ts | 8 +- src/typings/api.d.ts | 49 ++++---- src/typings/app.d.ts | 204 ++++++++++++++++---------------- src/typings/elegant-router.d.ts | 3 + src/typings/vite-env.d.ts | 85 +++++++------ src/utils/service.ts | 16 +-- src/views/cesium/index.vue | 19 +++ 18 files changed, 302 insertions(+), 257 deletions(-) create mode 100644 src/views/cesium/index.vue diff --git a/.env b/.env index 4b59e331..17ba9ca4 100644 --- a/.env +++ b/.env @@ -1,60 +1,60 @@ -# the base url of the application, the default is "/" -# if use a sub directory, it must be end with "/", like "/admin/" but not "/admin" +# 应用的基础路径,默认为 "/" +# 如果使用子目录,必须以 "/" 结尾,如 "/admin/" 而不是 "/admin" VITE_BASE_URL=/ VITE_APP_TITLE=SoybeanAdmin -VITE_APP_DESC=SoybeanAdmin is a fresh and elegant admin template +VITE_APP_DESC=SoybeanAdmin 是一个清新优雅的管理后台模板 -# the prefix of the icon name +# 图标名称的前缀 VITE_ICON_PREFIX=icon -# the prefix of the local svg icon component, must include VITE_ICON_PREFIX -# format {VITE_ICON_PREFIX}-{local icon name} +# 本地 svg 图标组件的前缀,必须包含 VITE_ICON_PREFIX +# 格式为 {VITE_ICON_PREFIX}-{本地图标名} VITE_ICON_LOCAL_PREFIX=icon-local -# auth route mode: static | dynamic +# 权限路由模式:static | dynamic VITE_AUTH_ROUTE_MODE=static -# static auth route home +# static 权限路由的首页 VITE_ROUTE_HOME=home -# default menu icon +# 默认菜单图标 VITE_MENU_ICON=mdi:menu -# whether to enable http proxy when is dev mode +# 是否在开发模式下启用 http 代理 VITE_HTTP_PROXY=Y -# vue-router mode: hash | history | memory +# vue-router 模式:hash | history | memory VITE_ROUTER_HISTORY_MODE=history -# success code of backend service, when the code is received, the request is successful +# 后端服务的成功状态码,收到该状态码时请求成功 VITE_SERVICE_SUCCESS_CODE=0000 -# logout codes of backend service, when the code is received, the user will be logged out and redirected to login page +# 后端服务登出状态码,收到该状态码时用户会被登出并跳转到登录页 VITE_SERVICE_LOGOUT_CODES=8888,8889 -# modal logout codes of backend service, when the code is received, the user will be logged out by displaying a modal +# 后端服务弹窗登出状态码,收到该状态码时会弹窗提示并登出 VITE_SERVICE_MODAL_LOGOUT_CODES=7777,7778 -# token expired codes of backend service, when the code is received, it will refresh the token and resend the request +# 后端服务 token 过期状态码,收到该状态码时会刷新 token 并重新发送请求 VITE_SERVICE_EXPIRED_TOKEN_CODES=9999,9998,3333 -# when the route mode is static, the defined super role +# 路由模式为 static 时定义的超级角色 VITE_STATIC_SUPER_ROLE=R_SUPER -# sourcemap +# 是否生成 sourcemap VITE_SOURCE_MAP=N -# Used to differentiate storage across different domains +# 用于区分不同域名下的存储 VITE_STORAGE_PREFIX=SOY_ -# used to control whether the program automatically detects updates +# 控制程序打包后是否自动检测更新 VITE_AUTOMATICALLY_DETECT_UPDATE=Y -# show proxy url log in terminal +# 是否在终端显示代理地址日志 VITE_PROXY_LOG=Y -# used to control whether to launch editor -# by the way, this plugin is only available in dev mode, not in build mode +# 控制是否启动编辑器 +# 此插件仅在开发模式下可用,构建模式下不可用 VITE_DEVTOOLS_LAUNCH_EDITOR=code diff --git a/.env.prod b/.env.prod index f5677640..0975b508 100644 --- a/.env.prod +++ b/.env.prod @@ -1,7 +1,7 @@ -# backend service base url, prod environment +# # 后端服务基础地址,生产环境 VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default -# other backend service base url, prod environment +# 其他后端服务基础地址,生产环境 VITE_OTHER_SERVICE_BASE_URL= `{ "demo": "http://localhost:9529" }` diff --git a/.env.test b/.env.test index dd18d7bb..f08e735d 100644 --- a/.env.test +++ b/.env.test @@ -1,7 +1,7 @@ -# backend service base url, test environment +# 后端服务基础地址,测试环境 VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default -# other backend service base url, test environment +# 其他后端服务基础地址,测试环境 VITE_OTHER_SERVICE_BASE_URL= `{ "demo": "http://localhost:9528" }` diff --git a/build/config/proxy.ts b/build/config/proxy.ts index e307d30e..27460e68 100644 --- a/build/config/proxy.ts +++ b/build/config/proxy.ts @@ -4,10 +4,10 @@ import { consola } from 'consola'; import { createServiceConfig } from '../../src/utils/service'; /** - * Set http proxy + * 设置 http 代理 * - * @param env - The current env - * @param enable - If enable http proxy + * @param env - 当前环境变量 + * @param enable - 是否启用 http 代理 */ export function createViteProxy(env: Env.ImportMeta, enable: boolean) { const isEnableHttpProxy = enable && env.VITE_HTTP_PROXY === 'Y'; @@ -27,6 +27,12 @@ export function createViteProxy(env: Env.ImportMeta, enable: boolean) { return proxy; } +/** + * 创建单个代理项 + * + * @param item 代理配置项 + * @param enableLog 是否启用日志 + */ function createProxyItem(item: App.Service.ServiceConfigItem, enableLog: boolean) { const proxy: Record = {}; diff --git a/packages/scripts/src/index.ts b/packages/scripts/src/index.ts index 34367d79..5e6d3ba7 100755 --- a/packages/scripts/src/index.ts +++ b/packages/scripts/src/index.ts @@ -12,22 +12,22 @@ type CommandAction = (args?: A) => Promise | void; type CommandWithAction = Record }>; interface CommandArg { - /** Execute additional command after bumping and before git commit. Defaults to 'pnpm sa changelog' */ + /** bump 版本并 git commit 之前执行的额外命令,默认为 'pnpm sa changelog' */ execute?: string; - /** Indicates whether to push the git commit and tag. Defaults to true */ + /** 是否推送 git commit 和 tag,默认为 true */ push?: boolean; - /** Generate changelog by total tags */ + /** 是否根据所有 tag 生成 changelog */ total?: boolean; /** - * The glob pattern of dirs to clean up + * 需要清理的目录的 glob 模式 * - * If not set, it will use the default value + * 如果未设置,则使用默认值 * - * Multiple values use "," to separate them + * 多个值用 "," 分隔 */ cleanupDir?: string; /** - * display lang of cli + * CLI 显示语言 * * @default 'en-us' */ @@ -41,58 +41,52 @@ export async function setupCli() { cli .version(lightGreen(version)) - .option( - '-e, --execute [command]', - "Execute additional command after bumping and before git commit. Defaults to 'npx soy changelog'" - ) - .option('-p, --push', 'Indicates whether to push the git commit and tag') - .option('-t, --total', 'Generate changelog by total tags') - .option( - '-c, --cleanupDir ', - 'The glob pattern of dirs to cleanup, If not set, it will use the default value, Multiple values use "," to separate them' - ) - .option('-l, --lang ', 'display lang of cli', { default: 'en-us', type: [String] }) + .option('-e, --execute [command]', "bump 版本并 git commit 之前执行的额外命令,默认为 'npx soy changelog'") + .option('-p, --push', '是否推送 git commit 和 tag') + .option('-t, --total', '是否根据所有 tag 生成 changelog') + .option('-c, --cleanupDir ', '需要清理的目录的 glob 模式,未设置则使用默认值,多个值用 "," 分隔') + .option('-l, --lang ', 'CLI 显示语言', { default: 'en-us', type: [String] }) .help(); const commands: CommandWithAction = { cleanup: { - desc: 'delete dirs: node_modules, dist, etc.', + desc: '删除 node_modules、dist 等目录', action: async () => { await cleanup(cliOptions.cleanupDirs); } }, 'update-pkg': { - desc: 'update package.json dependencies versions', + desc: '更新 package.json 依赖版本', action: async () => { await updatePkg(cliOptions.ncuCommandArgs); } }, 'git-commit': { - desc: 'git commit, generate commit message which match Conventional Commits standard', + desc: 'git commit,生成符合 Conventional Commits 规范的提交信息', action: async args => { await gitCommit(args?.lang); } }, 'git-commit-verify': { - desc: 'verify git commit message, make sure it match Conventional Commits standard', + desc: '校验 git commit 信息,确保符合 Conventional Commits 规范', action: async args => { await gitCommitVerify(args?.lang, cliOptions.gitCommitVerifyIgnores); } }, changelog: { - desc: 'generate changelog', + desc: '生成 changelog', action: async args => { await genChangelog(cliOptions.changelogOptions, args?.total); } }, release: { - desc: 'release: update version, generate changelog, commit code', + desc: '发布:更新版本、生成 changelog、提交代码', action: async args => { await release(args?.execute, args?.push); } }, 'gen-route': { - desc: 'generate route', + desc: '生成路由', action: async () => { await generateRoute(); } diff --git a/src/locales/langs/en-us.ts b/src/locales/langs/en-us.ts index bd7db0ff..d29b6d0a 100644 --- a/src/locales/langs/en-us.ts +++ b/src/locales/langs/en-us.ts @@ -166,7 +166,8 @@ const local: App.I18n.Schema = { 404: 'Page Not Found', 500: 'Server Error', 'iframe-page': 'Iframe', - home: 'Home' + home: 'Home', + cesium: 'Cesium' }, page: { login: { diff --git a/src/locales/langs/zh-cn.ts b/src/locales/langs/zh-cn.ts index 446a596e..23dbad81 100644 --- a/src/locales/langs/zh-cn.ts +++ b/src/locales/langs/zh-cn.ts @@ -166,7 +166,8 @@ const local: App.I18n.Schema = { 404: '页面不存在', 500: '服务器错误', 'iframe-page': '外链页面', - home: '首页' + home: '首页', + cesium: '三维地球' }, page: { login: { diff --git a/src/router/elegant/imports.ts b/src/router/elegant/imports.ts index ce1b9d7d..433891f0 100644 --- a/src/router/elegant/imports.ts +++ b/src/router/elegant/imports.ts @@ -20,5 +20,6 @@ export const views: Record Promise import("@/views/_builtin/500/index.vue"), "iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"), login: () => import("@/views/_builtin/login/index.vue"), + cesium: () => import("@/views/cesium/index.vue"), home: () => import("@/views/home/index.vue"), }; diff --git a/src/router/elegant/routes.ts b/src/router/elegant/routes.ts index 9566e125..9f025c94 100644 --- a/src/router/elegant/routes.ts +++ b/src/router/elegant/routes.ts @@ -39,6 +39,16 @@ export const generatedRoutes: GeneratedRoute[] = [ hideInMenu: true } }, + { + name: 'cesium', + path: '/cesium', + component: 'layout.base$view.cesium', + meta: { + title: 'cesium', + i18nKey: 'route.cesium', + order: 1 + } + }, { name: 'home', path: '/home', @@ -47,7 +57,7 @@ export const generatedRoutes: GeneratedRoute[] = [ title: 'home', i18nKey: 'route.home', icon: 'mdi:monitor-dashboard', - order: 1 + order: 0 } }, { diff --git a/src/router/elegant/transform.ts b/src/router/elegant/transform.ts index ba892572..5fc82a44 100644 --- a/src/router/elegant/transform.ts +++ b/src/router/elegant/transform.ts @@ -166,6 +166,7 @@ const routeMap: RouteMap = { "403": "/403", "404": "/404", "500": "/500", + "cesium": "/cesium", "home": "/home", "iframe-page": "/iframe-page/:url", "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?" diff --git a/src/router/guard/route.ts b/src/router/guard/route.ts index 1a36989c..6d628537 100644 --- a/src/router/guard/route.ts +++ b/src/router/guard/route.ts @@ -12,9 +12,9 @@ import { localStg } from '@/utils/storage'; import { getRouteName } from '@/router/elegant/transform'; /** - * create route guard + * 创建路由守卫 * - * @param router router instance + * @param router 路由实例 */ export function createRouteGuard(router: Router) { router.beforeEach(async (to, from, next) => { @@ -38,39 +38,39 @@ export function createRouteGuard(router: Router) { const hasRole = authStore.userInfo.roles.some(role => routeRoles.includes(role)); const hasAuth = authStore.isStaticSuper || !routeRoles.length || hasRole; - // if it is login route when logged in, then switch to the root page + // 已登录时访问登录页,跳转到首页 if (to.name === loginRoute && isLogin) { next({ name: rootRoute }); return; } - // if the route does not need login, then it is allowed to access directly + // 路由不需要登录,直接放行 if (!needLogin) { handleRouteSwitch(to, from, next); return; } - // the route need login but the user is not logged in, then switch to the login page + // 路由需要登录但用户未登录,跳转到登录页 if (!isLogin) { next({ name: loginRoute, query: { redirect: to.fullPath } }); return; } - // if the user is logged in but does not have authorization, then switch to the 403 page + // 已登录但无权限,跳转到 403 页面 if (!hasAuth) { next({ name: noAuthorizationRoute }); return; } - // switch route normally + // 正常切换路由 handleRouteSwitch(to, from, next); }); } /** - * initialize route + * 初始化路由 * - * @param to to route + * @param to 目标路由 */ async function initRoute(to: RouteLocationNormalized): Promise { const routeStore = useRouteStore(); @@ -78,12 +78,12 @@ async function initRoute(to: RouteLocationNormalized): Promise({ url: '/route/getConstantRoutes' }); } -/** get user routes */ +/** 获取用户路由 */ export function fetchGetUserRoutes() { return request({ url: '/route/getUserRoutes' }); } /** - * whether the route is exist + * 判断路由是否存在 * - * @param routeName route name + * @param routeName 路由名称 */ export function fetchIsRouteExist(routeName: string) { return request({ url: '/route/isRouteExist', params: { routeName } }); diff --git a/src/typings/api.d.ts b/src/typings/api.d.ts index 5a8e2552..f716d22a 100644 --- a/src/typings/api.d.ts +++ b/src/typings/api.d.ts @@ -1,64 +1,67 @@ /** - * Namespace Api + * 命名空间 Api * - * All backend api type + * 所有后端 API 类型 */ 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 extends PaginatingCommonParams { + /** 数据列表 */ records: T[]; } - /** common search params of table */ + /** 表格通用搜索参数 */ type CommonSearchParams = Pick; /** - * enable status + * 启用状态 * - * - "1": enabled - * - "2": disabled + * - "1": 启用 + * - "2": 禁用 */ type EnableStatus = '1' | '2'; - /** common record */ + /** 通用记录 */ type CommonRecord = { - /** record id */ + /** 记录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; } /** - * namespace Auth + * 命名空间 Auth * - * backend api module: "auth" + * 后端 API 模块:"auth" */ namespace Auth { + /** 登录令牌 */ interface LoginToken { token: string; refreshToken: string; } + /** 用户信息 */ interface UserInfo { userId: string; userName: string; @@ -68,17 +71,19 @@ declare namespace Api { } /** - * namespace Route + * 命名空间 Route * - * backend api module: "route" + * 后端 API 模块:"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; diff --git a/src/typings/app.d.ts b/src/typings/app.d.ts index 2e0fbf86..d19e9f31 100644 --- a/src/typings/app.d.ts +++ b/src/typings/app.d.ts @@ -1,121 +1,121 @@ -/** The global namespace for the app */ +/** 应用全局命名空间 */ declare namespace App { - /** Theme namespace */ + /** 主题命名空间 */ namespace Theme { type ColorPaletteNumber = import('@sa/color').ColorPaletteNumber; - /** 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; - /** Other color */ + /** 其他颜色 */ otherColor: OtherColor; - /** Whether info color is followed by the primary color */ + /** info颜色是否跟随主色 */ isInfoFollowPrimary: boolean; - /** Reset cache strategy */ + /** 重置缓存策略 */ resetCacheStrategy: UnionKey.ResetCacheStrategy; - /** Layout */ + /** 布局 */ layout: { - /** Layout mode */ + /** 布局模式 */ mode: UnionKey.ThemeLayoutMode; - /** Scroll mode */ + /** 滚动模式 */ scrollMode: UnionKey.ThemeScrollMode; /** - * Whether to reverse the horizontal mix + * 是否反转横向混合 * - * if true, the vertical child level menus in left and horizontal first level menus in top + * 如果为 true,左侧为垂直子菜单,顶部为横向一级菜单 */ reverseHorizontalMix: boolean; }; - /** 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; }; - /** 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' or 'horizontal-mix' */ + /** 混合布局下侧边栏宽度 */ mixWidth: number; - /** Collapsed sider width when the layout is 'vertical-mix' or 'horizontal-mix' */ + /** 混合布局下收起宽度 */ mixCollapsedWidth: number; - /** Child menu width when the layout is 'vertical-mix' or 'horizontal-mix' */ + /** 混合布局下子菜单宽度 */ mixChildMenuWidth: number; }; - /** 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 'horizontal-mix' */ + /** 混合布局下页脚是否右浮动 */ 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; }; - /** define some theme settings tokens, will transform to css variables */ + /** 定义部分主题 token,会转换为 css 变量 */ tokens: { light: ThemeSettingToken; dark?: { @@ -144,7 +144,7 @@ declare namespace App { type BaseToken = Record>; interface ThemeSettingTokenColor { - /** the progress bar color, if not set, will use the primary color */ + /** 进度条颜色,未设置时使用主色 */ nprogress?: string; container: string; layout: string; @@ -165,14 +165,14 @@ declare namespace App { type ThemeTokenColor = ThemePaletteColor & ThemeSettingTokenColor; - /** Theme token CSS variables */ + /** 主题 token CSS 变量 */ type 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; @@ -181,41 +181,41 @@ declare namespace App { type RoutePath = import('@elegant-router/types').RoutePath; type LastLevelRouteKey = import('@elegant-router/types').LastLevelRouteKey; - /** The router push options */ + /** 路由跳转参数 */ type RouterPushOptions = { query?: Record; params?: Record; }; - /** The global header props */ + /** 全局头部属性 */ interface HeaderProps { - /** Whether to show the logo */ + /** 是否显示 logo */ showLogo?: boolean; - /** Whether to show the menu toggler */ + /** 是否显示菜单切换按钮 */ showMenuToggler?: boolean; - /** Whether to show the menu */ + /** 是否显示菜单 */ showMenu?: boolean; } - /** The global menu */ + /** 全局菜单 */ type Menu = { /** - * The menu key + * 菜单 key * - * Equal to the route key + * 等同于路由 key */ key: string; - /** The menu label */ + /** 菜单名称 */ label: string; - /** The menu i18n key */ + /** 菜单 i18n key */ i18nKey?: I18n.I18nKey | null; - /** The route key */ + /** 路由 key */ routeKey: RouteKey; - /** The route path */ + /** 路由 path */ routePath: RoutePath; - /** The menu icon */ + /** 菜单图标 */ icon?: () => VNode; - /** The menu children */ + /** 子菜单 */ children?: Menu[]; }; @@ -223,63 +223,63 @@ declare namespace App { options?: Breadcrumb[]; }; - /** Tab route */ + /** 标签页路由 */ type TabRoute = Pick & Partial>; - /** The global tab */ + /** 全局标签页 */ type Tab = { - /** The tab id */ + /** 标签页 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 */ + /** 标签页路由 key */ routeKey: LastLevelRouteKey; - /** The tab route path */ + /** 标签页路由 path */ routePath: RouteMap[LastLevelRouteKey]; - /** The tab route full path */ + /** 标签页完整路径 */ fullPath: string; - /** The tab fixed index */ + /** 固定标签页索引 */ fixedIndex?: number | null; /** - * Tab icon + * 标签页图标 * - * Iconify icon + * Iconify 图标 */ 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 */ + /** 全局下拉菜单 key */ type DropdownKey = 'closeCurrent' | 'closeOther' | 'closeLeft' | 'closeRight' | 'closeAll'; } /** - * I18n namespace + * I18n 命名空间 * - * Locales type + * 多语言类型 */ namespace I18n { type RouteKey = import('@elegant-router/types').RouteKey; @@ -549,15 +549,15 @@ declare namespace App { } } - /** Service namespace */ + /** 服务命名空间 */ namespace Service { - /** Other baseURL key */ + /** 其他 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; } @@ -565,9 +565,9 @@ declare namespace App { key: OtherBaseURLKey; } - /** The backend service config */ + /** 后端服务配置 */ interface ServiceConfig extends ServiceConfigItem { - /** Other backend service config */ + /** 其他后端服务配置 */ other: OtherServiceConfigItem[]; } @@ -575,23 +575,23 @@ declare namespace App { other: Record; } - /** The backend service response data */ + /** 后端服务响应数据 */ type Response = { - /** 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 */ + /** demo 后端服务响应数据 */ type DemoResponse = { - /** The backend service response code */ + /** 响应码 */ status: string; - /** The backend service response message */ + /** 响应信息 */ message: string; - /** The backend service response data */ + /** 响应数据 */ result: T; }; } diff --git a/src/typings/elegant-router.d.ts b/src/typings/elegant-router.d.ts index 63025132..aa342812 100644 --- a/src/typings/elegant-router.d.ts +++ b/src/typings/elegant-router.d.ts @@ -20,6 +20,7 @@ declare module "@elegant-router/types" { "403": "/403"; "404": "/404"; "500": "/500"; + "cesium": "/cesium"; "home": "/home"; "iframe-page": "/iframe-page/:url"; "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?"; @@ -57,6 +58,7 @@ declare module "@elegant-router/types" { | "403" | "404" | "500" + | "cesium" | "home" | "iframe-page" | "login" @@ -81,6 +83,7 @@ declare module "@elegant-router/types" { | "500" | "iframe-page" | "login" + | "cesium" | "home" >; diff --git a/src/typings/vite-env.d.ts b/src/typings/vite-env.d.ts index c94bbc7e..9d4c804d 100644 --- a/src/typings/vite-env.d.ts +++ b/src/typings/vite-env.d.ts @@ -1,114 +1,113 @@ /** - * Namespace Env + * 命名空间 Env * - * It is used to declare the type of the import.meta object + * 用于声明 import.meta 对象的类型 */ declare namespace Env { - /** The router history mode */ + /** 路由历史模式 */ type RouterHistoryMode = 'hash' | 'history' | 'memory'; - /** Interface for import.meta */ + /** import.meta 的接口 */ // eslint-disable-next-line @typescript-eslint/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 */ + /** iconify 图标前缀 */ readonly VITE_ICON_PREFIX: 'icon'; /** - * The prefix of the local icon + * 本地图标前缀 * - * This prefix is start with the icon prefix + * 该前缀以 icon 前缀开头 */ 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 + * 后端服务 token 过期状态码 * - * when the code is received, it will refresh the token and resend the request + * 收到该状态码时,会刷新 token 并重新发送请求 * - * use "," to separate multiple codes + * 多个状态码用 "," 分隔 */ readonly VITE_SERVICE_EXPIRED_TOKEN_CODES: string; - /** when the route mode is static, the defined super role */ + /** 路由模式为 static 时定义的超级角色 */ readonly VITE_STATIC_SUPER_ROLE: string; /** - * other backend service base url + * 其他后端服务基础地址 * - * the value is a json + * 值为 json 格式 */ readonly VITE_OTHER_SERVICE_BASE_URL: string; /** - * Whether to enable the http proxy + * 是否启用 http 代理 * - * 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 + * - static:前端生成权限路由 + * - dynamic:后端生成权限路由 */ readonly VITE_AUTH_ROUTE_MODE: 'static' | 'dynamic'; /** - * The home route key + * 首页路由 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 + * 仅在权限路由模式为 static 时生效,dynamic 时由后端定义 */ readonly VITE_ROUTE_HOME: import('@elegant-router/types').LastLevelRouteKey; /** - * Default menu icon if menu icon is not set + * 默认菜单图标(未设置菜单图标时使用) * - * Iconify icon name + * Iconify 图标名 */ readonly VITE_MENU_ICON: string; - /** Whether to build with sourcemap */ + /** 是否构建 sourcemap */ readonly VITE_SOURCE_MAP?: CommonType.YesOrNo; /** - * Iconify api provider url + * Iconify API 提供者地址 * - * If the project is deployed in intranet, you can set the api provider url to the local iconify server + * 如果项目部署在内网,可设置为本地 iconify 服务地址 * * @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']; } } diff --git a/src/utils/service.ts b/src/utils/service.ts index a275b39d..c6e55f99 100644 --- a/src/utils/service.ts +++ b/src/utils/service.ts @@ -1,9 +1,9 @@ import json5 from 'json5'; /** - * Create service config by current env + * 根据当前环境创建服务配置 * - * @param env The current env + * @param env 当前环境变量 */ export function createServiceConfig(env: Env.ImportMeta) { const { VITE_SERVICE_BASE_URL, VITE_OTHER_SERVICE_BASE_URL } = env; @@ -13,7 +13,7 @@ export function createServiceConfig(env: Env.ImportMeta) { other = json5.parse(VITE_OTHER_SERVICE_BASE_URL); } catch { // eslint-disable-next-line no-console - console.error('VITE_OTHER_SERVICE_BASE_URL is not a valid json5 string'); + console.error('VITE_OTHER_SERVICE_BASE_URL 不是有效的 json5 字符串'); } const httpConfig: App.Service.SimpleServiceConfig = { @@ -41,10 +41,10 @@ export function createServiceConfig(env: Env.ImportMeta) { } /** - * get backend service base url + * 获取后端服务基础地址 * - * @param env - the current env - * @param isProxy - if use proxy + * @param env 当前环境变量 + * @param isProxy 是否使用代理 */ export function getServiceBaseURL(env: Env.ImportMeta, isProxy: boolean) { const { baseURL, other } = createServiceConfig(env); @@ -62,9 +62,9 @@ export function getServiceBaseURL(env: Env.ImportMeta, isProxy: boolean) { } /** - * Get proxy pattern of backend service base url + * 获取后端服务基础地址的代理前缀 * - * @param key If not set, will use the default key + * @param key 如果未设置,则使用默认 key */ function createProxyPattern(key?: App.Service.OtherBaseURLKey) { if (!key) { diff --git a/src/views/cesium/index.vue b/src/views/cesium/index.vue new file mode 100644 index 00000000..accd61a3 --- /dev/null +++ b/src/views/cesium/index.vue @@ -0,0 +1,19 @@ + + + + +