Browse Source

提交更改

master
my_mir 6 days ago
parent
commit
0dda75dbe2
  1. 221
      .cursor/rules/coding-standards.mdc
  2. 119
      .cursor/rules/project-guide.mdc
  3. 216
      .cursor/rules/social-login-errors.mdc
  4. 180
      .cursor/rules/troubleshooting.mdc

221
.cursor/rules/coding-standards.mdc

@ -1,5 +1,222 @@
---
description:
globs:
description:
globs:
alwaysApply: false
---
# 智慧生态项目编码规范
## 代码风格
### JavaScript/Vue 规范
1. 使用 ES6+ 语法特性
2. 变量命名:
- 常量使用 UPPER_SNAKE_CASE
- 变量和函数使用 camelCase
- 组件名使用 PascalCase
3. 缩进使用 Tab 制表符
4. 字符串优先使用单引号
5. 语句末尾不加分号(遵循项目现有风格)
### Vue 组件规范
```vue
<template>
<view class="container">
<!-- 组件内容 -->
</view>
</template>
<script>
export default {
name: 'ComponentName',
data() {
return {
// 数据定义
}
},
onLoad() {
// uni-app 生命周期
},
methods: {
// 方法定义
}
}
</script>
<style lang="scss" scoped>
// 样式定义
</style>
```
## API 接口规范
### 接口定义示例
参考 [login.js](mdc:api/login.js) 的实现方式:
```javascript
import request from '@/utils/request'
// 登录方法
export function login(username, password, captchaVerification) {
const data = {
username,
password,
captchaVerification
}
return request({
url: '/system/auth/login',
headers: {
isToken: false
},
'method': 'POST',
'data': data
})
}
```
### 请求响应处理
1. 使用 [request.js](mdc:utils/request.js) 统一处理请求
2. 错误码定义在 [errorCode.js](mdc:utils/errorCode.js)
3. 统一的响应拦截和错误处理
## 状态管理规范
### Vuex Module 示例
```javascript
const state = {
// 状态定义
}
const mutations = {
SET_STATE(state, value) {
state.property = value
}
}
const actions = {
async fetchData({ commit }) {
const res = await api.getData()
commit('SET_STATE', res.data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
```
## 工具函数规范
### 工具函数定义
参考 [common.js](mdc:utils/common.js) 和 [ruoyi.js](mdc:utils/ruoyi.js):
1. 单一职责原则
2. 函数命名清晰
3. 添加必要的注释
## uni-app 特定规范
### 条件编译
```javascript
// #ifdef MP-WEIXIN
// 微信小程序特有代码
// #endif
// #ifdef APP-PLUS
// APP 特有代码
// #endif
```
### 页面跳转
使用 uni-app 的路由 API:
```javascript
// 保留当前页面,跳转到应用内的某个页面
uni.navigateTo({
url: '/pages/detail/detail'
})
// 关闭当前页面,跳转到应用内的某个页面
uni.redirectTo({
url: '/pages/index/index'
})
// 关闭所有页面,打开到应用内的某个页面
uni.reLaunch({
url: '/pages/login/login'
})
```
### 数据存储
使用 [storage.js](mdc:utils/storage.js) 封装的方法:
```javascript
import storage from '@/utils/storage'
// 存储
storage.set('key', value)
// 获取
const value = storage.get('key')
// 删除
storage.remove('key')
```
## 权限控制
### 路由权限
参考 [permission.js](mdc:permission.js) 实现:
1. 定义白名单页面
2. 使用拦截器进行权限验证
3. 未授权自动跳转登录页
### 接口权限
使用 [auth.js](mdc:utils/auth.js) 管理 Token:
```javascript
import { getAccessToken } from '@/utils/auth'
// 在请求头中携带 Token
const token = getAccessToken()
```
## 错误处理
### 统一错误提示
```javascript
uni.showToast({
title: '操作失败',
icon: 'none'
})
// 或使用封装的提示方法
this.$modal.msg('操作成功')
this.$modal.msgError('操作失败')
```
### 异常捕获
```javascript
try {
const res = await api.getData()
// 处理成功响应
} catch (error) {
console.error('请求失败:', error)
this.$modal.msgError('获取数据失败')
}
```
## 性能优化
### 小程序分包
1. 主包保持精简,只包含核心页面
2. 按功能模块进行分包
3. 在 [pages.json](mdc:pages.json) 中配置 subPackages
### 图片优化
1. 使用合适的图片格式
2. 控制图片大小
3. 使用懒加载
### 数据缓存
1. 合理使用本地存储
2. 避免频繁请求相同数据
3. 设置合理的缓存过期时间

119
.cursor/rules/project-guide.mdc

