commit 78af453fe15a4a47c21ec239dd9b40c8a831a334 Author: O昵称重要吗O Date: Fri Mar 13 10:03:05 2026 +0800 chore: 初始化项目基础结构和资源文件 - 添加项目图标文件(app-icon.png、各平台图标) - 配置开发环境文件(.env、.nvmrc、.npmrc) - 添加静态资源文件(背景图片、字体、音频) - 初始化Tauri后端结构(build.rs、main.rs、模块文件) - 配置前端项目结构(TypeScript、Vue组件、样式) - 添加Node.js API服务基础结构 - 配置构建和开发工具(vite、prettier、gitignore) diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..873f1fc --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,17 @@ +{ + "permissions": { + "allow": [ + "Write", + "Bash(cd:*)", + "Bash(git update-index:*)" + ] + }, + "enabledPlugins": { + "typescript-lsp@claude-plugins-official": true, + "rust-analyzer-lsp@claude-plugins-official": true, + "circleback@claude-plugins-official": true, + "superpowers@claude-plugins-official": true, + "jdtls-lsp@claude-plugins-official": true, + "code-review@claude-plugins-official": true + } +} diff --git a/.env b/.env new file mode 100644 index 0000000..fdaec5a --- /dev/null +++ b/.env @@ -0,0 +1,4 @@ +# 阿里云OSS地址前缀(用于拼接完整地址) +VITE_BASE_OSS_URL = "https://oss.qyzhjy.com/" + + \ No newline at end of file diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..3f2417f --- /dev/null +++ b/.env.development @@ -0,0 +1,29 @@ + + +# 视频会议地址 +# VITE_METTING_JK_URL="https://jk.qyzhjy.com/MettingJK.shtml" +VITE_METTING_JK_URL="https://socket.qyzhjy.com/JKList/MettingJK.shtml" + +# 实时字幕地址 +# VITE_TEACHERCONTROL_JK_URL="https://jk.qyzhjy.com/TeacherControl_bak.shtml" +VITE_TEACHERCONTROL_JK_URL="https://socket.qyzhjy.com/JKList/TeacherControl_bak.shtml" + + +# 会议专用请求地址 +# VITE_MEETING_BASE_URL="http://172.16.10.135:4001" +VITE_MEETING_BASE_URL="http://127.0.0.1:4001" + +# 会议专用地址 +# VITE_MEETING_WEBSOCKET_BASE_URL="ws://172.16.10.135:4001" +VITE_MEETING_WEBSOCKET_BASE_URL="ws://127.0.0.1:4001" + +# 上传地址 +VITE_BASE_UPLOAD_URL="https://api.qyzhjy.com" + +# 请求接口 陈龙 +# VITE_BASE_URL="http://172.16.10.133:8080" +# 请求接口 测试服务器 +# VITE_BASE_URL="http://192.168.20.150:8080" +VITE_BASE_URL="https://api.qyzhjy.com" +# VITE_BASE_URL="https://frp.qyzhjy.com:40443" + diff --git a/.env.prod_150_8080 b/.env.prod_150_8080 new file mode 100644 index 0000000..6c47a40 --- /dev/null +++ b/.env.prod_150_8080 @@ -0,0 +1,17 @@ + +# 视频会议地址 +# VITE_METTING_JK_URL="https://jk.qyzhjy.com/MettingJK.shtml" +VITE_METTING_JK_URL="https://socket.qyzhjy.com/JKList/MettingJK.shtml" + +# 实时字幕地址 +# VITE_TEACHERCONTROL_JK_URL="https://jk.qyzhjy.com/TeacherControl_bak.shtml" +VITE_TEACHERCONTROL_JK_URL="https://socket.qyzhjy.com/JKList/TeacherControl_bak.shtml" + + +# 上传地址 +VITE_BASE_UPLOAD_URL="https://api.qyzhjy.com" + + +# 请求接口 测试服务器 +VITE_BASE_URL="http://192.168.20.150:8080" + diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..9723488 --- /dev/null +++ b/.env.production @@ -0,0 +1,29 @@ + +# 视频会议地址 +VITE_METTING_JK_URL="https://jk.qyzhjy.com/MettingJK.shtml" +# VITE_METTING_JK_URL="https://socket.qyzhjy.com/JKList/MettingJK.shtml" + +# 实时字幕地址 +VITE_TEACHERCONTROL_JK_URL="https://jk.qyzhjy.com/TeacherControl_bak.shtml" +# VITE_TEACHERCONTROL_JK_URL="https://socket.qyzhjy.com/JKList/TeacherControl_bak.shtml" + + +# 会议专用请求地址 +VITE_MEETING_BASE_URL="https://meeting.qyzhjy.com" + + +# 会议专用地址 +VITE_MEETING_WEBSOCKET_BASE_URL="wss://meeting.qyzhjy.com" + +# webSocket地址 +VITE_WEBSOCKET_BASE_URL="wss://jk.qyzhjy.com" +# VITE_WEBSOCKET_BASE_URL="wss://socket.qyzhjy.com" + +# 上传地址 +VITE_BASE_UPLOAD_URL="https://api.qyzhjy.com" + +# 请求接口 +VITE_BASE_URL="https://api.qyzhjy.com" +# VITE_BASE_URL="http://192.168.10.150:8080" + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5819531 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +node_modules/ +dist/ +dist-ssr/ +.DS_Store + +*.local + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.cache/ +.idea/ +.vscode/ +.vs/ +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +dist/electron/ +auto-imports.d.ts +components.d.ts +src/types/auto-imports.d.ts +src/types/components.d.ts +.MyPrivateConfig +release/ +build-output/ + + + diff --git a/.hintrc b/.hintrc new file mode 100644 index 0000000..5b0d6a9 --- /dev/null +++ b/.hintrc @@ -0,0 +1,6 @@ +{ + "extends": ["development"], + "hints": { + "no-inline-styles": "off" + } +} diff --git a/.lingma/rules/base.md b/.lingma/rules/base.md new file mode 100644 index 0000000..57e47ee --- /dev/null +++ b/.lingma/rules/base.md @@ -0,0 +1,12 @@ +--- +trigger: always_on +--- + +1. 用中文回答提出的问题包括但不限于总结,因为我英语太差了 +2. 前端项目方法尽量用function定义,注释要详细,打印的日志必须是中文,错误信息也必须是中文 +3. TS类型的每一个参数都要有注释,返回值也必须要有注释,然后每一个函数和方法都要注释 (/\*\* \*/形式中文注释) +4. VUE组件的Props/emit以及store(pinia、vuex等)中的每一个字段都要注释, +5. vue的 ref/computed/reactive/useTemplateRef等都需要有注释 (/\*\* \*/形式中文注释) +6. rust语言中:注释要详细,输出的日志必须是中文,错误信息也必须是中文,尽量使用0拷贝,尽量无锁,枚举和结构体要的每一个字段都要注释,每个函数和方法都要注释 +7. 不管前端还是rust所有注释都尽量简介明了的阐述功能就行了,不要写优化了什么,修复了什么,如果有特别需要注意或提醒的可以写出来 +8. 不用生成总结文档(不用生成md文件) diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..918fa4a --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmmirror.com/ \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..18c92ea --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v24 \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..fd32aad --- /dev/null +++ b/.prettierrc @@ -0,0 +1,20 @@ +{ + "printWidth": 160, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": true, + "jsxSingleQuote": false, + "trailingComma": "es5", + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "always", + "quoteProps": "preserve", + "requirePragma": false, + "insertPragma": false, + "proseWrap": "preserve", + "endOfLine": "auto", + "embeddedLanguageFormatting": "auto", + "singleAttributePerLine": false, + "vueIndentScriptAndStyle": true +} diff --git a/.qoder/agents/meeting-refactor-agent.md b/.qoder/agents/meeting-refactor-agent.md new file mode 100644 index 0000000..a284577 --- /dev/null +++ b/.qoder/agents/meeting-refactor-agent.md @@ -0,0 +1,61 @@ +--- +name: meeting-refactor-agent +description: 专门重构 meeting 模块代码,按照 base.md 规范进行规范化改造。处理中文注释、函数定义、去除 any 类型、详细类型注释等。 +tools: Read, Write, Edit, Grep, Glob +--- + +# 角色定义 + +你是前端代码重构专家,专门负责按照项目规范重构 Vue 组件代码。 + +## 重构规范(必须严格遵守) + +### 1. 语言要求 + +- 所有注释、日志、错误信息必须使用中文 +- 代码中不要出现英文注释 + +### 2. 函数定义 + +- 使用 `function` 关键字定义函数,不使用箭头函数 +- 例如:`function handleClick() {}` 而不是 `const handleClick = () => {}` + +### 3. 注释规范 + +- 所有函数必须使用 JSDoc 格式注释(`/** */`) +- 参数必须有 `@param` 注释 +- 返回值必须有 `@returns` 注释 +- Vue 的 ref/computed/reactive/useTemplateRef 等都需要有注释 + +### 4. 类型规范 + +- 禁止使用 `any` 类型 +- 所有类型必须明确定义 +- 声网 SDK 的类型要使用官方定义(如 `IAgoraRTCClient`, `IAgoraRTCRemoteUser` 等) + +### 5. 日志规范 + +- 所有 console.log/error 必须使用中文 +- 错误信息必须清晰描述问题 + +## 工作流程 + +1. 读取目标文件内容 +2. 识别所有需要重构的部分(any 类型、箭头函数、缺少注释等) +3. 按照规范逐块重构 +4. 确保重构后代码功能不变 +5. 输出重构后的完整代码 + +## 输出格式 + +**重构内容总结** + +- 修改点 1 +- 修改点 2 + ... + +**重构后的代码** + +```vue +完整代码 +``` diff --git a/.qoder/rules/base.md b/.qoder/rules/base.md new file mode 100644 index 0000000..e7419c5 --- /dev/null +++ b/.qoder/rules/base.md @@ -0,0 +1,11 @@ +--- +trigger: always_on +--- + +1. 用中文回答提出的问题包括但不限于总结,因为我英语太差了 +2. 前端项目方法尽量用function定义,注释要详细,打印的日志必须是中文,错误信息也必须是中文 +3. TS类型的每一个参数都要有注释,返回值也必须要有注释,然后每一个函数和方法都要注释 (/\*\* \*/形式中文注释) +4. VUE组件的Props/emit以及store(pinia、vuex等)中的每一个字段都要注释, +5. vue的 ref/computed/reactive/useTemplateRef等都需要有注释 (/\*\* \*/形式中文注释) +6. rust语言中:注释要详细,输出的日志必须是中文,错误信息也必须是中文,尽量使用0拷贝,尽量无锁,枚举和结构体要的每一个字段都要注释,每个函数和方法都要注释 +7. 不管前端还是rust所有注释都尽量简介明了的阐述功能就行了,不要写优化了什么,修复了什么,如果有特别需要注意或提醒的可以写出来 diff --git a/.qoderignore b/.qoderignore new file mode 100644 index 0000000..b567081 --- /dev/null +++ b/.qoderignore @@ -0,0 +1,11 @@ +/src-tauri/target/ +/src-tauri/icons/ +/src/node_modules/ +.husky/ +.trae/ +dist/ +.idea/ +.vscode/ +.claude/ + + diff --git a/.trae/rules/gf.md b/.trae/rules/gf.md new file mode 100644 index 0000000..c0ff32c --- /dev/null +++ b/.trae/rules/gf.md @@ -0,0 +1,5 @@ +1. 用中文回答提出的问题包括但不限于总结,因为我英语太差了 +2. 前端项目方法尽量用function定义,注释要详细,打印的日志必须是中文,错误信息也必须是中文 +3. TS类型的每一个参数都要有注释,返回值也必须要有注释,然后每一个函数和方法都要注释 (/\*\* \*/形式中文注释) +4. VUE组件的Props/emit以及store(pinia、vuex等)中的每一个字段都要注释,每一个字段都要注释 ,ref/computed/reactive/useTemplateRef等都需要有注释 (/\*\* \*/形式中文注释) +5. rust注释要详细,输出的日志必须是中文,错误信息也必须是中文,尽量使用0拷贝,尽量无锁,枚举和结构体要的每一个字段都要注释,每个函数和方法都要注释 diff --git a/README.md b/README.md new file mode 100644 index 0000000..9ba8ca8 --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +# 说明 + +[VSCode](https://code.visualstudio.com/) + [vue3.4+](https://vue3js.cn/docs/zh/) + [typescript5.3+](https://www.typescriptlang.org/zh/) + [vite5.0+](https://vitejs.cn/) + [element-plus2.6+](https://element-plus.gitee.io/#/zh-CN) + +## crates地址 + +[crates](https://crates.io/) + +## 解决 提交代码时提示 npx: not found + +1. 在`C:\Users\你等用户名\.config\husky` 目录下新建 `init.sh` +2. 在`init.sh`文件中输入`eval "$(fnm env --use-on-cd)"`并保存 +3. 重启vscode + +## 使用淘宝源镜像(解决安装慢) + +```bash +# 全局设置全局设置后无需每次 添加后缀--registry https://registry.npmmirror.com/ +npm config set registry https://registry.npmmirror.com/ + +# 配置后可通过下面方式来验证是否成功 +npm config get registry + +# 果想还原npm仓库地址的话,只需要在把地址配置成npm镜像就可以了 +npm config set registry https://registry.npmjs.com + +# 仅在每次使用时指定淘宝源,即在后面添加 --registry https://registry.npmmirror.com/ 如安装yarn: +npm install -g yarn --registry https://registry.npmmirror.com/ +npm install -g npm-check-updates --registry https://registry.npmmirror.com/ +``` + +## 代理 + +### 命令提示符 (CMD)​ + +```bash +#依次输入以下命令: +set https_proxy=http://127.0.0.1:7890 +set http_proxy=http://127.0.0.1:7890 +set all_proxy=socks5://127.0.0.1:7890 +``` + +### PowerShell + +```bash +#依次输入以下命令: +$env:https_proxy="http://127.0.0.1:7890" +$env:http_proxy="http://127.0.0.1:7890" +$env:all_proxy="socks5://127.0.0.1:7890" +``` + +## 初始化 + +```bash +npm install +``` + +## 运行 + +```bash +npm run dev # 测试版 +npm run build # 构建正式版 +npm run serve # 正式版预览 (需要先运行 npm run build) +``` + +## 快速删除 node_modules 包 + +```bash +npm install rimraf -g +``` + +## 检测或更新依赖包 + +```bash +# 先安装检测工具 +npm install -g npm-check-updates # 或 yarn add -g npm-check-updates + +ncu # 或 npm-check-updates 检测 +ncu -g # 全局检测 +ncu -u # 或 npm-check-updates -u 更新 +ncu --target greatest # 检测最大版本(不一定是最新) +ncu --target newest # 检测最新的(包含测试版) +``` + +## 其他说明 + +**Element Plus 可以在支持 [ES2018(ES9)](https://caniuse.com/?feats=mdn-javascript_builtins_regexp_dotall,mdn-javascript_builtins_regexp_lookbehind_assertion,mdn-javascript_builtins_regexp_named_capture_groups,mdn-javascript_builtins_regexp_property_escapes,mdn-javascript_builtins_symbol_asynciterator,mdn-javascript_functions_method_definitions_async_generator_methods,mdn-javascript_grammar_template_literals_template_literal_revision,mdn-javascript_operators_destructuring_rest_in_objects,mdn-javascript_operators_spread_spread_in_destructuring,promise-finally) 和 [ResizeObserver](https://caniuse.com/resizeobserver) 的浏览器上运行。 如果您确实需要支持旧版本的浏览器,请自行添加 Babel 和相应的 Polyfill 。** + +**代码还使用了 [可选链 (?.)](https://caniuse.com/mdn-javascript_operators_optional_chaining) ,在测试环境下请注意浏览器是否支持可选链,打包时可通过配置 vite 中的 [build.target](https://vitejs.dev/config/build-options.html#build-target) 来兼容 。** + +### 部分 api 支持的最低版本 + +| API | chrome | firefox | safari | +| -------------- | ------ | ------- | ------ | +| 可选链(?.) | 80 | 74 | 13.1 | +| ResizeObserver | 69 | 64 | 13.1 | + +### 当前主流浏览器内核版本号(2022.10.12) + +| 浏览器 | 内核版本 | 是否支持 | +| --------------- | -------- | --------------------------------- | +| Opera浏览器 | 103 | 完全支持 | +| 青鸟浏览器 | 97 | 完全支持 | +| 遨游浏览器 | 96 | 完全支持 | +| QQ浏览器 | 94 | 完全支持 | +| 双核浏览器 | 101 | 完全支持 | +| 360浏览器 | 114 | 完全支持 | +| 360极速浏览器 | 108 | 完全支持 | +| 搜狗浏览器 | 94 | 完全支持 | +| 猎豹浏览器8 | 79 | 仅编译后支持,开发阶段不支持可选链 | +| 2345 加速浏览器 | 109 | 完全支持 | diff --git a/app-icon.png b/app-icon.png new file mode 100644 index 0000000..4782c68 Binary files /dev/null and b/app-icon.png differ diff --git a/commitlint.config.ts b/commitlint.config.ts new file mode 100644 index 0000000..ab248f9 --- /dev/null +++ b/commitlint.config.ts @@ -0,0 +1,117 @@ +import { RuleConfigSeverity, type UserConfig } from '@commitlint/types'; + +const Configuration: UserConfig = { + ignores: [(commit) => commit.includes('init')], + extends: ['@commitlint/config-conventional'], + rules: { + 'body-leading-blank': [RuleConfigSeverity.Error, 'always'], + 'footer-leading-blank': [RuleConfigSeverity.Warning, 'always'], + 'header-max-length': [RuleConfigSeverity.Error, 'always', 108], + 'subject-empty': [RuleConfigSeverity.Error, 'never'], + 'type-empty': [RuleConfigSeverity.Error, 'never'], + 'type-enum': [RuleConfigSeverity.Error, 'always', ['feat', 'fix', 'perf', 'style', 'docs', 'test', 'refactor', 'build', 'ci', 'chore', 'revert']], + }, + prompt: { + settings: {}, + messages: { + skip: '按 Enter 键可以跳过该字段', + max: '最大字符数', + min: '最小字符数', + emptyWarning: '字段不能为空', + upperLimitWarning: '超出字符限制', + lowerLimitWarning: '字符小于下限', + }, + + questions: { + type: { + description: '选择你要提交的变更类型:', + enum: { + feat: { + description: '特性: ✨ 新增功能', + title: '特征', + emoji: '✨', + }, + fix: { + description: '修复: 🐛 修复缺陷', + title: 'bug修复', + emoji: '🐛', + }, + docs: { + description: '文档: 📝 文档变更(更新README文件,或者注释)', + title: '文档', + emoji: '📚', + }, + style: { + description: '格式: 🌈 代码格式(空格、格式化、缺失的分号等)', + title: '格式', + emoji: '🌈', + }, + refactor: { + description: '重构: 🔄 代码重构(不修复错误也不添加特性的代码更改)', + title: '重构', + emoji: '🔄', + }, + perf: { + description: '性能: 🚀 性能优化', + title: '性能', + emoji: '🚀', + }, + test: { + description: '测试: 🧪 添加疏漏测试或已有测试改动', + title: '测试', + emoji: '🧪', + }, + build: { + description: '构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 vite 配置等)', + title: '依赖', + emoji: '📦️', + }, + ci: { + description: '集成: ⚙️ 修改 CI 配置、脚本', + title: 'ci', + emoji: '⚙️', + }, + chore: { + description: '其他: 🛠️ 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)', + title: 'Chores', + emoji: '🛠️', + }, + revert: { + description: '回退: ↩️ 回滚之前提交', + title: '回退', + emoji: '🗑', + }, + }, + }, + scope: { + description: '这个更改的范围是什么(例如组件或文件名)', + }, + subject: { + description: '写一个简短的,修改的变化描述', + }, + body: { + description: '提供更长的变更描述', + }, + isBreaking: { + description: '有什么突破性的变化吗?', + }, + breakingBody: { + description: '一个破坏性变更提交需要一个主体。请输入更长的提交描述。', + }, + breaking: { + description: '描述突破性的变化', + }, + isIssueAffected: { + description: '这一变化是否会影响任何悬而未决的问题?', + }, + issuesBody: { + description: '如果问题已关闭,则提交需要一个主体。请输入更长的提交描述', + }, + issues: { + description: '添加问题引用(例如:“fix #123”,“re #123”。)', + }, + }, + }, +}; + +export default Configuration; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..79b7339 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,1429 @@ +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import pluginVue from 'eslint-plugin-vue'; +import parserVue from 'vue-eslint-parser'; +import jsdoc from 'eslint-plugin-jsdoc'; +import globals from 'globals'; +import configPrettier from 'eslint-config-prettier'; +import { defineConfig } from 'eslint/config'; +/** 得到vue版本 (如:3.2.45) */ +const vueVersions = '3.4.27'; +const vueVersionsNumb = 3.3; +/** 是否有TS验证规则 */ +const tsVerify = true; + +export default defineConfig( + { + ignores: ['**/src/sdk/tstudy_digital_pen/src/*.js'], + }, + eslint.configs.recommended, + configPrettier, + ...pluginVue.configs['flat/recommended'], + ...tseslint.configs.strict, + ...tseslint.configs.stylistic, + { + languageOptions: { + globals: { + ...globals.node, + ...globals.browser, + ElMessage: 'readonly', + ElLoading: 'readonly', + ElMessageBox: 'readonly', + __APP_VERSION_TIMESTAMP__: 'readonly', // APP版本号时间戳(在vite.config中配置) + }, + }, + plugins: { + jsdoc, + }, + rules: { + ...getBaseRules(), + ...getJsDocRules(), + }, + }, + { + files: ['**/*.ts', '**/*.cts', '**/*.mts', '**/*.ctsx', '**/*.mtsx', '**/*.tsx'], + languageOptions: { + parser: tseslint.parser, + parserOptions: { + sourceType: 'module', + }, + }, + plugins: { + '@typescript-eslint': tseslint.plugin, + }, + rules: { + ...getTypescriptRules(), + }, + }, + { + files: ['**/*.d.ts'], + + rules: { + 'init-declarations': 'off', + }, + }, + { + files: ['**/*.js', '**/*.cjs', '**/*.mjs', '**/*.cjsx', '**/*.mjsx', '**/*.jsx'], + rules: { + '@typescript-eslint/no-require-imports': 'off', + '@typescript-eslint/no-var-requires': 'off', + }, + }, + { + files: ['**/*.vue'], + languageOptions: { + globals: {}, + parser: parserVue, + ecmaVersion: 'latest', // 启用es2020的语法包含以下版本 2015(同6)、2016(同7)、2017(同8)、2018(同9)、2019(同10)、2020(同11)、2021(同为 12)或 2022(与 13 相同)以使用基于年份的命名。您还可以设置 “latest” 以使用最新支持的版本 + sourceType: 'module', + parserOptions: { + extraFileExtensions: ['.vue'], + parser: tseslint.parser, + sourceType: 'module', + // project: true, + // tsconfigRootDir: import.meta.dirname, + ecmaFeatures: { + jsx: true, + impliedStrict: true, // 启用全局严格模式 + }, + }, + }, + plugins: { + vue: pluginVue, + '@typescript-eslint': tseslint.plugin, + }, + processor: pluginVue.processors['.vue'], + rules: { + ...getVueRules(), + ...getTypescriptRules(), + }, + }, + { + files: ['**/*.js'], + rules: { + 'no-undef': 'error', + 'no-unused-vars': 'error', + 'default-param-last': 'error', + 'init-declarations': ['error', 'always'], + 'no-empty-function': 'error', + 'no-shadow': 'error', + '@typescript-eslint/no-unused-expressions': 'off', + }, + } +); + +/** + * 得到eslint的规则 + */ +function getBaseRules() { + return { + /** *************************************************** 这些规则与代码中可能的逻辑错误有关 */ + // 强制数组方法的回调函数中有 return 语句 + 'array-callback-return': 'error', + // 强制在子类构造函数中用super()调用父类构造函数,TypeScrip的编译器也会提示 + 'constructor-super': 'error', + // 强制 “for” 循环中更新子句的计数器朝着正确的方向移动 + 'for-direction': 'error', + // 强制在 getter 属性中出现一个 return 语句。每个 getter 都期望有返回值。 + 'getter-return': 'error', + // 禁止使用异步函数作为 Promise executor + 'no-async-promise-executor': 'error', + // 不允许await在循环体内使用。 + 'no-await-in-loop': 'error', + // 禁止修改类声明的变量 + 'no-class-assign': 'error', + // 针对试图与-0进行比较的代码发出警告,因为这不会按预期工作。也就是说,像x === -0这样的代码将通过+0和-0。作者可能打算 Object.is(x,-0)。 + 'no-compare-neg-zero': 'error', + // 禁止条件表达式中出现赋值操作符 + 'no-cond-assign': 'error', + // 禁止修改 const 声明的变量 + 'no-const-assign': 'error', + // 将始终评估为真或假的比较以及始终短路或从不短路的逻辑表达式 ( ||, &&, ??) 都可能表明程序员错误 + 'no-constant-binary-expression': 'error', + // [对应 vue/no-constant-condition]禁止在条件中使用常量表达式 [if (false) {} 错] [if (aa===false) {} 对] + 'no-constant-condition': 'error', + // 不允许从构造函数返回值 + 'no-constructor-return': 'error', + // 禁止在正则表达式中使用控制字符 :new RegExp("\x1f") + 'no-control-regex': 'error', + // 禁用 debugger + 'no-debugger': 'error', + // 禁止 function 定义中出现重名参数 + 'no-dupe-args': 'error', + // 禁止类成员中出现重复的名称 + // 'no-dupe-class-members': 'error', + // 不允许 if-else-if 链中的重复条件 + 'no-dupe-else-if': 'error', + // 禁止对象字面量中出现重复的 key + 'no-dupe-keys': 'error', + // 禁止重复的 case 标签 + 'no-duplicate-case': 'error', + // 不允许复制模块的进口 + 'no-duplicate-imports': 'error', + // 禁止在正则表达式中使用空字符集 (/^abc[]/) + 'no-empty-character-class': 'error', + // [对应 vue/no-empty-pattern]禁止使用空解构模式no-empty-pattern + 'no-empty-pattern': 'error', + // 禁止对 catch 子句的参数重新赋值 + 'no-ex-assign': 'error', + // 禁止 case 语句落空 + 'no-fallthrough': 'error', + // 禁止对 function 声明重新赋值 + 'no-func-assign': 'error', + // 禁止对 function 声明重新赋值 + 'no-import-assign': 'error', + // 禁止在嵌套的块中出现 function 或 var 声明 + 'no-inner-declarations': ['error', 'both'], + // 禁止 RegExp 构造函数中无效的正则表达式字符串 + 'no-invalid-regexp': 'error', + // 禁止在字符串和注释之外不规则的空白 + 'no-irregular-whitespace': ['error', { skipStrings: true }], + // 不允许丢失精度的数值 + 'no-loss-of-precision': 'error', + // 不允许在字符类语法中出现由多个代码点组成的字符, 因为Unicode 包括由多个代码点组成的字符。RegExp 字符类语法 (/[abc]/) 不能处理由多个代码点组成的字符 + 'no-misleading-character-class': 'error', + // 不允许在字符类语法中出现由多个代码点组成的字符, 因为Unicode 包括由多个代码点组成的字符。RegExp 字符类语法 (/[abc]/) 不能处理由多个代码点组成的字符 + 'no-new-native-nonconstructor': 'error', // 禁止在不能使用new的变量前使用new + // 禁止 Symbol 的构造函数 + 'no-new-symbol': 'error', + // 禁止把全局对象 (Math 和 JSON) 作为函数调用 错误:var math = Math(); + 'no-obj-calls': 'error', + // 不允许从 Promise 执行器函数返回值 + 'no-promise-executor-return': 'error', + // 禁止直接使用 Object.prototypes的内置属性 例如,foo.hasOwnProperty("bar") 应该替换为 Object.prototype.hasOwnProperty.call(foo, "bar") + 'no-prototype-builtins': 'error', + // 禁止自我赋值 + 'no-self-assign': 'error', + // 禁止自身比较 + 'no-self-compare': 'error', + // 虽然从 setter 返回值不会产生错误,但返回的值将被忽略。因此,从 setter 返回值要么是不必要的,要么是可能的错误,因为不能使用返回的值。 + 'no-setter-return': 'error', + // [对应 vue/no-sparse-arrays]禁用稀疏数组 + 'no-sparse-arrays': 'error', + // 警告常规字符串包含看起来像模板字面占位符的内容。"Hello ${name}!"; + 'no-template-curly-in-string': 'error', + // 禁止在构造函数中,在调用 super() 之前使用 this 或 super + 'no-this-before-super': 'error', + // 禁用未声明的变量,除非它们在 /*global */ 注释中被提到 + 'no-undef': tsVerify ? 'off' : 'error', + // 禁止出现令人困惑的多行表达式 + 'no-unexpected-multiline': 'error', + // 禁用一成不变的循环条件 + 'no-unmodified-loop-condition': 'error', + // 禁止在return、throw、continue 和 break语句之后出现不可达代码 + 'no-unreachable': 'error', + // 禁止无法访问的循环 + 'no-unreachable-loop': 'error', + // 禁止在 finally 语句块中出现控制流语句 + 'no-unsafe-finally': 'error', + // 禁止否定关系运算符的左操作数 + 'no-unsafe-negation': ['error', { enforceForOrderingRelations: true }], + // 禁止在不允许使用值的上下文中使用[可选链?.] 如(undefined) + 'no-unsafe-optional-chaining': 'error', + // 禁止未使用的私有类成员 + 'no-unused-private-class-members': 'error', + // 禁止出现未使用过的变量 + 'no-unused-vars': tsVerify ? 'off' : 'error', + // 不允许在变量定义之前使用它们 + 'no-use-before-define': ['error', { functions: false, classes: true, variables: true }], + // 禁止在正则表达式中使用无用的反向引用 + 'no-useless-backreference': 'error', + // 禁止由于 await 或 yield的使用而可能导致出现竞态条件的赋值 + 'require-atomic-updates': ['error', { allowProperties: true }], + // 不允许比较"NaN"。判断数字是否是NaN,得用isNaN + 'use-isnan': 'error', + // 强制 typeof 表达式与有效的字符串进行比较 + 'valid-typeof': 'error', + + /** *************************************************** 这些规则建议了不同的做事方式 */ + + // 定义对象的set存取器属性时,强制定义get + 'accessor-pairs': ['error', { setWithoutGet: true, getWithoutSet: true }], + // 要求箭头函数体使用大括号 + 'arrow-body-style': ['off', 'as-needed'], + // 强制把变量的使用限制在其定义的作用域范围内 + 'block-scoped-var': 'error', + // [对应 vue/camelcase] 强制执行驼峰命名约定 + camelcase: 'off', + // 注释 大写字母开头,不推荐 注释的代码会报错 + 'capitalized-comments': 'off', + // 如果一个类方法没有使用this,它有时可以变成一个静态函数。如果将该方法转换为静态函数,那么调用该特定方法的类的实例也必须转换为静态调用 + 'class-methods-use-this': 'off', + // 限制圈复杂度,也就是类似if else能连续接多少个 + complexity: 'off', + // 要求 return 语句要么总是指定返回的值,要么不指定 + 'consistent-return': 'error', + // 用于指统一在回调函数中指向this的变量名, var that = this; that不能指向其他任何值,this也不能赋值给that以外的其他值 + 'consistent-this': ['error', 'that'], + // 强制所有控制语句使用一致的括号风格 + curly: ['error', 'all'], + // switch 语句强制 default 分支,也可添加 // no default 注释取消此次警告 + 'default-case': 'error', + // 将 switch 语句中的缺省子句强制为最后一个 + 'default-case-last': 'error', + // 将默认参数强制放在最后 + 'default-param-last': tsVerify ? 'off' : 'error', + // [对应 vue/dot-notation]强制使用.号取属性 + 'dot-notation': 'error', + // [对应 vue/eqeqeq]使用 === 替代 == allow-null允许null和undefined== + eqeqeq: ['error', 'always'], + // 要求函数名称与它们所分配的变量或属性的名称相匹配 + 'func-name-matching': 'error', + // 强制使用命名的 function 表达式 + 'func-names': ['error', 'always', { generators: 'as-needed' }], + // 强制一致地使用函数声明或函数表达式,方法定义风格 + 'func-style': ['error', 'declaration', { allowArrowFunctions: true }], + // 强制如果一个属性有一个 getter 和一个 setter,那么 setter 应该在 getter 之后定义 + 'grouped-accessor-pairs': ['error', 'getBeforeSet'], + // 要求 for-in 循环中有一个 if 语句 + 'guard-for-in': 'off', + // 禁止使用指定的标识符 + 'id-denylist': 'off', + // 强制标识符的最小和最大长度 (变量名长度) + 'id-length': 'off', + // 要求标识符匹配一个指定的正则表达式 + 'id-match': 'off', + // 要求或禁止 var 声明中的初始化(初值) + 'init-declarations': tsVerify ? 'off' : ['error', 'always'], + // 要求或禁止逻辑赋值逻辑运算符速记 + 'logical-assignment-operators': ['error', 'never'], + // 强制实施每个文件的最大类数 + 'max-classes-per-file': 'off', + // 强制执行嵌套块的最大深度,以降低代码复杂度。"max"(默认为4) + 'max-depth': ['off', { max: 6 }], + // 强制文件的最大行数 + 'max-lines': 'off', + // 强制文件的最大行数 + 'max-lines-per-function': 'off', + // 强制回调函数最大嵌套深度 5层 + 'max-nested-callbacks': ['off', { max: 5 }], + // 强制 function 定义中最多允许的参数数量 + 'max-params': ['off', { max: 12 }], + // 强制 function 块最多允许的的语句数量 + 'max-statements': 'off', + // 强化多行评论的特定风格。 + 'multiline-comment-style': 'off', + // 要求构造函数首字母大写 (要求调用 new 操作符时有首字母大小的函数,允许调用首字母大写的函数时没有 new 操作符。) + 'new-cap': ['error', { newIsCap: true, capIsNew: false }], + // 禁用 alert、confirm 和 prompt + 'no-alert': 'error', + // 禁止使用 Array 构造函数 + 'no-array-constructor': 'error', + // 禁用按位运算符 + 'no-bitwise': 'error', + // 禁用 arguments.caller 或 arguments.callee + 'no-caller': 'error', + // 不允许在 case 子句中使用词法声明 + 'no-case-declarations': 'error', + // 禁用 console + 'no-console': 'off', + // 禁用 continue 语句 + 'no-continue': 'error', + // 禁止删除变量 + 'no-delete-var': 'error', + // 禁止除法操作符显式的出现在正则表达式开始的位置 + 'no-div-regex': 'error', + // 禁止 if 语句中有 return 之后有 else + 'no-else-return': 'off', + // 禁止空语句块 + 'no-empty': ['error', { allowEmptyCatch: true }], + // 禁止出现空函数. 如果一个函数包含了一条注释,它将不会被认为有问题。 + 'no-empty-function': tsVerify ? 'off' : 'error', + // 禁止空静态块 + 'no-empty-static-block': 'error', + // 禁止在没有类型检查操作符的情况下与 null 进行比较 + 'no-eq-null': 'error', + // 禁用 eval() + 'no-eval': 'error', + // 禁止扩展原生类型 + 'no-extend-native': ['error', { exceptions: ['Object', 'Array'] }], + // 禁止不必要的 .bind() 调用 + 'no-extra-bind': 'error', + // 禁止不必要的布尔转换 + 'no-extra-boolean-cast': 'error', + // 禁用不必要的标签 + 'no-extra-label': 'error', + // 此规则不允许修改只读全局变量。 + 'no-global-assign': 'error', + // 禁止使用短符号进行类型转换(!!fOO) + 'no-implicit-coercion': 'error', + // 禁止在全局范围内使用 var 和命名的 function 声明 + 'no-implicit-globals': 'error', + // 禁止使用类似 eval() 的方法 + 'no-implied-eval': 'error', + // 禁止在代码行后使用内联注释 + 'no-inline-comments': 'off', + // 禁止 this 关键字出现在类和类对象之外 + 'no-invalid-this': 'error', + // 禁用 __iterator__ 属性 + 'no-iterator': 'error', + // 不允许标签与变量同名 + 'no-label-var': 'error', + // 禁用标签语句 + 'no-labels': 'error', + // 禁用不必要的嵌套块 + 'no-lone-blocks': 'error', + // 禁止 if 作为唯一的语句出现在 else 语句中 + 'no-lonely-if': 'off', + // 禁止在循环中出现 function 声明和表达式 + 'no-loop-func': 'error', + // 禁用魔术数字(3.14什么的用常量代替) + 'no-magic-numbers': 'off', + // 不允许在单个语句中使用多个分配。a = b = c = d; + 'no-multi-assign': 'error', + // 禁止使用多行字符串,在 JavaScript 中,可以在新行之前使用斜线创建多行字符串 + 'no-multi-str': 'error', + // 不允许否定的表达式 + 'no-negated-condition': 'off', + // 不允许使用嵌套的三元表达式 var foo = bar ? baz : qux === quxx ? bing : bam; + 'no-nested-ternary': 'off', + // 禁止在非赋值或条件语句中使用 new 操作符 + 'no-new': 'off', + // 禁止对 Function 对象使用 new 操作符 + 'no-new-func': 'error', + // 禁止对 String,Number 和 Boolean 使用 new 操作符 + 'no-new-wrappers': 'error', + // 禁止字符串文本中的序列并转义序列\8\9 + 'no-nonoctal-decimal-escape': 'error', + // 通常不鼓励使用构造函数来构造新的空对象,而支持对象文字表示法,因为简洁,并且全局可以重新定义。 例外情况是,当构造函数用于有意包装作为参数传递的指定值时 + 'no-object-constructor': 'error', + // 禁用八进制字面量 + 'no-octal': 'error', + // 禁止在字符串中使用八进制转义序列 + 'no-octal-escape': 'error', + // 不允许对 function 的参数进行重新赋值 + 'no-param-reassign': 'error', + // 禁止使用一元操作符 ++ 和 -- + 'no-plusplus': 'off', + // 禁用 __proto__ 属性 + 'no-proto': 'error', + // 禁止使用 var 多次声明同一变量 + 'no-redeclare': 'error', + // 禁止正则表达式字面量中出现多个空格 + 'no-regex-spaces': 'error', + // 禁止在导出中指定名称 + 'no-restricted-exports': 'off', + // 禁止在导出中指定名称 restrictedNamedExports中就是限制导出的名称 禁用特定的全局变量 + 'no-restricted-globals': ['error', { name: 'event', message: 'event请在方法的参数中定义event' }], + // 禁止加载指定的模块 paths中就是需要禁止加载的模块 + 'no-restricted-imports': ['off', { paths: ['import1', 'import2'] }], + // 禁止某些对象上的某些属性 如果省略对象名称,则不允许所有对象使用该属性;如果省略属性名称,则不允许访问给定对象的任何属性 + 'no-restricted-properties': [ + 'off', + { + object: '对象名称', + property: '对象对象下的属性名称', + message: '提示消息', + }, + ], + // 禁止使用特定的语法 + 'no-restricted-syntax': ['off', { selector: '语法', message: '提示消息' }], + // 禁止在返回语句中赋值 (return foo = bar + 2; 错误) + 'no-return-assign': 'error', + // 禁止使用 javascript: url + 'no-script-url': 'error', + // 禁用逗号操作符 + 'no-sequences': 'error', + // 禁止变量声明与外层作用域的变量同名 + 'no-shadow': tsVerify ? 'off' : 'error', + // 禁止覆盖受限制的标识符 + 'no-shadow-restricted-names': 'error', + // 不允许使用三元操作符 + 'no-ternary': 'off', + // 禁止抛出非异常字面量 + 'no-throw-literal': 'error', + // 禁止将变量初始化为undefined + 'no-undef-init': 'off', + // 禁止将 undefined 作为标识符 + 'no-undefined': 'off', + // 禁止标识符中有悬空下划线_bar + 'no-underscore-dangle': 'off', + // 禁止在有比三元操作符更简单表达式时使用三元操作符 + 'no-unneeded-ternary': 'error', + // 禁止出现未使用过的表达式 + 'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }], + // 禁用未使用过的标签 + 'no-unused-labels': 'error', + // 禁止不必要的 .call() 和 .apply() + 'no-useless-call': 'error', + // 禁止不必要的 catch 子句 + 'no-useless-catch': 'error', + // 禁止不必要的计算性能键对象的文字 + 'no-useless-computed-key': 'error', + // [对应 vue/no-useless-concat]禁止不必要的字符串字面量或模板字面量的连接 + 'no-useless-concat': 'error', + // ES2015 会提供默认的类构造函数。因此,没有必要提供一个空构造函数或一个简单地委托给它的父类的构造函数, + 'no-useless-constructor': 'error', + // 禁用不必要的转义字符 + 'no-useless-escape': 'error', + // 不允许将导入、导出和解构分配重命名为相同的名称。 + 'no-useless-rename': 'error', + // 禁止冗余返回语句 + 'no-useless-return': 'error', + // 要求使用 let 或 const 而不是 var + 'no-var': 'error', + // 禁用 void 操作符 + 'no-void': 'error', + // 禁止在注释中使用特定的警告术语 + 'no-warning-comments': 'off', + // 禁用 with 语句 + 'no-with': 'error', + // 要求或禁止对象字面量中方法和属性使用简写语法 + 'object-shorthand': ['error', 'always'], + // 强制函数中的变量要么一起声明要么分开声明 + 'one-var': ['error', 'never'], + // 要求或禁止在可能的情况下要求使用简化的赋值操作符 + 'operator-assignment': ['error', 'always'], + // 要求使用箭头函数作为回调 + 'prefer-arrow-callback': 'error', + // 要求使用 const 声明那些声明后不再被修改的变量 + 'prefer-const': 'error', + // 优先使用数组和对象解构 + 'prefer-destructuring': 'off', + // 禁止使用 有利于运营商的Math.pow() + 'prefer-exponentiation-operator': 'error', + // 强制在正则表达式中使用命名捕获组 + 'prefer-named-capture-group': 'off', + // 禁止调用parseInt()或Number.parseInt()使用两个参数调用:一个字符串; 和2(二进制),8(八进制)或16(十六进制)的基数选项。 + 'prefer-numeric-literals': 'error', + // 禁止使用Object.prototype.hasOwnProperty.call() 而应该使用Object.hasOwn() + 'prefer-object-has-own': 'error', + // 优先使用扩展("...")而不是Object.assign + 'prefer-object-spread': 'error', + // 确保承诺只被Error对象拒绝。 + 'prefer-promise-reject-errors': 'off', + // 不允许使用构造函数创建正则表达式 + 'prefer-regex-literals': 'off', + // 禁止使用 arguments 而应该使用 ...args + 'prefer-rest-params': 'error', + // 要求使用扩展运算符而非 .apply() + 'prefer-spread': 'error', + // [对应 vue/prefer-template]要求使用模板字面量而非字符串连接 + 'prefer-template': 'error', + // 强制在parseInt()使用基数参数 + radix: 'off', + // 禁止无用的赋值 + 'no-useless-assignment': 'off', + // 异步函数必须具有await表达式 + 'require-await': 'error', + // 在正则表达式上强制使用标志 + 'require-unicode-regexp': 'off', + // 要求generator 函数内有 yield + 'require-yield': 'error', + // 强制模块内的 import 排序 + 'sort-imports': ['error', { ignoreDeclarationSort: true }], + // 所有属性定义并验证所有变量是按字母顺序排序的。 + 'sort-keys': 'off', + // 要求同一个声明块中的变量按顺序排列 + 'sort-vars': 'error', + // 要求或禁止使用严格模式指令 + strict: ['error', 'global'], + // var foo = Symbol("some description"); 一定要有描述 + 'symbol-description': 'error', + // 要求所有的 var 声明出现在它们所在的作用域顶部 + 'vars-on-top': 'error', + // 要求或禁止 “Yoda” 条件 + yoda: 'error', + + /** *************************************************** 这些规则关心代码的外观,而不是它的执行方式 */ + // 强制行注释可以位于代码上方或旁边。该规则有助于团队保持一致的风格。 + 'line-comment-position': 'off', + // 要求或不允许 Unicode 字节顺序标记 + 'unicode-bom': ['error', 'never'], + }; +} + +/** + * 得到规则对象 + */ +function getVueRules() { + const v2v3 = {}; + const v2 = {}; + const v3 = {}; + const rest = {}; + + /** *************************************************** 基本规则(启用正确的 ESLint 解析) */ + + // 支持中的注释指令 + v2v3['vue/comment-directive'] = 'error'; + // 规则将查找 JSX 中使用的变量,并将它们标记为已使用 + v2v3['vue/jsx-uses-vars'] = 'error'; + + /** *************************************************** 优先级 A:基本(错误预防) */ + + // 此规则要求组件名称始终是多字的,但根组件除外,以及 Vue 提供的内置组件,例如或 。这可防止与现有和未来的 HTML 元素发生冲突,因为所有 HTML 元素都是一个词 + v2v3['vue/multi-word-component-names'] = 'off'; + // 不允许使用箭头功能来定义观察者 (watch),原因是箭头函数绑定的this不是vue实例 + v2v3['vue/no-arrow-functions-in-watch'] = 'error'; + // 计算属性(computed)中禁止出现异步函数 , + v2v3['vue/no-async-in-computed-properties'] = 'error'; + // v-html和v-text不允许出现子元素 [
正确][
{{ aaa }}
错误] + v2v3['vue/no-child-content'] = 'error'; + // 在data中禁止访问计算属性(computed)因为data中computed的属性还没被生成 + v2v3['vue/no-computed-properties-in-data'] = 'error'; + // 禁止v-model自定义修饰器 + v2['vue/no-custom-modifiers-on-v-model'] = 'error'; + // 禁止在data上使用弃用的对象声明 + v3['vue/no-deprecated-data-object-declaration'] = 'error'; + // 禁止使用已经废弃的生命周期函数(vue3.0) + v3['vue/no-deprecated-destroyed-lifecycle'] = 'error'; + // 禁止使用 $listeners 因为 $listeners 已废弃 (vue3.0) + v3['vue/no-deprecated-dollar-listeners-api'] = 'error'; + // 禁止使用 .$scopedSlots 因为 .$scopedSlots 已废弃 (vue3.0) + v3['vue/no-deprecated-dollar-scopedslots-api'] = 'error'; + // 禁止使用 $on,$off,$once 因为 $on,$off,$once 已废弃 (vue3.0) + v3['vue/no-deprecated-events-api'] = 'error'; + // 禁止使用 {{ msg | filter }} filter已废弃 (vue3.0) + v3['vue/no-deprecated-filter'] = 'error'; + // 禁止使用