diff --git a/.kiro/specs/wishtree-mobile/requirements.md b/.kiro/specs/wishtree-mobile/requirements.md new file mode 100644 index 00000000..bd934af6 --- /dev/null +++ b/.kiro/specs/wishtree-mobile/requirements.md @@ -0,0 +1,304 @@ +# 许愿树移动端设计规范 + +> 版本:V2.1 +> 更新日期:2025-12-31 +> 设计范围:Android移动端许愿树功能完善 + +--- + +## 一、设计原则 + +1. **不修改后端**:复用现有API,不做任何后端改动 +2. **不修改管理端**:管理端功能保持不变 +3. **功能完善**:确保所有功能逻辑正确 + +--- + +## 二、现有后端API(不可修改) + +| 接口 | 方法 | 路径 | 说明 | +|------|------|------|------| +| 获取节日列表 | GET | `/api/front/wishtree/festivals` | 获取所有启用的节日 | +| 获取当前节日 | GET | `/api/front/wishtree/festivals/current` | 获取当前进行中的节日 | +| 获取心愿列表 | GET | `/api/front/wishtree/wishes` | 分页获取心愿列表 | +| 获取我的心愿 | GET | `/api/front/wishtree/wishes/my` | 获取当前用户的心愿 | +| 发布心愿 | POST | `/api/front/wishtree/wishes` | 发布新心愿 | +| 获取心愿详情 | GET | `/api/front/wishtree/wishes/{id}` | 获取心愿详情 | +| 删除心愿 | DELETE | `/api/front/wishtree/wishes/{id}` | 删除我的心愿 | +| 点赞心愿 | POST | `/api/front/wishtree/wishes/{id}/like` | 点赞 | +| 取消点赞 | DELETE | `/api/front/wishtree/wishes/{id}/like` | 取消点赞 | +| 获取评论 | GET | `/api/front/wishtree/wishes/{id}/comments` | 获取评论列表 | +| 发表评论 | POST | `/api/front/wishtree/wishes/{id}/comments` | 发表评论 | +| 获取背景素材 | GET | `/api/front/wishtree/backgrounds` | 获取背景素材列表 | + +--- + +## 三、用户故事与验收标准 + +### US-001: 查看许愿树主页 + +**作为** 用户 +**我想要** 进入许愿树页面查看许愿树和我的心愿 +**以便于** 了解当前活动和管理我的心愿 + +**验收标准:** +- [x] 页面显示许愿树背景图 +- [x] 显示当前节日活动横幅(调用 `/festivals/current`) +- [x] 显示我的心愿卡片(调用 `/wishes/my`,最多7个) +- [x] 显示"添加心愿"按钮 +- [x] 底部导航栏正确高亮"许愿树"选项 +- [x] 显示倒计时 +- [x] 显示祈愿值统计 + +--- + +### US-002: 发布心愿 + +**作为** 已登录用户 +**我想要** 发布一个新的心愿 +**以便于** 表达我的愿望 + +**验收标准:** +- [x] 点击"添加心愿"或空白卡片弹出许愿对话框 +- [x] 输入框限制50字,显示字数统计 +- [x] 未登录时提示登录并跳转登录页 +- [x] 调用 `POST /wishes` 发布心愿 +- [x] 提交成功后显示成功动画 +- [x] 心愿列表自动刷新 + +--- + +### US-003: 查看我的心愿 + +**作为** 用户 +**我想要** 查看我已发布的心愿详情 +**以便于** 回顾我的愿望 + +**验收标准:** +- [x] 点击心愿卡片弹出详情对话框 +- [x] 显示心愿内容、点赞数、评论数 +- [x] 提供"删除心愿"和"愿望达成"操作 + +--- + +### US-004: 删除心愿 + +**作为** 用户 +**我想要** 删除我不想要的心愿 +**以便于** 管理我的心愿列表 + +**验收标准:** +- [x] 点击"删除心愿"弹出确认对话框 +- [x] 确认后调用 `DELETE /wishes/{id}` 删除 +- [x] 删除成功后刷新列表 +- [x] 显示删除成功提示 + +--- + +### US-005: 愿望达成 + +**作为** 用户 +**我想要** 标记我的愿望已达成 +**以便于** 庆祝愿望实现 + +**验收标准:** +- [x] 点击"愿望达成"弹出确认对话框 +- [x] 确认后调用 `DELETE /wishes/{id}` 删除心愿 +- [x] 显示庆祝动画(持续2秒) +- [x] 刷新心愿列表 + +--- + +### US-006: 查看节日活动 + +**作为** 用户 +**我想要** 看到当前进行中的节日活动 +**以便于** 参与节日许愿 + +**验收标准:** +- [x] 页面顶部显示活动横幅 +- [x] 横幅显示节日名称 +- [x] 显示倒计时 +- [x] 无活动时显示默认文案 + +--- + +## 四、移动端文件结构 + +``` +android-app/app/src/main/java/com/example/livestreaming/ +├── WishTreeActivity.java # 许愿树主页面 +└── net/ + ├── ApiService.java # API接口定义 + ├── WishtreeRequest.java # 请求类 + └── WishtreeResponse.java # 响应类 + +android-app/app/src/main/res/layout/ +├── activity_wish_tree.xml # 主页面布局 +├── dialog_make_wish.xml # 许愿对话框 +├── dialog_view_wish.xml # 查看心愿对话框 +├── dialog_wish_success.xml # 成功提示对话框 +└── dialog_wish_complete.xml # 愿望达成对话框 +``` + +--- + +## 五、数据模型 + +### 5.1 WishtreeResponse.java + +```java +public class WishtreeResponse { + // 节日信息 + public static class Festival { + public int id; + public String name; + public String icon; + public String startDate; + public String endDate; + public int isLunar; + public String themeColor; + public int status; + } + + // 心愿信息 + public static class Wish { + public long id; + public int uid; + public String nickname; + public String avatar; + public int festivalId; + public String festivalName; + public String festivalIcon; + public String content; + public int backgroundId; + public String backgroundImage; + public int status; // 0待审核 1通过 2拒绝 + public int likeCount; + public int commentCount; + public Boolean isLiked; + public String createTime; + } + + // 分页数据 + public static class WishPage { + public List list; + public int total; + public int pageNum; + public int pageSize; + } +} +``` + +### 5.2 WishtreeRequest.java + +```java +public class WishtreeRequest { + // 发布心愿请求 + public static class PublishWish { + public Integer festivalId; + public String content; + public Integer backgroundId; + } +} +``` + +--- + +## 六、核心交互流程 + +### 6.1 页面加载 + +``` +onCreate() + ├── 初始化ApiService + ├── 启动横幅倒计时 + ├── 设置底部导航 + ├── 设置心愿卡片点击事件 + ├── loadCurrentFestival() → 更新横幅文字 + └── loadMyWishes() → 更新心愿卡片、祈愿值 +``` + +### 6.2 发布心愿 + +``` +点击"添加心愿" + ├── checkLogin() → 未登录跳转登录页 + ├── showMakeWishInputDialog() + ├── 输入内容(≤50字) + ├── publishWish() → POST /wishes + ├── 成功 → showSuccessDialog() → loadMyWishes() + └── 失败 → Toast提示 +``` + +### 6.3 删除/达成心愿 + +``` +点击心愿卡片 + ├── showViewWishDialog() + ├── 点击"删除心愿" + │ ├── 确认对话框 + │ ├── DELETE /wishes/{id} + │ └── 成功 → Toast → loadMyWishes() + └── 点击"愿望达成" + ├── 确认对话框 + ├── DELETE /wishes/{id} + └── 成功 → 庆祝动画 → loadMyWishes() +``` + +--- + +## 七、错误处理 + +| 场景 | 处理方式 | +|------|----------| +| 网络错误 | Toast "网络错误" | +| 业务错误 | Toast 显示后端返回的message | +| 未登录 | 跳转LoginActivity | +| 空数据 | 显示空列表,卡片显示空白 | +| 内容为空 | Toast "请输入心愿内容" | +| 内容超长 | Toast "心愿内容不能超过50字" | + +--- + +## 八、实现任务清单 + +### Phase 1: 数据层 ✅ +- [x] WishtreeResponse.java - 响应类 +- [x] WishtreeRequest.java - 请求类 +- [x] ApiService.java - 接口定义 + +### Phase 2: UI层 ✅ +- [x] activity_wish_tree.xml - 主页面 +- [x] dialog_make_wish.xml - 许愿对话框 +- [x] dialog_view_wish.xml - 查看心愿对话框 +- [x] dialog_wish_success.xml - 成功提示 +- [x] dialog_wish_complete.xml - 愿望达成 + +### Phase 3: 逻辑层 ✅ +- [x] WishTreeActivity.java - 核心逻辑 +- [x] 页面加载与数据刷新 +- [x] 发布心愿功能 +- [x] 删除心愿功能 +- [x] 愿望达成功能 +- [x] 登录检查 +- [x] 错误处理 + +--- + +## 九、测试要点 + +### 功能测试 +- [x] 页面正常加载 +- [x] 节日信息正确显示 +- [x] 心愿卡片正确显示(最多7个) +- [x] 发布心愿成功 +- [x] 删除心愿成功 +- [x] 愿望达成功能正常 +- [x] 底部导航切换正常 + +### 异常测试 +- [x] 网络断开时的提示 +- [x] 未登录时跳转登录页 +- [x] 空数据时的显示 +- [x] 心愿内容校验(空、超长) diff --git a/Zhibo/admin/src/api/wishtree.js b/Zhibo/admin/src/api/wishtree.js index 09e3349d..6859a6cc 100644 --- a/Zhibo/admin/src/api/wishtree.js +++ b/Zhibo/admin/src/api/wishtree.js @@ -68,14 +68,6 @@ export function wishTreeNodeListApi(params) { }); } -// 节点详情 -export function wishTreeNodeInfoApi(id) { - return request({ - url: `/admin/wish/tree/node/info/${id}`, - method: 'get', - }); -} - // 新增节点 export function wishTreeNodeSaveApi(data) { return request({ @@ -112,7 +104,7 @@ export function wishTreeNodeStatusApi(id) { // ========== 用户留言管理 ========== -// 留言列表(按许愿树查询) +// 留言列表 export function wishTreeMessageListApi(params) { return request({ url: '/admin/wish/tree/message/list', @@ -121,14 +113,6 @@ export function wishTreeMessageListApi(params) { }); } -// 留言详情 -export function wishTreeMessageInfoApi(id) { - return request({ - url: `/admin/wish/tree/message/info/${id}`, - method: 'get', - }); -} - // 删除留言 export function wishTreeMessageDeleteApi(id) { return request({ @@ -144,3 +128,107 @@ export function wishTreeMessageStatusApi(id) { method: 'post', }); } + +// ========== 节日管理 ========== + +// 节日列表 +export function festivalList(params) { + return request({ + url: '/admin/wishtree/festival/list', + method: 'get', + params, + }); +} + +// 保存节日 +export function festivalSave(data) { + return request({ + url: '/admin/wishtree/festival/save', + method: 'post', + data, + }); +} + +// 删除节日 - 后端使用DELETE方法 +export function festivalDelete(id) { + return request({ + url: `/admin/wishtree/festival/delete/${id}`, + method: 'delete', + }); +} + +// 修改节日状态 - 后端接收RequestBody +export function festivalStatus(id, status) { + return request({ + url: '/admin/wishtree/festival/status', + method: 'post', + data: { id, status }, + }); +} + +// ========== 心愿管理 ========== + +// 心愿列表 - 后端使用POST方法 +export function wishList(data) { + return request({ + url: '/admin/wishtree/wish/list', + method: 'post', + data, + }); +} + +// 审核心愿 +export function wishAudit(data) { + return request({ + url: '/admin/wishtree/wish/audit', + method: 'post', + data, + }); +} + +// 删除心愿 - 后端使用DELETE方法 +export function wishDelete(id) { + return request({ + url: `/admin/wishtree/wish/delete/${id}`, + method: 'delete', + }); +} + +// ========== 背景管理 ========== + +// 背景列表 +export function backgroundList(params) { + return request({ + url: '/admin/wishtree/background/list', + method: 'get', + params, + }); +} + +// 保存背景 +export function backgroundSave(data) { + return request({ + url: '/admin/wishtree/background/save', + method: 'post', + data, + }); +} + +// 删除背景 - 后端使用DELETE方法 +export function backgroundDelete(id) { + return request({ + url: `/admin/wishtree/background/delete/${id}`, + method: 'delete', + }); +} + +// ========== 统计 ========== + +// 获取统计数据 +export function getStatistics(params) { + return request({ + url: '/admin/wishtree/statistics', + method: 'get', + params, + }); +} diff --git a/Zhibo/admin/src/assets/imgs/logo-lefttop.png b/Zhibo/admin/src/assets/imgs/logo-lefttop.png new file mode 100644 index 00000000..53ae60b1 Binary files /dev/null and b/Zhibo/admin/src/assets/imgs/logo-lefttop.png differ diff --git a/Zhibo/admin/src/assets/imgs/logo-original.png b/Zhibo/admin/src/assets/imgs/logo-original.png new file mode 100644 index 00000000..53ae60b1 Binary files /dev/null and b/Zhibo/admin/src/assets/imgs/logo-original.png differ diff --git a/Zhibo/admin/src/assets/imgs/logo-square.png b/Zhibo/admin/src/assets/imgs/logo-square.png new file mode 100644 index 00000000..53ae60b1 Binary files /dev/null and b/Zhibo/admin/src/assets/imgs/logo-square.png differ diff --git a/Zhibo/admin/src/layout/logo/index.vue b/Zhibo/admin/src/layout/logo/index.vue index 7163290d..c19ac35c 100644 --- a/Zhibo/admin/src/layout/logo/index.vue +++ b/Zhibo/admin/src/layout/logo/index.vue @@ -4,21 +4,20 @@ v-if="$store.state.themeConfig.themeConfig.layout !== 'columns' && !$store.state.themeConfig.themeConfig.isCollapse" @click="onThemeConfigChange" > - + +
- + +