@ -1,5 +1,120 @@
---
description:
globs:
description:
globs:
alwaysApply: false
---
# 智慧生态小程序项目指南
## 项目概述
这是一个基于 uni-app 开发的跨平台应用,支持微信小程序和移动端 APP。项目采用 Vue 2.x 技术栈,后端使用 RuoYi 框架。
## 技术栈
- **前端框架**: uni-app (Vue 2.x)
- **状态管理**: Vuex
- **后端框架**: RuoYi
- **加密库**: crypto-js
- **支持平台**: 微信小程序、Android/iOS APP、H5
## 项目结构
### 核心文件
- [main.js](mdc:main.js) - 应用入口文件
- [App.vue](mdc:App.vue) - 根组件
- [manifest.json](mdc:manifest.json) - 应用配置文件
- [pages.json](mdc:pages.json) - 页面路由配置
- [config.js](mdc:config.js) - 全局配置(API 地址等)
### 目录结构
```
├── api/ # API 接口模块
│ ├── system/ # 系统管理接口
│ ├── task/ # 任务管理接口
│ ├── enterprise/ # 企业管理接口
│ ├── inspections/ # 检查管理接口
│ └── login.js # 登录接口
├── components/ # 公共组件
├── pages/ # 主包页面
│ ├── index.vue # 首页
│ ├── login.vue # 登录页
│ ├── task.vue # 任务页
│ ├── owner.vue # 业主页
│ └── enterprise.vue # 企业页
├── sub/ # 分包目录(优化小程序体积)
│ ├── task/ # 任务模块分包
│ ├── owner/ # 业主模块分包
│ ├── enterprise/ # 企业模块分包
│ └── inspection/ # 检查模块分包
├── store/ # Vuex 状态管理
│ ├── index.js # Store 入口
│ ├── getters.js # 全局 getters
│ └── modules/ # 状态模块
├── utils/ # 工具函数
│ ├── request.js # 请求封装
│ ├── auth.js # 认证相关
│ ├── permission.js # 权限控制
│ └── storage.js # 本地存储
└── static/ # 静态资源
```
## 开发规范
### API 调用规范
1. 所有 API 请求都应通过 `utils/request.js` 封装的方法
2. API 模块按功能领域组织在 `api/` 目录下
3. 使用统一的错误处理机制
### 路由权限控制
- 使用 [permission.js](mdc:permission.js) 进行路由拦截
- 白名单页面定义在 `whiteList` 数组中
- 未登录用户自动跳转到登录页
### 状态管理规范
1. 全局状态使用 Vuex 管理
2. 模块化组织 store,每个业务模块独立管理
3. 通过 getters 暴露需要的状态
### 组件开发规范
1. 公共组件放在 `components/` 目录
2. 页面组件放在 `pages/` 或 `sub/` 目录
3. 组件命名使用 PascalCase
4. 组件文件名与组件名保持一致
### 样式规范
- 使用 [uni.scss](mdc:uni.scss) 定义的全局样式变量
- 支持 scss 预处理器
- 遵循 uni-app 的样式编写规范
## 配置说明
### 环境配置
在 [config.js](mdc:config.js) 中配置:
- `baseUrl`: API 服务器地址
- `baseApi`: API 基础路径
- `appInfo`: 应用基本信息
### 小程序配置
在 [manifest.json](mdc:manifest.json) 中的 `mp-weixin` 节点配置:
- `appid`: 小程序 AppID
- `permission`: 权限申请说明
- `requiredPrivateInfos`: 隐私接口声明
## 常用功能模块
### 登录认证
- 登录接口: `api/login.js`
- Token 管理: `utils/auth.js`
- 权限验证: `utils/permission.js`
### 文件上传
- 上传工具: `utils/upload.js`
- 支持图片、文件上传到服务器
### 数据字典
- 字典工具: `utils/dict.js`
- 统一管理下拉选项等枚举数据
## 注意事项
1. 开发时注意区分平台差异,使用条件编译
2. 小程序有包大小限制,合理使用分包
3. 遵循 uni-app 的生命周期和 API 使用规范
4. 注意处理网络请求的异常情况

216
.cursor/rules/social-login-errors.mdc

