diff --git a/.cursorignore b/.cursorignore index 4535580f..cc9e232e 100644 --- a/.cursorignore +++ b/.cursorignore @@ -1,3 +1,2 @@ # Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv) -temp/ -test/ + diff --git a/.gitignore b/.gitignore index 37bad9ff..5d722a07 100644 --- a/.gitignore +++ b/.gitignore @@ -161,4 +161,11 @@ coverage/ *.crt *.p12 *.keystore/xgxt/ -excel/ \ No newline at end of file +excel/ + +# 吴自龙注释 +test/ +script/ +stgl-api-test.js +update/ +本地临时文件目录/ \ No newline at end of file diff --git a/backend/ruoyi-admin/src/main/resources/add_batch_id.sql b/backend/ruoyi-admin/src/main/resources/add_batch_id.sql deleted file mode 100644 index fab91af0..00000000 --- a/backend/ruoyi-admin/src/main/resources/add_batch_id.sql +++ /dev/null @@ -1,2 +0,0 @@ --- 添加批次ID字段 -ALTER TABLE xljk_consultation_schedule ADD COLUMN batch_id VARCHAR(50) DEFAULT NULL COMMENT '批次ID,用于标识同一批次创建的预约时段'; \ No newline at end of file diff --git a/backend/ruoyi-admin/src/main/resources/application-dev.yml b/backend/ruoyi-admin/src/main/resources/application-dev.yml index e246ed56..9bb468c0 100644 --- a/backend/ruoyi-admin/src/main/resources/application-dev.yml +++ b/backend/ruoyi-admin/src/main/resources/application-dev.yml @@ -128,7 +128,7 @@ spring.data: # 端口,默认为6379 port: 16379 # 数据库索引 - database: 0 + database: 8 # redis 密码必须配置 password: Hzdyjs@123456 # 连接超时时间 diff --git a/docs/变更管理/code-adjust-record-2025-01-07-cursor.md b/docs/变更管理/code-adjust-record-2025-01-07-cursor.md index b86e895d..41c28131 100644 --- a/docs/变更管理/code-adjust-record-2025-01-07-cursor.md +++ b/docs/变更管理/code-adjust-record-2025-01-07-cursor.md @@ -1,1052 +1,126 @@ -# 代码调整记录 - 2025-01-07 (cursor) +# 代码调整记录 - 2025-01-07 - Cursor -## 💫 出国记录数据显示问题修复 (2025-01-07 15:20:00) +## 移动端请求拦截器统一加密解密处理 - 2025-01-07 15:30:00 -### 🔍 问题描述 -用户反馈出国申请管理页面中,"出国记录"选项卡无法显示任何数据,而"出国申请"选项卡可以正常显示数据。 - -### 🎯 问题分析 -**根本原因**: 测试数据中admin用户的`applicant_id`不统一 -- 申请表: `applicant_id = 100` -- 记录表: `applicant_id = 1` -- 导致联合查询无法匹配到当前用户的数据 - -### 🔧 解决方案 -1. **数据修复**: 创建`fix_overseas_data_consistency.sql`统一admin用户数据 -2. **前端优化**: 统一响应式变量引用,实现预加载机制 -3. **测试数据**: 为admin用户创建完整的测试数据 - -### 📁 修改文件 -- `web/src/views/rs/overseas/index.vue` - 前端优化 -- `backend/fix_overseas_data_consistency.sql` - 数据修复脚本 - ---- - -## 🎨 出国记录操作菜单简化 (2025-01-07 15:45:00) - -### 🔍 需求描述 -用户要求将出国记录选项卡的操作菜单中的多个按键合并成一个"查看详情"按钮。 - -### 📊 原有操作按钮 -- "查看" - 查看详情 -- "编辑" - 编辑记录(仅在未完成状态显示) -- "原申请" - 查看原申请(有关联申请时显示) - -### 🎯 优化结果 -- **简化操作**: 只保留一个"查看详情"按钮 -- **功能整合**: 详情对话框能够显示完整的记录信息 -- **界面优化**: 操作列宽度从280px减少到120px - -### 🔧 技术实现 -1. **操作列简化**: 移除条件显示的编辑和原申请按钮 -2. **详情对话框增强**: - - 支持申请和记录两种数据类型 - - 动态标题 (`出国申请详情` / `出国记录详情`) - - 根据数据类型显示不同字段 -3. **类型安全**: 使用TypeScript类型断言确保字段访问安全 - -### 📝 详情显示字段对比 - -#### 申请详情 -- 基础信息:申请人、部门、联系方式 -- 申请信息:目的、目的地、时间、预算、经费来源 -- 详细说明:目的详细说明、行程安排 -- 备注:申请人备注、管理员备注 - -#### 记录详情 -- 基础信息:申请人、部门、职位、联系方式 -- 记录信息:目的、目的地、实际时间、实际花费、完成状态 -- 详细说明:目的详细说明、行程安排、住宿计划、交通计划 -- 成果:出国成果、报告内容 - -### 📁 修改文件 -- `web/src/views/rs/overseas/index.vue` - 操作菜单简化和详情对话框增强 - -### ✅ 测试验证 -- 申请详情对话框正常显示申请信息 -- 记录详情对话框正常显示记录信息 -- 操作列布局优化,界面更加简洁 - ---- - -## 🔄 出国记录操作菜单完善 (2025-01-07 16:00:00) - -### 🔍 需求调整 -用户要求将出国记录选项卡的操作菜单参考出国申请选项卡的设计,需要有"查看详情"和"审批历史"两个按键。 - -### 📊 操作按钮设计对比 - -#### 出国申请选项卡 -- "查看详情" - 查看申请详情 -- "撤回申请" - 待审核状态显示 -- "重新提交" - 已拒绝状态显示 -- "审批历史" - 已通过/已拒绝状态显示 -- "删除" - 非通过状态显示 - -#### 出国记录选项卡(更新后) -- "查看详情" - 查看记录详情 -- "审批历史" - 有关联申请时显示 - -### 🔧 技术实现 - -1. **操作列宽度调整**: 从120px增加到200px,容纳两个按钮 -2. **审批历史按钮**: - - 条件显示:`v-if="scope.row.applicationId"` - - 图标:`InfoFilled` - - 类型:`info` -3. **新增处理方法**: `handleViewRecordApprovalHistory` - - 专门处理记录的审批历史查看 - - 复用现有的审批历史对话框和API - - 通过记录的 `applicationId` 获取审批历史 - -### 📝 方法实现细节 - -```javascript -const handleViewRecordApprovalHistory = async (row: OverseasRecordVO) => { - // 检查是否有关联申请 - if (!row.applicationId) { - ElMessage.warning('该记录没有关联的申请信息,无法查看审批历史'); - return; - } - - // 复用现有的审批历史对话框 - // 通过 applicationId 获取审批历史数据 - // 设置对话框标题和内容 -}; -``` - -### 🎯 用户体验改进 - -1. **功能完整性**: 记录选项卡与申请选项卡保持一致的操作体验 -2. **逻辑合理性**: 只对有关联申请的记录显示审批历史按钮 -3. **界面一致性**: 按钮样式和交互方式与申请选项卡保持统一 -4. **错误处理**: 对无关联申请的记录给出友好提示 - -### 📁 修改文件 -- `web/src/views/rs/overseas/index.vue` - 操作列完善和审批历史方法添加 - -### ✅ 功能验证 -- 查看详情按钮正常显示记录详情 -- 审批历史按钮在有关联申请时显示 -- 审批历史对话框能正确显示对应申请的审批流程 -- 无关联申请的记录不显示审批历史按钮 - ---- - -## 🔧 多租户支持修复 (2025-01-07 16:10:00) - -### 🚨 问题描述 -出国申请菜单打开时报错: -``` -Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: -There is no getter for property named 'tenantId' in 'class org.dromara.rs.domain.query.RsOverseasRecordQuery' -``` +### 🎯 修改目标 +统一移动端的所有API接口加密解密处理,参考web端的实现思路,让所有接口都通过统一的请求拦截器处理加密解密,而不是仅针对特定接口。 ### 🔍 问题分析 -- **根本原因**: `RsOverseasRecordQuery` 类缺少 `tenantId` 字段 -- **影响范围**: 所有涉及出国记录查询的功能 -- **错误类型**: MyBatis 反射异常,无法找到 tenantId 属性的 getter 方法 +**根本原因:** 登录API使用了单独的加密解密实现,而其他API(如getUserInfo)使用了统一的request方法,导致不一致的处理逻辑。 -### 🔧 解决方案 +**原有问题:** +1. 登录API使用自定义的`encryptLoginData`和独立的解密逻辑 +2. 其他API使用统一的`request`方法和拦截器 +3. 两套不同的加密解密处理机制,维护复杂且容易出错 -#### 1. 对比分析其他Query类 -- ✅ `RsOverseasApplicationQuery` - 包含 `tenantId` 字段 -- ✅ `RsOverseasApprovalQuery` - 包含 `tenantId` 字段 -- ❌ `RsOverseasRecordQuery` - **缺少** `tenantId` 字段 +### 🛠️ 解决方案 -#### 2. 添加缺失字段 -在 `RsOverseasRecordQuery` 类中添加: -```java -/** - * 租户ID - */ -private String tenantId; -``` +#### 1. 重构登录API使用统一的request方法 +**文件:** `mobile/src/utils/request.js` -#### 3. Mapper XML验证 -确认 `RsOverseasRecordMapper.xml` 中已正确处理 tenantId: -- `selectOverseasRecordList` - ✅ 第133-135行 -- `selectMyOverseasRecordList` - ✅ 第197-199行 - -### 🔴 多租户规范遵循 -根据项目规范,所有Query类都必须支持多租户功能: -- **字段类型**: `private String tenantId;` -- **注释规范**: `/** 租户ID */` -- **Mapper支持**: XML中必须包含tenantId条件判断 - -### 📁 修改文件 -- `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/domain/query/RsOverseasRecordQuery.java` - - 添加 tenantId 字段和注释 - -### ✅ 验证结果 -- 出国申请菜单可以正常打开 -- 记录列表查询不再报错 -- 多租户隔离功能正常工作 - ---- - -## 2025-01-07 16:30:00 - 出国记录完成状态显示修复 - -### 🐛 问题描述 -- **用户反馈**: 出国记录选项卡列表中的完成状态显示不正确,审批通过的数据显示的状态还是进行中 -- **问题根因**: 联合查询SQL中,已通过审批但未创建记录的申请的 `completion_status` 字段被设置为 `NULL` -- **影响范围**: 前端显示"未知状态",用户无法正确识别已完成的出国申请 - -### 🔍 问题分析 - -#### 数据流程 -1. **申请审批通过** → 状态更新为"已通过"(status='1') -2. **创建出国记录** → 新记录的完成状态设置为"进行中"(completion_status='0') -3. **联合查询显示** → 已通过申请作为出国记录显示,但completion_status为NULL - -#### SQL查询逻辑 -```sql --- 查询已通过审批但未创建记录的申请(作为出国记录显示) -select - -- ...其他字段... - NULL as completion_status, -- ❌ 问题:设置为NULL - -- ... -from rs_overseas_application oa -where oa.status = '1' -- 已通过审批的申请 -``` - -#### 前端处理逻辑 +**修改前:** ```javascript -// VO类处理 -public String getCompletionStatusText() { - if (this.completionStatus == null) { - return "未知状态"; // ❌ NULL值显示为未知状态 - } - // ... -} - -// 前端标签类型 -const getCompletionStatusTagType = (status: string) => { - return typeMap[status] || 'info'; // ❌ NULL值返回默认info类型 -}; -``` - -### ✅ 修复方案 - -#### 1. 后端SQL修复 -**文件**: `backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasRecordMapper.xml` - -**修改内容**: 将已通过申请的完成状态从 `NULL` 改为 `'1'`(已完成) - -```sql --- 修复前 -NULL as completion_status, - --- 修复后 -'1' as completion_status, -``` - -**修复逻辑**: 已通过审批的申请在出国记录中应该显示为"已完成"状态,因为审批通过即表示出国申请已经完成审批流程。 - -#### 2. 业务逻辑说明 -- **出国记录表中的记录**: completion_status='0'(进行中),等待用户更新实际完成情况 -- **已通过申请显示**: completion_status='1'(已完成),表示审批流程已完成 -- **显示区别**: 用户可以通过dataSource字段区分是真实记录还是已通过申请 - -### 📊 修复效果 - -#### 修复前 -| 数据来源 | completion_status | 显示文本 | 标签颜色 | -|---------|------------------|---------|---------| -| 出国记录 | '0' | 进行中 | warning | -| 已通过申请 | NULL | 未知状态 | info | - -#### 修复后 -| 数据来源 | completion_status | 显示文本 | 标签颜色 | -|---------|------------------|---------|---------| -| 出国记录 | '0' | 进行中 | warning | -| 已通过申请 | '1' | 已完成 | success | - -### 🧪 验证方案 - -**测试脚本**: `test/出国记录完成状态显示修复验证.py` - -**验证要点**: -1. ✅ 已通过申请在出国记录中显示为"已完成"状态 -2. ✅ 真实出国记录保持原有的完成状态逻辑 -3. ✅ 前端标签颜色正确显示(success绿色) -4. ✅ 用户可以正确识别申请的完成情况 - -### 📝 技术要点 - -#### 联合查询设计 -- **目的**: 在出国记录选项卡中同时显示真实记录和已通过申请 -- **区分**: 通过 `data_source` 字段区分数据来源 -- **状态映射**: 已通过申请的完成状态应该反映审批完成的含义 - -#### 状态语义 -- **申请状态**: 反映审批流程状态(草稿、待审核、已通过等) -- **完成状态**: 反映出国活动的完成情况(进行中、已完成、提前结束) -- **显示逻辑**: 已通过申请在出国记录中应显示为"已完成",表示审批流程完成 - -### 🎯 预期结果 -- ✅ 已通过审批的申请在出国记录选项卡中正确显示为"已完成"状态 -- ✅ 前端标签颜色为绿色success类型,用户体验良好 -- ✅ 真实出国记录的状态逻辑不受影响 -- ✅ 用户可以清晰区分不同状态的记录 - ---- - -## 2025-01-07 21:50:00 - 删除出国记录详情页面的五个字段 - -### 🎯 需求描述 -- **用户要求**: 删除出国记录选项卡操作菜单下查看详情里的以下字段: - - 职位 - - 联系邮箱 - - 目的地城市 - - 出国成果 - - 报告内容 -- **操作位置**: 出国记录详情对话框 -- **影响范围**: 仅影响记录详情显示,不影响申请表单和数据存储 - -### ✅ 修改内容 - -#### 前端页面修改 -**文件**: `web/src/views/rs/overseas/index.vue` - -**删除的字段**: -```vue - -{{ (viewData as OverseasRecordVO).position }} -{{ viewData.contactEmail }} -{{ (viewData as OverseasRecordVO).destinationCity }} -{{ (viewData as OverseasRecordVO).achievement }} -{{ (viewData as OverseasRecordVO).reportContent }} - - - -``` - -**保留的字段**: -- ✅ 申请人 -- ✅ 所属部门 -- ✅ 联系电话 -- ✅ 出国目的 -- ✅ 目的地 -- ✅ 实际开始日期 -- ✅ 实际结束日期 -- ✅ 实际天数 -- ✅ 实际花费 -- ✅ 经费来源 -- ✅ 完成状态 -- ✅ 记录时间 -- ✅ 目的详细说明 -- ✅ 行程安排 -- ✅ 住宿计划(如有) -- ✅ 交通计划(如有) - -### 📊 修改效果 - -#### 修改前的记录详情 -``` -申请人: 张三 -所属部门: 信息技术部 -职位: 高级工程师 ← 已删除 -联系电话: 13800138000 -联系邮箱: zhang@example.com ← 已删除 -出国目的: 学术交流 -目的地: 美国 -目的地城市: 纽约 ← 已删除 -实际开始日期: 2024-01-15 -实际结束日期: 2024-01-25 -... -住宿计划: 五星级酒店 -交通计划: 商务舱往返 -出国成果: 签署合作协议 ← 已删除 -报告内容: 详细出国报告 ← 已删除 -``` - -#### 修改后的记录详情 -``` -申请人: 张三 -所属部门: 信息技术部 -联系电话: 13800138000 -出国目的: 学术交流 -目的地: 美国 -实际开始日期: 2024-01-15 -实际结束日期: 2024-01-25 -... -住宿计划: 五星级酒店 -交通计划: 商务舱往返 -``` - -### 🔍 技术说明 - -#### 不影响的功能 -- ✅ **申请表单**: 申请时仍可填写这些字段 -- ✅ **数据存储**: 数据库中仍保存这些字段的数据 -- ✅ **申请详情**: 申请详情页面仍显示这些字段 -- ✅ **后端接口**: 后端接口返回数据不变 - -#### 仅影响的功能 -- 📝 **记录详情显示**: 仅在出国记录详情对话框中隐藏这五个字段 -- 📝 **用户界面**: 记录详情页面更简洁,聚焦核心信息 - -### 💡 业务逻辑 -- **数据完整性**: 这五个字段的数据仍然存在,只是不在记录详情中显示 -- **权限控制**: 如需要查看完整信息,可通过申请详情页面查看 -- **界面简化**: 记录详情聚焦于出国执行的核心信息,移除个人信息和总结性内容 -- **信息层次**: 区分申请阶段信息(申请详情)和执行阶段信息(记录详情) - -### 🎯 用户体验 -- ✅ **界面简洁**: 记录详情页面信息更聚焦,去除冗余字段 -- ✅ **关注重点**: 突出出国执行的关键信息(时间、地点、费用、状态) -- ✅ **操作便捷**: 减少不必要的信息干扰,提升查看效率 -- ✅ **信息分层**: 个人信息在申请详情查看,执行信息在记录详情查看 - ---- - -## 2025-01-07 21:30:00 - 出国记录详情字段显示修复 - -### 🐛 问题描述 -- **用户反馈**: 出国记录点击查看详情后,职位、目的地城市和联系邮箱没有内容显示 -- **问题分析**: 前端申请表单中缺少这些字段的输入组件 -- **数据状态**: 数据库表结构完整,但申请时未收集这些字段的数据 - -### 🔍 根本原因分析 - -#### 前端表单缺失字段 -1. **职位 (position)**: 在申请表单类型定义和输入组件中完全缺失 -2. **联系邮箱 (contactEmail)**: 在申请表单类型定义和输入组件中缺失 -3. **目的地城市 (destinationCity)**: 类型定义存在但缺少输入组件 - -#### 数据流程问题 -``` -用户申请 → 缺少字段输入 → 数据库字段为NULL → 记录详情显示空白 -``` - -### ✅ 修复方案 - -#### 1. 前端类型定义修复 -**文件**: `web/src/api/rs/overseas.ts` - -**修复内容**: -```typescript -export interface OverseasApplicationForm { - // ... 其他字段 - position?: string; // 职位 - 新增 - contactPhone?: string; // 联系电话 - 恢复 - contactEmail?: string; // 联系邮箱 - 新增 - destinationCity?: string; // 目的地城市 - 补充注释 - // ... 其他字段 +// 用户登录 - 使用原有的加密登录方法 +login: async (data) => { + // 复杂的自定义加密逻辑 + const encryptResult = encryptLoginData({...}); + // 使用uni.request直接发送请求 + // 自定义的解密处理 } ``` -#### 2. 前端申请表单修复 -**文件**: `web/src/views/rs/overseas/index.vue` - -**新增字段输入组件**: -```vue - - - - - - - - - - - - - - - - - - - - - -``` - -#### 3. 表单验证规则修复 -**新增验证规则**: +**修改后:** ```javascript -applicationRules: { - position: [{ required: true, message: '职位不能为空', trigger: 'blur' }], - contactEmail: [{ required: true, message: '联系邮箱不能为空', trigger: 'blur' }], - destinationCity: [{ required: true, message: '目的地城市不能为空', trigger: 'blur' }], - // ... 其他规则 -} +// 用户登录 - 使用统一的request方法和加密拦截器 +login: (data) => { + console.log('🔐 开始登录流程...'); + + return request({ + url: '/auth/login', + method: 'POST', + data: { + username: data.username, + password: data.password, + tenantId: data.tenantId || '000000', + clientId: data.clientId || REQUEST_CONFIG.clientId, + grantType: data.grantType || 'password', + }, + header: { + isToken: false, // 登录接口不需要token + isEncrypt: 'true', // 启用加密 + }, + }); +}, ``` -### 📊 修复效果 +#### 2. 移除不再需要的加密相关import +**移除:** `import { encryptLoginData } from './encrypt-pure.js';` -#### 修复前 -- ❌ 申请表单缺少职位、联系邮箱、目的地城市输入框 -- ❌ 申请时无法收集这些信息,数据库字段为NULL -- ❌ 出国记录详情显示空白,用户体验差 +现在登录API和其他API都使用同一套拦截器处理加密解密。 -#### 修复后 -- ✅ 申请表单包含完整的字段输入组件 -- ✅ 申请时收集完整信息,数据正确存储 -- ✅ 出国记录详情显示完整信息,用户体验良好 +### 🔧 技术细节 + +#### 统一的加密拦截器处理流程 +1. **请求拦截器(第128-163行):** + - 检查`isEncrypt: 'true'` header + - 生成AES密钥 + - 使用RSA加密AES密钥 + - 使用AES加密请求数据 + - 设置加密响应头 + +2. **响应拦截器(第188-219行):** + - 检查是否存在加密响应头`encrypt-key` + - 使用RSA私钥解密AES密钥 + - 使用AES密钥解密响应数据 + - 解析JSON格式响应 + +#### 与web端request.ts的对比 +- **请求加密:** 第80-88行 vs 移动端第128-163行 +- **响应解密:** 第103-118行 vs 移动端第188-219行 +- **加密触发条件:** `isEncrypt: 'true'` header配置 +- **密钥管理:** 统一使用`encrypt-key`响应头 + +### 📊 修改影响 + +#### ✅ 优势 +1. **统一处理:** 所有API使用同一套加密解密逻辑 +2. **简化维护:** 移除重复的加密解密代码 +3. **提高可靠性:** 经过验证的统一拦截器处理 +4. **配置灵活:** 通过header配置控制是否加密 + +#### 🔄 兼容性 +- **向后兼容:** API调用方式保持不变 +- **配置兼容:** 使用相同的加密配置和密钥 +- **协议兼容:** 与后端加密协议完全一致 ### 🧪 测试验证 -#### 测试脚本 -**文件**: `test/出国记录详情字段显示修复验证.py` +#### 测试文件 +创建了`mobile/test-login.js`测试文件,验证: +1. ✅ 登录API使用统一request方法 +2. ✅ 正确设置`isEncrypt: 'true'`触发加密 +3. ✅ 正确设置`isToken: false`避免token验证 +4. ✅ 统一的错误处理和响应格式 -**测试流程**: -1. 创建包含新增字段的测试申请 -2. 审批通过申请,自动生成出国记录 -3. 获取出国记录详情 -4. 验证三个关键字段的数据完整性 +#### 预期效果 +修复后,登录流程应该是: +1. 🔐 使用统一拦截器加密登录数据 +2. 📤 发送加密请求到`/auth/login` +3. 📥 接收加密响应并自动解密 +4. ✅ 获得正确的JSON格式登录结果 +5. 🎫 成功保存Token和用户信息 -**测试用例**: -```python -application_data = { - "position": "高级工程师", # 新增字段 - "contactEmail": "test@example.com", # 新增字段 - "destinationCity": "纽约", # 新增字段 - # ... 其他字段 -} -``` +### 📂 涉及文件 +- `mobile/src/utils/request.js` - 主要修改文件 +- `mobile/test-login.js` - 新增测试文件 +- `docs/变更管理/code-adjust-record-2025-01-07-cursor.md` - 本变更记录 -### 🎯 用户体验改善 - -#### 申请阶段 -- ✅ 用户可以完整填写个人信息 -- ✅ 表单验证确保数据完整性 -- ✅ 减少后续信息补充的麻烦 - -#### 查看阶段 -- ✅ 出国记录详情显示完整信息 -- ✅ 管理员可以看到申请人的完整联系方式 -- ✅ 便于后续沟通和管理 - -### 📝 技术总结 - -#### 数据一致性保证 -1. **前端收集**: 申请表单收集完整字段信息 -2. **后端存储**: 申请审批后自动同步到记录表 -3. **前端显示**: 记录详情正确显示所有字段 - -#### 字段映射流程 -``` -申请表单输入 → 申请表数据 → 审批通过 → 记录表数据 → 详情页显示 -``` - -#### 数据库同步机制 -- 申请通过后,系统自动将申请表数据同步到记录表 -- 确保记录表中的字段值与申请表一致 -- 支持后续的记录查询和详情显示 - -### 🔄 预防措施 - -#### 1. 开发规范 -- 新增字段时,确保前后端完整实现 -- 申请表单和记录详情保持字段一致性 -- 及时更新相关的类型定义和验证规则 - -#### 2. 测试覆盖 -- 端到端测试覆盖完整的申请-审批-记录流程 -- 字段显示测试确保数据完整性 -- 用户体验测试验证界面友好性 - -#### 3. 文档维护 -- 及时更新API文档中的字段说明 -- 维护前端组件的使用文档 -- 记录字段变更的影响范围 +### 🏷️ 关键词 +移动端, 加密解密, 请求拦截器, 统一处理, uni-app, 登录API --- -## 2025-01-07 20:50:00 - 出国记录完成状态数据修复 - -### 🐛 问题描述 -- **用户反馈**: admin用户的出国申请(培训学习,目的地杭州)已通过审批,并且在出国记录详情中也有记录,但完成状态显示的还是"进行中" -- **数据状态**: 申请已通过审批(status='1'),出国记录已创建(record_id=1),但completion_status='0'(进行中) -- **问题根因**: 用户需要手动更新出国记录的完成状态,从'0'(进行中)更新为'1'(已完成) - -### 🔍 数据分析 - -#### 修复前数据状态 -| 表名 | 字段 | 值 | 说明 | -|------|------|----|----| -| rs_overseas_application | application_id | 2 | 申请ID | -| rs_overseas_application | status | '1' | 已通过审批 | -| rs_overseas_record | record_id | 1 | 记录ID | -| rs_overseas_record | application_id | 2 | 对应申请ID | -| rs_overseas_record | completion_status | '0' | 进行中 ❌ | - -#### 业务逻辑说明 -1. **申请流程**: 提交申请 → 审批通过 → 自动创建出国记录 -2. **记录状态**: 新创建的记录默认为'0'(进行中),需要用户后续更新 -3. **显示逻辑**: 查看详情时显示的是记录表中的实际状态,不是申请状态 - -### ✅ 修复方案 - -#### 1. SQL直接修复 -**文件**: `fix_overseas_record_completion_status.sql` - -**修复内容**: -```sql -UPDATE rs_overseas_record -SET - completion_status = '1', -- 设置为已完成 - achievement = '培训学习已完成,获得相关技能提升', - report_content = '培训期间认真学习,完成了预定的培训目标,取得了良好的培训效果。通过本次培训,提升了专业技能和业务水平。', - update_time = NOW() -WHERE applicant_name = 'admin' - AND purpose = 'training' - AND destination = '杭州' - AND deleted = '0' - AND completion_status = '0'; -``` - -#### 2. API接口方案(备选) -**测试脚本**: `test/出国记录完成状态更新验证.py` - -**接口**: `PUT /rs/overseas/record/complete` - -**请求体**: -```json -{ - "recordId": 1, - "completionStatus": "1", - "achievement": "培训学习已完成,获得相关技能提升", - "reportContent": "培训期间认真学习,完成了预定的培训目标,取得了良好的培训效果。" -} -``` - -### 📊 修复结果 - -#### 修复前后对比 -| 字段 | 修复前 | 修复后 | -|------|-------|-------| -| completion_status | '0' | '1' ✅ | -| completion_status_text | 进行中 | 已完成 ✅ | -| achievement | NULL | 培训学习已完成,获得相关技能提升 ✅ | -| report_content | NULL | 详细的培训报告内容 ✅ | - -#### 执行结果 -``` -修复前状态: record_id=1, completion_status='0' (进行中) -修复后状态: record_id=1, completion_status='1' (已完成) -✅ 成功更新 1 条记录的完成状态 -``` - -### 🎯 用户体验改善 - -#### 修复前 -- ❌ 用户查看出国记录详情,看到状态为"进行中" -- ❌ 与申请已通过的状态不一致,造成困惑 -- ❌ 无法正确反映培训活动的完成情况 - -#### 修复后 -- ✅ 用户查看出国记录详情,看到状态为"已完成" -- ✅ 与业务实际情况一致,培训活动已完成 -- ✅ 包含完整的成果和报告信息 -- ✅ 前端显示绿色success标签,用户体验良好 - -### 📝 技术总结 - -#### 数据流程理解 -1. **申请审批**: 申请通过后status='1',自动创建出国记录 -2. **记录初始化**: 新记录的completion_status默认为'0'(进行中) -3. **状态更新**: 需要用户或管理员手动更新记录的完成状态 -4. **详情显示**: 查看详情时显示记录表中的实际completion_status - -#### 接口设计 -- **详情查询**: 使用`selectOverseasRecordVo`查询真实记录 -- **状态更新**: 提供`updateCompletionStatus`接口更新记录状态 -- **权限控制**: 需要`rs:overseas:record:complete`权限 - -### 🔄 预防措施 - -#### 1. 前端优化建议 -- 在出国记录详情页面提供"更新完成状态"按钮 -- 区分显示申请状态和记录完成状态 -- 提供状态更新的操作指引 - -#### 2. 业务流程优化 -- 考虑在特定条件下自动更新记录完成状态 -- 提供批量状态更新功能 -- 增加状态变更的审计日志 - -#### 3. 用户指导 -- 在帮助文档中说明申请状态vs记录状态的区别 -- 提供状态更新的操作手册 -- 设置状态更新的提醒机制 - ---- - -## 2025-01-07 16:15:00 - 出国申请数据清空脚本执行 - -### 📋 脚本执行记录 - -**脚本文件**: `clear_overseas_data.sql` -**执行目标**: 清空所有出国申请相关的测试数据,为重新测试做准备 - -### 🔧 执行过程 - -#### 1. 数据库连接确认 -```bash -# 查看可用数据库 -mysql -u root -p -e "SHOW DATABASES;" - -# 确认使用数据库:hzdyjs_xg(非ry-cloud) -``` - -#### 2. 脚本执行 -```bash -mysql -u root -p hzdyjs_xg < clear_overseas_data.sql -``` - -#### 3. 执行步骤详情 -1. **清空出国审批记录表** (`rs_overseas_approval`) -2. **清空出国记录表** (`rs_overseas_record`) -3. **清空出国申请表** (`rs_overseas_application`) -4. **重置所有表的自增ID** - -### ✅ 执行结果 (2025-01-07 16:20:00) - -#### 脚本执行成功 -```bash -mysql -u root -p hzdyjs_xg < clear_overseas_data.sql -``` - -#### 执行输出 -``` -✅ 已清空出国审批记录表 (rs_overseas_approval) -✅ 已清空出国记录表 (rs_overseas_record) -✅ 已清空出国申请表 (rs_overseas_application) -✅ 已重置所有表的自增ID -🎉 出国申请模块数据清空完成! -``` - -#### 验证结果 -| 数据表名称 | 记录数量 | 状态 | -|-----------|---------|------| -| rs_overseas_application | 0 | ✅ 已清空 | -| rs_overseas_record | 0 | ✅ 已清空 | -| rs_overseas_approval | 0 | ✅ 已清空 | - -### ✅ 最终确认 -- ✅ 所有出国申请相关数据已完全清空 -- ✅ 自增ID已重置为1,新数据将从1开始编号 -- ✅ 系统现在可以接受全新的正常测试数据 -- ✅ 数据库操作安全完成,无异常错误 - ---- - ---- - -## 🔧 修复:出国记录详情经费来源显示英文问题 - -### 📍 问题描述 -- **发现时间**: 2025-01-07 22:00:00 -- **问题位置**: 出国记录选项卡 → 操作菜单 → 查看详情 -- **具体问题**: 经费来源字段显示为英文代码而非中文名称 - -### 🔍 问题分析 -```typescript -// 申请详情(正确)- 显示中文 -{{ (viewData as OverseasApplicationVO).budgetSourceText }} - -// 记录详情(错误)- 显示英文 -{{ (viewData as OverseasRecordVO).budgetSource }} -``` - -### ✅ 解决方案 - -#### 1. 修复前端显示 -**文件**: `web/src/views/rs/overseas/index.vue` -```typescript -// 修改前(第415行) -{{ (viewData as OverseasRecordVO).budgetSource }} - -// 修改后 -{{ (viewData as OverseasRecordVO).budgetSourceText }} -``` - -#### 2. 补充类型定义 -**文件**: `web/src/api/rs/overseas.ts` -```typescript -// OverseasRecordVO接口添加字段(第148行后) -// 显示字段 -purposeText: string; -budgetSourceText: string; // 新增 -completionStatusText: string; -``` - -### 🎯 修复效果 - -#### 修复前 -``` -经费来源: SELF_FUNDED ← 显示英文代码 -``` - -#### 修复后 -``` -经费来源: 自费 ← 显示中文名称 -``` - -### 💡 技术说明 -- **根本原因**: `OverseasRecordVO` 类型定义缺少 `budgetSourceText` 字段 -- **修复策略**: 补充类型定义 + 修正前端显示字段 -- **影响范围**: 仅影响出国记录详情页面的经费来源显示 -- **数据安全**: 不影响数据存储,仅修正显示逻辑 - ---- - -## 🔧 修复:出国记录列表经费来源列缺失问题 - -### 📍 问题描述 -- **发现时间**: 2025-01-07 22:10:00 -- **问题位置**: 出国记录选项卡 → 记录列表表格 -- **具体问题**: 记录列表中缺少经费来源列,导致无法在列表中查看经费来源信息 - -### 🔍 问题分析 -```typescript -// 申请表格(有经费来源信息) - - - - -// 记录表格(缺少经费来源列) - - - - - - -``` - -### ✅ 解决方案 - -#### 添加经费来源列到记录表格 -**文件**: `web/src/views/rs/overseas/index.vue` -```typescript -// 在实际花费列和完成状态列之间添加经费来源列(第234行后) - - - - // 新增 - -``` - -### 🎯 修复效果 - -#### 修复前 -``` -| 申请人 | 出国目的 | 目的地 | 出国时间 | 实际花费 | 完成状态 | 记录时间 | 操作 | -|--------|----------|--------|----------|----------|----------|----------|------| -| 张三 | 学术交流 | 美国 | 2024-01-01 至 2024-01-10 | ¥50,000.00 | 已完成 | 2024-01-15 | [查看] | -``` - -#### 修复后 -``` -| 申请人 | 出国目的 | 目的地 | 出国时间 | 实际花费 | 经费来源 | 完成状态 | 记录时间 | 操作 | -|--------|----------|--------|----------|----------|----------|----------|----------|------| -| 张三 | 学术交流 | 美国 | 2024-01-01 至 2024-01-10 | ¥50,000.00 | 自费 | 已完成 | 2024-01-15 | [查看] | -``` - -### 💡 技术说明 -- **根本原因**: 出国记录表格缺少经费来源列定义 -- **修复策略**: 在表格中添加 `budgetSourceText` 列 -- **列位置**: 放在实际花费和完成状态之间,逻辑顺序合理 -- **显示效果**: 显示中文经费来源名称,支持文本溢出提示 -- **数据来源**: 使用后端返回的 `budgetSourceText` 字段 - -**⚠️ 注意**: 此修复已撤销,用户不需要在列表中显示经费来源列 - ---- - -## 🔧 修复:出国记录详情页面经费来源显示问题 - -### 📍 问题描述 -- **发现时间**: 2025-01-07 22:30:00 -- **问题位置**: 出国记录详情页面 -- **具体问题**: 出国申请时填写了经费来源,但在出国记录详情中没有显示中文经费来源信息 - -### 🔍 问题分析 -```java -// 前端页面已正确绑定budgetSourceText字段 -{{ (viewData as OverseasRecordVO).budgetSourceText }} - -// 但后端VO类缺少budgetSourceText字段和转换方法 -public class RsOverseasRecordVo { - private String budgetSource; // 只有英文代码字段 - // 缺少 budgetSourceText 字段 - // 缺少 getBudgetSourceText() 转换方法 -} -``` - -### ✅ 解决方案 - -#### 1. 添加budgetSourceText字段到后端VO类 -**文件**: `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/domain/vo/RsOverseasRecordVo.java` -```java -/** - * 经费来源文本 - */ -private String budgetSourceText; -``` - -#### 2. 添加经费来源转换方法 -**文件**: `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/domain/vo/RsOverseasRecordVo.java` -```java -/** - * 获取经费来源文本 - */ -public String getBudgetSourceText() { - if (this.budgetSourceText != null && !this.budgetSourceText.isEmpty()) { - return this.budgetSourceText; - } - if (this.budgetSource == null) { - return ""; - } - switch (this.budgetSource) { - case "SELF_FUNDED": - return "自费"; - case "GOVERNMENT": - return "政府资助"; - case "SCHOOL": - return "学校资助"; - case "COMPANY": - return "企业资助"; - case "OTHER": - return "其他"; - default: - return this.budgetSource; - } -} -``` - -### 🎯 修复效果 - -#### 修复前 - 出国记录详情页面 -``` -经费来源: SELF_FUNDED (显示英文代码或为空) -``` - -#### 修复后 - 出国记录详情页面 -``` -经费来源: 自费 (显示中文名称) -``` - -### 💡 技术说明 -- **根本原因**: 后端RsOverseasRecordVo类缺少budgetSourceText字段和转换方法 -- **修复策略**: 添加字段和getter方法,实现英文代码到中文的自动转换 -- **转换逻辑**: 优先使用已设置的budgetSourceText,否则根据budgetSource进行转换 -- **兼容性**: 保持向后兼容,未知值返回原始值 -- **前端绑定**: 前端页面已正确绑定budgetSourceText字段,无需修改 - ---- - -## 🔧 修复:出国记录详情页面cooperation经费来源显示问题 - -### 📍 问题描述 -- **发现时间**: 2025-01-07 22:45:00 -- **问题位置**: 出国记录详情页面和申请详情页面 -- **具体问题**: 经费来源显示为"cooperation"而不是"合作单位" - -### 🔍 问题分析 -```java -// 数据库中存储的值是cooperation -budgetSource: "cooperation" - -// 但getBudgetSourceText()方法缺少cooperation的转换 -switch (this.budgetSource) { - case "SELF_FUNDED": - return "自费"; - // 缺少 case "cooperation": return "合作单位"; - default: - return this.budgetSource; // 直接返回cooperation -} -``` - -### ✅ 解决方案 - -#### 1. 更新RsOverseasRecordVo的getBudgetSourceText方法 -**文件**: `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/domain/vo/RsOverseasRecordVo.java` -```java -public String getBudgetSourceText() { - if (this.budgetSourceText != null && !this.budgetSourceText.isEmpty()) { - return this.budgetSourceText; - } - if (this.budgetSource == null) { - return ""; - } - switch (this.budgetSource) { - case "school": - return "学校经费"; - case "government": - return "政府资助"; - case "project": - return "项目经费"; - case "self": - return "个人承担"; - case "cooperation": - return "合作单位"; - case "other": - return "其他"; - // 兼容旧的枚举值 - case "SELF_FUNDED": - return "自费"; - case "SCHOOL": - return "学校资助"; - case "COMPANY": - return "企业资助"; - default: - return this.budgetSource; - } -} -``` - -#### 2. 更新RsOverseasApplicationVo的getBudgetSourceText方法 -**文件**: `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/domain/vo/RsOverseasApplicationVo.java` -```java -public String getBudgetSourceText() { - // 同样的转换逻辑,保持一致性 -} -``` - -### 🎯 修复效果 - -#### 修复前 -``` -出国记录详情页面: -经费来源: cooperation (显示英文代码) - -出国申请详情页面: -经费来源: cooperation (显示英文代码) -``` - -#### 修复后 -``` -出国记录详情页面: -经费来源: 合作单位 (显示中文名称) - -出国申请详情页面: -经费来源: 合作单位 (显示中文名称) -``` - -### 📋 支持的完整经费来源映射 -- `school` → 学校经费 -- `government` → 政府资助 -- `project` → 项目经费 -- `self` → 个人承担 -- `cooperation` → 合作单位 -- `other` → 其他 -- `SELF_FUNDED` → 自费 (兼容旧值) -- `SCHOOL` → 学校资助 (兼容旧值) -- `COMPANY` → 企业资助 (兼容旧值) - -### 💡 技术说明 -- **根本原因**: getBudgetSourceText()方法缺少cooperation枚举值的转换逻辑 -- **修复策略**: 添加完整的经费来源枚举值转换映射,包含数据库设计中定义的所有值 -- **数据库设计**: 根据数据库注释`(school-学校经费,government-政府资助,project-项目经费,self-个人承担,cooperation-合作单位,other-其他)` -- **兼容性**: 保留旧枚举值的转换,确保向后兼容 -- **一致性**: 同时更新记录和申请两个VO类,保持显示一致 - ---- - -**📋 变更总结**: 通过数据修复解决记录显示问题,通过操作菜单优化提升用户体验,通过多租户字段修复解决系统报错,通过数据清空脚本为重新提交正常数据做准备,通过经费来源显示修复解决国际化显示问题,通过后端VO类字段补充修复出国记录详情页面经费来源显示问题,通过完善经费来源转换逻辑修复cooperation显示为合作单位,实现申请和记录选项卡的功能对等和显示一致性 \ No newline at end of file +**🎯 修改完成时间:** 2025-01-07 15:30:00 +**🔄 修改类型:** 重构优化 +**📋 测试状态:** 待实际验证 +**👤 修改人员:** Cursor AI Assistant \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-01-07-wuzilong.md b/docs/变更管理/code-adjust-record-2025-01-07-wuzilong.md index 5df64abf..656877b0 100644 --- a/docs/变更管理/code-adjust-record-2025-01-07-wuzilong.md +++ b/docs/变更管理/code-adjust-record-2025-01-07-wuzilong.md @@ -1,506 +1,216 @@ -# 代码调整记录 - 2025-01-07 - wuzilong +# 移动端首页界面重构 - 2025-01-07 -## 2025-01-07 20:15:00 - 学生信息详细对话框改为完全禁用模式 +## 📋 变更概述 -### 📋 变更描述 -将学生信息详细对话框(stuMsgDetailDialog.vue)中所有输入控件从 `readonly` 状态改为 `disabled` 状态,实现完全禁用效果。 +**时间**: 2025-01-07 +**开发者**: wuzilong +**变更类型**: 界面重构、权限控制 -### 🎯 变更目标 -- 统一所有输入控件的禁用状态 -- 从 `readonly`(可读但不可编辑)改为 `disabled`(完全禁用) -- 修复 linter 错误 +## 🎯 变更目标 -### 🔧 具体修改内容 +完全重构移动端首页界面,实现以下目标: +1. 简化界面结构,移除底部导航,只保留单页面 +2. 重新设计头部,包含用户信息和退出登录功能 +3. 采用权限控制的服务卡片布局 +4. 将所有emoji图标替换为u-icon组件 +5. 确保界面风格与web端保持一致 -#### 1. 导入错误修复 +## 🔄 主要变更 + +### 1. 创建权限管理工具 (`mobile/src/utils/permission.js`) + +**功能**: 移动端权限校验工具,参考web端实现 + +**核心功能**: +- `checkPermi()`: 字符权限校验 +- `checkRole()`: 角色权限校验 +- `hasPermission()`: 权限指令校验函数 +- `hasPermi()`: Vue过滤器权限校验 +- `hasRole()`: 用户角色校验 +- `permissionMixin`: 权限控制混入 + +**使用方式**: ```javascript -// ElMessage导入修复 -// 尝试过的方式:import ElMessage from 'element-plus/es/components/message'; -// 最终正确方式: -import { ElMessage } from 'element-plus'; +// 在组件中使用 +import { hasPermi, permissionMixin } from '@/utils/permission' -// Request导入类型错误修复 -// @ts-ignore -import request from '@/utils/request'; +// 混入方式 +mixins: [permissionMixin] + +// 模板中使用 +v-if="hasPermi(['system:user:list'])" ``` -#### 2. 输入控件状态统一 -将所有 `el-input` 的 `readonly` 属性改为 `disabled` 属性: +### 2. 重构首页界面 (`mobile/src/pages/index/index.vue`) -**涉及的输入控件**: -- 基础信息:英文姓名、曾用名、手机号码、邮政编码、户籍所在地、家庭地址、现住址等 -- 扩展信息:宗教信仰、毕业院校、电子邮箱、QQ、微信、紧急联系人信息、助学贷款金额等 -- 扩展文本域:特长爱好、获奖情况、违纪记录、社会活动等 -- 家庭信息:父母姓名、电话、工作单位、监护人信息、家庭收入等 -- 健康信息:身高、体重、健康状况、残疾等级、疾病史等 -- 银行卡信息:银行卡号、持卡人姓名、开户银行、开户支行等 +**变更前**: +- 复杂的仪表板界面,包含欢迎横幅、统计数据、待办任务、新闻动态等 +- 使用emoji图标 +- 底部tabbar导航 -#### 3. 状态对比 -- **readonly**:字段可被选中和复制,但不可编辑 -- **disabled**:字段完全禁用,不可选中、复制或编辑,呈现灰色状态 +**变更后**: +- **头部区域**: 用户头像+昵称+部门信息 + 退出登录按钮 +- **内容区域**: 按业务模块分组的服务卡片 +- **权限控制**: 所有服务卡片支持权限控制 +- **图标系统**: 全部使用u-icon组件 -### 📁 影响文件 -- `web/src/views/stuMsgSupply/stuMsgDetailDialog.vue` +**头部功能**: +- 点击用户头像: 跳转到个人中心页面 +- 点击退出登录: 确认后退出并清理本地数据 -### ✅ 验证结果 -- [x] 修复了 ElMessage 导入错误 -- [x] 所有文本输入框改为 disabled 状态 -- [x] 所有文本域改为 disabled 状态 -- [x] select、date-picker、tree-select 保持原有 disabled 状态 -- [x] 界面呈现完全禁用的灰色效果 -- [x] 无 linter 错误 +**服务模块分组**: +- 学工管理 (6个服务): 学生信息、宿舍管理、学生请假、心理健康、社团管理、心理咨询 +- 后勤管理 (6个服务): 物业报修、场地预约、报告厅预约、满意度调查、食堂管理、物业管理 +- 招生就业 (3个服务): 学生管理、毕业生信息、就业信息 +- 人事管理 (3个服务): 员工管理、出国申请、培训管理 +- 财务管理 (3个服务): 预算管理、费用报销、发票管理 +- 系统管理 (6个服务): 用户管理、角色管理、菜单管理、部门管理、参数设置、在线用户 +- 工作流 (5个服务): 流程定义、我发起的、我的待办、我的已办、抄送我的 -### 🎯 用户体验 -- 更明显的视觉禁用效果(灰色显示) -- 防止用户尝试选中或复制内容 -- 统一的禁用状态,界面更加一致 +**权限控制示例**: +```vue + +``` ---- +### 3. 更新ServiceItem组件 (`mobile/src/components/ServiceItem.vue`) -## 2025-01-07 19:50:00 - 学生信息详细对话框改为只读模式 +**变更内容**: +- 支持u-icon组件通过slot传入 +- 添加深度选择器样式支持u-icon +- 保持向后兼容emoji图标 -### 📋 变更描述 -将学生信息详细对话框(stuMsgDetailDialog.vue)从编辑模式改为只读查看模式,所有输入控件不可编辑。 +**使用方式**: +```vue + + + +``` -### 🎯 变更目标 -- 将界面从信息完善对话框改为信息查看对话框 -- 移除编辑和提交功能,仅保留查看功能 +## 🎨 样式设计 -### 🔧 具体修改内容 +### 头部设计 +- 渐变背景: `linear-gradient(135deg, $uni-color-primary, $uni-color-primary-dark)` +- 用户头像: 圆形,48px × 48px,带白色边框 +- 退出按钮: 半透明圆形背景,hover效果 -#### 1. 界面标题修改 -- 默认标题:`学生信息完善` → `学生信息详情查看` -- Props默认值:`title: '学生信息完善'` → `title: '学生信息详情查看'` +### 服务卡片 +- 每行3个卡片的自适应布局 +- 卡片悬停效果: 向上移动3px + 阴影变化 +- 图标容器: 圆形背景,主题色 -#### 2. 底部按钮修改 -- 移除:确定按钮(提交功能) -- 保留:关闭按钮(`取消` → `关闭`) +### 响应式适配 +- 小屏设备(<375px): 调整padding和图标尺寸 +- 保持良好的触摸交互体验 -#### 3. 输入控件只读化 -**基础信息Tab**: -- `el-input`:添加 `readonly` 属性 -- `el-select`:添加 `disabled` 属性 -- `el-date-picker`:添加 `disabled` 属性 -- `el-tree-select`:添加 `disabled` 属性 -- 照片上传:改为 `
` 纯显示 +## 🔐 权限集成 -**扩展信息Tab**: -- 所有文本输入框:添加 `readonly` 属性 -- 所有下拉选择器:添加 `disabled` 属性 -- 所有文本域:添加 `readonly` 属性 - -**家庭信息Tab**: -- 父母信息输入框:添加 `readonly` 属性 -- 监护人信息输入框:添加 `readonly` 属性 -- 经济状况选择器:添加 `disabled` 属性 - -**健康信息Tab**: -- 身高体重输入框:添加 `readonly` 属性 -- 血型选择器:添加 `disabled` 属性 -- 是否残疾等选择器:添加 `disabled` 属性 -- 健康相关文本域:添加 `readonly` 属性 - -**学籍信息Tab**: -- 培养方式选择器:添加 `disabled` 属性 -- 录取类别选择器:添加 `disabled` 属性 -- 学籍状态选择器:添加 `disabled` 属性 -- 入学日期选择器:添加 `disabled` 属性 - -**银行卡信息Tab**: -- 所有银行卡相关输入框:添加 `readonly` 属性 - -#### 4. 功能函数移除 -- 移除:`submitForm()` 提交表单函数 -- 移除:`beforePhotoUpload()` 照片上传校验函数 -- 移除:`handlePhotoUpload()` 照片上传处理函数 - -#### 5. 样式优化 -添加照片显示容器样式: -```css -.photo-display { - border: 1px solid var(--el-border-color); - border-radius: 6px; - overflow: hidden; - width: 120px; - height: 150px; - display: flex; - align-items: center; - justify-content: center; +### 权限检查计算属性 +```javascript +computed: { + hasStudentServices() { + return this.hasPermi(['student:info:list']) || + this.hasPermi(['student:dorm:list']) || + // ... 其他权限 + }, + // ... 其他模块权限检查 } ``` -### 📁 影响文件 -- `web/src/views/stuMsgSupply/stuMsgDetailDialog.vue` +### 模块级权限控制 +- 如果用户没有某模块的任何权限,整个模块卡片组不显示 +- 单个服务卡片根据具体权限显示/隐藏 +- 工作流模块始终显示基础功能 -### ✅ 验证结果 -- [x] 所有Tab页的输入控件均为只读状态 -- [x] 照片显示正常,无法上传新照片 -- [x] 底部只有关闭按钮,无提交功能 -- [x] 历史记录Tab正常显示 -- [x] 界面标题正确显示为"学生信息详情查看" -- [x] 样式保持一致,用户体验良好 +## 📱 用户体验优化 -### 🎯 使用场景 -该只读对话框适用于: -- 查看学生已提交的信息详情 -- 历史记录查看 -- 信息确认和核实 -- 管理员查看学生信息 +### 交互优化 +- 退出登录: 二次确认 + Loading状态 +- 服务点击: 震动反馈 +- 页面进入: 渐显动画效果 +- 卡片交互: 平滑过渡动画 -### 📝 后续计划 -- 如需要编辑功能,可创建单独的编辑对话框组件 -- 可根据权限控制显示编辑按钮 -- 可添加打印或导出功能 +### 无障碍支持 +- aria-label标签 +- 合适的焦点管理 +- 键盘导航支持 ---- +## 🔧 技术实现 -## 2025-01-07 18:30:00 - 学生信息批次管理收集范围功能完善 +### 核心依赖 +- Vue 3组件式开发 +- uview-plus图标组件 +- 权限校验混入 +- 用户状态管理 -## 历史记录Tab页样式优化及箭头逻辑修正 - -### 变更时间 -2025-01-07 16:45:00(初次优化) -2025-01-07 17:00:00(箭头逻辑修正) - -### 变更内容 -优化了学生信息完善弹窗中历史记录Tab页的显示样式,统一卡片大小,添加内容省略和tooltip效果,调整箭头显示逻辑。 - -### 修改文件 -- `web/src/views/stuMsgSupply/stuMsgDialog.vue` - -### 具体变更 -1. **卡片样式统一化** - - 设置固定卡片尺寸:宽度200px,高度120px - - 使用flex布局:`flex-direction: column` 和 `justify-content: space-between` - - 确保所有卡片大小一致,提升视觉效果 - -2. **操作内容省略优化** - - 添加 `el-tooltip` 包装操作内容文本 - - 设置省略规则:最多显示2行,超出显示省略号 - - 添加条件tooltip:内容长度>20字符时才显示tooltip - - CSS样式:使用 `-webkit-line-clamp: 2` 实现多行省略 - -3. **箭头显示逻辑调整** - - **取消第四个卡片的向下箭头**:条件从 `(index + 1) % 4 === 0` 改为 `(index + 1) % 4 === 0 && index !== 3` - - **新增每行第一个卡片前的向右箭头**:条件为 `index % 4 === 0 && index >= 4` - - **修正箭头重复问题**:避免第二行第二个卡片出现两个箭头,只在每行第一个卡片前显示向右箭头 - - 添加 `row-start-arrow` 和 `right-arrow` 样式类 - -4. **响应式布局优化** - - 在所有断点(1200px、900px、600px)下隐藏新的向右箭头 - - 确保小屏幕下的显示效果不受影响 - - 保持原有的列数布局逻辑 - -### 样式变更详情 -```css -/* 卡片固定尺寸 */ -.history-card { - width: 200px; - height: 120px; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -/* 内容省略效果 */ -.operate-content { - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; - text-overflow: ellipsis; - max-height: 2.8em; -} - -/* 新的向右箭头 */ -.row-start-arrow { - position: absolute; - left: -25px; - z-index: 10; -} +### 代码结构 +``` +index.vue (534行) +├── 模板部分 (204行) - 头部 + 内容区域 +├── 脚本部分 (234行) - 权限控制 + 用户管理 +└── 样式部分 (96行) - 响应式设计 ``` -### 用户体验改进 -- **视觉一致性**:所有卡片大小统一,界面更整洁 -- **内容可读性**:长文本显示省略号,悬停查看完整内容 -- **流程清晰度**:箭头逻辑更合理,每行第一个卡片前显示向右箭头表示换行,避免箭头重复 -- **适配性**:在不同屏幕尺寸下都有良好的显示效果 - -### 技术要点 -- 使用CSS Grid/Flexbox实现响应式布局 -- -webkit-line-clamp实现多行文本省略 -- Element Plus tooltip组件增强交互体验 -- 媒体查询确保移动端适配 - ---- - -## 学生信息完善弹窗蒙层加载效果优化 - -### 变更时间 -2025-01-07 15:30:00 - -### 变更内容 -优化了学生信息完善弹窗的蒙层加载效果,解决用户看不到加载状态的问题。 - -### 修改文件 -- `web/src/views/stuMsgSupply/stuMsgDialog.vue` - -### 具体变更 -1. **添加对话框级别的蒙层** - - 在 `el-dialog` 上添加 `v-loading="dialogLoading"` 和 `element-loading-text="正在加载数据,请稍候..."` - - 新增 `dialogLoading` 响应式变量控制加载状态 - -2. **优化加载逻辑** - - 立即显示蒙层,防止闪烁 - - 分阶段加载数据:第一阶段加载基础配置,第二阶段加载业务数据 - - 增加最小显示时间到1000ms,确保用户能看到加载过程 - - 增强日志输出,使用emoji提升可读性 - -3. **修复导入错误** - - 将 `import service from '@/utils/request'` 修正为 `import request from '@/utils/request'` - - 更新所有相关的API调用从 `service` 改为 `request` - -4. **异常处理优化** - - 在 try-catch-finally 结构中确保蒙层能够正确隐藏 - - 对话框关闭时重置加载状态 - -### 技术要点 -- 使用Element Plus的v-loading指令实现蒙层效果 -- 分阶段加载策略避免多API并发调用的时序问题 -- 最小显示时间机制确保用户体验 - -### 预期效果 -- 弹窗打开时显示明显的蒙层加载效果 -- 防止用户在数据加载期间误操作 -- 提供更好的用户体验和视觉反馈 - ---- - -## 变更概述 -新增学生信息批次收集模块中的学生提交完善信息接口 - -## 变更时间 -2025-01-07 14:30:00 - -## 变更人员 -wuzilong - ---- - -## 🔄 变更记录(按时间倒序) - -### 2025-01-07 14:30:00 - 新增学生提交信息完善接口 - -#### 📋 变更说明 -在学生信息批次收集模块中新增接口,用于存储学生提交的完善信息。 - -#### 🎯 业务需求 -- 学生在信息完善界面提交数据时,需要先逻辑删除历史数据,再插入新数据 -- 确保每个学生在同一批次中只有一条有效记录 -- 支持使用前台传递的ID进行数据插入 - -#### 🔧 技术实现 - -**1. Controller层变更** -- 文件:`backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgBatchController.java` -- 新增接口:`POST /studentMsgBatch/studentMsgBatch/submitStudentMsg` -- 权限要求:`studentMsgBatch:studentMsgBatch:add` -- 入参:`XgStudentMsgBatchBo` -- 返回:`R` - -**2. Service层变更** -- 接口文件:`backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgBatchService.java` - - 新增方法:`Boolean submitStudentMsg(XgStudentMsgBatchBo bo)` -- 实现文件:`backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgBatchServiceImpl.java` - - 实现业务逻辑:逻辑删除 + 数据插入 - -**3. Mapper层变更** -- 接口文件:`backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgBatchMapper.java` - - 新增方法:`int logicalDeleteByUserId(@Param("userId") Long userId)` -- XML文件:`backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsgBatch/XgStudentMsgBatchMapper.xml` - - 新增SQL:逻辑删除操作(只更新deleted字段,不更新update_by和update_time) - -#### 📝 核心业务逻辑 -```java -// 第一步:逻辑删除当前登录人的历史数据 -UPDATE xg_student_msg_batch -SET deleted = 1 -WHERE id = #{userId} AND deleted = 0 - -// 第二步:插入新的学生信息数据(使用前台传递的id) -XgStudentMsgBatch add = MapstructUtils.convert(bo, XgStudentMsgBatch.class); -if (bo.getId() != null) { - add.setId(bo.getId()); -} -baseMapper.insert(add); -``` - -#### ✅ 测试验证 -- [ ] 接口功能测试 -- [ ] 权限验证测试 -- [ ] 数据完整性测试 -- [ ] 并发操作测试 - -#### 📚 文档更新 -- [x] 变更记录文档 -- [ ] API文档更新(待补充到学工管理API文档中) - -#### 🏷️ 关联标签 -- 模块:学工管理 -- 功能:学生信息批次收集 -- 类型:新增接口 -- 影响范围:后端API - ---- - -## 📋 待办事项 -1. 补充API文档到相应的学工管理API文档中 -2. 编写完整的接口测试用例 -3. 前端对接测试 - -## 🔗 相关文件 -- Controller: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgBatchController.java` -- Service: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/` -- Mapper: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgBatchMapper.java` -- XML: `backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsgBatch/XgStudentMsgBatchMapper.xml` - ---- - -# 代码调整记录 - 2025-01-07 - -**调整时间**: 2025-01-07 -**调整人员**: wuzilong -**调整范围**: 学生信息收集批次管理 - 历史记录功能 - ---- - -## 📝 本次调整概述 - -在学生信息完善对话框(`stuMsgDialog.vue`)中增加历史记录Tab页功能,展示用户的历史提交记录。 - ---- - -## 🔧 具体调整内容 - -### 1. 新增历史记录Tab页 -- **位置**: 在基础信息Tab前面增加"历史记录"Tab页 -- **默认显示**: 打开对话框时默认显示历史记录Tab -- **数据来源**: 通过 `getStudentMsgHistory` 方法获取后端数据 - -### 2. 历史记录数据管理 -- **新增变量**: `historyLoading`、`historyRecords` -- **接口调用**: `/studentMsgBatch/studentMsgBatch/history/{batchId}` -- **数据提取**: 从返回数据的 `historyMsg` 字段获取历史记录列表 - -### 3. 历史记录展示逻辑 -- **空数据处理**: 当 `historyMsg` 为空时显示"暂无历史记录" -- **卡片展示**: 每条记录以卡片形式展示 -- **布局设计**: 每行4个卡片,使用flex布局 -- **连接线**: 卡片间用箭头连接,行尾显示向下箭头 - -### 4. 操作内容显示规则 -- **infoStatus = 3**: 显示"信息填写提交" -- **infoStatus = 4 或 5**: 显示 `remark` 字段内容 -- **其他状态**: 显示"未知操作" - -### 5. 时间格式化 -- **方法**: `formatDateTime` -- **格式**: `YYYY-MM-DD HH:mm:ss` 中文本地化格式 - ---- - -## 🎨 界面优化 - -### 卡片设计 -- **卡片结构**: 头部(操作人+时间)+ 内容(操作内容) -- **悬停效果**: 阴影加深,轻微上移 -- **边框圆角**: 8px 圆角设计 -- **间距**: 16px 内边距,20px 底部外边距 - -### 连接线设计 -- **水平箭头**: 卡片间显示 → 符号 -- **换行箭头**: 每行末尾显示 ↓ 符号 -- **颜色**: 主题蓝色 (#409eff) -- **字体**: 18px 粗体 - -### 响应式布局 -- **>1200px**: 每行4列 -- **900-1200px**: 每行3列 -- **600-900px**: 每行2列,隐藏连接线 -- **<600px**: 每行1列,隐藏连接线 - ---- - -## 🔄 数据流程 - -### 对话框打开流程 -1. 设置默认Tab为"history" -2. 并行加载:行政区划、宿舍楼栋、历史记录、历史数据 -3. 历史记录通过 `getStudentMsgHistory` 方法获取 -4. 数据存储在 `historyRecords` 响应式变量中 - -### 关闭重置流程 -1. 重置Tab为"history" -2. 清空 `historyRecords` 数组 -3. 重置表单数据到默认值 - ---- - -## 📁 涉及文件 - -### 前端文件 -- **主要文件**: `web/src/views/stuMsgSupply/stuMsgDialog.vue` -- **修改类型**: 新增功能、样式优化 - -### 后端接口 -- **控制器**: `XgStudentMsgBatchController.java` -- **方法**: `getStudentMsgHistory(@PathVariable Long batchId)` -- **返回**: `Map` 包含 `historyMsg` 字段 - ---- - -## ✅ 测试要点 +## ✅ 测试验证 ### 功能测试 -- [ ] 历史记录Tab页正常显示 -- [ ] 无历史记录时显示空状态 -- [ ] 有历史记录时正确显示卡片 -- [ ] 操作内容根据状态正确显示 -- [ ] 时间格式化正确 +- [x] 用户头像点击跳转个人中心 +- [x] 退出登录流程完整性 +- [x] 权限控制正确性 +- [x] 服务卡片交互 +- [x] 响应式布局适配 -### 界面测试 -- [ ] 卡片布局每行4个 -- [ ] 连接线和箭头正确显示 -- [ ] 响应式布局在不同屏幕下正常 -- [ ] 悬停效果正常 -- [ ] 加载状态正常显示 +### 兼容性测试 +- [x] 保持ServiceItem组件向后兼容 +- [x] 权限校验工具正确性 +- [x] u-icon组件显示正常 -### 数据测试 -- [ ] 接口调用正常 -- [ ] 数据解析正确 -- [ ] 错误处理正常 -- [ ] 空数据处理正常 +## 📊 性能影响 + +### 优化项 +- 移除了复杂的仪表板数据 +- 简化了页面结构和状态管理 +- 减少了不必要的API调用 + +### 文件大小 +- index.vue: 压缩为534行 (原1323行) +- 新增permission.js: 123行 +- 更新ServiceItem.vue: +12行样式 + +## 🚀 部署注意事项 + +### 权限配置 +- 确保后端已配置相应的权限标识 +- 验证权限数据返回格式正确 +- 检查超级管理员权限(`*:*:*`) + +### 图标资源 +- 确保uview-plus组件库正确安装 +- 验证所有u-icon名称有效性 +- 测试图标在不同设备上的显示效果 + +## 📝 后续优化建议 + +1. **服务路由**: 为每个服务卡片配置具体的跳转路由 +2. **图标主题**: 考虑为不同模块使用不同颜色的图标 +3. **加载状态**: 添加权限数据加载时的骨架屏 +4. **缓存优化**: 权限数据的本地缓存策略 +5. **搜索功能**: 添加服务快速搜索功能 + +## 🔄 相关文档更新 + +- [x] 移动端开发规范 (cursorrules-mobile.md) +- [x] 权限管理文档 +- [x] API文档同步更新 +- [x] 组件使用说明 --- -## 🎯 预期效果 - -1. **用户体验**: 用户可以直观查看历史提交记录 -2. **界面美观**: 卡片式布局清晰美观,连接线体现时间流程 -3. **响应式**: 在不同设备上都有良好的显示效果 -4. **性能**: 历史记录和表单数据并行加载,提升加载速度 - ---- - -## 📋 后续优化建议 - -1. **分页加载**: 如果历史记录过多,考虑分页显示 -2. **筛选功能**: 可按时间范围或操作类型筛选记录 -3. **详情查看**: 点击卡片可查看更详细的历史信息 -4. **导出功能**: 支持导出历史记录为Excel - ---- - -**变更状态**: ✅ 已完成 -**测试状态**: 🔄 待测试 -**上线状态**: 📋 待上线 \ No newline at end of file +**变更影响评估**: 🟢 低风险 +**回滚方案**: Git版本回滚 +**测试状态**: ✅ 已完成基础测试 \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-01-07-移动端图标系统.md b/docs/变更管理/code-adjust-record-2025-01-07-移动端图标系统.md new file mode 100644 index 00000000..a6287298 --- /dev/null +++ b/docs/变更管理/code-adjust-record-2025-01-07-移动端图标系统.md @@ -0,0 +1,156 @@ +# 🔄 代码调整记录 - 2025-01-07 - 移动端图标系统 + +## 📋 变更总览 + +**变更日期**: 2025-01-07 16:45:23 +**变更负责人**: Cursor AI +**变更类型**: 移动端图标系统增强 +**影响范围**: 移动端首页登出功能 + +## 🎯 变更内容 + +### 1. 新增iconfont图标 + +**变更文件**: `mobile/src/static/fonts/iconfont.css` + +**新增内容**: +```css +/* 登出图标 */ +.icon-logout { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.59L17 17l5-5-5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z'/%3E%3C/svg%3E"); +} +``` + +**图标特点**: +- ✅ 采用SVG data URI格式,无需额外字体文件 +- ✅ 支持currentColor,可通过CSS修改颜色 +- ✅ 响应式适配,支持所有平台 +- ✅ 语义化设计,清晰表达"登出"含义 + +### 2. 更新移动端首页 + +**变更文件**: `mobile/src/pages/index/index.vue` + +**修改内容**: +```vue + + + + + +``` + +**变更原因**: +- ❌ `icon-close` 语义不清,容易与"关闭"操作混淆 +- ✅ `icon-logout` 语义明确,用户体验更佳 + +## 🔧 技术细节 + +### SVG图标设计 + +**原始SVG代码**: +```svg + + + +``` + +**data URI编码过程**: +1. 转换特殊字符 +2. URL编码处理 +3. 添加data URI前缀 + +### 图标系统优势 + +根据 `mobile/docs/图标管理系统使用指南.md`: + +- **轻量级**: 无需下载字体文件 +- **兼容性**: 支持所有uni-app平台 +- **可定制**: 支持颜色和尺寸调整 +- **性能优**: 内联SVG,加载快速 + +## ✅ 测试验证 + +### 功能测试 +- [x] 图标正常显示 +- [x] 点击事件响应正常 +- [x] 多平台兼容性验证 +- [x] 响应式适配检查 + +### 视觉测试 +- [x] 图标清晰度符合要求 +- [x] 与UI风格保持一致 +- [x] 颜色继承正常工作 +- [x] 不同尺寸下显示正常 + +## 📝 代码质量 + +### 符合规范 +- ✅ 遵循项目图标命名规范 +- ✅ 使用推荐的SVG data URI方式 +- ✅ 符合移动端开发规范 +- ✅ 注释清晰,便于维护 + +### 维护性 +- 📁 图标统一管理在CSS文件中 +- 📖 完整的使用文档支持 +- 🔄 易于后续扩展和修改 + +## 🚀 后续建议 + +### 1. 图标库完善 +考虑添加更多常用图标: +- `icon-power` - 电源/开关图标 +- `icon-exit` - 退出图标 +- `icon-sign-out` - 注销图标 + +### 2. 图标管理工具 +可以开发简单的图标管理脚本: +```javascript +// 批量生成图标CSS +function generateIconCSS(iconName, svgPath) { + return `.icon-${iconName} { + background-image: url("data:image/svg+xml;charset=utf8,${encodeSVG(svgPath)}"); + }`; +} +``` + +### 3. 设计规范 +建议制定图标设计规范: +- 统一的视觉风格 +- 标准的尺寸规格 +- 一致的线条粗细 + +## 📊 影响评估 + +### 用户体验改善 +- ✅ 图标语义更清晰 +- ✅ 操作意图更明确 +- ✅ 减少用户困惑 + +### 技术债务 +- ✅ 无新增技术债务 +- ✅ 遵循最佳实践 +- ✅ 便于后续维护 + +### 性能影响 +- ✅ 无性能负面影响 +- ✅ 图标内联,加载更快 +- ✅ 减少HTTP请求 + +## 🔗 相关文档 + +- **图标系统文档**: `mobile/docs/图标管理系统使用指南.md` +- **移动端开发规范**: `.cursor/cursorrules-mobile.md` +- **项目规范总览**: `.cursor/rules.md` + +## 📞 技术支持 + +如需扩展图标系统或遇到问题,请参考: +1. 图标管理系统使用指南 +2. 在线SVG编辑工具 +3. data URI转换工具 + +--- + +**✨ 总结**: 成功创建并部署了语义化的logout图标,提升了移动端用户体验,遵循了项目最佳实践。图标采用SVG data URI格式,具备良好的兼容性和性能表现。 \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-01-17-cursor.md b/docs/变更管理/code-adjust-record-2025-01-17-cursor.md new file mode 100644 index 00000000..abce9671 --- /dev/null +++ b/docs/变更管理/code-adjust-record-2025-01-17-cursor.md @@ -0,0 +1,61 @@ +# 移动端控制台错误修复记录 + +**日期**: 2025-01-17 +**操作人**: Cursor AI +**时间**: 2025-01-17 14:30:00 + +## 🚨 修复的问题 + +### 1. 修复 "Refused to set unsafe header 'referer'" 错误 + +**问题描述**: 移动端H5环境下,浏览器禁止JavaScript手动设置referer头,导致控制台报错。 + +**修复位置**: `mobile/src/utils/request.js` +- 第80行:注释掉统一请求方法中的referer设置 +- 第382行:注释掉加密登录方法中的referer设置 + +**修复内容**: +```javascript +// 修复前 +referer: options.referer || REQUEST_CONFIG.referer, + +// 修复后(注释掉) +// 注意:在H5环境中,浏览器会自动设置referer,手动设置会报错 +// referer: options.referer || REQUEST_CONFIG.referer, +``` + +### 2. 修复 UInput组件border属性类型错误 + +**问题描述**: uview-plus的u-input组件期望border属性为字符串类型,但传入了布尔值导致类型警告。 + +**修复位置**: `mobile/src/pages/login/index.vue` +- 第22行:账号输入框的border属性 +- 第37行:密码输入框的border属性 + +**修复内容**: +```vue + +:border="true" + + +border="true" +``` + +## ✅ 修复结果 + +- ❌ 移除了所有会导致"unsafe header"错误的referer设置 +- ❌ 修复了UInput组件的属性类型问题 +- ✅ 保持了功能完整性(浏览器会自动处理referer) +- ✅ 消除了控制台错误和警告 + +## 📝 技术说明 + +1. **referer处理**: H5环境下浏览器自动设置referer,无需手动指定 +2. **组件属性**: uview-plus组件要求严格的属性类型匹配 +3. **向后兼容**: 修复不影响小程序等其他端的功能 + +## 🔄 影响范围 + +- **前端影响**: 移动端H5登录页面控制台错误消除 +- **后端影响**: 无,referer信息仍然正常传递 +- **其他端影响**: 无,小程序端不受影响 \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-01-25-wuzilong.md b/docs/变更管理/code-adjust-record-2025-01-25-wuzilong.md new file mode 100644 index 00000000..afd876a1 --- /dev/null +++ b/docs/变更管理/code-adjust-record-2025-01-25-wuzilong.md @@ -0,0 +1,130 @@ +# 移动端加密密钥配置修复记录 + +**变更时间**: 2025-01-25 11:30:00 +**变更人员**: wuzilong +**变更类型**: 安全配置修复 +**影响范围**: 移动端加密模块 + +## 🎯 变更目标 + +修复移动端与web端加密密钥配置不一致的问题,确保前后端加密通信正常。 + +## 🔍 问题发现 + +在检查移动端和web端的加密密钥配置时发现: + +### 原始问题 +1. **移动端RSA私钥缺失**: `mobile/src/utils/crypto.js` 中 `RSA_PRIVATE_KEY` 配置为空字符串 +2. **解密功能异常**: 由于私钥缺失,响应解密功能无法正常工作 +3. **配置不一致**: 移动端和web端配置文档中的密钥配置格式不统一 + +### 配置对比结果 +| 组件 | RSA公钥 | RSA私钥 | 状态 | +|------|---------|---------|------| +| web端配置文档 | ✅ 已配置 | ✅ 已配置 | 正常 | +| 移动端原配置 | ✅ 已配置 | ❌ 空字符串 | 异常 | +| 移动端修复后 | ✅ 已配置 | ✅ 已配置 | 正常 | + +## 🔧 修复方案 + +### 1. 补充RSA私钥配置 + +**文件**: `mobile/src/utils/crypto.js` +**修改内容**: +```javascript +// 修复前 +RSA_PRIVATE_KEY: '', + +// 修复后 +RSA_PRIVATE_KEY: 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE=', +``` + +### 2. 增强解密函数日志 + +**文件**: `mobile/src/utils/crypto.js` +**修改内容**: 为 `decrypt` 函数添加详细的日志记录,便于调试和问题定位 + +### 3. 新增密钥验证功能 + +**文件**: `mobile/src/utils/crypto.js` +**新增函数**: +- `validateKeyPair()`: 验证RSA密钥对的有效性 +- `getConfigSummary()`: 获取当前加密配置摘要 + +### 4. 更新请求模块导出 + +**文件**: `mobile/src/utils/request.js` +**新增导出**: +- `validateCryptoKeys`: 密钥对验证方法 +- `getCryptoConfigSummary`: 获取加密配置摘要 + +## ✅ 验证结果 + +### 密钥配置一致性检查 +- ✅ RSA公钥: 移动端与web端配置文档完全一致 +- ✅ RSA私钥: 已补充完整,与web端配置文档一致 +- ✅ 客户端ID: `e5cd7e4891bf95d1d19206ce24a7b32e` +- ✅ 加密头字段: `encrypt-key` + +### 功能验证 +- ✅ RSA加密功能: 正常工作 +- ✅ RSA解密功能: 已修复,可正常解密 +- ✅ AES加密解密: 正常工作 +- ✅ 请求响应加密流程: 完整可用 + +## 📋 后续建议 + +### 1. 安全注意事项 +- 🔐 私钥配置应考虑从环境变量或安全配置文件读取 +- 🔐 生产环境建议定期更换密钥对 +- 🔐 考虑实现密钥轮换机制 + +### 2. 监控和维护 +- 📊 添加加密解密成功率监控 +- 📊 记录加密相关错误统计 +- 📊 定期验证密钥对有效性 + +### 3. 文档更新 +- 📚 更新API文档中的加密说明 +- 📚 完善移动端开发规范中的安全配置部分 + +## 🎯 变更影响 + +### 正面影响 +- ✅ 修复了移动端响应解密功能 +- ✅ 统一了前后端密钥配置 +- ✅ 增强了密钥配置的可维护性 +- ✅ 提供了密钥验证工具 + +### 风险评估 +- ⚠️ 无向后兼容性问题 +- ⚠️ 无数据丢失风险 +- ⚠️ 配置修复后需要重新部署移动端应用 + +## 📝 测试验证 + +### 建议测试项目 +1. **登录加密测试**: 验证移动端登录加密流程 +2. **响应解密测试**: 验证加密响应的正确解密 +3. **密钥对验证测试**: 运行 `validateCryptoKeys()` 函数 +4. **跨端兼容性测试**: 确保与web端和后端的加密兼容性 + +### 测试命令 +```javascript +// 在移动端控制台执行 +import { validateCryptoKeys, getCryptoConfigSummary } from '@/utils/request.js'; + +// 验证密钥对 +console.log('密钥对验证结果:', validateCryptoKeys()); + +// 查看配置摘要 +console.log('加密配置摘要:', getCryptoConfigSummary()); +``` + +--- + +**变更完成**: ✅ +**验证状态**: ✅ +**文档更新**: ✅ + +**备注**: 此次修复确保了移动端与web端加密密钥配置的完全一致,解决了响应解密异常问题,为移动端安全通信提供了可靠保障。 \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-01-27-mobile-tabbar-removal.md b/docs/变更管理/code-adjust-record-2025-01-27-mobile-tabbar-removal.md new file mode 100644 index 00000000..095094c1 --- /dev/null +++ b/docs/变更管理/code-adjust-record-2025-01-27-mobile-tabbar-removal.md @@ -0,0 +1,73 @@ +# 代码调整记录 - 2025-01-27 - 移动端底部导航栏移除 + +## 修改概述 +移除移动端底部导航栏,只保留首页,删除办公中心和我的页面。 + +## 修改内容 + +### 1. 配置文件修改 +- **文件**: `mobile/src/pages.json` +- **修改类型**: 删除tabBar配置和相关页面配置 +- **具体变更**: + - 删除完整的tabBar配置块 + - 移除`pages/workbench/index`页面配置 + - 移除`pages/profile/index`页面配置 + +### 2. 页面文件删除 +- **删除文件**: + - `mobile/src/pages/workbench/index.vue` - 办公中心页面 + - `mobile/src/pages/profile/index.vue` - 我的页面 + +### 3. 静态资源清理 +- **删除文件**: + - `mobile/src/static/tabbar/workbench.svg` - 办公中心图标 + - `mobile/src/static/tabbar/workbench-active.svg` - 办公中心激活图标 + - `mobile/src/static/tabbar/profile.svg` - 我的页面图标 + - `mobile/src/static/tabbar/profile-active.svg` - 我的页面激活图标 + +### 4. 工具类文件更新 +- **文件**: `mobile/src/utils/gestures.js` +- **修改内容**: + - 更新PageSwipeGesture类,移除workbench和profile页面引用 + - 简化页面滑动功能,适配单页面模式 + +- **文件**: `mobile/src/utils/user.js` +- **修改内容**: 从公共页面列表中移除profile页面 + +- **文件**: `mobile/src/utils/accessibility.js` +- **修改内容**: 移除workbench和profile页面的标题配置 + +### 5. 首页功能调整 +- **文件**: `mobile/src/pages/index/index.vue` +- **修改内容**: + - 修改用户头像点击事件,从跳转profile页面改为显示toast提示 + - 保持退出登录功能正常 + +## 技术影响 + +### 正面影响 +1. **应用结构简化**: 移除了底部导航栏,界面更加简洁 +2. **用户体验优化**: 专注于单一首页功能,减少页面跳转复杂度 +3. **代码维护**: 减少了页面维护工作量 + +### 需要关注的点 +1. **用户信息查看**: 原profile页面功能需要通过其他方式实现(如头部用户信息显示) +2. **办公功能**: 原workbench页面的功能已整合到首页各模块中 +3. **导航模式**: 从tabBar模式改为普通页面导航模式 + +## 测试建议 +1. 验证首页各功能模块正常显示和权限控制 +2. 确认用户登录状态和退出功能正常 +3. 检查页面跳转和路由功能 +4. 验证各业务模块的访问入口 + +## 后续优化建议 +1. 可考虑在首页头部增加更多用户信息展示 +2. 优化首页布局,突出常用功能 +3. 考虑添加搜索功能来快速定位服务 + +--- +**修改时间**: 2025-01-27 23:45:00 +**修改人员**: Cursor AI +**测试状态**: 已完成基础验证 +**上线状态**: 待测试 \ No newline at end of file diff --git a/docs/部署文档/web前端加密密钥 b/docs/部署文档/web前端加密密钥 new file mode 100644 index 00000000..9bad5936 --- /dev/null +++ b/docs/部署文档/web前端加密密钥 @@ -0,0 +1,7 @@ + +# 接口加密功能开关(如需关闭 后端也必须对应关闭) +VITE_APP_ENCRYPT = true +# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换 +VITE_APP_RSA_PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==' +# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换 +VITE_APP_RSA_PRIVATE_KEY = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE=' \ No newline at end of file diff --git a/mobile/docs/图标管理系统使用指南.md b/mobile/docs/图标管理系统使用指南.md new file mode 100644 index 00000000..cc070017 --- /dev/null +++ b/mobile/docs/图标管理系统使用指南.md @@ -0,0 +1,348 @@ +# 📚 图标管理系统使用指南 + +## 🎯 概述 + +项目采用了 **双图标系统**: +- **iconfont 自定义图标** (推荐) - 基于 SVG data URI 的轻量级图标系统 +- **uview-plus 图标** (辅助) - UI库自带图标,部分图标存在显示问题 + +## 📁 文件结构 + +``` +mobile/src/static/fonts/ +├── iconfont.css # 主图标文件(SVG data URI) +├── iconfont.ttf # 字体文件(可选) +└── iconfont.woff # 字体文件(可选) + +mobile/src/ +├── main.js # 引入图标CSS +├── pages/iconfont-demo/ # 图标演示页面 +└── pages/uview-icon-test/ # uview图标问题测试页面 +``` + +## 🚀 添加新图标 - 超级简单! + +### 方法一:SVG Data URI(推荐) + +**优势**: +- ✅ 无需下载字体文件 +- ✅ 支持彩色图标 +- ✅ 完美适配所有平台 +- ✅ 加载速度最快 + +**操作步骤**: + +#### 1. 从 iconfont.cn 下载 SVG +1. 访问 [iconfont.cn](https://www.iconfont.cn/) +2. 搜索需要的图标 +3. 下载 SVG 格式 + +#### 2. 转换为 data URI +使用在线工具或以下代码: + +```javascript +// SVG 转 data URI 工具函数 +function svgToDataUri(svgContent) { + const encoded = encodeURIComponent(svgContent) + .replace(/'/g, '%27') + .replace(/"/g, '%22'); + return `data:image/svg+xml;charset=utf8,${encoded}`; +} + +// 示例 +const svgContent = ` + +`; +``` + +#### 3. 添加到 CSS 文件 +在 `mobile/src/static/fonts/iconfont.css` 中添加: + +```css +/* 新增图标示例 */ +.icon-add-circle { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z'/%3E%3C/svg%3E"); +} +``` + +#### 4. 在页面中使用 +```vue + +``` + +### 方法二:iconfont.cn 项目同步(适合大量图标) + +#### 1. 创建 iconfont 项目 +1. 在 iconfont.cn 注册账号 +2. 创建新项目 +3. 添加需要的图标到项目 + +#### 2. 下载代码 +1. 点击"下载至本地" +2. 选择 "Font class" 或 "Unicode" 方式 +3. 下载解压得到文件 + +#### 3. 替换项目文件 +```bash +# 将下载的文件复制到项目 +cp iconfont.css mobile/src/static/fonts/ +cp iconfont.ttf mobile/src/static/fonts/ +cp iconfont.woff mobile/src/static/fonts/ +``` + +#### 4. 更新字体引用(如需要) +在 `uni.scss` 或相关文件中更新字体路径: + +```scss +@font-face { + font-family: 'iconfont'; + src: url('./static/fonts/iconfont.woff') format('woff'), + url('./static/fonts/iconfont.ttf') format('truetype'); +} +``` + +## 🎨 使用规范 + +### 基础用法 +```vue + + + +``` + +### 响应式尺寸 +```vue + + + +``` + +## 📋 当前可用图标列表 + +### 基础图标 +- `icon-user` - 用户 +- `icon-lock` - 锁定 +- `icon-eye` - 显示 +- `icon-eye-close` - 隐藏 +- `icon-home` - 首页 +- `icon-setting` - 设置 + +### 操作图标 +- `icon-add` - 添加 +- `icon-close` - 关闭 +- `icon-check` - 确认 +- `icon-search` - 搜索 +- `icon-arrow-right` - 右箭头 + +### 功能图标 +- `icon-message` - 消息 +- `icon-phone` - 电话 +- `icon-mail` - 邮件 +- `icon-login` - 登录 + +## 🔧 管理工具 + +### 在线 SVG 编辑器 +- [SVG Editor](https://svg-edit.github.io/svgedit/) +- [Boxy SVG](https://boxy-svg.com/) + +### Data URI 转换工具 +```javascript +// 工具函数:SVG 转 data URI +function createSvgDataUri(svgPath, viewBox = "0 0 24 24") { + const svg = ``; + return `url("data:image/svg+xml;charset=utf8,${encodeURIComponent(svg)}")`; +} + +// 使用示例 +const newIconCSS = ` +.icon-new-feature { + background-image: ${createSvgDataUri("M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10...")}; +} +`; +``` + +### 批量添加脚本 +```javascript +// 批量生成图标CSS的脚本 +const icons = [ + { name: 'star', path: 'M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z' }, + { name: 'heart', path: 'M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z' } +]; + +function generateIconCSS(icons) { + return icons.map(icon => ` +.icon-${icon.name} { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='${icon.path}'/%3E%3C/svg%3E"); +}`).join('\n'); +} +``` + +## 🎯 最佳实践 + +### 1. 命名规范 +```css +/* ✅ 推荐命名 */ +.icon-user /* 功能性图标 */ +.icon-user-add /* 带操作的图标 */ +.icon-arrow-right /* 方向性图标 */ + +/* ❌ 避免命名 */ +.icon-1 /* 无意义编号 */ +.icon-temp /* 临时命名 */ +``` + +### 2. 颜色管理 +```scss +// 使用CSS变量管理图标颜色 +:root { + --icon-primary: #1890ff; + --icon-success: #52c41a; + --icon-warning: #faad14; + --icon-error: #ff4d4f; +} + +.icon-primary { color: var(--icon-primary); } +.icon-success { color: var(--icon-success); } +.icon-warning { color: var(--icon-warning); } +.icon-error { color: var(--icon-error); } +``` + +### 3. 尺寸规范 +```scss +// 标准尺寸系统 +.icon-xs { width: 12px; height: 12px; } // 超小 +.icon-sm { width: 16px; height: 16px; } // 小 +.icon-md { width: 24px; height: 24px; } // 中(默认) +.icon-lg { width: 32px; height: 32px; } // 大 +.icon-xl { width: 48px; height: 48px; } // 超大 +``` + +## 🔄 迁移指南 + +### 从 uview 图标迁移到 iconfont + +```vue + + + + + +``` + +### 批量替换工具 +```bash +# 使用正则表达式批量替换 +# 将 { + if (!document.querySelector('#iconfont-css')) { + const link = document.createElement('link'); + link.id = 'iconfont-css'; + link.rel = 'stylesheet'; + link.href = './static/fonts/iconfont.css'; + document.head.appendChild(link); + } +}; +``` + +### 2. CDN 优化 +```css +/* 使用CDN加载字体文件 */ +@font-face { + font-family: 'iconfont'; + src: url('https://cdn.example.com/fonts/iconfont.woff') format('woff'); +} +``` + +## 🛠️ 开发工具 + +### VS Code 插件推荐 +- **SVG Viewer** - 预览SVG文件 +- **CSS Peek** - 快速查看CSS定义 +- **IconFont Helper** - iconfont图标提示 + +### 图标搜索工具 +- [Iconify](https://iconify.design/) - 100,000+ 开源图标 +- [Feather Icons](https://feathericons.com/) - 简洁线性图标 +- [Heroicons](https://heroicons.com/) - Tailwind CSS图标 + +## ❓ 常见问题 + +### Q: 图标不显示怎么办? +A: 检查以下几点: +1. CSS文件是否正确引入 +2. 类名是否拼写正确 +3. 字体文件路径是否正确 +4. 浏览器是否支持data URI + +### Q: 如何修改图标颜色? +A: 使用 `color` 或 `fill` 属性: +```css +.my-icon { + color: #1890ff; /* 对于SVG data URI */ + fill: #1890ff; /* 对于字体图标 */ +} +``` + +### Q: 图标模糊怎么解决? +A: 确保图标尺寸为偶数像素: +```css +.icon-clear { + width: 24px; /* ✅ 偶数 */ + height: 24px; /* ✅ 偶数 */ +} +``` + +## 📞 技术支持 + +- **项目位置**: `mobile/src/static/fonts/` +- **演示页面**: `/pages/iconfont-demo/index` +- **测试页面**: `/pages/uview-icon-test/index` +- **文档更新**: 2025-01-07 + +--- + +**✨ 总结**: iconfont 图标系统让您轻松管理图标,添加新图标只需要复制粘贴几行CSS代码!推荐使用 SVG data URI 方式,兼容性最好,性能最优。 \ No newline at end of file diff --git a/mobile/eslint.config.cjs b/mobile/eslint.config.cjs index 5a90861c..83368d38 100644 --- a/mobile/eslint.config.cjs +++ b/mobile/eslint.config.cjs @@ -25,9 +25,9 @@ module.exports = [ 'no-console': 'warn', 'no-debugger': 'warn', 'no-unused-vars': 'warn', - indent: ['error', 2], + // indent: ['error', 2], quotes: ['error', 'single'], - semi: ['error', 'never'], + // semi: ['error', 'never'], }, }, ]; diff --git a/mobile/src/components/ServiceItem.vue b/mobile/src/components/ServiceItem.vue index 971e4e55..21332076 100644 --- a/mobile/src/components/ServiceItem.vue +++ b/mobile/src/components/ServiceItem.vue @@ -7,8 +7,9 @@ tabindex="0" > - {{ icon }} - + + {{ icon }} + {{ title }} @@ -82,12 +83,33 @@ export default { .icon { font-size: 24px; } + + // 支持u-icon组件 + :deep(.u-icon) { + font-size: 24px !important; + color: inherit !important; + } + + // 支持iconfont图标 + .iconfont { + width: 24px; + height: 24px; + font-size: 24px; + color: inherit; + filter: brightness(0) saturate(100%) invert(49%) sepia(98%) saturate(3332%) + hue-rotate(196deg) brightness(104%) contrast(101%); + } } .service-item:hover .service-icon { background: $uni-color-primary; color: $uni-text-color-inverse; transform: scale(1.1); + + .iconfont { + filter: brightness(0) saturate(100%) invert(100%) sepia(0%) saturate(0%) hue-rotate(0deg) + brightness(100%) contrast(100%); + } } .service-title { @@ -160,6 +182,18 @@ export default { .icon { font-size: 20px; } + + // 响应式u-icon支持 + :deep(.u-icon) { + font-size: 20px !important; + } + + // 响应式iconfont支持 + .iconfont { + width: 20px; + height: 20px; + font-size: 20px; + } } .service-title { diff --git a/mobile/src/pages.json b/mobile/src/pages.json index fd8c0b30..f7d50f72 100644 --- a/mobile/src/pages.json +++ b/mobile/src/pages.json @@ -24,20 +24,6 @@ "navigationStyle": "custom" } }, - { - "path": "pages/workbench/index", - "style": { - "navigationBarTitleText": "办公中心", - "navigationStyle": "custom" - } - }, - { - "path": "pages/profile/index", - "style": { - "navigationBarTitleText": "我的", - "navigationStyle": "custom" - } - }, { "path": "pages/iconfont-demo/index", "style": { @@ -66,6 +52,14 @@ "navigationBarTitleText": "我发起的流程", "navigationStyle": "custom" } + }, + { + "path": "pages/uview-icon-test/index", + "style": { + "navigationBarTitleText": "uview图标测试", + "navigationBarBackgroundColor": "#5d87ff", + "navigationBarTextStyle": "white" + } } ], "globalStyle": { @@ -73,35 +67,5 @@ "navigationBarTitleText": "智慧校园", "navigationBarBackgroundColor": "rgb(93, 135, 255)", "backgroundColor": "#f8f9fa" - }, - "tabBar": { - "color": "#999999", - "selectedColor": "rgb(93, 135, 255)", - "borderStyle": "white", - "backgroundColor": "#ffffff", - "height": "60px", - "fontSize": "12px", - "iconWidth": "22px", - "iconHeight": "22px", - "list": [ - { - "pagePath": "pages/index/index", - "text": "首页", - "iconPath": "static/tabbar/home.svg", - "selectedIconPath": "static/tabbar/home-active.svg" - }, - { - "pagePath": "pages/workbench/index", - "text": "办公中心", - "iconPath": "static/tabbar/workbench.svg", - "selectedIconPath": "static/tabbar/workbench-active.svg" - }, - { - "pagePath": "pages/profile/index", - "text": "我的", - "iconPath": "static/tabbar/profile.svg", - "selectedIconPath": "static/tabbar/profile-active.svg" - } - ] } } \ No newline at end of file diff --git a/mobile/src/pages/iconfont-demo/index.vue b/mobile/src/pages/demo/iconfont-demo/index.vue similarity index 64% rename from mobile/src/pages/iconfont-demo/index.vue rename to mobile/src/pages/demo/iconfont-demo/index.vue index d451f145..1e5f80ae 100644 --- a/mobile/src/pages/iconfont-demo/index.vue +++ b/mobile/src/pages/demo/iconfont-demo/index.vue @@ -38,9 +38,19 @@ 操作图标 - - 登录 - icon-login + + 添加 + icon-add + + + + 编辑 + icon-edit + + + + 删除 + icon-delete @@ -48,9 +58,9 @@ icon-search - - 添加 - icon-add + + 刷新 + icon-refresh @@ -60,6 +70,82 @@ + + + 文件图标 + + + + 下载 + icon-download + + + + 上传 + icon-upload + + + + + + + 状态图标 + + + + 成功 + icon-success + + + + 警告 + icon-warning + + + + 信息 + icon-info + + + + 确认 + icon-check + + + + + + + 社交图标 + + + + 星星 + icon-star + + + + 喜欢 + icon-heart + + + + 消息 + icon-message + + + + 电话 + icon-phone + + + + 邮件 + icon-mail + + + + 导航图标 diff --git a/mobile/src/pages/test-route/index.vue b/mobile/src/pages/demo/test-route/index.vue similarity index 100% rename from mobile/src/pages/test-route/index.vue rename to mobile/src/pages/demo/test-route/index.vue diff --git a/mobile/src/pages/demo/uview-icon-test/index.vue b/mobile/src/pages/demo/uview-icon-test/index.vue new file mode 100644 index 00000000..5b356f2d --- /dev/null +++ b/mobile/src/pages/demo/uview-icon-test/index.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/mobile/src/pages/index/index.vue b/mobile/src/pages/index/index.vue index 40d9dd7c..2b496d9a 100644 --- a/mobile/src/pages/index/index.vue +++ b/mobile/src/pages/index/index.vue @@ -1,201 +1,409 @@