docs: 修订实施计划 — 修复 EditorView 目标类/apiClient.data/主题后端已存在
This commit is contained in:
@@ -154,29 +154,11 @@ git commit -m "feat(app): 添加 EditorBloc.LoadJournal event — 加载已有
|
|||||||
**Files:**
|
**Files:**
|
||||||
- Modify: `app/lib/features/editor/views/editor_page.dart`
|
- Modify: `app/lib/features/editor/views/editor_page.dart`
|
||||||
|
|
||||||
- [ ] **Step 1: 在 _EditorStackState.initState 中加载已有日记**
|
> ⚠️ **重要:** `_loadExistingJournal` 已存在于 `_EditorViewState`(line ~278-331),使用多个细粒度事件(TitleChanged, MoodChanged, TagsLoaded, StrokesLoaded, ElementsLoaded)。本任务将其替换为单一的原子 `LoadJournal` 事件。修改目标是 **`_EditorViewState`**,不是 `_EditorStackState`。
|
||||||
|
|
||||||
修改 `_EditorStackState` 的 `initState`:
|
- [ ] **Step 1: 替换 `_EditorViewState._loadExistingJournal` 方法**
|
||||||
|
|
||||||
```dart
|
找到 `_EditorViewState._loadExistingJournal`(约 line 287-331),替换为使用 LoadJournal 的版本:
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_titleController = TextEditingController(text: widget.state.title);
|
|
||||||
|
|
||||||
// 如果打开已有日记,加载其数据
|
|
||||||
if (widget.journalId != null) {
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
if (!mounted) return;
|
|
||||||
_loadExistingJournal(widget.journalId!);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 2: 实现 _loadExistingJournal 方法**
|
|
||||||
|
|
||||||
在 `_EditorStackState` 中添加:
|
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
/// 加载已有日记数据并 dispatch LoadJournal
|
/// 加载已有日记数据并 dispatch LoadJournal
|
||||||
@@ -217,50 +199,30 @@ Future<void> _loadExistingJournal(String journalId) async {
|
|||||||
lastSavedAt: entry.updatedAt,
|
lastSavedAt: entry.updatedAt,
|
||||||
));
|
));
|
||||||
|
|
||||||
// 同步标题输入框
|
// 同步标题输入框(_EditorStackState 中的 controller)
|
||||||
_titleController.text = entry.title;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('加载日记失败: $e');
|
debugPrint('加载日记失败: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3: 确认 JournalRepository 有 getElements 方法**
|
- [ ] **Step 2: 验证 JournalRepository.getElements 已存在(完整性检查,预计已存在)**
|
||||||
|
|
||||||
Run: `cd g:/nj/app && grep -n "getElements" lib/data/repositories/journal_repository.dart`
|
Run: `cd g:/nj/app && grep -n "getElements" lib/data/repositories/journal_repository.dart`
|
||||||
|
|
||||||
如果不存在,需要在 `JournalRepository` 接口和实现中添加:
|
Expected: 找到方法声明,无需添加。
|
||||||
|
|
||||||
```dart
|
- [ ] **Step 3: 运行 flutter analyze 确认无错误**
|
||||||
// journal_repository.dart
|
|
||||||
Future<List<JournalElement>> getElements(String journalId);
|
|
||||||
|
|
||||||
// isar_journal_repository.dart
|
|
||||||
@override
|
|
||||||
Future<List<JournalElement>> getElements(String journalId) async {
|
|
||||||
// 查询 isar 中该 journalId 的所有元素
|
|
||||||
final collections = await isar.journalElementCollections
|
|
||||||
.where()
|
|
||||||
.filter()
|
|
||||||
.journalIdEqualTo(journalId)
|
|
||||||
.findAll();
|
|
||||||
return collections.map(_collectionToElement).toList();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 4: 运行 flutter analyze 确认无错误**
|
|
||||||
|
|
||||||
Run: `cd g:/nj/app && flutter analyze`
|
Run: `cd g:/nj/app && flutter analyze`
|
||||||
Expected: No issues found
|
Expected: No issues found
|
||||||
|
|
||||||
- [ ] **Step 5: 提交**
|
- [ ] **Step 4: 提交**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd g:/nj
|
cd g:/nj
|
||||||
git add app/lib/features/editor/views/editor_page.dart
|
git add app/lib/features/editor/views/editor_page.dart
|
||||||
git add app/lib/data/repositories/journal_repository.dart
|
git commit -m "feat(app): EditorPage 加载已有日记 — 替换为 LoadJournal 原子事件"
|
||||||
git add app/lib/data/repositories/isar_journal_repository.dart
|
|
||||||
git commit -m "feat(app): EditorPage 加载已有日记 — initState 触发 LoadJournal"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -604,7 +566,7 @@ class _CommentCountBadge extends StatelessWidget {
|
|||||||
Future<List<dynamic>> _fetchComments() async {
|
Future<List<dynamic>> _fetchComments() async {
|
||||||
try {
|
try {
|
||||||
final response = await apiClient.get('/diary/journals/$journalId/comments');
|
final response = await apiClient.get('/diary/journals/$journalId/comments');
|
||||||
return response as List<dynamic>;
|
return response.data as List<dynamic>;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -667,7 +629,7 @@ class _CommentListFuture extends StatelessWidget {
|
|||||||
Future<List<Comment>> _fetchComments() async {
|
Future<List<Comment>> _fetchComments() async {
|
||||||
try {
|
try {
|
||||||
final response = await apiClient.get('/diary/journals/$journalId/comments');
|
final response = await apiClient.get('/diary/journals/$journalId/comments');
|
||||||
final list = response as List<dynamic>;
|
final list = response.data as List<dynamic>;
|
||||||
return list.map((json) => Comment(
|
return list.map((json) => Comment(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
journalId: json['journal_id'] as String,
|
journalId: json['journal_id'] as String,
|
||||||
@@ -920,7 +882,22 @@ git commit -m "fix(server): 补充暖记管理端菜单 seed — 贴纸/主题/
|
|||||||
- Modify: `crates/erp-diary/src/handler/sticker_handler.rs`
|
- Modify: `crates/erp-diary/src/handler/sticker_handler.rs`
|
||||||
- Modify: `crates/erp-diary/src/lib.rs`
|
- Modify: `crates/erp-diary/src/lib.rs`
|
||||||
|
|
||||||
- [ ] **Step 1: 在 sticker_service.rs 添加 CRUD 方法**
|
- [ ] **Step 1: 在 dto.rs 添加 UpdateStickerPackReq DTO**
|
||||||
|
|
||||||
|
参考已有的 `CreateStickerPackReq`,在 `crates/erp-diary/src/dto.rs` 中添加:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[derive(Debug, Deserialize, Validate, ToSchema)]
|
||||||
|
pub struct UpdateStickerPackReq {
|
||||||
|
#[validate(length(min = 1, max = 100))]
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub category: Option<String>,
|
||||||
|
pub is_free: Option<bool>,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: 在 sticker_service.rs 添加 CRUD 方法**
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// 创建贴纸包
|
// 创建贴纸包
|
||||||
@@ -931,7 +908,7 @@ pub async fn update_sticker_pack(&self, id: &str, req: UpdateStickerPackReq) ->
|
|||||||
pub async fn delete_sticker_pack(&self, id: &str) -> Result<()> { ... }
|
pub async fn delete_sticker_pack(&self, id: &str) -> Result<()> { ... }
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: 在 sticker_handler.rs 添加 handler**
|
- [ ] **Step 3: 在 sticker_handler.rs 添加 handler**
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// POST /diary/sticker-packs — 需 diary.sticker.manage 权限
|
// POST /diary/sticker-packs — 需 diary.sticker.manage 权限
|
||||||
@@ -944,14 +921,14 @@ pub async fn update_sticker_pack(...) { ... }
|
|||||||
pub async fn delete_sticker_pack(...) { ... }
|
pub async fn delete_sticker_pack(...) { ... }
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3: 在 lib.rs 注册路由**
|
- [ ] **Step 4: 在 lib.rs 注册路由**
|
||||||
|
|
||||||
- [ ] **Step 4: 运行 cargo check + cargo test**
|
- [ ] **Step 5: 运行 cargo check + cargo test**
|
||||||
|
|
||||||
Run: `cd g:/nj && cargo check && cargo test`
|
Run: `cd g:/nj && cargo check && cargo test`
|
||||||
Expected: PASS
|
Expected: PASS
|
||||||
|
|
||||||
- [ ] **Step 5: 提交**
|
- [ ] **Step 6: 提交**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add crates/erp-diary/
|
git add crates/erp-diary/
|
||||||
@@ -998,20 +975,25 @@ git commit -m "feat(web): 贴纸包管理 CRUD UI — 创建/编辑/删除"
|
|||||||
### Task 15: 主题编辑/停用
|
### Task 15: 主题编辑/停用
|
||||||
|
|
||||||
**Files:**
|
**Files:**
|
||||||
- Modify: `crates/erp-diary/src/service/topic_service.rs`
|
- Verify: `crates/erp-diary/src/handler/topic_handler.rs` (update_topic + deactivate_topic 已存在)
|
||||||
- Modify: `crates/erp-diary/src/handler/topic_handler.rs`
|
|
||||||
- Modify: `crates/erp-diary/src/lib.rs`
|
|
||||||
- Modify: `apps/web/src/api/diary/topics.ts`
|
- Modify: `apps/web/src/api/diary/topics.ts`
|
||||||
- Modify: `apps/web/src/pages/diary/TopicList.tsx`
|
- Modify: `apps/web/src/pages/diary/TopicList.tsx`
|
||||||
|
|
||||||
- [ ] **Step 1: 后端添加主题更新/停用**
|
> ⚠️ **后端已实现** — `topic_handler.rs` 已有 `update_topic` (PUT) 和 `deactivate_topic` (PATCH) handler,`lib.rs` 已注册路由。只需补全管理端 UI。
|
||||||
|
|
||||||
```rust
|
- [ ] **Step 1: 验证后端 API 可用**
|
||||||
// PUT /diary/topics/{id} — 编辑主题(标题/描述/截止日期)
|
|
||||||
// PATCH /diary/topics/{id}/deactivate — 停用主题
|
Run: `cd g:/nj && grep -n "update_topic\|deactivate_topic" crates/erp-diary/src/handler/topic_handler.rs`
|
||||||
|
Expected: 找到两个方法
|
||||||
|
|
||||||
|
- [ ] **Step 2: 在 topics.ts 添加 update/deactivate API 调用**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
update: (id: string, data: UpdateTopicReq) => api.put(`/diary/topics/${id}`, data),
|
||||||
|
deactivate: (id: string) => api.patch(`/diary/topics/${id}/deactivate`),
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: 管理端 TopicList.tsx 添加编辑/停用按钮**
|
- [ ] **Step 3: 管理端 TopicList.tsx 添加编辑/停用按钮**
|
||||||
|
|
||||||
- [ ] **Step 3: 提交**
|
- [ ] **Step 3: 提交**
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user