refactor(backend): 修改App结构体并调整互斥锁使用

将App.FilePath字段改为可序列化以便服务器重启后恢复
将saveApps函数中的RLock改为Lock以确保数据一致性
清理未使用的文档文件
This commit is contained in:
2025-12-25 14:12:02 +08:00
parent 4fb50e6b56
commit 20ccfbc205
8 changed files with 5 additions and 270 deletions

View File

@@ -1,38 +0,0 @@
## 优化计划
### 1. CSS样式简化
- 删除所有装饰性样式(颜色、背景、阴影、圆角、过渡等)
- 只保留基本布局和定位
- 保持所有CSS选择器不变方便后续手动设计
### 2. 添加后端API调用
- 在JavaScript中添加后端API基础URL配置
- 将localStorage存储替换为后端API调用
- 修改以下函数:
- `getAppsFromStorage()` → 调用 GET /api/apps
- `saveAppsToStorage()` → 调用 POST /api/apps
- `uploadApp()` → 调用 POST /api/apps 上传文件
### 3. 后端API设计
- 端口3000
- 无需鉴权
- 接口列表:
- `GET /api/apps` - 获取App列表
- `POST /api/apps` - 上传App支持multipart/form-data
- `GET /api/apps/:id` - 下载指定App
### 4. 前端修改要点
- 保持现有登录逻辑不变
- 保持所有HTML结构不变
- 保持所有CSS选择器不变
- 只修改JavaScript中的数据存储逻辑
### 5. 文件修改清单
- `style.css` - 简化样式
- `script.js` - 添加后端API调用
### 6. 技术要求
- 后端API采用RESTful设计
- 支持CORS跨域请求
- 支持文件上传和下载
- 简单易用,便于快速实现

View File

@@ -1,10 +0,0 @@
1. 创建go.mod文件引入gin框架和必要依赖
2. 创建main.go文件实现Gin服务器
3. 实现GET /api/apps接口返回App列表
4. 实现POST /api/apps接口支持文件上传
5. 实现GET /api/apps/:id接口支持文件下载
6. 添加CORS中间件支持跨域请求
7. 使用互斥锁保护共享资源,确保线程安全
8. 确保文件操作安全,将文件存储在./files目录
9. 配置服务器端口

View File

@@ -1,108 +0,0 @@
## 前端生产级健壮性提升计划
### 1. 核心改进点
#### 添加刷新按钮
* 在下载区域标题旁添加刷新按钮
* 点击按钮重新加载App列表
* 保持与现有按钮风格一致
#### 增强API调用健壮性
* 统一API请求处理添加错误处理
* 完善各种错误场景的用户反馈
* 添加加载状态提示
* 处理网络错误和超时情况
#### 改进用户体验
* 添加操作成功/失败的视觉反馈
* 优化表单验证
* 改进文件上传反馈
#### 前后端适配协调
* 确保前端请求与后端API完全匹配
* 处理后端返回的各种响应状态
* 优化数据处理逻辑
### 2. 实现细节
#### 文件修改
1. **index.html**
* 在下载区域标题旁添加刷新按钮
* 添加加载状态指示器
2. **script.js**
* 添加`refreshAppList()`函数
* 统一API请求处理函数
* 完善错误处理逻辑
* 添加加载状态管理
* 优化现有函数确保与后端API适配
3. **style.css**
* 微调样式以适应刷新按钮
* 添加加载状态样式
#### 关键功能实现
* **刷新功能**:点击按钮调用`loadAppList()`重新加载App列表
* **API健壮性**添加try-catch、错误状态码处理、超时处理
* **用户反馈**:添加加载中提示、操作结果反馈
* **表单验证**:增强对输入的验证,防止无效请求
### 3. 保持极简风格
* 不添加复杂UI元素
* 保持现有配色和布局
* 使用原生JavaScript实现
* 不引入额外库
### 4. 预期效果
* 前端与后端API适配更协调
* 提供更好的用户反馈和错误处理
* 添加刷新功能方便用户手动更新App列表
* 提升系统整体健壮性和用户体验
### 5. 测试要点
* 刷新功能正常工作
* API请求错误处理
* 网络异常情况处理
* 各种边界情况测试
* 保持极简风格不变

View File

