zhibo/模块文档/缘池与许愿树管理端设计文档.md

1764 lines
64 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 缘池与许愿树管理端设计文档
> 版本V2.0
> 更新日期2025-12-30
> 设计范围:缘池社区 + 许愿树管理
> 核心特性:**服务端实时存储,数据云端同步**
---
## 一、设计概述
### 1.1 核心改动
将原本地存储改为服务端实时存储:
- ❌ 原方案SharedPreferences本地存储数据仅存在单设备
- ✅ 新方案服务端API实时存储数据云端同步多端共享
### 1.2 数据流架构
```
┌─────────────┐ API请求 ┌─────────────┐ 数据库 ┌─────────────┐
│ 移动端APP │ ◄──────────────► │ 后端服务 │ ◄──────────────► │ MySQL │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
│ │
▼ ▼
实时获取数据 管理端审核
发布/删除心愿 数据统计
点赞/评论 内容管理
```
### 1.3 功能对照
| 功能 | 原方案(本地) | 新方案(服务端) |
|------|---------------|-----------------|
| 心愿存储 | SharedPreferences | MySQL + API |
| 数据同步 | 无 | 实时同步 |
| 多端访问 | 不支持 | 支持 |
| 内容审核 | 无 | 自动+人工审核 |
| 数据统计 | 无 | 管理端统计 |
| 用户互动 | 无 | 点赞/评论 |
---
## 二、移动端API设计前台接口
### 2.1 缘池移动端API
```
基础路径: /api/front/community
板块相关:
GET /categories # 获取板块列表(启用状态)
消息相关:
GET /messages # 获取消息列表
?categoryId={id}&page=1&limit=20
POST /messages # 发布消息(自动审核)
GET /messages/{id} # 获取消息详情
DELETE /messages/{id} # 删除我的消息
用户匹配:
GET /nearby-users # 获取附近用户(轨道展示)
?latitude={lat}&longitude={lng}&radius=5000&limit=6
```
### 2.2 许愿树移动端API
```
基础路径: /api/front/wishtree
节日相关:
GET /festivals # 获取节日列表(启用状态)
GET /festivals/current # 获取当前进行中的节日
心愿相关:
GET /wishes # 获取心愿列表
?festivalId={id}&page=1&limit=20
GET /wishes/my # 获取我的心愿列表
POST /wishes # 发布心愿(自动审核)
GET /wishes/{id} # 获取心愿详情
DELETE /wishes/{id} # 删除我的心愿
互动相关:
POST /wishes/{id}/like # 点赞心愿
DELETE /wishes/{id}/like # 取消点赞
GET /wishes/{id}/comments # 获取评论列表
POST /wishes/{id}/comments # 发表评论
素材相关:
GET /backgrounds # 获取背景素材列表
```
### 2.3 移动端请求/响应示例
#### 发布心愿
```json
// POST /api/front/wishtree/wishes
// Request:
{
"festivalId": 1,
"content": "新年快乐,万事如意!",
"backgroundId": 1
}
// Response:
{
"code": 200,
"message": "发布成功",
"data": {
"id": 10001,
"uid": 1001,
"festivalId": 1,
"content": "新年快乐,万事如意!",
"backgroundId": 1,
"status": 1,
"auditRemark": "自动审核通过",
"likeCount": 0,
"createTime": "2025-12-30 12:00:00"
}
}
```
#### 获取我的心愿列表
```json
// GET /api/front/wishtree/wishes/my?page=1&limit=10
// Response:
{
"code": 200,
"data": {
"list": [
{
"id": 10001,
"content": "新年快乐,万事如意!",
"festivalName": "元旦",
"festivalIcon": "🎉",
"backgroundImage": "https://xxx/bg1.jpg",
"status": 1,
"likeCount": 128,
"commentCount": 32,
"createTime": "2025-12-30 12:00:00"
}
],
"total": 5,
"page": 1,
"limit": 10
}
}
```
---
## 三、管理端前端设计
### 3.1 路由配置
文件:`Zhibo/admin/src/router/modules/communityManage.js`
```javascript
import Layout from '@/layout';
const communityManageRouter = {
path: '/community',
component: Layout,
redirect: '/community/category',
name: 'Community',
alwaysShow: true,
meta: {
title: '缘池管理',
icon: 'el-icon-s-opportunity',
},
children: [
{
path: 'category',
component: () => import('@/views/community/category/index'),
name: 'CommunityCategory',
meta: { title: '板块管理' },
},
{
path: 'message',
component: () => import('@/views/community/message/index'),
name: 'CommunityMessage',
meta: { title: '消息管理' },
},
{
path: 'match-config',
component: () => import('@/views/community/matchConfig/index'),
name: 'MatchConfig',
meta: { title: '匹配配置' },
},
],
};
export default communityManageRouter;
```
文件:`Zhibo/admin/src/router/modules/wishtreeManage.js`
```javascript
import Layout from '@/layout';
const wishtreeManageRouter = {
path: '/wishtree',
component: Layout,
redirect: '/wishtree/festival',
name: 'Wishtree',
alwaysShow: true,
meta: {
title: '许愿树管理',
icon: 'el-icon-present',
},
children: [
{
path: 'festival',
component: () => import('@/views/wishtree/festival/index'),
name: 'WishtreeFestival',
meta: { title: '节日管理' },
},
{
path: 'wish',
component: () => import('@/views/wishtree/wish/index'),
name: 'WishtreeWish',
meta: { title: '心愿管理' },
},
{
path: 'background',
component: () => import('@/views/wishtree/background/index'),
name: 'WishtreeBackground',
meta: { title: '背景素材' },
},
{
path: 'statistics',
component: () => import('@/views/wishtree/statistics/index'),
name: 'WishtreeStatistics',
meta: { title: '数据统计' },
},
],
};
export default wishtreeManageRouter;
```
### 3.2 API接口
文件:`Zhibo/admin/src/api/community.js`
```javascript
import request from '@/utils/request';
// ==================== 板块管理 ====================
export function categoryList() {
return request({ url: '/admin/community/category/list', method: 'get' });
}
export function categorySave(data) {
return request({ url: '/admin/community/category/save', method: 'post', data });
}
export function categoryDelete(id) {
return request({ url: `/admin/community/category/delete/${id}`, method: 'delete' });
}
export function categoryStatus(data) {
return request({ url: '/admin/community/category/status', method: 'post', data });
}
// ==================== 消息管理 ====================
export function messageList(data) {
return request({ url: '/admin/community/message/list', method: 'post', data });
}
export function messageAudit(data) {
return request({ url: '/admin/community/message/audit', method: 'post', data });
}
export function messageDelete(id) {
return request({ url: `/admin/community/message/delete/${id}`, method: 'delete' });
}
// ==================== 匹配配置 ====================
export function getMatchConfig() {
return request({ url: '/admin/community/match/config', method: 'get' });
}
export function saveMatchConfig(data) {
return request({ url: '/admin/community/match/config/save', method: 'post', data });
}
```
文件:`Zhibo/admin/src/api/wishtree.js`
```javascript
import request from '@/utils/request';
// ==================== 节日管理 ====================
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 });
}
export function festivalDelete(id) {
return request({ url: `/admin/wishtree/festival/delete/${id}`, method: 'delete' });
}
export function festivalStatus(data) {
return request({ url: '/admin/wishtree/festival/status', method: 'post', data });
}
// ==================== 心愿管理 ====================
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 });
}
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 });
}
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 });
}
export function getWishTrend(params) {
return request({ url: '/admin/wishtree/statistics/trend', method: 'get', params });
}
```
### 3.3 页面设计
#### 3.3.1 缘池 - 板块管理
```
┌─────────────────────────────────────────────────────────────────┐
│ [+ 新增板块] │
├─────────────────────────────────────────────────────────────────┤
│ 图标 │ 名称 │ 类型 │ 跳转页面 │ 排序 │ 状态 │ 操作 │
├──────┼────────────┼────────┼──────────────┼──────┼──────┼──────┤
│ 🎤 │ 语音匹配 │ 快捷 │ VoiceMatch │ 100 │ ●启用│ 编辑 │
│ 💕 │ 心动信号 │ 快捷 │ Heartbeat │ 99 │ ●启用│ 编辑 │
│ 💑 │ 在线处对象 │ 功能卡 │ OnlineDating │ 90 │ ●启用│ 编辑 │
│ 🎮 │ 找人玩游戏 │ 功能卡 │ FindGame │ 89 │ ●启用│ 编辑 │
│ 🎵 │ 一起KTV │ 功能卡 │ KTVTogether │ 88 │ ●启用│ 编辑 │
└─────────────────────────────────────────────────────────────────┘
```
#### 3.3.2 缘池 - 消息管理
```
┌─────────────────────────────────────────────────────────────────────┐
│ 板块[全部▼] 状态[全部▼] 时间[起始-结束] [搜索] │
├─────────────────────────────────────────────────────────────────────┤
│ 用户 │ 板块 │ 内容 │ 状态 │ 审核 │ 时间 │ 操作 │
├──────────┼──────────┼──────────────┼────────┼────────┼───────┼──────┤
│ 👤张三 │ 找人玩游戏│ 有人一起.. │ 已通过 │ 自动 │ 12:30 │ 删除 │
│ 👤李四 │ 在线处对象│ 真诚交友.. │ 待审核 │ - │ 11:20 │ ✓ ✗ │
│ 👤王五 │ 一起KTV │ 周末约歌.. │ 已拒绝 │ 自动 │ 10:15 │ 删除 │
└─────────────────────────────────────────────────────────────────────┘
```
#### 3.3.3 缘池 - 匹配配置
```
┌─────────────────────────────────────────────────────────────────┐
│ 用户匹配配置 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 匹配半径(公里) [____5____] │
│ │
│ 每次推荐用户数 [____6____] │
│ │
│ 优先显示在线用户 [========●] │
│ │
│ 优先显示同城用户 [========●] │
│ │
│ 优先显示异性用户 [========●] │
│ │
│ 自动审核开关 [========●] │
│ │
│ [保存配置] │
└─────────────────────────────────────────────────────────────────┘
```
#### 3.3.4 许愿树 - 节日管理
```
┌─────────────────────────────────────────────────────────────────────┐
│ [+ 新增节日] │
├─────────────────────────────────────────────────────────────────────┤
│ 图标 │ 节日名称 │ 开始日期 │ 结束日期 │ 主题色 │ 状态 │ 操作 │
├──────┼──────────┼────────────┼────────────┼─────────┼──────┼───────┤
│ 🎉 │ 元旦 │ 12-31 │ 01-03 │ #FF6B6B │ ●启用│ 编辑 │
│ 🧧 │ 春节 │ 农历除夕 │ 正月十五 │ #E74C3C │ ●启用│ 编辑 │
│ 💕 │ 情人节 │ 02-13 │ 02-15 │ #FF69B4 │ ●启用│ 编辑 │
│ 🎂 │ 生日祝福 │ 全年 │ 全年 │ #FFB6C1 │ ●启用│ 编辑 │
│ ✨ │ 日常祝福 │ 全年 │ 全年 │ #9B59B6 │ ●启用│ 编辑 │
└─────────────────────────────────────────────────────────────────────┘
```
#### 3.3.5 许愿树 - 心愿管理
```
┌─────────────────────────────────────────────────────────────────────┐
│ 节日[全部▼] 状态[全部▼] 时间[起始-结束] [搜索] │
├─────────────────────────────────────────────────────────────────────┤
│ 用户 │ 节日 │ 心愿内容 │ 状态 │ 审核 │ 时间 │ 操作 │
├──────────┼────────┼────────────────┼────────┼────────┼───────┼──────┤
│ 👤张三 │ 元旦 │ 新年快乐.. │ 已通过 │ 自动 │ 12:30 │ 删除 │
│ 👤李四 │ 生日 │ 祝自己生日.. │ 待审核 │ - │ 11:20 │ ✓ ✗ │
│ 👤王五 │ 日常 │ 希望一切.. │ 已通过 │ 自动 │ 10:15 │ 删除 │
└─────────────────────────────────────────────────────────────────────┘
```
#### 3.3.6 许愿树 - 背景素材
```
┌─────────────────────────────────────────────────────────────────────┐
│ [+ 上传背景] 类型[全部▼] │
├─────────────────────────────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 🎄 │ │ 🧧 │ │ 💕 │ │ 🎂 │ │ ✨ │ │
│ │ 元旦 │ │ 春节 │ │ 情人节 │ │ 生日 │ │ 日常 │ │
│ │ [删除] │ │ [删除] │ │ [删除] │ │ [删除] │ │ [删除] │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 🌸 │ │ 🎈 │ │ 🌙 │ │
│ │ 妇女节 │ │ 儿童节 │ │ 七夕 │ │
│ │ [删除] │ │ [删除] │ │ [删除] │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────────────────┘
```
#### 3.3.7 许愿树 - 数据统计
```
┌─────────────────────────────────────────────────────────────────────┐
│ 数据统计 时间范围[近7天▼] │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ 总心愿数 │ │ 今日新增 │ │ 待审核 │ │ 总点赞数 │ │
│ │ 12,580 │ │ 156 │ │ 23 │ │ 89,320 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 心愿发布趋势 │ │
│ │ 📈 折线图 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────┐ ┌────────────────────────────────┐ │
│ │ 节日分布(饼图) │ │ 热门心愿TOP10 │ │
│ │ 🎉元旦 35% │ │ 1. 新年快乐... ❤128 │ │
│ │ 🧧春节 28% │ │ 2. 万事如意... ❤96 │ │
│ │ 💕情人节 15% │ │ 3. 心想事成... ❤85 │ │
│ │ ✨日常 22% │ │ ... │ │
│ └──────────────────────────┘ └────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
```
---
## 四、后端设计
### 4.1 移动端Controller前台接口
#### CommunityFrontController.java
```java
@RestController
@RequestMapping("/api/front/community")
@Api(tags = "缘池-移动端")
public class CommunityFrontController {
@Autowired
private CommunityService communityService;
@ApiOperation("获取板块列表")
@GetMapping("/categories")
public CommonResult<List<CommunityCategory>> getCategories() {
return CommonResult.success(communityService.getEnabledCategories());
}
@ApiOperation("获取消息列表")
@GetMapping("/messages")
public CommonResult<PageInfo<CommunityMessageVO>> getMessages(
@RequestParam(required = false) Integer categoryId,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "20") Integer limit) {
return CommonResult.success(communityService.getFrontMessageList(categoryId, page, limit));
}
@ApiOperation("发布消息")
@PostMapping("/messages")
public CommonResult<CommunityMessage> publishMessage(@RequestBody CommunityMessageRequest request) {
return CommonResult.success(communityService.publishMessage(request));
}
@ApiOperation("删除我的消息")
@DeleteMapping("/messages/{id}")
public CommonResult<String> deleteMyMessage(@PathVariable Long id) {
communityService.deleteMyMessage(id);
return CommonResult.success("删除成功");
}
@ApiOperation("获取附近用户")
@GetMapping("/nearby-users")
public CommonResult<List<NearbyUserVO>> getNearbyUsers(
@RequestParam Double latitude,
@RequestParam Double longitude,
@RequestParam(defaultValue = "5000") Integer radius,
@RequestParam(defaultValue = "6") Integer limit) {
return CommonResult.success(communityService.getNearbyUsers(latitude, longitude, radius, limit));
}
}
```
#### WishtreeFrontController.java
```java
@RestController
@RequestMapping("/api/front/wishtree")
@Api(tags = "许愿树-移动端")
public class WishtreeFrontController {
@Autowired
private WishtreeService wishtreeService;
// ==================== 节日相关 ====================
@ApiOperation("获取节日列表")
@GetMapping("/festivals")
public CommonResult<List<WishtreeFestival>> getFestivals() {
return CommonResult.success(wishtreeService.getEnabledFestivals());
}
@ApiOperation("获取当前进行中的节日")
@GetMapping("/festivals/current")
public CommonResult<WishtreeFestival> getCurrentFestival() {
return CommonResult.success(wishtreeService.getCurrentFestival());
}
// ==================== 心愿相关 ====================
@ApiOperation("获取心愿列表")
@GetMapping("/wishes")
public CommonResult<PageInfo<WishtreeWishVO>> getWishes(
@RequestParam(required = false) Integer festivalId,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "20") Integer limit) {
return CommonResult.success(wishtreeService.getFrontWishList(festivalId, page, limit));
}
@ApiOperation("获取我的心愿列表")
@GetMapping("/wishes/my")
public CommonResult<PageInfo<WishtreeWishVO>> getMyWishes(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit) {
return CommonResult.success(wishtreeService.getMyWishList(page, limit));
}
@ApiOperation("发布心愿")
@PostMapping("/wishes")
public CommonResult<WishtreeWish> publishWish(@RequestBody WishtreeWishRequest request) {
return CommonResult.success(wishtreeService.publishWish(request));
}
@ApiOperation("获取心愿详情")
@GetMapping("/wishes/{id}")
public CommonResult<WishtreeWishVO> getWishDetail(@PathVariable Long id) {
return CommonResult.success(wishtreeService.getWishDetail(id));
}
@ApiOperation("删除我的心愿")
@DeleteMapping("/wishes/{id}")
public CommonResult<String> deleteMyWish(@PathVariable Long id) {
wishtreeService.deleteMyWish(id);
return CommonResult.success("删除成功");
}
// ==================== 互动相关 ====================
@ApiOperation("点赞心愿")
@PostMapping("/wishes/{id}/like")
public CommonResult<String> likeWish(@PathVariable Long id) {
wishtreeService.likeWish(id);
return CommonResult.success("点赞成功");
}
@ApiOperation("取消点赞")
@DeleteMapping("/wishes/{id}/like")
public CommonResult<String> unlikeWish(@PathVariable Long id) {
wishtreeService.unlikeWish(id);
return CommonResult.success("取消成功");
}
@ApiOperation("获取评论列表")
@GetMapping("/wishes/{id}/comments")
public CommonResult<PageInfo<WishtreeCommentVO>> getComments(
@PathVariable Long id,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "20") Integer limit) {
return CommonResult.success(wishtreeService.getCommentList(id, page, limit));
}
@ApiOperation("发表评论")
@PostMapping("/wishes/{id}/comments")
public CommonResult<WishtreeComment> addComment(
@PathVariable Long id,
@RequestBody WishtreeCommentRequest request) {
return CommonResult.success(wishtreeService.addComment(id, request));
}
// ==================== 素材相关 ====================
@ApiOperation("获取背景素材列表")
@GetMapping("/backgrounds")
public CommonResult<List<WishtreeBackground>> getBackgrounds() {
return CommonResult.success(wishtreeService.getEnabledBackgrounds());
}
}
```
### 4.2 管理端Controller后台接口
#### CommunityAdminController.java
文件:`crmeb-admin/src/main/java/com/zbkj/admin/controller/CommunityAdminController.java`
```java
package com.zbkj.admin.controller;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.community.*;
import com.zbkj.common.request.*;
import com.zbkj.common.response.*;
import com.zbkj.common.result.CommonResult;
import com.zbkj.service.service.CommunityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/admin/community")
@Api(tags = "缘池管理")
public class CommunityAdminController {
@Autowired
private CommunityService communityService;
// ==================== 板块管理 ====================
@ApiOperation("板块列表")
@GetMapping("/category/list")
public CommonResult<List<CommunityCategory>> categoryList() {
return CommonResult.success(communityService.getCategoryList());
}
@ApiOperation("保存板块")
@PostMapping("/category/save")
public CommonResult<String> categorySave(@RequestBody CommunityCategory category) {
communityService.saveCategory(category);
return CommonResult.success("保存成功");
}
@ApiOperation("删除板块")
@DeleteMapping("/category/delete/{id}")
public CommonResult<String> categoryDelete(@PathVariable Integer id) {
communityService.deleteCategory(id);
return CommonResult.success("删除成功");
}
@ApiOperation("更新板块状态")
@PostMapping("/category/status")
public CommonResult<String> categoryStatus(@RequestBody CommunityCategory category) {
communityService.updateCategoryStatus(category.getId(), category.getStatus());
return CommonResult.success("更新成功");
}
// ==================== 消息管理 ====================
@ApiOperation("消息列表")
@PostMapping("/message/list")
public CommonResult<PageInfo<CommunityMessageVO>> messageList(
@RequestBody CommunityMessageRequest request) {
return CommonResult.success(communityService.getMessageList(request));
}
@ApiOperation("审核消息")
@PostMapping("/message/audit")
public CommonResult<String> messageAudit(@RequestBody AuditRequest request) {
communityService.auditMessage(request.getId(), request.getStatus(), request.getRemark());
return CommonResult.success("审核成功");
}
@ApiOperation("删除消息")
@DeleteMapping("/message/delete/{id}")
public CommonResult<String> messageDelete(@PathVariable Long id) {
communityService.deleteMessage(id);
return CommonResult.success("删除成功");
}
// ==================== 匹配配置 ====================
@ApiOperation("获取匹配配置")
@GetMapping("/match/config")
public CommonResult<CommunityMatchConfig> getMatchConfig() {
return CommonResult.success(communityService.getMatchConfig());
}
@ApiOperation("保存匹配配置")
@PostMapping("/match/config/save")
public CommonResult<String> saveMatchConfig(@RequestBody CommunityMatchConfig config) {
communityService.saveMatchConfig(config);
return CommonResult.success("保存成功");
}
}
```
#### WishtreeAdminController.java
文件:`crmeb-admin/src/main/java/com/zbkj/admin/controller/WishtreeAdminController.java`
```java
package com.zbkj.admin.controller;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.wishtree.*;
import com.zbkj.common.request.*;
import com.zbkj.common.response.*;
import com.zbkj.common.result.CommonResult;
import com.zbkj.service.service.WishtreeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/admin/wishtree")
@Api(tags = "许愿树管理")
public class WishtreeAdminController {
@Autowired
private WishtreeService wishtreeService;
// ==================== 节日管理 ====================
@ApiOperation("节日列表")
@GetMapping("/festival/list")
public CommonResult<List<WishtreeFestival>> festivalList() {
return CommonResult.success(wishtreeService.getFestivalList());
}
@ApiOperation("保存节日")
@PostMapping("/festival/save")
public CommonResult<String> festivalSave(@RequestBody WishtreeFestival festival) {
wishtreeService.saveFestival(festival);
return CommonResult.success("保存成功");
}
@ApiOperation("删除节日")
@DeleteMapping("/festival/delete/{id}")
public CommonResult<String> festivalDelete(@PathVariable Integer id) {
wishtreeService.deleteFestival(id);
return CommonResult.success("删除成功");
}
@ApiOperation("更新节日状态")
@PostMapping("/festival/status")
public CommonResult<String> festivalStatus(@RequestBody WishtreeFestival festival) {
wishtreeService.updateFestivalStatus(festival.getId(), festival.getStatus());
return CommonResult.success("更新成功");
}
// ==================== 心愿管理 ====================
@ApiOperation("心愿列表")
@PostMapping("/wish/list")
public CommonResult<PageInfo<WishtreeWishVO>> wishList(@RequestBody WishtreeWishRequest request) {
return CommonResult.success(wishtreeService.getWishList(request));
}
@ApiOperation("审核心愿")
@PostMapping("/wish/audit")
public CommonResult<String> wishAudit(@RequestBody AuditRequest request) {
wishtreeService.auditWish(request.getId(), request.getStatus(), request.getRemark());
return CommonResult.success("审核成功");
}
@ApiOperation("删除心愿")
@DeleteMapping("/wish/delete/{id}")
public CommonResult<String> wishDelete(@PathVariable Long id) {
wishtreeService.deleteWish(id);
return CommonResult.success("删除成功");
}
// ==================== 背景素材 ====================
@ApiOperation("背景列表")
@GetMapping("/background/list")
public CommonResult<List<WishtreeBackground>> backgroundList() {
return CommonResult.success(wishtreeService.getBackgroundList());
}
@ApiOperation("保存背景")
@PostMapping("/background/save")
public CommonResult<String> backgroundSave(@RequestBody WishtreeBackground background) {
wishtreeService.saveBackground(background);
return CommonResult.success("保存成功");
}
@ApiOperation("删除背景")
@DeleteMapping("/background/delete/{id}")
public CommonResult<String> backgroundDelete(@PathVariable Integer id) {
wishtreeService.deleteBackground(id);
return CommonResult.success("删除成功");
}
}
```
### 4.3 Service核心方法
#### CommunityService.java核心方法
```java
@Service
public class CommunityService {
@Autowired
private CommunityCategoryDao categoryDao;
@Autowired
private CommunityMessageDao messageDao;
@Autowired
private CommunityMatchConfigDao matchConfigDao;
@Autowired
private SensitiveWordService sensitiveWordService;
// 板块管理
public List<CommunityCategory> getCategoryList() {
return categoryDao.selectList(new QueryWrapper<CommunityCategory>()
.orderByDesc("sort"));
}
public void saveCategory(CommunityCategory category) {
if (category.getId() != null) {
categoryDao.updateById(category);
} else {
categoryDao.insert(category);
}
}
// 消息管理
public PageInfo<CommunityMessageVO> getMessageList(CommunityMessageRequest request) {
PageHelper.startPage(request.getPage(), request.getLimit());
List<CommunityMessageVO> list = messageDao.selectMessageList(request);
return new PageInfo<>(list);
}
// 自动审核
public void autoAuditMessage(CommunityMessage message) {
CommunityMatchConfig config = getMatchConfig();
if (config.getAutoAudit() != 1) {
message.setStatus(0);
return;
}
List<String> words = sensitiveWordService.findAll(message.getContent());
if (words.isEmpty()) {
message.setStatus(1);
message.setAuditRemark("自动审核通过");
} else {
message.setStatus(0);
message.setAuditRemark("含敏感词:" + String.join(",", words));
}
message.setAuditType(0);
}
// 匹配配置
public CommunityMatchConfig getMatchConfig() {
return matchConfigDao.selectById(1);
}
public void saveMatchConfig(CommunityMatchConfig config) {
config.setId(1);
matchConfigDao.updateById(config);
}
}
```
#### WishtreeService.java核心方法
```java
@Service
public class WishtreeService {
@Autowired
private WishtreeFestivalDao festivalDao;
@Autowired
private WishtreeWishDao wishDao;
@Autowired
private WishtreeBackgroundDao backgroundDao;
@Autowired
private WishtreeLikeDao likeDao;
@Autowired
private WishtreeCommentDao commentDao;
@Autowired
private SensitiveWordService sensitiveWordService;
// ==================== 移动端方法 ====================
// 获取启用的节日列表
public List<WishtreeFestival> getEnabledFestivals() {
return festivalDao.selectList(new QueryWrapper<WishtreeFestival>()
.eq("status", 1)
.orderByDesc("sort"));
}
// 获取当前进行中的节日
public WishtreeFestival getCurrentFestival() {
// 根据当前日期匹配节日
return festivalDao.selectCurrentFestival();
}
// 获取心愿列表(移动端)
public PageInfo<WishtreeWishVO> getFrontWishList(Integer festivalId, Integer page, Integer limit) {
PageHelper.startPage(page, limit);
List<WishtreeWishVO> list = wishDao.selectFrontWishList(festivalId);
return new PageInfo<>(list);
}
// 获取我的心愿列表
public PageInfo<WishtreeWishVO> getMyWishList(Integer page, Integer limit) {
Integer uid = SecurityUtil.getLoginUserVo().getUser().getId();
PageHelper.startPage(page, limit);
List<WishtreeWishVO> list = wishDao.selectMyWishList(uid);
return new PageInfo<>(list);
}
// 发布心愿(自动审核)
@Transactional
public WishtreeWish publishWish(WishtreeWishRequest request) {
Integer uid = SecurityUtil.getLoginUserVo().getUser().getId();
WishtreeWish wish = new WishtreeWish();
wish.setUid(uid);
wish.setFestivalId(request.getFestivalId());
wish.setContent(request.getContent());
wish.setBackgroundId(request.getBackgroundId());
wish.setLikeCount(0);
wish.setCommentCount(0);
wish.setIsDelete(0);
// 自动审核
autoAuditWish(wish);
wishDao.insert(wish);
return wish;
}
// 删除我的心愿
public void deleteMyWish(Long id) {
Integer uid = SecurityUtil.getLoginUserVo().getUser().getId();
WishtreeWish wish = wishDao.selectById(id);
if (wish != null && wish.getUid().equals(uid)) {
wish.setIsDelete(1);
wishDao.updateById(wish);
}
}
// 点赞心愿
@Transactional
public void likeWish(Long wishId) {
Integer uid = SecurityUtil.getLoginUserVo().getUser().getId();
// 检查是否已点赞
WishtreeLike existing = likeDao.selectOne(new QueryWrapper<WishtreeLike>()
.eq("uid", uid).eq("wish_id", wishId));
if (existing != null) return;
// 添加点赞记录
WishtreeLike like = new WishtreeLike();
like.setUid(uid);
like.setWishId(wishId);
likeDao.insert(like);
// 更新点赞数
wishDao.incrementLikeCount(wishId);
}
// 取消点赞
@Transactional
public void unlikeWish(Long wishId) {
Integer uid = SecurityUtil.getLoginUserVo().getUser().getId();
likeDao.delete(new QueryWrapper<WishtreeLike>()
.eq("uid", uid).eq("wish_id", wishId));
wishDao.decrementLikeCount(wishId);
}
// 发表评论
@Transactional
public WishtreeComment addComment(Long wishId, WishtreeCommentRequest request) {
Integer uid = SecurityUtil.getLoginUserVo().getUser().getId();
WishtreeComment comment = new WishtreeComment();
comment.setWishId(wishId);
comment.setUid(uid);
comment.setContent(request.getContent());
comment.setStatus(1); // 自动通过或待审核
// 自动审核评论
List<String> words = sensitiveWordService.findAll(request.getContent());
if (!words.isEmpty()) {
comment.setStatus(0); // 待审核
}
commentDao.insert(comment);
// 更新评论数
if (comment.getStatus() == 1) {
wishDao.incrementCommentCount(wishId);
}
return comment;
}
// ==================== 管理端方法 ====================
// 节日管理
public List<WishtreeFestival> getFestivalList() {
return festivalDao.selectList(new QueryWrapper<WishtreeFestival>()
.orderByDesc("sort"));
}
public void saveFestival(WishtreeFestival festival) {
if (festival.getId() != null) {
festivalDao.updateById(festival);
} else {
festivalDao.insert(festival);
}
}
// 心愿管理
public PageInfo<WishtreeWishVO> getWishList(WishtreeWishRequest request) {
PageHelper.startPage(request.getPage(), request.getLimit());
List<WishtreeWishVO> list = wishDao.selectWishList(request);
return new PageInfo<>(list);
}
// 自动审核心愿
public void autoAuditWish(WishtreeWish wish) {
List<String> words = sensitiveWordService.findAll(wish.getContent());
if (words.isEmpty()) {
wish.setStatus(1);
wish.setAuditRemark("自动审核通过");
} else {
wish.setStatus(0);
wish.setAuditRemark("含敏感词:" + String.join(",", words));
}
wish.setAuditType(0);
}
// 数据统计
public WishtreeStatisticsVO getStatistics() {
WishtreeStatisticsVO vo = new WishtreeStatisticsVO();
vo.setTotalWishes(wishDao.countTotal());
vo.setTodayWishes(wishDao.countToday());
vo.setPendingWishes(wishDao.countPending());
vo.setTotalLikes(wishDao.sumLikes());
return vo;
}
// 背景素材
public List<WishtreeBackground> getBackgroundList() {
return backgroundDao.selectList(new QueryWrapper<WishtreeBackground>()
.orderByDesc("sort"));
}
public List<WishtreeBackground> getEnabledBackgrounds() {
return backgroundDao.selectList(new QueryWrapper<WishtreeBackground>()
.eq("status", 1)
.orderByDesc("sort"));
}
}
```
---
## 五、数据库设计
### 5.1 缘池相关表
```sql
-- ============================================
-- 缘池管理数据库表
-- ============================================
-- 1. 板块表
CREATE TABLE `eb_community_category` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '板块ID',
`name` varchar(50) NOT NULL COMMENT '板块名称',
`icon` varchar(255) DEFAULT '' COMMENT '图标',
`type` varchar(20) DEFAULT 'card' COMMENT '类型 quick=快捷入口 card=功能卡片',
`jump_page` varchar(100) DEFAULT '' COMMENT '跳转页面',
`sort` int DEFAULT 0 COMMENT '排序',
`status` tinyint DEFAULT 1 COMMENT '状态 0禁用 1启用',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缘池板块表';
-- 2. 消息表
CREATE TABLE `eb_community_message` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '消息ID',
`uid` int NOT NULL COMMENT '用户ID',
`category_id` int NOT NULL COMMENT '板块ID',
`content` text COMMENT '消息内容',
`images` varchar(1000) DEFAULT '' COMMENT '图片(逗号分隔)',
`status` tinyint DEFAULT 1 COMMENT '状态 0待审核 1通过 2拒绝',
`audit_type` tinyint DEFAULT 0 COMMENT '审核方式 0自动 1人工',
`audit_remark` varchar(255) DEFAULT '' COMMENT '审核备注',
`is_delete` tinyint DEFAULT 0 COMMENT '是否删除',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_uid` (`uid`),
KEY `idx_category` (`category_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缘池消息表';
-- 3. 匹配配置表
CREATE TABLE `eb_community_match_config` (
`id` int NOT NULL AUTO_INCREMENT,
`match_radius` int DEFAULT 5 COMMENT '匹配半径(公里)',
`recommend_count` int DEFAULT 6 COMMENT '推荐用户数',
`priority_online` tinyint DEFAULT 1 COMMENT '优先在线用户',
`priority_same_city` tinyint DEFAULT 1 COMMENT '优先同城用户',
`priority_opposite_sex` tinyint DEFAULT 1 COMMENT '优先异性用户',
`auto_audit` tinyint DEFAULT 1 COMMENT '自动审核开关',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缘池匹配配置表';
-- 初始化匹配配置
INSERT INTO `eb_community_match_config` VALUES (1, 5, 6, 1, 1, 1, 1, NOW());
-- 初始化板块数据
INSERT INTO `eb_community_category` (`name`, `icon`, `type`, `jump_page`, `sort`) VALUES
('语音匹配', 'el-icon-microphone', 'quick', 'VoiceMatchActivity', 100),
('心动信号', 'el-icon-star-on', 'quick', 'HeartbeatSignalActivity', 99),
('在线处对象', 'el-icon-user', 'card', 'OnlineDatingActivity', 90),
('找人玩游戏', 'el-icon-video-play', 'card', 'FindGameActivity', 89),
('一起KTV', 'el-icon-headset', 'card', 'KTVTogetherActivity', 88),
('你画我猜', 'el-icon-edit', 'card', 'DrawGuessActivity', 87),
('和平精英', 'el-icon-aim', 'card', 'PeaceEliteActivity', 86),
('桌游', 'el-icon-s-grid', 'card', 'TableGamesActivity', 85);
```
### 5.2 许愿树相关表
```sql
-- ============================================
-- 许愿树管理数据库表
-- ============================================
-- 1. 节日表
CREATE TABLE `eb_wishtree_festival` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '节日ID',
`name` varchar(50) NOT NULL COMMENT '节日名称',
`icon` varchar(255) DEFAULT '' COMMENT '节日图标',
`start_date` varchar(20) DEFAULT '' COMMENT '开始日期(MM-DD或农历)',
`end_date` varchar(20) DEFAULT '' COMMENT '结束日期',
`is_lunar` tinyint DEFAULT 0 COMMENT '是否农历 0否 1是',
`theme_color` varchar(20) DEFAULT '#FF6B6B' COMMENT '主题色',
`sort` int DEFAULT 0 COMMENT '排序',
`status` tinyint DEFAULT 1 COMMENT '状态 0禁用 1启用',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树节日表';
-- 2. 心愿表
CREATE TABLE `eb_wishtree_wish` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '心愿ID',
`uid` int NOT NULL COMMENT '用户ID',
`festival_id` int DEFAULT 0 COMMENT '节日ID',
`content` varchar(500) NOT NULL COMMENT '心愿内容',
`background_id` int DEFAULT 0 COMMENT '背景ID',
`status` tinyint DEFAULT 1 COMMENT '状态 0待审核 1通过 2拒绝',
`audit_type` tinyint DEFAULT 0 COMMENT '审核方式 0自动 1人工',
`audit_remark` varchar(255) DEFAULT '' COMMENT '审核备注',
`like_count` int DEFAULT 0 COMMENT '点赞数',
`comment_count` int DEFAULT 0 COMMENT '评论数',
`is_delete` tinyint DEFAULT 0 COMMENT '是否删除',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_uid` (`uid`),
KEY `idx_festival` (`festival_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树心愿表';
-- 3. 心愿点赞表
CREATE TABLE `eb_wishtree_like` (
`id` bigint NOT NULL AUTO_INCREMENT,
`uid` int NOT NULL COMMENT '用户ID',
`wish_id` bigint NOT NULL COMMENT '心愿ID',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_uid_wish` (`uid`, `wish_id`),
KEY `idx_wish` (`wish_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树点赞表';
-- 4. 心愿评论表
CREATE TABLE `eb_wishtree_comment` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '评论ID',
`wish_id` bigint NOT NULL COMMENT '心愿ID',
`uid` int NOT NULL COMMENT '用户ID',
`content` varchar(255) NOT NULL COMMENT '评论内容',
`parent_id` bigint DEFAULT 0 COMMENT '父评论ID',
`status` tinyint DEFAULT 1 COMMENT '状态 0待审核 1通过 2拒绝',
`is_delete` tinyint DEFAULT 0 COMMENT '是否删除',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_wish` (`wish_id`),
KEY `idx_uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树评论表';
-- 5. 背景素材表
CREATE TABLE `eb_wishtree_background` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '背景ID',
`name` varchar(50) NOT NULL COMMENT '背景名称',
`image` varchar(255) NOT NULL COMMENT '背景图片',
`festival_id` int DEFAULT 0 COMMENT '关联节日ID(0=通用)',
`sort` int DEFAULT 0 COMMENT '排序',
`status` tinyint DEFAULT 1 COMMENT '状态',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树背景素材表';
-- 初始化节日数据
INSERT INTO `eb_wishtree_festival` (`name`, `icon`, `start_date`, `end_date`, `is_lunar`, `theme_color`, `sort`) VALUES
('元旦', '🎉', '12-31', '01-03', 0, '#FF6B6B', 100),
('春节', '🧧', '除夕', '正月十五', 1, '#E74C3C', 99),
('情人节', '💕', '02-13', '02-15', 0, '#FF69B4', 98),
('妇女节', '🌸', '03-07', '03-09', 0, '#FFB6C1', 97),
('清明节', '🌿', '清明', '清明后2天', 1, '#90EE90', 96),
('劳动节', '💪', '04-30', '05-03', 0, '#FFA500', 95),
('母亲节', '🌹', '5月第2周日', '5月第2周日', 0, '#FF1493', 94),
('儿童节', '🎈', '05-31', '06-02', 0, '#87CEEB', 93),
('端午节', '🐲', '五月初五', '五月初七', 1, '#228B22', 92),
('七夕', '🌙', '七月初七', '七月初七', 1, '#9370DB', 91),
('中秋节', '🥮', '八月十五', '八月十七', 1, '#FFD700', 90),
('国庆节', '🇨🇳', '09-30', '10-07', 0, '#FF0000', 89),
('圣诞节', '🎄', '12-24', '12-26', 0, '#228B22', 88),
('生日祝福', '🎂', '全年', '全年', 0, '#FF69B4', 50),
('日常祝福', '✨', '全年', '全年', 0, '#9B59B6', 49);
```
---
## 六、实体类设计
### 6.1 缘池实体类
```java
// CommunityCategory.java
@Data
@TableName("eb_community_category")
public class CommunityCategory {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String icon;
private String type; // quick=快捷入口 card=功能卡片
private String jumpPage; // 跳转页面
private Integer sort;
private Integer status;
private Date createTime;
private Date updateTime;
}
// CommunityMessage.java
@Data
@TableName("eb_community_message")
public class CommunityMessage {
@TableId(type = IdType.AUTO)
private Long id;
private Integer uid;
private Integer categoryId;
private String content;
private String images;
private Integer status;
private Integer auditType;
private String auditRemark;
private Integer isDelete;
private Date createTime;
private Date updateTime;
}
// CommunityMatchConfig.java
@Data
@TableName("eb_community_match_config")
public class CommunityMatchConfig {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer matchRadius; // 匹配半径
private Integer recommendCount; // 推荐用户数
private Integer priorityOnline; // 优先在线
private Integer prioritySameCity; // 优先同城
private Integer priorityOppositeSex; // 优先异性
private Integer autoAudit; // 自动审核
private Date updateTime;
}
```
### 6.2 许愿树实体类
```java
// WishtreeFestival.java
@Data
@TableName("eb_wishtree_festival")
public class WishtreeFestival {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String icon;
private String startDate;
private String endDate;
private Integer isLunar; // 是否农历
private String themeColor;
private Integer sort;
private Integer status;
private Date createTime;
private Date updateTime;
}
// WishtreeWish.java
@Data
@TableName("eb_wishtree_wish")
public class WishtreeWish {
@TableId(type = IdType.AUTO)
private Long id;
private Integer uid;
private Integer festivalId;
private String content;
private Integer backgroundId;
private Integer status;
private Integer auditType;
private String auditRemark;
private Integer likeCount;
private Integer commentCount;
private Integer isDelete;
private Date createTime;
private Date updateTime;
}
// WishtreeLike.java
@Data
@TableName("eb_wishtree_like")
public class WishtreeLike {
@TableId(type = IdType.AUTO)
private Long id;
private Integer uid;
private Long wishId;
private Date createTime;
}
// WishtreeComment.java
@Data
@TableName("eb_wishtree_comment")
public class WishtreeComment {
@TableId(type = IdType.AUTO)
private Long id;
private Long wishId;
private Integer uid;
private String content;
private Long parentId;
private Integer status;
private Integer isDelete;
private Date createTime;
}
// WishtreeBackground.java
@Data
@TableName("eb_wishtree_background")
public class WishtreeBackground {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String image;
private Integer festivalId;
private Integer sort;
private Integer status;
private Date createTime;
}
```
### 6.3 VO/Request类
```java
// WishtreeWishVO.java - 心愿响应VO
@Data
public class WishtreeWishVO {
private Long id;
private Integer uid;
private String nickname;
private String avatar;
private Integer festivalId;
private String festivalName;
private String festivalIcon;
private String content;
private Integer backgroundId;
private String backgroundImage;
private Integer status;
private Integer auditType;
private String auditRemark;
private Integer likeCount;
private Integer commentCount;
private Boolean isLiked; // 当前用户是否已点赞
private Date createTime;
}
// WishtreeWishRequest.java - 发布心愿请求
@Data
public class WishtreeWishRequest {
private Integer festivalId;
private String content;
private Integer backgroundId;
// 管理端查询用
private Integer page;
private Integer limit;
private Integer status;
}
// WishtreeCommentVO.java - 评论响应VO
@Data
public class WishtreeCommentVO {
private Long id;
private Long wishId;
private Integer uid;
private String nickname;
private String avatar;
private String content;
private Long parentId;
private Integer status;
private Date createTime;
}
// WishtreeCommentRequest.java - 发表评论请求
@Data
public class WishtreeCommentRequest {
private String content;
private Long parentId;
}
// WishtreeStatisticsVO.java - 统计数据VO
@Data
public class WishtreeStatisticsVO {
private Integer totalWishes;
private Integer todayWishes;
private Integer pendingWishes;
private Integer totalLikes;
private List<FestivalStatVO> festivalStats;
private List<WishtreeWishVO> hotWishes;
}
```
---
## 七、文件清单
### 7.1 前端文件
```
Zhibo/admin/src/
├── api/
│ ├── community.js # 缘池API
│ └── wishtree.js # 许愿树API
├── router/modules/
│ ├── communityManage.js # 缘池路由
│ └── wishtreeManage.js # 许愿树路由
└── views/
├── community/
│ ├── category/index.vue # 板块管理
│ ├── message/index.vue # 消息管理
│ └── matchConfig/index.vue # 匹配配置
└── wishtree/
├── festival/index.vue # 节日管理
├── wish/index.vue # 心愿管理
└── background/index.vue # 背景素材
```
### 7.2 后端文件
```
Zhibo/zhibo-h/
├── crmeb-admin/src/main/java/com/zbkj/admin/controller/
│ ├── CommunityAdminController.java # 缘池管理端
│ └── WishtreeAdminController.java # 许愿树管理端
├── crmeb-front/src/main/java/com/zbkj/front/controller/
│ ├── CommunityFrontController.java # 缘池移动端API
│ └── WishtreeFrontController.java # 许愿树移动端API
├── crmeb-service/src/main/java/com/zbkj/service/
│ ├── service/
│ │ ├── CommunityService.java
│ │ └── WishtreeService.java
│ └── dao/
│ ├── CommunityCategoryDao.java
│ ├── CommunityMessageDao.java
│ ├── CommunityMatchConfigDao.java
│ ├── WishtreeFestivalDao.java
│ ├── WishtreeWishDao.java
│ ├── WishtreeLikeDao.java
│ ├── WishtreeCommentDao.java
│ └── WishtreeBackgroundDao.java
└── crmeb-common/src/main/java/com/zbkj/common/
├── model/
│ ├── community/
│ │ ├── CommunityCategory.java
│ │ ├── CommunityMessage.java
│ │ └── CommunityMatchConfig.java
│ └── wishtree/
│ ├── WishtreeFestival.java
│ ├── WishtreeWish.java
│ ├── WishtreeLike.java
│ ├── WishtreeComment.java
│ └── WishtreeBackground.java
├── request/
│ ├── WishtreeWishRequest.java
│ └── WishtreeCommentRequest.java
└── response/
├── WishtreeWishVO.java
├── WishtreeCommentVO.java
└── WishtreeStatisticsVO.java
```
### 7.3 数据库表
```
缘池:
├── eb_community_category # 板块表
├── eb_community_message # 消息表
└── eb_community_match_config # 匹配配置表
许愿树:
├── eb_wishtree_festival # 节日表
├── eb_wishtree_wish # 心愿表
├── eb_wishtree_like # 点赞表
├── eb_wishtree_comment # 评论表
└── eb_wishtree_background # 背景素材表
```
---
## 八、菜单配置SQL
```sql
-- 缘池管理菜单
INSERT INTO `eb_system_menu` (`pid`, `name`, `icon`, `perms`, `component`, `menu_type`, `sort`, `is_show`) VALUES
(0, '缘池管理', 'el-icon-s-opportunity', '', '/community', 'M', 140, 1);
SET @community_id = LAST_INSERT_ID();
INSERT INTO `eb_system_menu` (`pid`, `name`, `perms`, `component`, `menu_type`, `sort`, `is_show`) VALUES
(@community_id, '板块管理', 'admin:community:category', '/community/category', 'C', 3, 1),
(@community_id, '消息管理', 'admin:community:message', '/community/message', 'C', 2, 1),
(@community_id, '匹配配置', 'admin:community:match', '/community/match-config', 'C', 1, 1);
-- 许愿树管理菜单
INSERT INTO `eb_system_menu` (`pid`, `name`, `icon`, `perms`, `component`, `menu_type`, `sort`, `is_show`) VALUES
(0, '许愿树管理', 'el-icon-present', '', '/wishtree', 'M', 139, 1);
SET @wishtree_id = LAST_INSERT_ID();
INSERT INTO `eb_system_menu` (`pid`, `name`, `perms`, `component`, `menu_type`, `sort`, `is_show`) VALUES
(@wishtree_id, '节日管理', 'admin:wishtree:festival', '/wishtree/festival', 'C', 4, 1),
(@wishtree_id, '心愿管理', 'admin:wishtree:wish', '/wishtree/wish', 'C', 3, 1),
(@wishtree_id, '背景素材', 'admin:wishtree:background', '/wishtree/background', 'C', 2, 1),
(@wishtree_id, '数据统计', 'admin:wishtree:statistics', '/wishtree/statistics', 'C', 1, 1);
```
---
## 九、移动端改造说明
### 9.1 WishTreeActivity改造
原本地存储改为API调用
```java
// 原代码(本地存储)
private void loadWishes() {
for (int i = 0; i < 7; i++) {
wishes[i] = prefs.getString("wish_" + i, "");
}
}
// 新代码API调用
private void loadWishes() {
ApiService.getInstance()
.getMyWishes(1, 10)
.enqueue(new Callback<ApiResponse<PageData<WishVO>>>() {
@Override
public void onResponse(Call<ApiResponse<PageData<WishVO>>> call,
Response<ApiResponse<PageData<WishVO>>> response) {
if (response.isSuccessful() && response.body() != null) {
List<WishVO> list = response.body().getData().getList();
updateWishCards(list);
}
}
@Override
public void onFailure(Call<ApiResponse<PageData<WishVO>>> call, Throwable t) {
Toast.makeText(WishTreeActivity.this, "加载失败", Toast.LENGTH_SHORT).show();
}
});
}
```
### 9.2 ApiService接口定义
```java
public interface ApiService {
// ==================== 许愿树API ====================
@GET("api/front/wishtree/festivals")
Call<ApiResponse<List<Festival>>> getFestivals();
@GET("api/front/wishtree/festivals/current")
Call<ApiResponse<Festival>> getCurrentFestival();
@GET("api/front/wishtree/wishes")
Call<ApiResponse<PageData<WishVO>>> getWishes(
@Query("festivalId") Integer festivalId,
@Query("page") int page,
@Query("limit") int limit
);
@GET("api/front/wishtree/wishes/my")
Call<ApiResponse<PageData<WishVO>>> getMyWishes(
@Query("page") int page,
@Query("limit") int limit
);
@POST("api/front/wishtree/wishes")
Call<ApiResponse<Wish>> publishWish(@Body WishRequest request);
@DELETE("api/front/wishtree/wishes/{id}")
Call<ApiResponse<String>> deleteWish(@Path("id") long id);
@POST("api/front/wishtree/wishes/{id}/like")
Call<ApiResponse<String>> likeWish(@Path("id") long id);
@DELETE("api/front/wishtree/wishes/{id}/like")
Call<ApiResponse<String>> unlikeWish(@Path("id") long id);
@GET("api/front/wishtree/wishes/{id}/comments")
Call<ApiResponse<PageData<CommentVO>>> getComments(
@Path("id") long wishId,
@Query("page") int page,
@Query("limit") int limit
);
@POST("api/front/wishtree/wishes/{id}/comments")
Call<ApiResponse<Comment>> addComment(
@Path("id") long wishId,
@Body CommentRequest request
);
@GET("api/front/wishtree/backgrounds")
Call<ApiResponse<List<Background>>> getBackgrounds();
}
```
### 9.3 数据模型类
```java
// WishVO.java
@Data
public class WishVO {
private Long id;
private Integer uid;
private String nickname;
private String avatar;
private Integer festivalId;
private String festivalName;
private String festivalIcon;
private String content;
private String backgroundImage;
private Integer likeCount;
private Integer commentCount;
private Boolean isLiked;
private String createTime;
}
// WishRequest.java
@Data
public class WishRequest {
private Integer festivalId;
private String content;
private Integer backgroundId;
}
// CommentVO.java
@Data
public class CommentVO {
private Long id;
private Integer uid;
private String nickname;
private String avatar;
private String content;
private String createTime;
}
// CommentRequest.java
@Data
public class CommentRequest {
private String content;
}
```
---
## 十、开发顺序
1. **数据库** - 执行建表SQL8张表
2. **后端实体类** - 创建Model、VO、Request类
3. **后端DAO** - 创建DAO接口和Mapper
4. **后端Service** - 实现业务逻辑(含自动审核)
5. **后端Controller** - 实现管理端API + 移动端API
6. **前端API** - 创建管理端接口文件
7. **前端路由** - 配置路由并注册
8. **前端页面** - 实现7个管理页面
9. **菜单配置** - 执行菜单SQL
10. **移动端改造** - 修改WishTreeActivity接入API
---
## 十一、关键改动总结
| 项目 | 原方案 | 新方案 |
|------|--------|--------|
| 数据存储 | SharedPreferences | MySQL数据库 |
| 数据同步 | 无 | 实时API同步 |
| 心愿数量 | 固定7个 | 无限制 |
| 用户互动 | 无 | 点赞、评论 |
| 内容审核 | 无 | 自动+人工审核 |
| 多端访问 | 单设备 | 多端同步 |
| 数据统计 | 无 | 管理端统计 |
| 节日活动 | 无 | 可配置节日 |