@ -1,5 +1,217 @@
---
description:
globs:
description:
globs:
alwaysApply: false
---
# 社交登录错误码映射指南
## 错误码说明
### 微信小程序登录错误码
# 社交登录错误码映射指南
## 错误码说明
### 微信小程序登录错误码
| 错误码 | 错误信息 | 前端处理建议 |
|--------|----------|--------------|
| 1002018000 | 社交授权失败,原因是:{} | 显示具体错误原因,引导用户重试 |
| 1002018001 | 社交授权失败,找不到对应的用户 | 提示用户账号未绑定,引导注册或绑定 |
| 1002018002 | 微信授权码已过期,请重新授权 | 自动调用 `uni.login()` 重新获取 code |
| 1002018003 | 微信授权码无效或已被使用 | 清除本地存储的 code,重新获取 |
| 1002018005 | 微信服务器连接失败,请稍后重试 | 提示网络问题,延迟后重试 |
| 1002018006 | 用户身份验证失败,请重新登录 | 清除本地 token,跳转登录页 |
## 参数验证说明
### 使用 @Valid 注解进行参数验证
在控制器方法中使用 `@Valid` 注解时,Spring 会自动验证请求对象的字段:
```java
@PostMapping("/app_login")
public CommonResult<AuthLoginRespVO> AppLogin(@RequestBody @Valid AuthSocialLoginReqVO reqVO) {
// 不需要手动检查 code、type、state 是否为空
// @Valid 会根据 AuthSocialLoginReqVO 中的注解自动验证
}
```
`AuthSocialLoginReqVO` 中的验证规则:
- `code`: `@NotEmpty(message = "授权码不能为空")`
- `type`: `@NotNull(message = "社交平台的类型不能为空")`
- `state`: `@NotEmpty(message = "state 不能为空")`
- `openid`: 无验证注解(需要手动验证)
- `userType`: 无验证注解
**注意**:当参数验证失败时,Spring 会自动返回 400 Bad Request 错误,包含详细的验证错误信息。
## 前端错误处理示例
```javascript
// 在 store/modules/user.js 中优化错误处理
Login({ commit }, userInfo) {
return new Promise((resolve, reject) => {
login(userInfo).then(res => {
const { data } = res
setToken(data)
resolve()
}).catch(error => {
// 根据错误码进行不同处理
const errorCode = error.code
switch(errorCode) {
case '1002018002': // code 过期
// 重新获取 code
uni.login({
success: (res) => {
setOpenId(res.code)
// 重试登录
this.dispatch('Login', {
...userInfo,
code: res.code
})
}
})
break
case '1002018003': // code 无效
// 清除本地 code
removeOpenId()
uni.showModal({
title: '提示',
content: '授权信息无效,请重新进入小程序',
showCancel: false,
success: () => {
// 可以选择重启小程序
uni.reLaunch({
url: '/pages/login'
})
}
})
break
case '1002018005': // 网络错误
uni.showToast({
title: '网络连接失败,请稍后重试',
icon: 'none',
duration: 2000
})
// 延迟后重试
setTimeout(() => {
this.dispatch('Login', userInfo)
}, 3000)
break
default:
// 显示默认错误信息
uni.showToast({
title: error.message || '登录失败',
icon: 'none'
})
}
reject(error)
})
})
}
```
## 最佳实践
### 1. 避免 code 重复使用
```javascript
// 错误做法:保存 code 供多次使用
setOpenId(res.code) // ❌ code 只能用一次
// 正确做法:获取后立即使用
uni.login({
success: res => {
// 立即调用登录接口
this.$store.dispatch('Login', {
type: 34,
code: res.code, // ✅ 立即使用
state: 'default'
})
}
})
```
### 2. 处理 code 过期
```javascript
// 设置 code 有效期检查
const CODE_EXPIRE_TIME = 4 * 60 * 1000 // 4分钟(保守估计)
// 保存 code 时记录时间
uni.login({
success: res => {
const codeData = {
code: res.code,
timestamp: Date.now()
}
uni.setStorageSync('wxCode', codeData)
}
})
// 使用时检查是否过期
const codeData = uni.getStorageSync('wxCode')
if (codeData && (Date.now() - codeData.timestamp < CODE_EXPIRE_TIME)) {
// 使用 code
} else {
// 重新获取
}
```
### 3. 优雅的错误提示
```javascript
const errorMessages = {
'1002018002': '登录信息已过期,正在重新获取...',
'1002018003': '授权无效,请重新进入小程序',
'1002018005': '网络连接失败,请检查网络设置',
'1002018006': '身份验证失败,请重新登录'
}
// 统一错误处理
function handleLoginError(error) {
const message = errorMessages[error.code] || error.message || '登录失败'
if (error.code === '1002018002') {
// 自动处理,不显示错误
console.log(message)
} else {
// 显示错误提示
uni.showToast({
title: message,
icon: 'none',
duration: 2000
})
}
}
```
## 后端日志查看
当前端遇到登录问题时,可以通过查看后端日志快速定位问题:
1. **查看请求日志**
```
[AppLogin][小程序登录开始,code(xxx) type(34) userType(3)]
```
2. **查看认证过程**
```
[getAuthUser][开始请求社交平台,type(34) userType(2) code(xxx)]
[miniAppLogin][获取到用户信息,openId(xxx) nickname(xxx)]
```
3. **查看错误日志**
```
[getAuthUser][社交授权失败,type(34) code(xxx) errorMsg(invalid code)]
[AppLogin][小程序登录失败,code(xxx) error(微信授权码无效或已被使用)]
```
通过这些日志可以快速判断:
- code 是否正确传递
- 微信接口返回的具体错误
- 用户是新用户还是老用户
- 绑定过程是否成功

