From 217a09ebd618f048f4e1606ac156f2b6c043d1ca Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:39:37 +0800 Subject: [PATCH] perf: global search (#5171) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: global search * perf: Update Dockerfile with new base image tag * perf: 完成基本搜索 * perf: show search direct * perf: change search style * perf: 优化 panel 格式,不再用 select * perf: search add route * perf: add route search * perf: change view --------- Co-authored-by: ibuler --- .prettierignore | 57 +++ .prettierrc | 11 - Dockerfile | 2 +- PRETTIER.md | 76 ++++ package.json | 301 +++++++------- src/components/Widgets/Icon/index.vue | 2 +- src/layout/components/NavHeader/Search.vue | 448 +++++++++++++++++++++ src/layout/components/NavHeader/index.vue | 321 ++++++++------- src/layout/components/NavLeft/index.vue | 46 ++- src/router/console/accounts.js | 5 +- src/router/console/assets.js | 2 +- src/router/console/sessions.js | 2 - yarn.lock | 320 +++++++++++++-- 13 files changed, 1217 insertions(+), 376 deletions(-) create mode 100644 .prettierignore delete mode 100644 .prettierrc create mode 100644 PRETTIER.md create mode 100644 src/layout/components/NavHeader/Search.vue diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..d24c0f627 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,57 @@ +# Dependencies +node_modules/ +dist/ +build/ +lina/ + +# Logs +*.log +logs/ + +# Runtime data +pids/ +*.pid +*.seed + +# Coverage directory used by tools like istanbul +coverage/ + +# Generated files +*.min.js +*.min.css + +# Package files +*.tgz +*.tar.gz + +# Lock files +package-lock.json +yarn.lock + +# Build outputs +*.map + +# Config files that shouldn't be formatted +.eslintrc.js +babel.config.js +jest.config.js +vue.config.js +postcss.config.js + +# Theme files +src/styles/fonts/ +public/fonts/ +lina/fonts/ + +# Assets +src/assets/ +public/ + +# Mock data +mock/ + +# Test files +tests/ + +# Documentation +*.md diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 4de821e3d..000000000 --- a/.prettierrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "printWidth": 100, - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "semi": false, - "trailingComma": "none", - "bracketSpacing": true, - "arrowParens": "avoid", - "endOfLine": "lf" -} diff --git a/Dockerfile b/Dockerfile index 8397471ca..5995c9a2d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM jumpserver/lina-base:20250805_081024 AS stage-build +FROM jumpserver/lina-base:20250901_103352 AS stage-build ARG VERSION ENV VERSION=$VERSION diff --git a/PRETTIER.md b/PRETTIER.md new file mode 100644 index 000000000..ef548abf7 --- /dev/null +++ b/PRETTIER.md @@ -0,0 +1,76 @@ +# Prettier 配置说明 + +本项目已配置 Prettier 代码格式化工具,**仅在保存时自动格式化**,不进行批量格式化,以保持现有代码风格。 + +## 配置文件 + +- `.prettierrc` - Prettier 配置文件 +- `.prettierignore` - 忽略格式化的文件列表 +- `.vscode/settings.json` - VSCode 编辑器配置(保存时自动格式化) +- `.vscode/extensions.json` - 推荐的 VSCode 扩展 + +## 使用方法 + +### 1. 安装依赖 +项目已安装以下依赖: +- `prettier@^2.8.8` - Prettier 核心 +- `eslint-plugin-prettier@^3.1.4` - ESLint 与 Prettier 集成 +- `eslint-config-prettier@^6.15.0` - 禁用与 Prettier 冲突的 ESLint 规则 + +### 2. 命令行使用 + +```bash +# ESLint 检查和修复 +npm run fix +``` + +**注意**:本项目配置为仅在保存时自动格式化,不提供批量格式化命令。 + +### 3. VSCode 编辑器配置 + +确保安装了推荐的扩展: +- Prettier - Code formatter (esbenp.prettier-vscode) +- ESLint (dbaeumer.vscode-eslint) +- Vetur (octref.vetur) + +配置已设置为保存时自动格式化。 + +### 4. Git 提交钩子 + +项目使用 `husky` 和 `lint-staged` 在提交时进行代码检查: +- 提交时运行 ESLint 检查和修复 +- 不进行批量格式化,保持原有代码风格 + +## Prettier 配置说明 + +```json +{ + "semi": false, // 不使用分号 + "singleQuote": true, // 使用单引号 + "tabWidth": 0, // 不使用缩进 + "useTabs": false, // 使用空格而不是制表符 + "trailingComma": "none", // 不使用尾随逗号 + "printWidth": 100, // 行宽 100 字符 + "bracketSpacing": true, // 对象括号内有空格 + "arrowParens": "avoid", // 箭头函数单参数时不使用括号 + "endOfLine": "lf", // 使用 LF 换行符 + "vueIndentScriptAndStyle": false // Vue 文件中 script 和 style 标签不缩进 +} +``` + +## 常见问题 + +### Q: 如何临时禁用格式化? +A: 使用注释: +```javascript +// prettier-ignore +const uglyCode = { + a:1,b:2 +} +``` + +### Q: 如何添加文件到忽略列表? +A: 编辑 `.prettierignore` 文件,添加文件或目录路径。 + +### Q: VSCode 保存时没有自动格式化? +A: 检查是否安装了 Prettier 扩展,并确认 `.vscode/settings.json` 配置正确。 diff --git a/package.json b/package.json index 72bd74c33..c9e0e0b31 100644 --- a/package.json +++ b/package.json @@ -1,150 +1,155 @@ { - "name": "lina", - "version": "v4.0.0", - "description": "JumpServer Web UI", - "author": "JumpServer Team ", - "license": "GPL-3.0-or-later", - "scripts": { - "dev": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve", - "serve": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve", - "build": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build", - "build:prod": "vue-cli-service build", - "build:stage": "vue-cli-service build --mode staging", - "preview": "node build/index.js --preview", - "lint": "eslint --ext .js,.vue src", - "fix": "eslint --ext .js,.vue --fix src", - "test:unit": "jest --clearCache && vue-cli-service test:unit", - "test:ci": "npm run lint && npm run test:unit", - "svgo": "svgo -f src/icons/svg --config=src/icas/svgo.yml", - "vue-i18n-extract": "vue-i18n-extract", - "vue-i18n-report": "vue-i18n-extract report -v './src/**/*.?(js|vue)' -l './src/i18n/langs/**/*.json'", - "vue-i18n-report-json": "vue-i18n-extract report -v './src/**/*.?(js|vue)' -l './src/i18n/langs/**/*.json' -o /tmp/abc.json", - "vue-i18n-report-add-miss": "vue-i18n-extract report -v './src/**/*.?(js|vue)' -l './src/i18n/langs/**/*.json' -a", - "diff-i18n": "python ./src/i18n/langs/i18n-util.py diff en ja zh_Hant", - "apply-i18n": "python ./src/i18n/langs/i18n-util.py apply en ja zh_Hant" - }, - "dependencies": { - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@fontsource/open-sans": "^5.0.24", - "@traptitech/markdown-it-katex": "^3.6.0", - "@ztree/ztree_v3": "3.5.44", - "axios": "0.28.0", - "axios-retry": "^3.1.9", - "caniuse-lite": "^1.0.30001642", - "cron-parser": "^4.0.0", - "crypto-js": "^4.1.1", - "css-color-function": "^1.3.3", - "decimal.js": "^10.4.3", - "deepmerge": "^4.2.2", - "dompurify": "^3.1.6", - "echarts": "4.7.0", - "element-ui": "^2.15.14", - "elementui-lts": "^2.16.0", - "eslint-plugin-html": "^6.0.0", - "highlight.js": "^11.9.0", - "install": "^0.13.0", - "jquery": "^3.6.1", - "js-cookie": "2.2.0", - "jsencrypt": "^3.2.1", - "less": "^3.10.3", - "less-loader": "^5.0.0", - "lodash": "^4.17.21", - "lodash.clonedeep": "^4.5.0", - "lodash.frompairs": "^4.0.1", - "lodash.get": "^4.4.2", - "lodash.has": "^4.5.2", - "lodash.includes": "^4.3.0", - "lodash.isempty": "^4.4.0", - "lodash.isequal": "^4.5.0", - "lodash.isplainobject": "^4.0.6", - "lodash.set": "^4.3.2", - "lodash.topairs": "^4.3.0", - "lodash.values": "^4.3.0", - "markdown-it": "^13.0.2", - "markdown-it-link-attributes": "^4.0.1", - "moment": "^2.29.4", - "moment-parseformat": "^4.0.0", - "normalize.css": "7.0.0", - "npm": "^7.8.0", - "nprogress": "0.2.0", - "path-to-regexp": "3.3.0", - "sortablejs": "^1.15.6", - "v-sanitize": "^0.0.13", - "vue": "2.6.10", - "vue-codemirror": "4.0.6", - "vue-cookie": "^1.1.4", - "vue-echarts": "^5.0.0-beta.0", - "vue-i18n": "^8.15.5", - "vue-json-editor": "^1.4.3", - "vue-markdown": "^2.2.4", - "vue-password-strength-meter": "^1.7.2", - "vue-router": "3.0.6", - "vue-select": "^3.9.5", - "vuejs-logger": "^1.5.4", - "vuex": "3.1.0", - "watermark-js-plus": "^1.5.8", - "xss": "^1.0.14", - "xterm": "^4.5.0", - "xterm-addon-fit": "^0.3.0", - "zxcvbn": "^4.4.2" - }, - "devDependencies": { - "@babel/core": "7.18.6", - "@babel/register": "7.0.0", - "@vue/cli-plugin-babel": "3.6.0", - "@vue/cli-plugin-eslint": "^3.9.1", - "@vue/cli-plugin-unit-jest": "3.6.3", - "@vue/cli-service": "3.6.0", - "@vue/test-utils": "1.0.0-beta.29", - "autoprefixer": "^9.5.1", - "babel-core": "7.0.0-bridge.0", - "babel-eslint": "10.0.1", - "babel-jest": "23.6.0", - "chalk": "2.4.2", - "compression-webpack-plugin": "^6.1.1", - "connect": "3.6.6", - "deasync": "^0.1.29", - "eslint": "^5.15.3", - "eslint-plugin-spellcheck": "^0.0.20", - "eslint-plugin-vue": "5.2.2", - "eslint-plugin-vue-i18n": "^0.3.0", - "github-markdown-css": "^5.1.0", - "html-webpack-plugin": "3.2.0", - "husky": "^4.2.3", - "less-loader": "^5.0.0", - "lint-staged": "^10.1.2", - "mockjs": "1.0.1-beta3", - "pretty-bytes": "^5.6.0", - "runjs": "^4.3.2", - "sass": "~1.32.6", - "sass-loader": "^7.1.0", - "script-ext-html-webpack-plugin": "2.1.3", - "script-loader": "0.7.2", - "serve-static": "^1.16.0", - "strip-ansi": "^7.1.0", - "svg-sprite-loader": "4.1.3", - "svgo": "1.2.2", - "vue-i18n-extract": "^1.1.1", - "vue-template-compiler": "2.6.10" - }, - "engines": { - "node": ">=8.9", - "npm": ">= 3.0.0" - }, - "browserslist": [ - "> 1%", - "last 4 versions", - "ie 11" - ], - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "src/**/*.{js,vue}": [ - "eslint --fix" - ] - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + "name": "lina", + "version": "v4.0.0", + "description": "JumpServer Web UI", + "author": "JumpServer Team ", + "license": "GPL-3.0-or-later", + "scripts": { + "dev": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve", + "serve": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve", + "build": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build", + "build:prod": "vue-cli-service build", + "build:stage": "vue-cli-service build --mode staging", + "preview": "node build/index.js --preview", + "lint": "eslint --ext .js,.vue src", + "fix": "eslint --ext .js,.vue --fix src", + "test:unit": "jest --clearCache && vue-cli-service test:unit", + "test:ci": "npm run lint && npm run test:unit", + "svgo": "svgo -f src/icons/svg --config=src/icas/svgo.yml", + "vue-i18n-extract": "vue-i18n-extract", + "vue-i18n-report": "vue-i18n-extract report -v './src/**/*.?(js|vue)' -l './src/i18n/langs/**/*.json'", + "vue-i18n-report-json": "vue-i18n-extract report -v './src/**/*.?(js|vue)' -l './src/i18n/langs/**/*.json' -o /tmp/abc.json", + "vue-i18n-report-add-miss": "vue-i18n-extract report -v './src/**/*.?(js|vue)' -l './src/i18n/langs/**/*.json' -a", + "diff-i18n": "python ./src/i18n/langs/i18n-util.py diff en ja zh_Hant", + "apply-i18n": "python ./src/i18n/langs/i18n-util.py apply en ja zh_Hant" + }, + "dependencies": { + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@fontsource/open-sans": "^5.0.24", + "@traptitech/markdown-it-katex": "^3.6.0", + "@ztree/ztree_v3": "3.5.44", + "axios": "0.28.0", + "axios-retry": "^3.1.9", + "babel-loader": "^10.0.0", + "cache-loader": "^4.1.0", + "caniuse-lite": "^1.0.30001642", + "cron-parser": "^4.0.0", + "crypto-js": "^4.1.1", + "css-color-function": "^1.3.3", + "decimal.js": "^10.4.3", + "deepmerge": "^4.2.2", + "dompurify": "^3.1.6", + "echarts": "4.7.0", + "element-ui": "^2.15.14", + "elementui-lts": "^2.16.0", + "eslint-plugin-html": "^6.0.0", + "highlight.js": "^11.9.0", + "install": "^0.13.0", + "jquery": "^3.6.1", + "js-cookie": "2.2.0", + "jsencrypt": "^3.2.1", + "less": "^3.10.3", + "less-loader": "^5.0.0", + "lodash": "^4.17.21", + "lodash.clonedeep": "^4.5.0", + "lodash.frompairs": "^4.0.1", + "lodash.get": "^4.4.2", + "lodash.has": "^4.5.2", + "lodash.includes": "^4.3.0", + "lodash.isempty": "^4.4.0", + "lodash.isequal": "^4.5.0", + "lodash.isplainobject": "^4.0.6", + "lodash.set": "^4.3.2", + "lodash.topairs": "^4.3.0", + "lodash.values": "^4.3.0", + "markdown-it": "^13.0.2", + "markdown-it-link-attributes": "^4.0.1", + "moment": "^2.29.4", + "moment-parseformat": "^4.0.0", + "normalize.css": "7.0.0", + "npm": "^7.8.0", + "nprogress": "0.2.0", + "path-to-regexp": "3.3.0", + "sortablejs": "^1.15.6", + "v-sanitize": "^0.0.13", + "vue": "2.6.10", + "vue-codemirror": "4.0.6", + "vue-cookie": "^1.1.4", + "vue-echarts": "^5.0.0-beta.0", + "vue-i18n": "^8.15.5", + "vue-json-editor": "^1.4.3", + "vue-markdown": "^2.2.4", + "vue-password-strength-meter": "^1.7.2", + "vue-router": "3.0.6", + "vue-select": "^3.9.5", + "vuejs-logger": "^1.5.4", + "vuex": "3.1.0", + "watermark-js-plus": "^1.5.8", + "xss": "^1.0.14", + "xterm": "^4.5.0", + "xterm-addon-fit": "^0.3.0", + "zxcvbn": "^4.4.2" + }, + "devDependencies": { + "@babel/core": "7.18.6", + "@babel/register": "7.0.0", + "@vue/cli-plugin-babel": "3.6.0", + "@vue/cli-plugin-eslint": "^3.9.1", + "@vue/cli-plugin-unit-jest": "3.6.3", + "@vue/cli-service": "3.6.0", + "@vue/test-utils": "1.0.0-beta.29", + "autoprefixer": "^9.5.1", + "babel-core": "6.26.3", + "babel-eslint": "10.0.1", + "babel-jest": "23.6.0", + "chalk": "2.4.2", + "compression-webpack-plugin": "^6.1.1", + "connect": "3.6.6", + "deasync": "^0.1.29", + "eslint": "^5.15.3", + "eslint-config-prettier": "^6.15.0", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-spellcheck": "^0.0.20", + "eslint-plugin-vue": "5.2.2", + "eslint-plugin-vue-i18n": "^0.3.0", + "github-markdown-css": "^5.1.0", + "html-webpack-plugin": "3.2.0", + "husky": "^4.2.3", + "less-loader": "^5.0.0", + "lint-staged": "^10.1.2", + "mockjs": "1.0.1-beta3", + "prettier": "^3.6.2", + "pretty-bytes": "^5.6.0", + "runjs": "^4.3.2", + "sass": "~1.32.6", + "sass-loader": "^7.1.0", + "script-ext-html-webpack-plugin": "2.1.3", + "script-loader": "0.7.2", + "serve-static": "^1.16.0", + "strip-ansi": "^7.1.0", + "svg-sprite-loader": "4.1.3", + "svgo": "1.2.2", + "vue-i18n-extract": "^1.1.1", + "vue-template-compiler": "2.6.10", + "webpack": "^4.28.4" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 4 versions", + "ie 11" + ], + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix" + ] + } } diff --git a/src/components/Widgets/Icon/index.vue b/src/components/Widgets/Icon/index.vue index db03f2060..e5ed3ec94 100644 --- a/src/components/Widgets/Icon/index.vue +++ b/src/components/Widgets/Icon/index.vue @@ -1,6 +1,6 @@ + + diff --git a/src/layout/components/NavHeader/index.vue b/src/layout/components/NavHeader/index.vue index 52e297829..8e253268b 100644 --- a/src/layout/components/NavHeader/index.vue +++ b/src/layout/components/NavHeader/index.vue @@ -1,6 +1,9 @@