@@ -1,67 +0,0 @@
## 前端生产级健壮性提升计划
### 1. 核心改进点
#### 添加刷新按钮
- 在下载区域标题旁添加刷新按钮
- 点击按钮重新加载App列表
- 保持与现有按钮风格一致
#### 增强API调用健壮性
- 统一API请求处理添加错误处理
- 完善各种错误场景的用户反馈
- 添加加载状态提示
- 处理网络错误和超时情况
#### 改进用户体验
- 添加操作成功/失败的视觉反馈
- 优化表单验证
- 改进文件上传反馈
#### 前后端适配协调
- 确保前端请求与后端API完全匹配
- 处理后端返回的各种响应状态
- 优化数据处理逻辑
### 2. 实现细节
#### 文件修改
1. **index.html**
- 在下载区域标题旁添加刷新按钮
- 添加加载状态指示器
2. **script.js**
- 添加`refreshAppList()`函数
- 统一API请求处理函数
- 完善错误处理逻辑
- 添加加载状态管理
- 优化现有函数确保与后端API适配
3. **style.css**
- 微调样式以适应刷新按钮
- 添加加载状态样式
#### 关键功能实现
- **刷新功能**:点击按钮调用`loadAppList()`重新加载App列表
- **API健壮性**添加try-catch、错误状态码处理、超时处理
- **用户反馈**:添加加载中提示、操作结果反馈
- **表单验证**:增强对输入的验证,防止无效请求
### 3. 保持极简风格
- 不添加复杂UI元素
- 保持现有配色和布局
- 使用原生JavaScript实现
- 不引入额外库
### 4. 预期效果
- 前端与后端API适配更协调
- 提供更好的用户反馈和错误处理
- 添加刷新功能方便用户手动更新App列表
- 提升系统整体健壮性和用户体验
### 5. 测试要点
- 刷新功能正常工作
- API请求错误处理
- 网络异常情况处理
- 各种边界情况测试
- 保持极简风格不变

View File

@@ -1,34 +0,0 @@
## 1. 测试执行计划
- **运行现有测试用例**先执行现有的main_test.go测试用例确保基础功能正常
- **生成假文件测试**:创建不同类型和大小的假文件,测试上传、下载和列表功能
- **观察目录变化**监控files目录和apps.json文件的变化确保文件操作正确
- **并发测试**:模拟多用户并发访问,测试系统稳定性
## 2. 代码改进计划
### 2.1 核心功能改进
- **解决文件命名冲突**:上传时生成唯一文件名,避免覆盖现有文件
- **增强并发安全性**优化mutex使用确保所有共享资源访问都被正确保护
- **改进错误处理**:提供更详细的错误信息,便于调试和用户理解
- **添加配置管理**:将硬编码的端口号、文件路径等提取为配置
- **增加日志记录**:添加详细的日志记录,便于监控和调试
### 2.2 测试用例优化
- **表驱动测试**:将重复的测试用例重构为表驱动测试,减少代码冗余
- **增强测试独立性**:确保每个测试用例之间相互独立,避免测试污染
- **增加边界条件测试**:测试极端情况,如超大文件、空文件等
## 3. 测试结果反哺计划
- **分析测试失败原因**:针对测试失败的用例,定位问题并修复
- **优化性能瓶颈**:根据测试结果,优化系统性能
- **完善错误处理**:根据测试中遇到的错误,完善错误处理机制
- **增强测试覆盖**:根据测试结果,补充缺失的测试用例
## 4. 实施步骤
1. 运行现有测试用例,记录结果
2. 生成假文件,进行功能测试
3. 观察目录变化,验证文件操作正确性
4. 执行并发测试,评估系统稳定性
5. 根据测试结果修改main.go代码
6. 优化测试用例,提高测试覆盖率
7. 再次运行测试,验证改进效果
8. 总结改进成果,形成最终代码

View File

@@ -1,10 +0,0 @@
1. 创建go.mod文件引入gin框架和必要依赖
2. 创建main.go文件实现Gin服务器
3. 实现GET /api/apps接口返回App列表
4. 实现POST /api/apps接口支持文件上传
5. 实现GET /api/apps/:id接口支持文件下载
6. 添加CORS中间件支持跨域请求
7. 使用互斥锁保护共享资源,确保线程安全
8. 确保文件操作安全,将文件存储在./files目录
9. 配置服务器端口

View File

@@ -1 +1,3 @@
[
]

View File

@@ -22,7 +22,7 @@ type App struct {
Name string `json:"name"` Name string `json:"name"`
FileName string `json:"fileName"` FileName string `json:"fileName"`
Date string `json:"date"` Date string `json:"date"`
FilePath string `json:"-"` // 内部使用,不序列化 FilePath string `json:"filePath"` // 序列化到JSON中用于服务器重启后恢复
} }
type Doc struct { type Doc struct {
DocBody string `json:"docBody"` DocBody string `json:"docBody"`
@@ -72,8 +72,8 @@ func loadApps() {
// 保存apps数据 // 保存apps数据
func saveApps() error { func saveApps() error {
appsMutex.RLock() appsMutex.Lock()
defer appsMutex.RUnlock() defer appsMutex.Unlock()
file, err := os.Create(jsonFile) file, err := os.Create(jsonFile)
if err != nil { if err != nil {