├── .env ├── .husky ├── README.md ├── .gitignore ├── commit-msg └── pre-commit ├── .env.staging ├── .env.development ├── .env.production ├── tsconfig.tsbuildinfo ├── .stylelintignore ├── src ├── styles │ ├── tailwind.css │ ├── var │ │ ├── index.scss │ │ ├── element │ │ │ └── theme │ │ │ │ ├── index.scss │ │ │ │ ├── dark.scss │ │ │ │ └── light.scss │ │ └── site-bar.scss │ ├── mixin.scss │ ├── intro.scss │ ├── transition.scss │ ├── theme.scss │ ├── nprogress.scss │ └── index.scss ├── assets │ ├── logo.png │ ├── login │ │ ├── bg.png │ │ └── logo.png │ └── icons │ │ ├── fold.svg │ │ ├── daosanjiao.svg │ │ ├── full_screen_close.svg │ │ ├── full_screen.svg │ │ ├── Vue.svg │ │ ├── link.svg │ │ ├── about.svg │ │ ├── password.svg │ │ ├── guide.svg │ │ ├── locales.svg │ │ ├── components.svg │ │ ├── moon.svg │ │ ├── editor.svg │ │ ├── echarts.svg │ │ └── full_screen_page.svg ├── enum │ ├── locales.ts │ └── role.ts ├── views │ ├── permissions │ │ ├── test-permissions-a │ │ │ └── index.vue │ │ ├── test-permissions-b │ │ │ └── index.vue │ │ └── page │ │ │ └── index.vue │ ├── nested │ │ ├── menu2 │ │ │ └── index.vue │ │ └── menu1 │ │ │ ├── menu1-1 │ │ │ └── index.vue │ │ │ ├── menu1-3 │ │ │ └── index.vue │ │ │ ├── menu1-2 │ │ │ ├── menu1-2-1 │ │ │ │ └── index.vue │ │ │ ├── menu1-2-2 │ │ │ │ └── index.vue │ │ │ └── index.vue │ │ │ └── index.vue │ ├── echarts │ │ └── bar │ │ │ ├── index.vue │ │ │ └── components │ │ │ └── BarRace.vue │ ├── components │ │ ├── count-to │ │ │ └── index.vue │ │ ├── calendar │ │ │ └── index.vue │ │ ├── date │ │ │ └── index.vue │ │ └── seamless-scroll │ │ │ └── index.vue │ ├── functions │ │ ├── guide │ │ │ └── index.vue │ │ ├── docx │ │ │ └── index.vue │ │ └── water-mark │ │ │ ├── hooks │ │ │ └── useWaterMark.ts │ │ │ └── index.vue │ ├── details-page │ │ ├── datails-params │ │ │ └── index.vue │ │ ├── datails-info │ │ │ └── index.vue │ │ ├── index.vue │ │ └── hooks │ │ │ └── useDatailsInfo.ts │ ├── external-link │ │ └── embedded-page │ │ │ └── index.vue │ ├── editor │ │ ├── markdown │ │ │ └── index.vue │ │ ├── rich-text │ │ │ └── index.vue │ │ └── logic-flow │ │ │ ├── index.vue │ │ │ └── adpter-for-turbo.ts │ ├── error │ │ ├── 403.vue │ │ ├── 404.vue │ │ └── 500.vue │ ├── index │ │ └── components │ │ │ ├── PieChart.vue │ │ │ ├── Comment.vue │ │ │ ├── AnalysisChart.vue │ │ │ └── WordCloud.vue │ ├── about │ │ └── index.vue │ └── login │ │ ├── index.vue │ │ └── compoontne │ │ └── form.vue ├── store │ ├── index.ts │ ├── modules │ │ ├── app.ts │ │ └── user.ts │ └── types.ts ├── server │ ├── config.ts │ ├── route.ts │ └── useInfo.ts ├── utils │ ├── axios │ │ ├── errorConfig.ts │ │ ├── axiosConfig.ts │ │ └── axiosStatus.ts │ ├── mitt.ts │ ├── plugin │ │ ├── progress.ts │ │ └── echarts │ │ │ └── index.ts │ ├── slotsHelper.ts │ ├── propTypes.ts │ ├── index.ts │ ├── operate │ │ └── index.ts │ ├── theme │ │ └── transformTheme.ts │ └── waterMark.ts ├── layouts │ ├── empty-layouts │ │ └── index.vue │ ├── redirect │ │ └── index.vue │ └── page-layouts │ │ ├── index.vue │ │ └── components │ │ ├── AppFold │ │ └── index.vue │ │ ├── Sidebar │ │ ├── Link.vue │ │ ├── MinSidebar.vue │ │ ├── Item.vue │ │ └── index.vue │ │ ├── AppMain │ │ └── index.vue │ │ ├── VerticalSidebar │ │ └── index.vue │ │ ├── AppLogo │ │ └── index.vue │ │ ├── SideNavigationBar │ │ └── index.vue │ │ ├── Seting │ │ └── pageSettings │ │ │ └── index.vue │ │ └── AppTabs │ │ └── hooks │ │ └── useTabsChange.ts ├── App.vue ├── components │ ├── Application │ │ ├── index.ts │ │ ├── AppLocale.vue │ │ ├── AppAccount.vue │ │ └── AppTheme.vue │ ├── TsxComponents.tsx │ ├── CountTo │ │ ├── src │ │ │ ├── rebound │ │ │ │ └── props.ts │ │ │ └── normal │ │ │ │ └── props.ts │ │ └── index.vue │ ├── Table │ │ ├── index.vue │ │ ├── types │ │ │ └── table.ts │ │ └── src │ │ │ └── components │ │ │ └── TableChild.tsx │ ├── Form │ │ ├── componentMap.ts │ │ ├── types │ │ │ └── from.ts │ │ ├── src │ │ │ └── components │ │ │ │ └── FormItem.vue │ │ └── index.vue │ ├── SvgIcon │ │ └── index.vue │ └── PreviewDocx │ │ └── index.vue ├── hooks │ ├── useCurrentInstance.ts │ ├── setting │ │ └── useRootSetting.ts │ ├── web │ │ ├── useTheme.ts │ │ ├── useMessage.tsx │ │ ├── useDetailsNavigation.ts │ │ ├── useI18n.ts │ │ ├── useSortable.ts │ │ ├── useIntro.ts │ │ └── useECharts.ts │ └── event │ │ └── useEventListener.ts ├── locales │ ├── types.ts │ └── index.ts ├── router │ ├── modules │ │ ├── home │ │ │ └── index.ts │ │ ├── about │ │ │ └── index.ts │ │ ├── echarts │ │ │ └── index.ts │ │ ├── root │ │ │ └── index.ts │ │ ├── externa-link │ │ │ └── index.ts │ │ ├── editor │ │ │ └── index.ts │ │ ├── error │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── details-page │ │ │ └── index.ts │ │ ├── permissions │ │ │ └── index.ts │ │ ├── functions │ │ │ └── index.ts │ │ ├── nested │ │ │ └── index.ts │ │ └── components │ │ │ └── index.ts │ ├── type.ts │ └── index.ts ├── main.ts ├── config │ └── index.ts └── instruct │ └── waterMark.ts ├── k8s └── base │ ├── namespace.yaml │ ├── serviceAccount.yaml │ ├── secret.yaml │ ├── kustomization.yaml │ ├── service.yaml │ ├── hap.yaml │ └── deployment.yaml ├── public ├── pwa │ ├── favicon.ico │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── mstile-150x150.png │ ├── apple-touch-icon.png │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── browserconfig.xml │ └── site.webmanifest └── serverConfig.json ├── .npmrc ├── .gitignore ├── .prettierignore ├── postcss.config.js ├── prettier.config.js ├── types ├── plugin.d.ts ├── env.d.ts ├── global.d.ts └── axios.d.ts ├── jsconfig.json ├── .github ├── ISSUE_TEMPLATE │ ├── custom.md │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ ├── release.yml │ ├── lint-and-type-checking.yml │ ├── auto-merge.yml │ └── git-pages.yml ├── Dockerfile ├── .vscode ├── extensions.json └── settings.json ├── tests └── TsxComponents.spec.ts ├── .editorconfig ├── tsconfig.node.json ├── eslint.config.js ├── vitest.config.ts ├── default.conf ├── LICENSE ├── tsconfig.json ├── commitlint.config.js ├── vite.config.ts ├── stylelint.config.js └── mock └── account.mock.ts /.env: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.husky/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.env.staging: -------------------------------------------------------------------------------- 1 | VITE_ENV = staging -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | VITE_ENV = development -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | VITE_ENV = production -------------------------------------------------------------------------------- /tsconfig.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"version":"4.9.4"} -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | dist 2 | public 3 | dist_electron -------------------------------------------------------------------------------- /src/styles/tailwind.css: -------------------------------------------------------------------------------- 1 | @import 'tailwindcss'; 2 | -------------------------------------------------------------------------------- /src/styles/var/index.scss: -------------------------------------------------------------------------------- 1 | @forward './site-bar'; 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | npx commitlint --edit $1 4 | -------------------------------------------------------------------------------- /src/styles/var/element/theme/index.scss: -------------------------------------------------------------------------------- 1 | @use './light'; 2 | @use './dark'; 3 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /src/enum/locales.ts: -------------------------------------------------------------------------------- 1 | export enum LocalesEnum { 2 | EN = 'en', 3 | ZHCN = 'zh-CN', 4 | } 5 | -------------------------------------------------------------------------------- /k8s/base/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: vue-xs-admin 5 | -------------------------------------------------------------------------------- /public/pwa/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/public/pwa/favicon.ico -------------------------------------------------------------------------------- /src/assets/login/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/src/assets/login/bg.png -------------------------------------------------------------------------------- /src/assets/login/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/src/assets/login/logo.png -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # # 防止npm用不支持的node版本 2 | # engine-strict = true 3 | 4 | # # 偏平化node_modules结构 5 | # shamefully-hoist=true -------------------------------------------------------------------------------- /public/pwa/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/public/pwa/favicon-16x16.png -------------------------------------------------------------------------------- /public/pwa/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/public/pwa/favicon-32x32.png -------------------------------------------------------------------------------- /public/pwa/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/public/pwa/mstile-150x150.png -------------------------------------------------------------------------------- /src/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin relative { 2 | position: relative; 3 | width: 100%; 4 | height: 100%; 5 | } 6 | -------------------------------------------------------------------------------- /public/pwa/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/public/pwa/apple-touch-icon.png -------------------------------------------------------------------------------- /public/pwa/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/public/pwa/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/pwa/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsxiaosi/vue-xs-admin/HEAD/public/pwa/android-chrome-512x512.png -------------------------------------------------------------------------------- /src/styles/var/element/theme/dark.scss: -------------------------------------------------------------------------------- 1 | @forward 'element-plus/theme-chalk/src/dark/var.scss' with ( 2 | $text-color: () 3 | ); 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.local 2 | 3 | .DS_Store 4 | package-lock.json 5 | yarn-error.log 6 | 7 | bin 8 | dist 9 | dist_electron 10 | node_modules -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .local 2 | .output.js 3 | .npmrc 4 | 5 | **/*.svg 6 | **/*.sh 7 | 8 | dist 9 | public 10 | node_modules 11 | dist_electron -------------------------------------------------------------------------------- /src/views/permissions/test-permissions-a/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /src/views/permissions/test-permissions-b/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | 'postcss-import': {}, 4 | '@tailwindcss/postcss': {}, 5 | autoprefixer: {}, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | import prettierConfig from '@jsxiaosi/eslint-config-prettier'; 2 | 3 | export default prettierConfig({ 4 | tailwindcss: true, 5 | }); 6 | -------------------------------------------------------------------------------- /src/views/nested/menu2/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /types/plugin.d.ts: -------------------------------------------------------------------------------- 1 | // vite-plugin-theme-preprocessor不支持ts,默认导出一个d.ts解决报错 2 | declare module '@zougt/*'; 3 | 4 | declare module 'editor.md/*'; 5 | 6 | declare module '*.js'; 7 | -------------------------------------------------------------------------------- /src/views/nested/menu1/menu1-1/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/views/nested/menu1/menu1-3/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "exclude": ["node_modules", "dist"] 9 | } 10 | -------------------------------------------------------------------------------- /k8s/base/serviceAccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: vue-xs-admin-sa 5 | namespace: vue-xs-admin 6 | imagePullSecrets: 7 | - name: jsxiaosi-docker 8 | -------------------------------------------------------------------------------- /src/enum/role.ts: -------------------------------------------------------------------------------- 1 | export enum RoleEnum { 2 | ADMIN = 'admin', 3 | TEST = 'test', 4 | } 5 | 6 | export enum PermissionMode { 7 | REAREND = 'REAREND', 8 | ROLE = 'ROLE', 9 | } 10 | -------------------------------------------------------------------------------- /src/views/nested/menu1/menu1-2/menu1-2-1/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/views/nested/menu1/menu1-2/menu1-2-2/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/views/nested/menu1/index.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:latest 2 | 3 | LABEL description="Nginx vue-xs-admin" 4 | 5 | COPY dist /usr/share/nginx/html 6 | 7 | COPY default.conf /etc/nginx/conf.d/ 8 | 9 | CMD [ "nginx", "-g", "daemon off;" ] 10 | 11 | -------------------------------------------------------------------------------- /src/views/nested/menu1/menu1-2/index.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /k8s/base/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | .dockerconfigjson: DOKER_CONFIG_JSON_BASE64_ENCODED_CONTENT 4 | kind: Secret 5 | metadata: 6 | name: jsxiaosi-docker 7 | namespace: vue-xs-admin 8 | type: kubernetes.io/dockerconfigjson 9 | -------------------------------------------------------------------------------- /src/assets/icons/fold.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia'; 2 | import type { App } from 'vue'; 3 | 4 | const store = createPinia(); 5 | 6 | export const configMainStore = (app: App) => { 7 | app.use(createPinia()); 8 | }; 9 | 10 | export { store }; 11 | -------------------------------------------------------------------------------- /src/views/echarts/bar/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /src/server/config.ts: -------------------------------------------------------------------------------- 1 | import type { AppConfig } from '@/store/types'; 2 | import { deffHttp } from '@/utils/axios'; 3 | 4 | enum Api { 5 | ROUTE_CONFIG_INFO = '/serverConfig.json', 6 | } 7 | 8 | export const getConfigInfo = () => deffHttp.get({ url: Api.ROUTE_CONFIG_INFO }); 9 | -------------------------------------------------------------------------------- /k8s/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: vue-xs-admin 4 | resources: 5 | - ./namespace.yaml 6 | - ./secret.yaml 7 | - ./serviceAccount.yaml 8 | - ./deployment.yaml 9 | - ./hap.yaml 10 | - ./service.yaml 11 | -------------------------------------------------------------------------------- /types/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare interface ViteEnv { 4 | readonly VITE_ENV: string; 5 | } 6 | 7 | interface ImportMetaEnv extends ViteEnv { 8 | _: unknown; 9 | } 10 | 11 | interface ImportMeta { 12 | readonly env: ImportMetaEnv; 13 | } 14 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "vue.volar", 4 | "bradlc.vscode-tailwindcss", 5 | "syler.sass-indented", 6 | "esbenp.prettier-vscode", 7 | "lokalise.i18n-ally", 8 | "dbaeumer.vscode-eslint", 9 | "donjayamanne.githistory" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /types/global.d.ts: -------------------------------------------------------------------------------- 1 | import 'vue/jsx'; 2 | 3 | declare global { 4 | interface Window {} 5 | 6 | type RefType = T | null; 7 | 8 | type Recordable = Record; 9 | 10 | interface Fn { 11 | (...arg: T[]): R; 12 | } 13 | } 14 | 15 | export {}; 16 | -------------------------------------------------------------------------------- /tests/TsxComponents.spec.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils'; 2 | import { expect, test } from 'vitest'; 3 | import TsxComponents from '../src/components/TsxComponents'; 4 | 5 | test('HelloWorld', () => { 6 | const wrapper = mount(TsxComponents); 7 | expect(wrapper.text()).toContain('admin'); 8 | }); 9 | -------------------------------------------------------------------------------- /public/pwa/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #2d89ef 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/utils/axios/errorConfig.ts: -------------------------------------------------------------------------------- 1 | import type { Result } from '#/axios'; 2 | import type { AxiosResponse } from 'axios'; 3 | 4 | export const errorData = (res: AxiosResponse>) => { 5 | return { 6 | data: null, 7 | message: res.data.message, 8 | code: res.data.code, 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | insert_final_newline = false 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /k8s/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: vue-xs-admin-service 5 | namespace: vue-xs-admin 6 | labels: 7 | app: vue-xs-admin-service 8 | spec: 9 | type: NodePort 10 | ports: 11 | - port: 80 12 | name: vue-xs-admin 13 | selector: 14 | app: vue-xs-admin-pod 15 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "baseUrl": "./", 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "types": ["vite/client"], 8 | "allowSyntheticDefaultImports": true 9 | }, 10 | "include": ["vite.config.ts", "build", "types", "mock"] 11 | } 12 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | # 已存在文件只需添加以下命令 2 | # npx eslint --fix --ext src/**/*.{vue} 3 | # npx prettier --write --loglevel warn src/**/*.{js,scss,vue} 4 | # npx stylelint --fix src/**/*.{vue,scss} --cache --cache-location node_modules/.cache/stylelint/ 5 | # npm run lint:eslint 6 | # npm run lint:prettier 7 | # npm run lint:stylelint 8 | npm run lint:staged -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import jsxiaosiConfig from '@jsxiaosi/eslint-config'; 2 | 3 | export default jsxiaosiConfig( 4 | { 5 | vue: true, 6 | prettier: { 7 | usePrettierrc: true, 8 | }, 9 | ignores: ['src/**/china.json'], 10 | }, 11 | { 12 | rules: { 13 | 'no-console': 'off', 14 | }, 15 | }, 16 | ); 17 | -------------------------------------------------------------------------------- /src/layouts/empty-layouts/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /src/styles/var/element/theme/light.scss: -------------------------------------------------------------------------------- 1 | /* 修改element颜色变量 */ 2 | @forward 'element-plus/theme-chalk/src/common/var.scss' with ( 3 | $colors: ( 4 | 'primary': ( 5 | 'base': #409eff, 6 | ), 7 | ), 8 | $text-color: ( 9 | 'primary': #909399, 10 | 'regular': #606266, 11 | 'placeholder': #ebeef5, 12 | ) 13 | ); 14 | -------------------------------------------------------------------------------- /src/assets/icons/daosanjiao.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /src/utils/mitt.ts: -------------------------------------------------------------------------------- 1 | import mitt from 'mitt'; 2 | import type { Emitter } from 'mitt'; 3 | import type { AppRouteRecordRaw } from '@/router/type'; 4 | 5 | interface Events { 6 | siteBarChange: { 7 | routeRaw: AppRouteRecordRaw; 8 | }; 9 | [key: string | symbol]: Recordable; 10 | } 11 | 12 | export const emitter: Emitter = mitt(); 13 | -------------------------------------------------------------------------------- /src/components/Application/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '@/utils'; 2 | import appAccount from './AppAccount.vue'; 3 | import appLocale from './AppLocale.vue'; 4 | import appTheme from './AppTheme.vue'; 5 | 6 | export const AppLocale = withInstall(appLocale); 7 | export const AppTheme = withInstall(appTheme); 8 | export const AppAccount = withInstall(appAccount); 9 | -------------------------------------------------------------------------------- /src/views/components/count-to/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /src/hooks/useCurrentInstance.ts: -------------------------------------------------------------------------------- 1 | import { getCurrentInstance } from 'vue'; 2 | import type { ComponentInternalInstance } from 'vue'; 3 | 4 | export function useCurrentInstance() { 5 | const { appContext } = getCurrentInstance() as ComponentInternalInstance; 6 | const globalProperties = appContext.config.globalProperties; 7 | return { 8 | ...globalProperties, 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /src/views/functions/guide/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /src/components/TsxComponents.tsx: -------------------------------------------------------------------------------- 1 | import { defineComponent, ref } from 'vue'; 2 | 3 | export default defineComponent({ 4 | name: 'TsxComponents', 5 | setup(_props) { 6 | const dataname = ref('admin'); 7 | return () => ( 8 | <> 9 |
TSX:{dataname.value}
10 |
11 |
12 |
13 | 14 | ); 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /src/utils/plugin/progress.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/rstacruz/nprogress 2 | import NProgress from 'nprogress'; 3 | import '@/styles/nprogress.scss'; 4 | 5 | NProgress.configure({ 6 | easing: 'ease', 7 | // 递增进度条的速度 8 | speed: 400, 9 | // 是否显示加载ico 10 | showSpinner: true, 11 | // 自动递增间隔 12 | trickleSpeed: 300, 13 | // 初始化时的最小百分比 14 | minimum: 0.2, 15 | }); 16 | 17 | export default NProgress; 18 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, mergeConfig } from 'vitest/config'; 2 | import viteConfig from './vite.config'; 3 | 4 | export default defineConfig(configEnv => 5 | mergeConfig( 6 | viteConfig(configEnv), 7 | defineConfig({ 8 | test: { 9 | environment: 'jsdom', 10 | testTransformMode: { 11 | web: ['*.tsx'], 12 | }, 13 | }, 14 | }), 15 | ), 16 | ); 17 | -------------------------------------------------------------------------------- /src/locales/types.ts: -------------------------------------------------------------------------------- 1 | import type { LocalesEnum } from '@/enum/locales'; 2 | import type en from './modules/en.json'; 3 | 4 | export type MessageSchema = typeof en; 5 | 6 | export type localeKey = (typeof LocalesEnum)[keyof typeof LocalesEnum]; 7 | 8 | export interface LocalesType { 9 | name: string; 10 | locale: localeKey; 11 | } 12 | 13 | export type LocaleMessages = { 14 | [K in localeKey]: MessageSchema; 15 | }; 16 | -------------------------------------------------------------------------------- /src/server/route.ts: -------------------------------------------------------------------------------- 1 | import { deffHttp } from '@/utils/axios'; 2 | 3 | enum Api { 4 | ROUTE_LIST = '/mock_api/getRoute', 5 | } 6 | 7 | interface Param { 8 | name: string; 9 | } 10 | 11 | export interface RouteDataItemType { 12 | path: string; 13 | name: string; 14 | children: RouteDataItemType[]; 15 | } 16 | 17 | export const getRouteApi = (data: Param) => deffHttp.post({ url: Api.ROUTE_LIST, data }); 18 | -------------------------------------------------------------------------------- /src/assets/icons/full_screen_close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/CountTo/src/rebound/props.ts: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue'; 2 | import { propTypes } from '@/utils/propTypes'; 3 | export const reboundProps = { 4 | delay: propTypes.number.def(1), 5 | blur: propTypes.number.def(2), 6 | i: { 7 | type: Number as PropType, 8 | required: false, 9 | default: 0, 10 | validator(value: number) { 11 | return value < 10 && value >= 0 && Number.isInteger(value); 12 | }, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /src/assets/icons/full_screen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /types/axios.d.ts: -------------------------------------------------------------------------------- 1 | export type ErrorMessageMode = 'none' | 'modal' | 'message' | undefined; 2 | export interface RequestOptions { 3 | // 网址前缀 留空使用默认 4 | urlPrefix?: string; 5 | // 设置token 6 | specialToken?: string; 7 | // 是否开启自定义请求报错提示 8 | errorMassge?: boolean; 9 | // 是否携带token 10 | withToken?: boolean; 11 | // 错误消息提示类型 12 | errorMessageMode?: ErrorMessageMode; 13 | } 14 | export interface Result { 15 | code: number; 16 | message: string; 17 | data: T; 18 | } 19 | -------------------------------------------------------------------------------- /src/layouts/redirect/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /src/utils/slotsHelper.ts: -------------------------------------------------------------------------------- 1 | import { isFunction } from '@jsxiaosi/utils'; 2 | import type { Slots } from 'vue'; 3 | 4 | export function getSlot(slots: Slots, slot = 'default', data?: T) { 5 | if (!slots || !Reflect.has(slots, slot)) { 6 | return null; 7 | } 8 | if (!isFunction(slots[slot])) { 9 | console.error(`${slot} is not a function!`); 10 | return null; 11 | } 12 | const slotFn = slots[slot]; 13 | if (!slotFn) return null; 14 | return slotFn(data); 15 | } 16 | -------------------------------------------------------------------------------- /public/serverConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "XsAdmin", 3 | "collapseMenu": false, 4 | "sidebarMode": "vertical", 5 | "themeMode": "dark", 6 | "locale": "zh-CN", 7 | "primaryColor": "#409eff", 8 | "greyMode": false, 9 | "colorWeaknessMode": false, 10 | "hideNavbart": false, 11 | "hideTabs": false, 12 | "closeTabDrag": false, 13 | "tabPersistent": true, 14 | "sidebarFold": "top", 15 | "permissionMode": "REAREND", 16 | "StorageConfig": { 17 | "expire": 0, 18 | "isEncrypt": false 19 | } 20 | } -------------------------------------------------------------------------------- /public/pwa/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-xs-admin", 3 | "short_name": "vue-xs-admin", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /src/styles/intro.scss: -------------------------------------------------------------------------------- 1 | .custom-intro-tooltip * { 2 | color: black; 3 | 4 | a { 5 | border: 1px solid var(--text-color-primary); 6 | background-color: #{--main-bg-color}; 7 | text-shadow: none; 8 | } 9 | } 10 | 11 | .custom-intro-tooltip { 12 | width: 300px; 13 | border: 1px solid var(--text-color-primary); 14 | background-color: #{--main-bg-color}; 15 | 16 | .introjs-skipbutton { 17 | font-size: var(--font-size-base); 18 | } 19 | } 20 | 21 | .custom-intro-highlight { 22 | border: 1px solid var(--text-color-primary); 23 | } 24 | -------------------------------------------------------------------------------- /src/hooks/setting/useRootSetting.ts: -------------------------------------------------------------------------------- 1 | import { merge } from 'lodash-es'; 2 | import { storeToRefs } from 'pinia'; 3 | import { useAppStoreHook } from '@/store/modules/app'; 4 | import type { AppConfig } from '@/store/types'; 5 | 6 | export function useRootSetting() { 7 | const appStore = useAppStoreHook(); 8 | const { appConfigMode } = storeToRefs(appStore); 9 | 10 | function setAppConfigMode(config: Partial) { 11 | appStore.setAppConfigMode(merge(appStore.appConfigMode, config)); 12 | } 13 | 14 | return { appConfig: appConfigMode, setAppConfigMode }; 15 | } 16 | -------------------------------------------------------------------------------- /src/assets/icons/Vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Additional context** 24 | Add any other context about the problem here. 25 | -------------------------------------------------------------------------------- /src/assets/icons/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/details-page/datails-params/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /k8s/base/hap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: vue-xs-admin-hpa 5 | namespace: vue-xs-admin 6 | spec: 7 | scaleTargetRef: 8 | apiVersion: apps/v1 9 | kind: Deployment 10 | name: vue-xs-admin-deploy 11 | minReplicas: 1 12 | maxReplicas: 5 13 | metrics: 14 | - type: Resource 15 | resource: 16 | name: cpu 17 | target: 18 | type: Utilization 19 | averageUtilization: 80 20 | - type: Resource 21 | resource: 22 | name: memory 23 | target: 24 | type: Utilization 25 | averageUtilization: 80 26 | -------------------------------------------------------------------------------- /src/router/modules/home/index.ts: -------------------------------------------------------------------------------- 1 | import { t } from '@/hooks/web/useI18n'; 2 | /* Layout */ 3 | // import Layout from '@/layouts/index.vue' 4 | // import AppMain from '@/layouts/components/AppMain/index.vue' 5 | import type { AppRouteRecordRaw } from '@/router/type'; 6 | 7 | const safeManagerRoutes: Array = [ 8 | { 9 | path: '/welcome', 10 | name: 'RtWelcome', 11 | component: () => import('@/views/index/index.vue'), 12 | meta: { 13 | title: t('route.pathName.index'), 14 | icon: 'iEL-home-filled', 15 | position: 1, 16 | keepAlive: true, 17 | }, 18 | }, 19 | ]; 20 | 21 | export default safeManagerRoutes; 22 | -------------------------------------------------------------------------------- /src/utils/propTypes.ts: -------------------------------------------------------------------------------- 1 | import { createTypes } from 'vue-types'; 2 | import type { CSSProperties, VNodeChild } from 'vue'; 3 | import type { VueTypesInterface, VueTypeValidableDef } from 'vue-types'; 4 | 5 | export type VueNode = VNodeChild | JSX.Element; 6 | 7 | type PropTypes = VueTypesInterface & { 8 | readonly style: VueTypeValidableDef; 9 | readonly VNodeChild: VueTypeValidableDef; 10 | }; 11 | 12 | const propTypes = createTypes({ 13 | func: undefined, 14 | bool: undefined, 15 | string: undefined, 16 | number: undefined, 17 | object: undefined, 18 | integer: undefined, 19 | }) as PropTypes; 20 | 21 | export { propTypes }; 22 | -------------------------------------------------------------------------------- /src/layouts/page-layouts/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 23 | -------------------------------------------------------------------------------- /src/assets/icons/about.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## PR 标题 2 | 3 | 简要描述本次 Pull Request 的目的或变更内容。 4 | 5 | ## 变更类型 6 | 7 | 请勾选本次 PR 属于以下哪种类型(可多选): 8 | 9 | - [ ] Bug 修复(修复现有问题) 10 | - [ ] 新功能(添加新功能或特性) 11 | - [ ] 文档更新(仅更改文档) 12 | - [ ] 性能优化(提升性能或代码质量) 13 | - [ ] 测试添加(增加或完善测试用例) 14 | - [ ] 重构代码(不影响功能的代码优化) 15 | 16 | ## 相关问题 17 | 18 | 请关联相关的 Issue 编号(如适用): 19 | 20 | - 关联问题:#123 21 | 22 | ## 变更内容描述 23 | 24 | 详细描述本次变更的内容: 25 | 26 | 1. 添加/更新的功能或逻辑。 27 | 2. 影响的模块或文件。 28 | 3. 其他说明信息。 29 | 30 | ## Checklist 31 | 32 | 在提交前,请确保已完成以下事项: 33 | 34 | - [ ] 我的代码遵循项目的编码规范。 35 | - [ ] 我已对代码进行了自测,并确保功能正常。 36 | - [ ] 我的变更不影响现有功能或测试通过。 37 | - [ ] 文档已更新(如适用)。 38 | 39 | ## 其他说明 40 | 41 | 其他需要告知审阅者的信息: 42 | 43 | - 示例:兼容性注意事项、已知问题等。 44 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # .github/workflows/release.yml 2 | 3 | name: Release 4 | 5 | permissions: 6 | contents: write 7 | 8 | on: 9 | push: 10 | tags: 11 | - 'v*' 12 | 13 | jobs: 14 | release: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | 21 | - name: Set node 22 | uses: actions/setup-node@v4 23 | with: 24 | registry-url: https://registry.npmjs.org/ 25 | node-version: lts/* 26 | 27 | - run: npx changelogithub # or changelogithub@0.12 if ensure the stable result 28 | env: 29 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 30 | -------------------------------------------------------------------------------- /src/views/details-page/datails-info/index.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/router/modules/about/index.ts: -------------------------------------------------------------------------------- 1 | import { t } from '@/hooks/web/useI18n'; 2 | import type { AppRouteRecordRaw } from '@/router/type'; 3 | 4 | const about: AppRouteRecordRaw[] = [ 5 | { 6 | path: '/about', 7 | redirect: '/about/index', 8 | name: 'RtAdminInfo', 9 | meta: { 10 | title: t('route.pathName.about'), 11 | icon: 'about', 12 | alwaysShow: false, 13 | position: 11, 14 | }, 15 | children: [ 16 | { 17 | path: 'index', 18 | name: 'RtAbout', 19 | component: () => import('@/views/about/index.vue'), 20 | meta: { title: t('route.pathName.about') }, 21 | }, 22 | ], 23 | }, 24 | ]; 25 | 26 | export default about; 27 | -------------------------------------------------------------------------------- /src/server/useInfo.ts: -------------------------------------------------------------------------------- 1 | import type { RoleEnum } from '@/enum/role'; 2 | import { deffHttp } from '@/utils/axios'; 3 | 4 | export interface UseInfoType { 5 | name: string; 6 | userid: string; 7 | email: string; 8 | signature: string; 9 | introduction: string; 10 | title: string; 11 | token: string; 12 | role: RoleEnum; 13 | } 14 | 15 | export interface UserParams { 16 | username: string; 17 | password: string; 18 | } 19 | 20 | export const getUserInfo = (user: string, pwd: string) => 21 | deffHttp.post( 22 | { 23 | url: '/mock_api/login', 24 | data: { username: user, password: pwd }, 25 | }, 26 | { errorMessageMode: 'modal', withToken: false }, 27 | ); 28 | -------------------------------------------------------------------------------- /src/views/details-page/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 22 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": "explicit", 4 | "source.fixAll.stylelint": "explicit" 5 | }, 6 | "files.associations": { 7 | "tailwind.css": "tailwindcss" 8 | }, 9 | "css.validate": false, 10 | "less.validate": false, 11 | "scss.validate": false, 12 | "eslint.validate": ["json", "javascript", "typescript", "typescriptreact", "javascriptreact"], 13 | "stylelint.enable": true, 14 | "stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"], 15 | "i18n-ally.localesPaths": ["src/locales/modules"], 16 | "i18n-ally.displayLanguage": "zh-CN", 17 | "i18n-ally.enabledFrameworks": ["vue"], 18 | "i18n-ally.sourceLanguage": "zh-CN", 19 | "i18n-ally.keystyle": "nested" 20 | } 21 | -------------------------------------------------------------------------------- /src/store/modules/app.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | import { getConfig } from '@/config'; 3 | import { store } from '@/store'; 4 | import type { AppConfig, AppState } from '../types'; 5 | 6 | const useAppStore = defineStore('app', { 7 | state: (): AppState => ({ 8 | appConfigMode: getConfig(), 9 | }), 10 | getters: { 11 | getAppConfigMode(): AppConfig { 12 | return this.appConfigMode; 13 | }, 14 | }, 15 | actions: { 16 | setAppConfigMode(data: AppConfig): void { 17 | const newData = data; 18 | localStorage.setItem('appConfigMode', JSON.stringify(newData)); 19 | this.appConfigMode = newData; 20 | }, 21 | }, 22 | }); 23 | 24 | export function useAppStoreHook() { 25 | return useAppStore(store); 26 | } 27 | -------------------------------------------------------------------------------- /src/views/permissions/page/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 26 | -------------------------------------------------------------------------------- /src/hooks/web/useTheme.ts: -------------------------------------------------------------------------------- 1 | import { useColorMode } from '@vueuse/core'; 2 | import { watch } from 'vue'; 3 | import type { AppConfig } from '@/store/types'; 4 | import { updateColor } from '@/utils/theme/transformTheme'; 5 | import { useRootSetting } from '../setting/useRootSetting'; 6 | 7 | export const useTheme = () => { 8 | const color = useColorMode({ disableTransition: false }); 9 | 10 | const { appConfig, setAppConfigMode } = useRootSetting(); 11 | 12 | const toggleDarkMode = () => { 13 | setAppConfigMode({ themeMode: color.value as AppConfig['themeMode'] }); 14 | }; 15 | 16 | watch(color, () => { 17 | toggleDarkMode(); 18 | updateColor(appConfig.value.primaryColor, color.value as AppConfig['themeMode']); 19 | }); 20 | 21 | return { color }; 22 | }; 23 | -------------------------------------------------------------------------------- /.github/workflows/lint-and-type-checking.yml: -------------------------------------------------------------------------------- 1 | name: Lint and type checking 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | lint-and-type-checking: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v4 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Setup pnpm 17 | uses: pnpm/action-setup@v4 18 | 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: '22' 23 | cache: pnpm 24 | 25 | - name: Install dependencies 26 | run: pnpm install 27 | 28 | - name: Run lint check 29 | run: npm run lint:eslint 30 | 31 | - name: Run type check 32 | run: npm run type:check 33 | -------------------------------------------------------------------------------- /src/layouts/page-layouts/components/AppFold/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 22 | 23 | 28 | -------------------------------------------------------------------------------- /src/views/functions/docx/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | -------------------------------------------------------------------------------- /src/router/modules/echarts/index.ts: -------------------------------------------------------------------------------- 1 | import { t } from '@/hooks/web/useI18n'; 2 | import type { AppRouteRecordRaw } from '@/router/type'; 3 | 4 | const echarts: AppRouteRecordRaw[] = [ 5 | { 6 | path: '/echarts', 7 | redirect: '/echarts/bar', 8 | name: 'RtEcharts', 9 | meta: { title: t('route.pathName.echarts'), icon: 'echarts', position: 3 }, 10 | children: [ 11 | { 12 | path: 'bar', 13 | name: 'RtBar', 14 | component: () => import('@/views/echarts/bar/index.vue'), 15 | meta: { title: t('route.pathName.echarts_bar') }, 16 | }, 17 | { 18 | path: 'map', 19 | name: 'RtMap', 20 | component: () => import('@/views/echarts/map/index.vue'), 21 | meta: { title: t('route.pathName.echarts_map') }, 22 | }, 23 | ], 24 | }, 25 | ]; 26 | 27 | export default echarts; 28 | -------------------------------------------------------------------------------- /src/assets/icons/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/hooks/web/useMessage.tsx: -------------------------------------------------------------------------------- 1 | import { ElMessage, ElMessageBox } from 'element-plus'; 2 | import type { ElMessageBoxOptions } from 'element-plus'; 3 | import { useI18n } from '@/hooks/web/useI18n'; 4 | 5 | const { t } = useI18n(); 6 | 7 | function createElMessageBox(message: string, title: string, options: ElMessageBoxOptions) { 8 | ElMessageBox.confirm(message, title, options) 9 | .then(() => {}) 10 | .catch(() => {}); 11 | } 12 | 13 | function createErrorModal(message: string) { 14 | createElMessageBox(message, t('sys.errorTip'), { 15 | confirmButtonText: t('sys.okText'), 16 | cancelButtonText: t('sys.closeText'), 17 | type: 'error', 18 | }); 19 | } 20 | 21 | function createErrorMsg(message: string) { 22 | ElMessage.error(message); 23 | } 24 | 25 | export function useMessage() { 26 | return { 27 | createErrorModal, 28 | createErrorMsg, 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /src/views/details-page/hooks/useDatailsInfo.ts: -------------------------------------------------------------------------------- 1 | import { useDetailsNavigation } from '@/hooks/web/useDetailsNavigation'; 2 | 3 | export function useDatailsInfo() { 4 | const { openDetails } = useDetailsNavigation(); 5 | 6 | function toDatailsInfo(params: string, model: string) { 7 | if (model === 'query') { 8 | // query 参数详情页 9 | openDetails({ 10 | path: `/details_page/details_info`, 11 | name: `RtDetailsInfo`, 12 | query: { id: `${params}` }, 13 | title: { 'zh-CN': `详情页-${params}`, en: `pageDatails-${params}` }, 14 | }); 15 | } else { 16 | // params 参数详情页 17 | openDetails({ 18 | path: `/details_page/details_params/${params}`, 19 | name: `RtDetailsParams`, 20 | title: { 'zh-CN': `详情页-params-${params}`, en: `pageDatails-${params}` }, 21 | }); 22 | } 23 | } 24 | 25 | return { toDatailsInfo }; 26 | } 27 | -------------------------------------------------------------------------------- /src/components/Table/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 23 | -------------------------------------------------------------------------------- /src/locales/index.ts: -------------------------------------------------------------------------------- 1 | import messages from '@intlify/unplugin-vue-i18n/messages'; 2 | import { createI18n } from 'vue-i18n'; 3 | import type { App } from 'vue'; 4 | import { LocalesEnum } from '@/enum/locales'; 5 | import type { localeKey, LocaleMessages, LocalesType } from './types'; 6 | 7 | const localesList: LocalesType[] = [ 8 | { 9 | name: 'English', 10 | locale: LocalesEnum.EN, 11 | }, 12 | { 13 | name: '中文简体', 14 | locale: LocalesEnum.ZHCN, 15 | }, 16 | ]; 17 | 18 | const i18n = createI18n({ 19 | legacy: false, 20 | locale: LocalesEnum.ZHCN, 21 | fallbackLocale: LocalesEnum.ZHCN, 22 | messages: messages as LocaleMessages, 23 | }); 24 | 25 | export const configMainI18n = (app: App, locale: localeKey) => { 26 | i18n.global.locale.value = locale; 27 | app.use(i18n); 28 | }; 29 | 30 | export const availableLocales: LocalesType[] = localesList; 31 | 32 | export default i18n; 33 | -------------------------------------------------------------------------------- /src/components/Form/componentMap.ts: -------------------------------------------------------------------------------- 1 | import type { Component } from 'vue'; 2 | // import { ElInput, ElDatePicker, ElCascader, ElSelect, ElCheckbox, ElRadio } from 'element-plus'; 3 | 4 | const componentMap = new Map(); 5 | 6 | // componentMap.set('ElInput', ElInput); 7 | // componentMap.set('ElDatePicker', ElDatePicker); 8 | // componentMap.set('ElCascader', ElCascader); 9 | 10 | // componentMap.set('ElSelect', ElSelect); 11 | // componentMap.set('ElOption', ElSelect.Option); 12 | // componentMap.set('ElCheckbox', ElCheckbox); 13 | // componentMap.set('ElCheckboxGroup', ElCheckbox.CheckboxGroup); 14 | // componentMap.set('ElRadio', ElRadio); 15 | // componentMap.set('ElRadioGroup', ElRadio.RadioGroup); 16 | 17 | const elComponentItem: Recordable = { 18 | ElSelect: 'ElOption', 19 | ElCheckboxGroup: 'ElCheckbox', 20 | ElRadioGroup: 'ElRadio', 21 | }; 22 | 23 | export { componentMap, elComponentItem }; 24 | -------------------------------------------------------------------------------- /src/components/Table/types/table.ts: -------------------------------------------------------------------------------- 1 | import type { RenderRowData, TableColumnCtx } from 'element-plus'; 2 | 3 | export interface TableColumnProps 4 | extends Partial, 'prop' | 'children'>> { 5 | isSlots?: boolean; 6 | prop?: keyof T; 7 | render?: (row: any) => JSX.Element; 8 | render_header?: (row: any) => JSX.Element; 9 | children?: TableColumnProps[]; 10 | } 11 | 12 | // export type TableSlotType = { 13 | // [key in keyof T as `${string & key}_header`]: (props: any) => void; 14 | // }; 15 | 16 | export type TableSlotType = { 17 | [key in keyof T]: (props: RenderRowData) => void; 18 | } & { 19 | [key in keyof T as `${string & key}_header`]: ( 20 | props: Omit, 'row' | 'treeNode' | 'expanded'> & { 21 | customItem: TableColumnProps; 22 | }, 23 | ) => void; 24 | }; 25 | -------------------------------------------------------------------------------- /src/layouts/page-layouts/components/Sidebar/Link.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 41 | -------------------------------------------------------------------------------- /src/hooks/web/useDetailsNavigation.ts: -------------------------------------------------------------------------------- 1 | import { useRouter } from 'vue-router'; 2 | import type { LocationQuery } from 'vue-router'; 3 | import type { Meta } from '@/router/type'; 4 | import { usePermissionStoreHook } from '@/store/modules/permission'; 5 | 6 | export interface DetailsNavigationOption { 7 | path: string; 8 | name: string; 9 | title: Meta['title']; 10 | query?: LocationQuery; 11 | } 12 | 13 | export const useDetailsNavigation = () => { 14 | const router = useRouter(); 15 | 16 | const openDetails = (options: DetailsNavigationOption) => { 17 | const { title, ...res } = options; 18 | usePermissionStoreHook().handleMultiTabs('add', { 19 | ...res, 20 | meta: { 21 | title, 22 | }, 23 | }); 24 | try { 25 | router.push({ path: res.path, query: res.query }); 26 | } catch (e) { 27 | console.log(e); 28 | } 29 | }; 30 | 31 | return { 32 | openDetails, 33 | }; 34 | }; 35 | -------------------------------------------------------------------------------- /src/styles/transition.scss: -------------------------------------------------------------------------------- 1 | // global transition css 2 | 3 | // fade 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter-from, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | // fade-transform 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all 0.5s; 18 | } 19 | 20 | .fade-transform-enter-from { 21 | transform: translateX(-30px); 22 | opacity: 0; 23 | } 24 | 25 | .fade-transform-leave-to { 26 | transform: translateX(30px); 27 | opacity: 0; 28 | } 29 | 30 | // breadcrumb transition 31 | .breadcrumb-enter-active, 32 | .breadcrumb-leave-active { 33 | transition: all 0.5s; 34 | } 35 | 36 | .breadcrumb-enter-from, 37 | .breadcrumb-leave-active { 38 | transform: translateX(20px); 39 | opacity: 0; 40 | } 41 | 42 | .breadcrumb-move { 43 | transition: all 0.5s; 44 | } 45 | 46 | .breadcrumb-leave-active { 47 | position: absolute; 48 | } 49 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import type { App, Plugin } from 'vue'; 2 | import 'virtual:svg-icons-register'; 3 | // import { setWindowAppConfig } from '@/store/modules/app'; 4 | 5 | // 定义全局钩子 6 | export const configMainGlobalProperties = (app: App): void => { 7 | // 全局定义属性 8 | app.config.globalProperties.foo = 'bar'; 9 | /** 10 | * 页面使用方法: 11 | * import { getCurrentInstance } from 'vue'; 12 | * const { proxy } = getCurrentInstance() 13 | * proxy.foo 14 | */ 15 | }; 16 | 17 | export const withInstall = (component: T, alias?: string) => { 18 | const comp = component as Recordable; 19 | comp.install = (app: App) => { 20 | app.component(comp.name || comp.displayName, comp); 21 | if (alias) { 22 | app.config.globalProperties[alias] = component; 23 | } 24 | }; 25 | return component as T & Plugin; 26 | }; 27 | 28 | export const converToArray = (number: number): Array => [...`${number}`].map(el => parseInt(el)); 29 | -------------------------------------------------------------------------------- /src/views/external-link/embedded-page/index.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 |