180
.cursor/rules/troubleshooting.mdc

@ -1,5 +1,181 @@
---
description:
globs:
description:
globs:
alwaysApply: false
---
# 智慧生态项目常见问题排查指南
## 登录相关问题
### Token 失效处理
问题:用户 Token 过期后的处理
解决方案:
1. 在 [request.js](mdc:utils/request.js) 中检测 401 错误
2. 清除本地 Token:`removeToken()`
3. 跳转到登录页:`uni.reLaunch({ url: '/pages/login' })`
### 权限拦截不生效
问题:页面权限拦截失效
检查点:
1. 确认 [permission.js](mdc:permission.js) 已在 [main.js](mdc:main.js) 中引入
2. 检查页面路径是否在白名单中
3. 确认使用了正确的跳转方法(navigateTo、redirectTo 等)
## API 请求问题
### 跨域问题
在开发环境中遇到跨域:
1. H5 开发:在 [manifest.json](mdc:manifest.json) 配置代理
2. 小程序:在小程序开发工具中关闭域名校验
3. 生产环境:确保服务器配置了正确的 CORS 头
### 请求超时
调整请求超时时间:
```javascript
// 在 request.js 中设置
const service = uni.request({
timeout: 10000 // 10秒超时
})
```
## 小程序特定问题
### 包体积超限
解决方案:
1. 使用分包加载,配置在 [pages.json](mdc:pages.json)
2. 压缩图片资源
3. 移除未使用的代码和依赖
4. 使用 CDN 加载大型资源
### 真机调试问题
1. 确保 [config.js](mdc:config.js) 中的 baseUrl 使用 HTTPS
2. 在小程序管理后台配置合法域名
3. 检查 [manifest.json](mdc:manifest.json) 中的权限申请
### 小程序授权失败
检查:
1. `manifest.json` 中的 `permission` 配置
2. `requiredPrivateInfos` 是否声明了需要的接口
3. 用户是否拒绝了授权
## 样式问题
### 样式不生效
1. 检查是否使用了 `scoped`
2. uni-app 不支持的 CSS 选择器
3. 使用 `/deep/` 或 `::v-deep` 穿透组件样式
### rpx 单位问题
```scss
// 使用 uni.scss 中的变量
@import '@/uni.scss';
.container {
padding: 20rpx; // 自动适配不同屏幕
}
```
## 状态管理问题
### Vuex 数据不更新
1. 确认使用了 `commit` 提交 mutation
2. 检查是否正确使用了命名空间
3. 使用 `mapState`、`mapGetters` 辅助函数
### 页面刷新数据丢失
解决方案:
1. 重要数据持久化到 storage
2. 在 `onShow` 生命周期重新获取数据
3. 使用 Vuex 配合持久化插件
## 性能优化
### 页面加载慢
1. 减少首屏加载的数据量
2. 使用图片懒加载
3. 分页加载列表数据
4. 使用骨架屏提升体验
### 列表滚动卡顿
```vue
<scroll-view
scroll-y
:show-scrollbar="false"
:enhanced="true"
:bounces="false">
<!-- 使用虚拟列表或分页加载 -->
</scroll-view>
```
## 开发环境问题
### HBuilderX 相关
1. 确保使用最新版本的 HBuilderX
2. 清理项目缓存:工具 -> 清理缓存
3. 重启 HBuilderX 和开发者工具
### 依赖安装问题
```powershell
# 清理缓存
Remove-Item -Recurse -Force node_modules
Remove-Item package-lock.json
# 重新安装
npm install
```
## 调试技巧
### 查看网络请求
1. 小程序:使用开发者工具的 Network 面板
2. H5:使用浏览器开发者工具
3. APP:使用 `console.log` 或远程调试
### 查看存储数据
```javascript
// 获取所有存储的键
const res = uni.getStorageInfoSync()
console.log('keys:', res.keys)
// 查看特定数据
const token = uni.getStorageSync('token')
console.log('token:', token)
```
### 页面栈信息
```javascript
// 获取当前页面栈
const pages = getCurrentPages()
console.log('页面栈:', pages)
// 获取当前页面实例
const currentPage = pages[pages.length - 1]
```
## 发布部署
### 小程序发布前检查
1. 关闭调试模式
2. 检查 API 地址是否正确
3. 压缩代码和资源
4. 测试各项权限申请
### 版本更新提示
```javascript
// 在 App.vue 中添加
onShow() {
// #ifdef MP-WEIXIN
const updateManager = uni.getUpdateManager()
updateManager.onUpdateReady(() => {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: (res) => {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
// #endif
}

Loading…
Cancel
Save