12月30号最后的管理端界面优化,前后端配置,数据添加测试

This commit is contained in:
cxytw 2025-12-30 20:36:50 +08:00
parent eb5daad9de
commit fe46b0ebac
74 changed files with 7508 additions and 160 deletions

View File

@ -0,0 +1,40 @@
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 });
}

View File

@ -11,3 +11,7 @@ export function familyLevelCreateApi(data) {
export function familyLevelUpdateApi(data) {
return request({ url: '/admin/family/level/update', method: 'post', data })
}
export function familyLevelDeleteApi(id) {
return request({ url: `/admin/family/level/delete/${id}`, method: 'post' })
}

View File

@ -0,0 +1,53 @@
import request from '@/utils/request';
// ==================== 节日管理 ====================
export function festivalList() {
return request({ url: 'admin/wishtree/festival/list', method: 'get' });
}
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() {
return request({ url: 'admin/wishtree/background/list', method: 'get' });
}
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 });
}

View File

@ -31,6 +31,8 @@ import contentManageRouter from './modules/contentManage'; // 内容管理
import feedbackManageRouter from './modules/feedbackManage'; // 用户反馈
import agentManageRouter from './modules/agentManage'; // 代理管理
import systemSettingRouter from './modules/systemSetting'; // 系统设置
import communityManageRouter from './modules/communityManage'; // 缘池管理
import wishtreeManageRouter from './modules/wishtreeManage'; // 许愿树管理
/**
* Note: sub-menu only appear when route children.length >= 1
@ -104,6 +106,10 @@ export const constantRoutes = [
agentManageRouter,
// 14. 系统设置
systemSettingRouter,
// 15. 缘池管理
communityManageRouter,
// 16. 许愿树管理
wishtreeManageRouter,
// 系统页面
{
path: '/404',

View File

@ -0,0 +1,35 @@
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;

View File

@ -0,0 +1,41 @@
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;

View File

@ -0,0 +1,137 @@
<template>
<div class="app-container">
<el-card>
<div slot="header">
<el-button type="primary" size="small" @click="handleAdd">新增板块</el-button>
</div>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="icon" label="图标" width="80" align="center">
<template slot-scope="scope">
<i :class="scope.row.icon" style="font-size: 24px;"></i>
</template>
</el-table-column>
<el-table-column prop="name" label="名称" width="150" />
<el-table-column prop="type" label="类型" width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.type === 'quick' ? 'success' : 'primary'" size="small">
{{ scope.row.type === 'quick' ? '快捷入口' : '功能卡片' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="jumpPage" label="跳转页面" />
<el-table-column prop="sort" label="排序" width="80" align="center" />
<el-table-column prop="status" label="状态" width="100" align="center">
<template slot-scope="scope">
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0"
@change="handleStatusChange(scope.row)" />
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center">
<template slot-scope="scope">
<el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 编辑弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="板块名称" prop="name">
<el-input v-model="form.name" placeholder="请输入板块名称" />
</el-form-item>
<el-form-item label="图标" prop="icon">
<el-input v-model="form.icon" placeholder="请输入图标类名,如 el-icon-star-on" />
</el-form-item>
<el-form-item label="类型" prop="type">
<el-radio-group v-model="form.type">
<el-radio label="quick">快捷入口</el-radio>
<el-radio label="card">功能卡片</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="跳转页面" prop="jumpPage">
<el-input v-model="form.jumpPage" placeholder="请输入跳转页面Activity名称" />
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="form.sort" :min="0" :max="999" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { categoryList, categorySave, categoryDelete, categoryStatus } from '@/api/community';
export default {
name: 'CommunityCategory',
data() {
return {
tableData: [],
dialogVisible: false,
dialogTitle: '新增板块',
form: {
id: null,
name: '',
icon: '',
type: 'card',
jumpPage: '',
sort: 0,
status: 1
},
rules: {
name: [{ required: true, message: '请输入板块名称', trigger: 'blur' }],
type: [{ required: true, message: '请选择类型', trigger: 'change' }]
}
};
},
created() {
this.getList();
},
methods: {
async getList() {
const res = await categoryList();
this.tableData = res || [];
},
handleAdd() {
this.dialogTitle = '新增板块';
this.form = { id: null, name: '', icon: '', type: 'card', jumpPage: '', sort: 0, status: 1 };
this.dialogVisible = true;
},
handleEdit(row) {
this.dialogTitle = '编辑板块';
this.form = { ...row };
this.dialogVisible = true;
},
async handleSubmit() {
this.$refs.form.validate(async (valid) => {
if (valid) {
await categorySave(this.form);
this.$message.success('保存成功');
this.dialogVisible = false;
this.getList();
}
});
},
async handleStatusChange(row) {
await categoryStatus({ id: row.id, status: row.status });
this.$message.success('状态更新成功');
},
handleDelete(row) {
this.$confirm('确定删除该板块吗?', '提示', { type: 'warning' }).then(async () => {
await categoryDelete(row.id);
this.$message.success('删除成功');
this.getList();
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,66 @@
<template>
<div class="app-container">
<el-card>
<div slot="header">用户匹配配置</div>
<el-form ref="form" :model="form" label-width="150px" style="max-width: 500px;">
<el-form-item label="匹配半径(公里)">
<el-input-number v-model="form.matchRadius" :min="1" :max="100" />
</el-form-item>
<el-form-item label="每次推荐用户数">
<el-input-number v-model="form.recommendCount" :min="1" :max="20" />
</el-form-item>
<el-form-item label="优先显示在线用户">
<el-switch v-model="form.priorityOnline" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item label="优先显示同城用户">
<el-switch v-model="form.prioritySameCity" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item label="优先显示异性用户">
<el-switch v-model="form.priorityOppositeSex" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item label="自动审核开关">
<el-switch v-model="form.autoAudit" :active-value="1" :inactive-value="0" />
<span style="margin-left: 10px; color: #909399; font-size: 12px;">开启后消息将自动审核通过</span>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSave">保存配置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import { getMatchConfig, saveMatchConfig } from '@/api/community';
export default {
name: 'MatchConfig',
data() {
return {
form: {
matchRadius: 5,
recommendCount: 6,
priorityOnline: 1,
prioritySameCity: 1,
priorityOppositeSex: 1,
autoAudit: 1
}
};
},
created() {
this.getConfig();
},
methods: {
async getConfig() {
const res = await getMatchConfig();
if (res) {
this.form = res;
}
},
async handleSave() {
await saveMatchConfig(this.form);
this.$message.success('保存成功');
}
}
};
</script>

View File

@ -0,0 +1,152 @@
<template>
<div class="app-container">
<el-card>
<!-- 搜索栏 -->
<el-form :inline="true" :model="queryParams" class="search-form">
<el-form-item label="板块">
<el-select v-model="queryParams.categoryId" placeholder="全部" clearable style="width: 150px;">
<el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="queryParams.status" placeholder="全部" clearable style="width: 120px;">
<el-option label="待审核" :value="0" />
<el-option label="已通过" :value="1" />
<el-option label="已拒绝" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="时间">
<el-date-picker v-model="dateRange" type="daterange" range-separator="-"
start-placeholder="开始" end-placeholder="结束" value-format="yyyy-MM-dd" style="width: 240px;" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
<!-- 表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column label="用户" width="150">
<template slot-scope="scope">
<div style="display: flex; align-items: center;">
<el-avatar :src="scope.row.avatar" size="small" />
<span style="margin-left: 8px;">{{ scope.row.nickname }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="categoryName" label="板块" width="120" />
<el-table-column prop="content" label="内容" show-overflow-tooltip />
<el-table-column prop="status" label="状态" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="statusType(scope.row.status)" size="small">{{ statusText(scope.row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="审核" width="80" align="center">
<template slot-scope="scope">
{{ scope.row.auditType === 0 ? '自动' : '人工' }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="时间" width="160" />
<el-table-column label="操作" width="150" align="center">
<template slot-scope="scope">
<template v-if="scope.row.status === 0">
<el-button type="text" style="color: #67C23A;" @click="handleAudit(scope.row, 1)">通过</el-button>
<el-button type="text" style="color: #F56C6C;" @click="handleAudit(scope.row, 2)">拒绝</el-button>
</template>
<el-button type="text" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination background layout="total, sizes, prev, pager, next" :total="total"
:page-size="queryParams.limit" :current-page="queryParams.page"
@size-change="handleSizeChange" @current-change="handlePageChange" style="margin-top: 20px;" />
</el-card>
</div>
</template>
<script>
import { messageList, messageAudit, messageDelete, categoryList } from '@/api/community';
export default {
name: 'CommunityMessage',
data() {
return {
tableData: [],
total: 0,
categoryOptions: [],
dateRange: [],
queryParams: {
categoryId: null,
status: null,
startTime: '',
endTime: '',
page: 1,
limit: 20
}
};
},
created() {
this.getCategories();
this.getList();
},
methods: {
async getCategories() {
const res = await categoryList();
this.categoryOptions = res || [];
},
async getList() {
if (this.dateRange && this.dateRange.length === 2) {
this.queryParams.startTime = this.dateRange[0] + ' 00:00:00';
this.queryParams.endTime = this.dateRange[1] + ' 23:59:59';
} else {
this.queryParams.startTime = '';
this.queryParams.endTime = '';
}
const res = await messageList(this.queryParams);
this.tableData = res && res.list ? res.list : [];
this.total = res && res.total ? res.total : 0;
},
statusType(status) {
return { 0: 'warning', 1: 'success', 2: 'danger' }[status] || 'info';
},
statusText(status) {
return { 0: '待审核', 1: '已通过', 2: '已拒绝' }[status] || '未知';
},
handleSearch() {
this.queryParams.page = 1;
this.getList();
},
handleReset() {
this.queryParams = { categoryId: null, status: null, startTime: '', endTime: '', page: 1, limit: 20 };
this.dateRange = [];
this.getList();
},
handleSizeChange(val) {
this.queryParams.limit = val;
this.getList();
},
handlePageChange(val) {
this.queryParams.page = val;
this.getList();
},
handleAudit(row, status) {
const action = status === 1 ? '通过' : '拒绝';
this.$confirm(`确定${action}该消息吗?`, '提示', { type: 'warning' }).then(async () => {
await messageAudit({ id: row.id, status, remark: `人工审核${action}` });
this.$message.success('审核成功');
this.getList();
}).catch(() => {});
},
handleDelete(row) {
this.$confirm('确定删除该消息吗?', '提示', { type: 'warning' }).then(async () => {
await messageDelete(row.id);
this.$message.success('删除成功');
this.getList();
}).catch(() => {});
}
}
};
</script>

View File

@ -9,12 +9,12 @@
<el-table v-loading="loading" :data="tableData" border>
<el-table-column prop="name" label="级别名称" min-width="120" />
<el-table-column prop="level" label="级别" width="80" />
<el-table-column prop="min_prestige" label="升级最小威望值" min-width="150" />
<el-table-column prop="max_prestige" label="升级最大威望值" min-width="150" />
<el-table-column prop="max_members" label="家族成员最大数量" min-width="150" />
<el-table-column label="操作" width="100" align="center" fixed="right">
<el-table-column prop="min_contribution" label="升级最小贡献值" min-width="150" />
<el-table-column prop="max_member" label="家族成员最大数量" min-width="150" />
<el-table-column label="操作" width="150" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="warning" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
@ -46,16 +46,12 @@
<el-col :span="16"><el-input v-model.number="form.level" placeholder="请输入级别"></el-input></el-col>
</el-row>
<el-row class="form-row">
<el-col :span="8" class="form-label">最小威望值</el-col>
<el-col :span="16"><el-input v-model.number="form.min_prestige" placeholder="请输入最小威望值"></el-input></el-col>
</el-row>
<el-row class="form-row">
<el-col :span="8" class="form-label">最大威望值</el-col>
<el-col :span="16"><el-input v-model.number="form.max_prestige" placeholder="请输入最大威望值"></el-input></el-col>
<el-col :span="8" class="form-label">最小贡献值</el-col>
<el-col :span="16"><el-input v-model.number="form.minContribution" placeholder="请输入最小贡献值"></el-input></el-col>
</el-row>
<el-row class="form-row">
<el-col :span="8" class="form-label">家族成员上限</el-col>
<el-col :span="16"><el-input v-model.number="form.max_members" placeholder="请输入家族成员上限"></el-input></el-col>
<el-col :span="16"><el-input v-model.number="form.maxMember" placeholder="请输入家族成员上限"></el-input></el-col>
</el-row>
</div>
<div slot="footer" class="dialog-footer" style="text-align: center;">
@ -67,7 +63,7 @@
</template>
<script>
import { familyLevelListApi, familyLevelCreateApi, familyLevelUpdateApi } from '@/api/familyLevel'
import { familyLevelListApi, familyLevelCreateApi, familyLevelUpdateApi, familyLevelDeleteApi } from '@/api/familyLevel'
export default {
name: 'FamilyLevel',
@ -80,7 +76,7 @@ export default {
total: 0,
dialogVisible: false,
dialogType: 'add',
form: { id: null, name: '', level: '', min_prestige: '', max_prestige: '', max_members: '' }
form: { id: null, name: '', level: '', minContribution: '', maxMember: '' }
}
},
mounted() {
@ -90,21 +86,39 @@ export default {
getList() {
this.loading = true
familyLevelListApi({ page: this.page, limit: this.limit }).then(res => {
this.tableData = res.data.list || []
this.total = res.data.total || 0
this.tableData = res.list || []
this.total = res.total || 0
this.loading = false
}).catch(() => { this.loading = false })
},
handleAdd() {
this.dialogType = 'add'
this.form = { id: null, name: '', level: '', min_prestige: '', max_prestige: '', max_members: '' }
this.form = { id: null, name: '', level: '', minContribution: '', maxMember: '' }
this.dialogVisible = true
},
handleEdit(row) {
this.dialogType = 'edit'
this.form = { id: row.id, name: row.name, level: row.level, min_prestige: row.min_prestige, max_prestige: row.max_prestige, max_members: row.max_members }
this.form = {
id: row.id,
name: row.name,
level: row.level,
minContribution: row.min_contribution,
maxMember: row.max_member
}
this.dialogVisible = true
},
handleDelete(row) {
this.$confirm('确定要删除该级别吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
familyLevelDeleteApi(row.id).then(() => {
this.$message.success('删除成功')
this.getList()
})
}).catch(() => {})
},
submitForm() {
const api = this.dialogType === 'add' ? familyLevelCreateApi : familyLevelUpdateApi
api(this.form).then(() => {

View File

@ -4,9 +4,9 @@
<div class="padding-add">
<!-- 搜索表单 -->
<el-form :inline="true" :model="searchForm" size="small" class="mb20">
<el-form-item><el-input v-model="searchForm.familyNo" placeholder="家族编号ID" clearable class="selWidth" /></el-form-item>
<el-form-item><el-input v-model="searchForm.familyNo" placeholder="家族ID" clearable class="selWidth" /></el-form-item>
<el-form-item><el-input v-model="searchForm.familyName" placeholder="请输入家族名称" clearable class="selWidth" /></el-form-item>
<el-form-item><el-input v-model="searchForm.leaderPhone" placeholder="族长手机号" clearable class="selWidth" /></el-form-item>
<el-form-item><el-input v-model="searchForm.leaderPhone" placeholder="族长名称" clearable class="selWidth" /></el-form-item>
<el-form-item>
<el-select v-model="searchForm.status" placeholder="状态" clearable class="selWidth">
<el-option label="全部" value="" /><el-option label="正常" value="1" /><el-option label="禁用" value="0" />
@ -26,27 +26,25 @@
<!-- 数据表格 -->
<el-table v-loading="loading" :data="tableData" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="id" label="家族ID" width="70" />
<el-table-column prop="family_no" label="家族编号ID" width="100" />
<el-table-column prop="name" label="家族名称" width="100" />
<el-table-column label="家族头像" width="80" align="center">
<el-table-column prop="id" label="家族ID" width="80" />
<el-table-column prop="name" label="家族名称" width="120" />
<el-table-column label="家族Logo" width="80" align="center">
<template slot-scope="scope">
<el-image v-if="scope.row.avatar" :src="scope.row.avatar" style="width: 40px; height: 40px" fit="cover" :preview-src-list="[scope.row.avatar]" />
<el-image v-if="scope.row.logo" :src="scope.row.logo" style="width: 40px; height: 40px" fit="cover" :preview-src-list="[scope.row.logo]" />
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column prop="member_count" label="家族成员数量" width="110" />
<el-table-column prop="prestige" label="家族威望值" width="100" />
<el-table-column prop="notice" label="家族公告" min-width="100" show-overflow-tooltip />
<el-table-column prop="level" label="家族级别" width="80" />
<el-table-column prop="member_count" label="成员数量" width="100" />
<el-table-column prop="level" label="家族等级" width="80" />
<el-table-column prop="total_income" label="总收入" width="100" />
<el-table-column prop="description" label="家族简介" min-width="150" show-overflow-tooltip />
<el-table-column label="状态" width="70" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" size="small">{{ scope.row.status === 1 ? '正常' : '禁用' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="leader_name" label="族长名称" width="90" />
<el-table-column prop="leader_phone" label="族长手机号" width="120" />
<el-table-column prop="create_time" label="创建时间" width="150" />
<el-table-column prop="owner_name" label="族长名称" width="100" />
<el-table-column prop="create_time" label="创建时间" width="160" />
<el-table-column label="操作" width="150" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="warning" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
@ -71,19 +69,8 @@
<el-col :span="16"><el-input v-model="form.name" placeholder="请输入家族名称"></el-input></el-col>
</el-row>
<el-row class="form-row">
<el-col :span="8" class="form-label">家族头像</el-col>
<el-col :span="16">
<div class="upLoadPicBox" @click="openUpload">
<div v-if="form.avatar" class="pictrue">
<img :src="form.avatar" /><i class="el-icon-close" @click.stop="form.avatar = ''"></i>
</div>
<div v-else class="upLoad"><i class="el-icon-plus"></i></div>
</div>
</el-col>
</el-row>
<el-row class="form-row">
<el-col :span="8" class="form-label">家族公告</el-col>
<el-col :span="16"><el-input v-model="form.notice" placeholder="请输入家族公告"></el-input></el-col>
<el-col :span="8" class="form-label">家族简介</el-col>
<el-col :span="16"><el-input v-model="form.notice" type="textarea" :rows="3" placeholder="请输入家族简介"></el-input></el-col>
</el-row>
<el-row class="form-row">
<el-col :span="8" class="form-label">状态</el-col>
@ -99,21 +86,18 @@
<el-button @click="dialogVisible = false">返回</el-button>
</div>
</el-dialog>
<upload-index v-if="uploadVisible" @getImage="getImage" :isMore="false" @close="uploadVisible = false"></upload-index>
</div>
</template>
<script>
import { familyListApi, familyUpdateApi, familyDeleteApi, familyBatchDeleteApi, familyCreateApi } from '@/api/familyList'
import uploadIndex from '@/components/uploadPicture/index.vue'
export default {
name: 'FamilyList',
components: { uploadIndex },
data() {
return {
loading: false, searchForm: { familyNo: '', familyName: '', leaderPhone: '', status: '', startTime: '', endTime: '' },
tableData: [], page: 1, limit: 10, total: 0, dialogVisible: false, uploadVisible: false,
form: { id: null, name: '', avatar: '', notice: '', status: 1 },
tableData: [], page: 1, limit: 10, total: 0, dialogVisible: false,
form: { id: null, name: '', notice: '', status: 1 },
selectedIds: [],
dialogTitle: '编辑'
}
@ -134,12 +118,12 @@ export default {
handleSearch() { this.page = 1; this.getList() },
handleAdd() {
this.dialogTitle = '添加'
this.form = { id: null, name: '', avatar: '', notice: '', status: 1 }
this.form = { id: null, name: '', notice: '', status: 1 }
this.dialogVisible = true
},
handleEdit(row) {
this.dialogTitle = '编辑'
this.form = { id: row.id, name: row.name, avatar: row.avatar || '', notice: row.notice || '', status: row.status }
this.form = { id: row.id, name: row.name, notice: row.description || '', status: row.status }
this.dialogVisible = true
},
handleDelete(row) {
@ -177,8 +161,6 @@ export default {
this.$message.success('保存成功'); this.dialogVisible = false; this.getList()
}).catch(() => {})
},
openUpload() { this.uploadVisible = true },
getImage(img) { this.form.avatar = img; this.uploadVisible = false },
handleSizeChange(val) { this.limit = val; this.page = 1; this.getList() },
handleCurrentChange(val) { this.page = val; this.getList() }
}
@ -191,5 +173,4 @@ export default {
.form-row { margin-bottom: 20px; display: flex; align-items: center; }
.form-label { text-align: right; padding-right: 15px; color: #333; border: 1px solid #eee; padding: 10px 15px; background: #fafafa; }
.form-row .el-col:last-child { border: 1px solid #eee; border-left: none; padding: 5px 10px; }
.upLoadPicBox { display: inline-block; .upLoad, .pictrue { width: 100px; height: 100px; border: 1px dashed #ddd; border-radius: 4px; cursor: pointer; display: flex; align-items: center; justify-content: center; position: relative; &:hover { border-color: #409eff; } } .upLoad i { font-size: 32px; color: #999; } .pictrue { img { width: 100%; height: 100%; object-fit: cover; border-radius: 4px; } .el-icon-close { position: absolute; top: -8px; right: -8px; background: #f56c6c; color: #fff; border-radius: 50%; font-size: 14px; cursor: pointer; } } }
</style>

View File

@ -192,8 +192,8 @@
<el-form-item label="特效版本">
<el-input v-model="formData.effectVersion" placeholder="请输入特效版本" />
</el-form-item>
<el-form-item label="排序">
<el-input-number v-model="formData.sort" :min="0" style="width: 100%;" />
<el-form-item label="特效地址">
<el-input v-model="formData.effectUrl" placeholder="请输入特效资源地址" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="formData.remark" type="textarea" :rows="2" placeholder="请输入备注" />
@ -235,7 +235,7 @@ export default {
belong: 'common',
remark: '',
effectVersion: '',
sort: 0
effectUrl: ''
},
formRules: {
name: [{ required: true, message: '请输入礼物名称', trigger: 'blur' }],
@ -281,7 +281,7 @@ export default {
this.formData = {
id: null, name: '', image: '', diamondPrice: 0, intimacy: 0,
status: true, isHeartbeat: false, buyType: 'diamond',
belong: 'common', remark: '', effectVersion: '', sort: 0
belong: 'common', remark: '', effectVersion: '', effectUrl: ''
};
this.dialogVisible = true;
},
@ -299,7 +299,7 @@ export default {
belong: row.belong || 'common',
remark: row.remark || '',
effectVersion: row.effectVersion || row.effect_version || '',
sort: row.sort || 0
effectUrl: row.effectUrl || row.effect_url || ''
};
this.dialogVisible = true;
},

View File

@ -180,8 +180,8 @@ export default {
name: this.searchForm.name || undefined,
};
const res = await headwearListApi(params);
this.tableData = (res.data && res.data.list) || [];
this.total = (res.data && res.data.total) || 0;
this.tableData = res.list || [];
this.total = res.total || 0;
} catch (error) {
this.$message.error(error.message || '获取列表失败');
} finally {

View File

@ -172,8 +172,8 @@ export default {
name: this.searchForm.name || undefined,
};
const res = await mountListApi(params);
this.tableData = (res.data && res.data.list) || [];
this.total = (res.data && res.data.total) || 0;
this.tableData = res.list || [];
this.total = res.total || 0;
} catch (error) {
this.$message.error(error.message || '获取列表失败');
} finally {

View File

@ -192,8 +192,8 @@ export default {
name: this.searchForm.name || undefined,
};
const res = await mountListApi(params);
this.tableData = (res.data && res.data.list) || [];
this.total = (res.data && res.data.total) || 0;
this.tableData = res.list || [];
this.total = res.total || 0;
} catch (error) {
this.$message.error(error.message || '获取列表失败');
} finally {

View File

@ -123,8 +123,8 @@ export default {
endTime: this.searchForm.endTime || undefined,
};
const res = await mountOrderListApi(params);
this.tableData = (res.data && res.data.list) || [];
this.total = (res.data && res.data.total) || 0;
this.tableData = res.list || [];
this.total = res.total || 0;
} catch (error) {
this.$message.error(error.message || '获取列表失败');
} finally {

View File

@ -0,0 +1,184 @@
<template>
<div class="app-container">
<el-card>
<div slot="header">
<el-button type="primary" size="small" @click="handleAdd">上传背景</el-button>
<el-select v-model="filterFestivalId" placeholder="全部节日" clearable style="margin-left: 20px; width: 150px;"
@change="filterList">
<el-option v-for="item in festivalOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
<!-- 背景素材列表 -->
<div class="background-list">
<div v-for="item in filteredList" :key="item.id" class="background-item">
<el-image :src="item.image" fit="cover" class="background-image" />
<div class="background-info">
<span class="name">{{ item.name }}</span>
<el-tag v-if="item.festivalId === 0" size="mini" type="info">通用</el-tag>
<el-tag v-else size="mini">{{ getFestivalName(item.festivalId) }}</el-tag>
</div>
<div class="background-actions">
<el-button type="text" size="mini" @click="handleEdit(item)">编辑</el-button>
<el-button type="text" size="mini" style="color: #F56C6C;" @click="handleDelete(item)">删除</el-button>
</div>
</div>
</div>
</el-card>
<!-- 编辑弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="背景名称" prop="name">
<el-input v-model="form.name" placeholder="请输入背景名称" />
</el-form-item>
<el-form-item label="背景图片" prop="image">
<el-input v-model="form.image" placeholder="请输入图片URL" />
<el-upload class="upload-demo" action="/admin/upload/image" :show-file-list="false"
:on-success="handleUploadSuccess" style="margin-top: 10px;">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
<el-form-item label="关联节日">
<el-select v-model="form.festivalId" placeholder="通用(不关联)" clearable style="width: 100%;">
<el-option label="通用" :value="0" />
<el-option v-for="item in festivalOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="排序">
<el-input-number v-model="form.sort" :min="0" :max="999" />
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { backgroundList, backgroundSave, backgroundDelete, festivalList } from '@/api/wishtree';
export default {
name: 'WishtreeBackground',
data() {
return {
tableData: [],
festivalOptions: [],
filterFestivalId: null,
dialogVisible: false,
dialogTitle: '上传背景',
form: {
id: null,
name: '',
image: '',
festivalId: 0,
sort: 0,
status: 1
},
rules: {
name: [{ required: true, message: '请输入背景名称', trigger: 'blur' }],
image: [{ required: true, message: '请上传背景图片', trigger: 'blur' }]
}
};
},
computed: {
filteredList() {
if (this.filterFestivalId === null) {
return this.tableData;
}
return this.tableData.filter(item => item.festivalId === this.filterFestivalId);
}
},
created() {
this.getFestivals();
this.getList();
},
methods: {
async getFestivals() {
const res = await festivalList();
this.festivalOptions = res || [];
},
async getList() {
const res = await backgroundList();
this.tableData = res || [];
},
getFestivalName(id) {
const festival = this.festivalOptions.find(f => f.id === id);
return festival ? festival.name : '未知';
},
filterList() {
// computed
},
handleAdd() {
this.dialogTitle = '上传背景';
this.form = { id: null, name: '', image: '', festivalId: 0, sort: 0, status: 1 };
this.dialogVisible = true;
},
handleEdit(row) {
this.dialogTitle = '编辑背景';
this.form = { ...row };
this.dialogVisible = true;
},
handleUploadSuccess(res) {
if (res.code === 200) {
this.form.image = res.data.url;
this.$message.success('上传成功');
}
},
async handleSubmit() {
this.$refs.form.validate(async (valid) => {
if (valid) {
await backgroundSave(this.form);
this.$message.success('保存成功');
this.dialogVisible = false;
this.getList();
}
});
},
handleDelete(row) {
this.$confirm('确定删除该背景吗?', '提示', { type: 'warning' }).then(async () => {
await backgroundDelete(row.id);
this.$message.success('删除成功');
this.getList();
}).catch(() => {});
}
}
};
</script>
<style scoped>
.background-list {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.background-item {
width: 200px;
border: 1px solid #eee;
border-radius: 8px;
overflow: hidden;
}
.background-image {
width: 100%;
height: 120px;
}
.background-info {
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.background-info .name {
font-size: 14px;
color: #333;
}
.background-actions {
padding: 0 10px 10px;
text-align: center;
}
</style>

View File

@ -0,0 +1,147 @@
<template>
<div class="app-container">
<el-card>
<div slot="header">
<el-button type="primary" size="small" @click="handleAdd">新增节日</el-button>
</div>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="icon" label="图标" width="80" align="center">
<template slot-scope="scope">
<span style="font-size: 24px;">{{ scope.row.icon }}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="节日名称" width="120" />
<el-table-column prop="startDate" label="开始日期" width="120" />
<el-table-column prop="endDate" label="结束日期" width="120" />
<el-table-column label="农历" width="80" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.isLunar === 1 ? 'success' : 'info'" size="small">
{{ scope.row.isLunar === 1 ? '是' : '否' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="主题色" width="100" align="center">
<template slot-scope="scope">
<div :style="{ background: scope.row.themeColor, width: '40px', height: '20px', borderRadius: '4px', margin: '0 auto' }"></div>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="80" align="center" />
<el-table-column prop="status" label="状态" width="100" align="center">
<template slot-scope="scope">
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0"
@change="handleStatusChange(scope.row)" />
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center">
<template slot-scope="scope">
<el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 编辑弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="节日名称" prop="name">
<el-input v-model="form.name" placeholder="请输入节日名称" />
</el-form-item>
<el-form-item label="图标" prop="icon">
<el-input v-model="form.icon" placeholder="请输入emoji图标如 🎉" />
</el-form-item>
<el-form-item label="开始日期" prop="startDate">
<el-input v-model="form.startDate" placeholder="如 12-31 或 除夕" />
</el-form-item>
<el-form-item label="结束日期" prop="endDate">
<el-input v-model="form.endDate" placeholder="如 01-03 或 正月十五" />
</el-form-item>
<el-form-item label="是否农历">
<el-switch v-model="form.isLunar" :active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item label="主题色">
<el-color-picker v-model="form.themeColor" />
</el-form-item>
<el-form-item label="排序">
<el-input-number v-model="form.sort" :min="0" :max="999" />
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { festivalList, festivalSave, festivalDelete, festivalStatus } from '@/api/wishtree';
export default {
name: 'WishtreeFestival',
data() {
return {
tableData: [],
dialogVisible: false,
dialogTitle: '新增节日',
form: {
id: null,
name: '',
icon: '',
startDate: '',
endDate: '',
isLunar: 0,
themeColor: '#FF6B6B',
sort: 0,
status: 1
},
rules: {
name: [{ required: true, message: '请输入节日名称', trigger: 'blur' }]
}
};
},
created() {
this.getList();
},
methods: {
async getList() {
const res = await festivalList();
this.tableData = res || [];
},
handleAdd() {
this.dialogTitle = '新增节日';
this.form = { id: null, name: '', icon: '', startDate: '', endDate: '', isLunar: 0, themeColor: '#FF6B6B', sort: 0, status: 1 };
this.dialogVisible = true;
},
handleEdit(row) {
this.dialogTitle = '编辑节日';
this.form = { ...row };
this.dialogVisible = true;
},
async handleSubmit() {
this.$refs.form.validate(async (valid) => {
if (valid) {
await festivalSave(this.form);
this.$message.success('保存成功');
this.dialogVisible = false;
this.getList();
}
});
},
async handleStatusChange(row) {
await festivalStatus({ id: row.id, status: row.status });
this.$message.success('状态更新成功');
},
handleDelete(row) {
this.$confirm('确定删除该节日吗?', '提示', { type: 'warning' }).then(async () => {
await festivalDelete(row.id);
this.$message.success('删除成功');
this.getList();
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,192 @@
<template>
<div class="app-container">
<!-- 时间选择 -->
<el-card style="margin-bottom: 20px;">
<el-form :inline="true">
<el-form-item label="时间范围">
<el-select v-model="days" @change="getStatistics">
<el-option label="近7天" :value="7" />
<el-option label="近15天" :value="15" />
<el-option label="近30天" :value="30" />
</el-select>
</el-form-item>
</el-form>
</el-card>
<!-- 统计卡片 -->
<el-row :gutter="20" style="margin-bottom: 20px;">
<el-col :span="6">
<el-card class="stat-card">
<div class="stat-title">总心愿数</div>
<div class="stat-value">{{ statistics.totalWishes || 0 }}</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card class="stat-card">
<div class="stat-title">今日新增</div>
<div class="stat-value" style="color: #67C23A;">{{ statistics.todayWishes || 0 }}</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card class="stat-card">
<div class="stat-title">待审核</div>
<div class="stat-value" style="color: #E6A23C;">{{ statistics.pendingWishes || 0 }}</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card class="stat-card">
<div class="stat-title">总点赞数</div>
<div class="stat-value" style="color: #F56C6C;">{{ statistics.totalLikes || 0 }}</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 心愿趋势 -->
<el-col :span="16">
<el-card>
<div slot="header">心愿发布趋势</div>
<div ref="trendChart" style="height: 300px;"></div>
</el-card>
</el-col>
<!-- 节日分布 -->
<el-col :span="8">
<el-card>
<div slot="header">节日分布</div>
<div ref="pieChart" style="height: 300px;"></div>
</el-card>
</el-col>
</el-row>
<!-- 热门心愿 -->
<el-card style="margin-top: 20px;">
<div slot="header">热门心愿 TOP10</div>
<el-table :data="statistics.hotWishes || []" border>
<el-table-column type="index" label="排名" width="60" align="center" />
<el-table-column label="用户" width="150">
<template slot-scope="scope">
<div style="display: flex; align-items: center;">
<el-avatar :src="scope.row.avatar" size="small" />
<span style="margin-left: 8px;">{{ scope.row.nickname }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="content" label="心愿内容" show-overflow-tooltip />
<el-table-column prop="likeCount" label="点赞数" width="100" align="center">
<template slot-scope="scope">
<span style="color: #F56C6C;"> {{ scope.row.likeCount }}</span>
</template>
</el-table-column>
<el-table-column prop="commentCount" label="评论数" width="100" align="center" />
<el-table-column prop="createTime" label="发布时间" width="160" />
</el-table>
</el-card>
</div>
</template>
<script>
import { getStatistics } from '@/api/wishtree';
import * as echarts from 'echarts';
export default {
name: 'WishtreeStatistics',
data() {
return {
days: 7,
statistics: {},
trendChart: null,
pieChart: null
};
},
mounted() {
this.getStatistics();
window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
if (this.trendChart) this.trendChart.dispose();
if (this.pieChart) this.pieChart.dispose();
},
methods: {
async getStatistics() {
const res = await getStatistics({ days: this.days });
this.statistics = res || {};
this.$nextTick(() => {
this.initTrendChart();
this.initPieChart();
});
},
initTrendChart() {
if (!this.$refs.trendChart) return;
if (this.trendChart) this.trendChart.dispose();
this.trendChart = echarts.init(this.$refs.trendChart);
const trend = this.statistics.wishTrend || [];
const option = {
tooltip: { trigger: 'axis' },
xAxis: {
type: 'category',
data: trend.map(item => item.date)
},
yAxis: { type: 'value' },
series: [{
name: '心愿数',
type: 'line',
smooth: true,
data: trend.map(item => item.count),
areaStyle: { opacity: 0.3 },
itemStyle: { color: '#409EFF' }
}]
};
this.trendChart.setOption(option);
},
initPieChart() {
if (!this.$refs.pieChart) return;
if (this.pieChart) this.pieChart.dispose();
this.pieChart = echarts.init(this.$refs.pieChart);
const distribution = this.statistics.festivalDistribution || [];
const option = {
tooltip: { trigger: 'item' },
series: [{
type: 'pie',
radius: ['40%', '70%'],
data: distribution.map(item => ({
name: item.festivalName,
value: item.count
})),
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
this.pieChart.setOption(option);
},
handleResize() {
if (this.trendChart) this.trendChart.resize();
if (this.pieChart) this.pieChart.resize();
}
}
};
</script>
<style scoped>
.stat-card {
text-align: center;
}
.stat-title {
font-size: 14px;
color: #909399;
margin-bottom: 10px;
}
.stat-value {
font-size: 28px;
font-weight: bold;
color: #409EFF;
}
</style>

View File

@ -0,0 +1,158 @@
<template>
<div class="app-container">
<el-card>
<!-- 搜索栏 -->
<el-form :inline="true" :model="queryParams" class="search-form">
<el-form-item label="节日">
<el-select v-model="queryParams.festivalId" placeholder="全部" clearable style="width: 150px;">
<el-option v-for="item in festivalOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="queryParams.status" placeholder="全部" clearable style="width: 120px;">
<el-option label="待审核" :value="0" />
<el-option label="已通过" :value="1" />
<el-option label="已拒绝" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="时间">
<el-date-picker v-model="dateRange" type="daterange" range-separator="-"
start-placeholder="开始" end-placeholder="结束" value-format="yyyy-MM-dd" style="width: 240px;" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
<!-- 表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column label="用户" width="150">
<template slot-scope="scope">
<div style="display: flex; align-items: center;">
<el-avatar :src="scope.row.avatar" size="small" />
<span style="margin-left: 8px;">{{ scope.row.nickname }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="节日" width="120">
<template slot-scope="scope">
<span>{{ scope.row.festivalIcon }} {{ scope.row.festivalName }}</span>
</template>
</el-table-column>
<el-table-column prop="content" label="心愿内容" show-overflow-tooltip />
<el-table-column prop="status" label="状态" width="100" align="center">
<template slot-scope="scope">
<el-tag :type="statusType(scope.row.status)" size="small">{{ statusText(scope.row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="审核" width="80" align="center">
<template slot-scope="scope">
{{ scope.row.auditType === 0 ? '自动' : '人工' }}
</template>
</el-table-column>
<el-table-column prop="likeCount" label="点赞" width="80" align="center" />
<el-table-column prop="commentCount" label="评论" width="80" align="center" />
<el-table-column prop="createTime" label="时间" width="160" />
<el-table-column label="操作" width="150" align="center">
<template slot-scope="scope">
<template v-if="scope.row.status === 0">
<el-button type="text" style="color: #67C23A;" @click="handleAudit(scope.row, 1)">通过</el-button>
<el-button type="text" style="color: #F56C6C;" @click="handleAudit(scope.row, 2)">拒绝</el-button>
</template>
<el-button type="text" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination background layout="total, sizes, prev, pager, next" :total="total"
:page-size="queryParams.limit" :current-page="queryParams.page"
@size-change="handleSizeChange" @current-change="handlePageChange" style="margin-top: 20px;" />
</el-card>
</div>
</template>
<script>
import { wishList, wishAudit, wishDelete, festivalList } from '@/api/wishtree';
export default {
name: 'WishtreeWish',
data() {
return {
tableData: [],
total: 0,
festivalOptions: [],
dateRange: [],
queryParams: {
festivalId: null,
status: null,
startTime: '',
endTime: '',
page: 1,
limit: 20
}
};
},
created() {
this.getFestivals();
this.getList();
},
methods: {
async getFestivals() {
const res = await festivalList();
this.festivalOptions = res || [];
},
async getList() {
if (this.dateRange && this.dateRange.length === 2) {
this.queryParams.startTime = this.dateRange[0] + ' 00:00:00';
this.queryParams.endTime = this.dateRange[1] + ' 23:59:59';
} else {
this.queryParams.startTime = '';
this.queryParams.endTime = '';
}
const res = await wishList(this.queryParams);
this.tableData = res && res.list ? res.list : [];
this.total = res && res.total ? res.total : 0;
},
statusType(status) {
return { 0: 'warning', 1: 'success', 2: 'danger' }[status] || 'info';
},
statusText(status) {
return { 0: '待审核', 1: '已通过', 2: '已拒绝' }[status] || '未知';
},
handleSearch() {
this.queryParams.page = 1;
this.getList();
},
handleReset() {
this.queryParams = { festivalId: null, status: null, startTime: '', endTime: '', page: 1, limit: 20 };
this.dateRange = [];
this.getList();
},
handleSizeChange(val) {
this.queryParams.limit = val;
this.getList();
},
handlePageChange(val) {
this.queryParams.page = val;
this.getList();
},
handleAudit(row, status) {
const action = status === 1 ? '通过' : '拒绝';
this.$confirm(`确定${action}该心愿吗?`, '提示', { type: 'warning' }).then(async () => {
await wishAudit({ id: row.id, status, remark: `人工审核${action}` });
this.$message.success('审核成功');
this.getList();
}).catch(() => {});
},
handleDelete(row) {
this.$confirm('确定删除该心愿吗?', '提示', { type: 'warning' }).then(async () => {
await wishDelete(row.id);
this.$message.success('删除成功');
this.getList();
}).catch(() => {});
}
}
};
</script>

View File

@ -31,7 +31,7 @@ public class ActivityController {
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<CommonPage<Map<String, Object>>> getList(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "status", required = false) String statusStr,
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "limit", defaultValue = "10") Integer limit) {
@ -41,11 +41,21 @@ public class ActivityController {
List<Object> params = new ArrayList<>();
List<Object> countParams = new ArrayList<>();
if (name != null && !name.isEmpty()) {
if (name != null && !name.trim().isEmpty()) {
sql.append(" AND name LIKE ?");
countSql.append(" AND name LIKE ?");
params.add("%" + name + "%");
countParams.add("%" + name + "%");
params.add("%" + name.trim() + "%");
countParams.add("%" + name.trim() + "%");
}
// 处理status参数
Integer status = null;
if (statusStr != null && !statusStr.trim().isEmpty()) {
try {
status = Integer.parseInt(statusStr.trim());
} catch (NumberFormatException e) {
// 忽略无效值
}
}
if (status != null) {

View File

@ -0,0 +1,103 @@
package com.zbkj.admin.controller;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.community.CommunityCategory;
import com.zbkj.common.model.community.CommunityMatchConfig;
import com.zbkj.common.request.AuditRequest;
import com.zbkj.common.request.CommunityMessageRequest;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.vo.CommunityMessageVO;
import com.zbkj.service.service.CommunityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 缘池管理控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/community")
@Api(tags = "缘池管理")
public class CommunityAdminController {
@Autowired
private CommunityService communityService;
// ==================== 板块管理 ====================
//@PreAuthorize("hasAuthority('admin:community:category')")
@ApiOperation("板块列表")
@GetMapping("/category/list")
public CommonResult<List<CommunityCategory>> categoryList() {
return CommonResult.success(communityService.getCategoryList());
}
//@PreAuthorize("hasAuthority('admin:community:category')")
@ApiOperation("保存板块")
@PostMapping("/category/save")
public CommonResult<String> categorySave(@RequestBody CommunityCategory category) {
communityService.saveCategory(category);
return CommonResult.success("保存成功");
}
//@PreAuthorize("hasAuthority('admin:community:category')")
@ApiOperation("删除板块")
@DeleteMapping("/category/delete/{id}")
public CommonResult<String> categoryDelete(@PathVariable Integer id) {
communityService.deleteCategory(id);
return CommonResult.success("删除成功");
}
//@PreAuthorize("hasAuthority('admin:community:category')")
@ApiOperation("更新板块状态")
@PostMapping("/category/status")
public CommonResult<String> categoryStatus(@RequestBody CommunityCategory category) {
communityService.updateCategoryStatus(category.getId(), category.getStatus());
return CommonResult.success("更新成功");
}
// ==================== 消息管理 ====================
//@PreAuthorize("hasAuthority('admin:community:message')")
@ApiOperation("消息列表")
@PostMapping("/message/list")
public CommonResult<PageInfo<CommunityMessageVO>> messageList(@RequestBody CommunityMessageRequest request) {
return CommonResult.success(communityService.getMessageList(request));
}
//@PreAuthorize("hasAuthority('admin:community:message')")
@ApiOperation("审核消息")
@PostMapping("/message/audit")
public CommonResult<String> messageAudit(@RequestBody AuditRequest request) {
communityService.auditMessage(request.getId(), request.getStatus(), request.getRemark());
return CommonResult.success("审核成功");
}
//@PreAuthorize("hasAuthority('admin:community:message')")
@ApiOperation("删除消息")
@DeleteMapping("/message/delete/{id}")
public CommonResult<String> messageDelete(@PathVariable Long id) {
communityService.deleteMessage(id);
return CommonResult.success("删除成功");
}
// ==================== 匹配配置 ====================
//@PreAuthorize("hasAuthority('admin:community:match')")
@ApiOperation("获取匹配配置")
@GetMapping("/match/config")
public CommonResult<CommunityMatchConfig> getMatchConfig() {
return CommonResult.success(communityService.getMatchConfig());
}
//@PreAuthorize("hasAuthority('admin:community:match')")
@ApiOperation("保存匹配配置")
@PostMapping("/match/config/save")
public CommonResult<String> saveMatchConfig(@RequestBody CommunityMatchConfig config) {
communityService.saveMatchConfig(config);
return CommonResult.success("保存成功");
}
}

View File

@ -29,36 +29,80 @@ public class FamilyLevelController {
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "limit", defaultValue = "10") Integer limit) {
String countSql = "SELECT COUNT(*) FROM eb_family_level";
Long total = jdbcTemplate.queryForObject(countSql, Long.class);
int offset = (page - 1) * limit;
String sql = "SELECT * FROM eb_family_level ORDER BY level_num ASC LIMIT " + offset + ", " + limit;
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
CommonPage<Map<String, Object>> result = new CommonPage<>();
result.setList(list);
result.setTotal(total);
result.setPage(page);
result.setLimit(limit);
result.setTotalPage((int) Math.ceil((double) total / limit));
return CommonResult.success(result);
try {
String countSql = "SELECT COUNT(*) FROM eb_family_level";
Long total = jdbcTemplate.queryForObject(countSql, Long.class);
int offset = (page - 1) * limit;
String sql = "SELECT * FROM eb_family_level ORDER BY level ASC LIMIT " + offset + ", " + limit;
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
CommonPage<Map<String, Object>> result = new CommonPage<>();
result.setList(list);
result.setTotal(total != null ? total : 0L);
result.setPage(page);
result.setLimit(limit);
result.setTotalPage((int) Math.ceil((double) (total != null ? total : 0) / limit));
return CommonResult.success(result);
} catch (Exception e) {
log.error("获取家族级别列表失败: {}", e.getMessage());
return CommonResult.failed("获取列表失败:" + e.getMessage());
}
}
@ApiOperation(value = "添加家族级别")
@RequestMapping(value = "/create", method = RequestMethod.POST)
public CommonResult<String> create(@RequestBody Map<String, Object> data) {
String sql = "INSERT INTO eb_family_level (name, level, min_prestige, max_prestige, max_members) VALUES (?, ?, ?, ?, ?)";
jdbcTemplate.update(sql, data.get("name"), data.get("level"), data.get("min_prestige"), data.get("max_prestige"), data.get("max_members"));
return CommonResult.success("添加成功");
try {
String sql = "INSERT INTO eb_family_level (level, name, icon, min_contribution, max_member, status, create_time) " +
"VALUES (?, ?, ?, ?, ?, ?, NOW())";
jdbcTemplate.update(sql,
data.get("level"),
data.get("name"),
data.get("icon"),
data.get("minContribution"),
data.get("maxMember"),
data.get("status") != null ? data.get("status") : 1
);
return CommonResult.success("添加成功");
} catch (Exception e) {
log.error("添加家族级别失败: {}", e.getMessage());
return CommonResult.failed("添加失败:" + e.getMessage());
}
}
@ApiOperation(value = "更新家族级别")
@RequestMapping(value = "/update", method = RequestMethod.POST)
public CommonResult<String> update(@RequestBody Map<String, Object> data) {
String sql = "UPDATE eb_family_level SET name = ?, level = ?, min_prestige = ?, max_prestige = ?, max_members = ? WHERE id = ?";
jdbcTemplate.update(sql, data.get("name"), data.get("level"), data.get("min_prestige"), data.get("max_prestige"), data.get("max_members"), data.get("id"));
return CommonResult.success("更新成功");
try {
String sql = "UPDATE eb_family_level SET level = ?, name = ?, icon = ?, min_contribution = ?, " +
"max_member = ?, status = ?, update_time = NOW() WHERE id = ?";
jdbcTemplate.update(sql,
data.get("level"),
data.get("name"),
data.get("icon"),
data.get("minContribution"),
data.get("maxMember"),
data.get("status"),
data.get("id")
);
return CommonResult.success("更新成功");
} catch (Exception e) {
log.error("更新家族级别失败: {}", e.getMessage());
return CommonResult.failed("更新失败:" + e.getMessage());
}
}
@ApiOperation(value = "删除家族级别")
@RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
public CommonResult<String> delete(@PathVariable Integer id) {
try {
jdbcTemplate.update("DELETE FROM eb_family_level WHERE id = ?", id);
return CommonResult.success("删除成功");
} catch (Exception e) {
log.error("删除家族级别失败: {}", e.getMessage());
return CommonResult.failed("删除失败:" + e.getMessage());
}
}
}

View File

@ -39,16 +39,16 @@ public class FamilyListController {
StringBuilder countSql = new StringBuilder("SELECT COUNT(*) FROM eb_family WHERE 1=1");
if (familyNo != null && !familyNo.isEmpty()) {
sql.append(" AND family_code = '").append(familyNo).append("'");
countSql.append(" AND family_code = '").append(familyNo).append("'");
sql.append(" AND id = '").append(familyNo).append("'");
countSql.append(" AND id = '").append(familyNo).append("'");
}
if (familyName != null && !familyName.isEmpty()) {
sql.append(" AND family_name LIKE '%").append(familyName).append("%'");
countSql.append(" AND family_name LIKE '%").append(familyName).append("%'");
sql.append(" AND name LIKE '%").append(familyName).append("%'");
countSql.append(" AND name LIKE '%").append(familyName).append("%'");
}
if (leaderPhone != null && !leaderPhone.isEmpty()) {
sql.append(" AND leader_name LIKE '%").append(leaderPhone).append("%'");
countSql.append(" AND leader_name LIKE '%").append(leaderPhone).append("%'");
sql.append(" AND owner_name LIKE '%").append(leaderPhone).append("%'");
countSql.append(" AND owner_name LIKE '%").append(leaderPhone).append("%'");
}
if (status != null && !status.isEmpty()) {
sql.append(" AND status = ").append(status);
@ -80,11 +80,43 @@ public class FamilyListController {
return CommonResult.success(result);
}
@ApiOperation(value = "创建家族")
@RequestMapping(value = "/create", method = RequestMethod.POST)
public CommonResult<String> create(@RequestBody Map<String, Object> data) {
String sql = "INSERT INTO eb_family (name, description, status, create_time) VALUES (?, ?, ?, NOW())";
jdbcTemplate.update(sql, data.get("name"), data.get("notice"), data.get("status"));
return CommonResult.success("创建成功");
}
@ApiOperation(value = "更新家族")
@RequestMapping(value = "/update", method = RequestMethod.POST)
public CommonResult<String> update(@RequestBody Map<String, Object> data) {
String sql = "UPDATE eb_family SET family_name = ?, introduction = ?, status = ? WHERE id = ?";
jdbcTemplate.update(sql, data.get("family_name"), data.get("introduction"), data.get("status"), data.get("id"));
String sql = "UPDATE eb_family SET name = ?, description = ?, status = ?, update_time = NOW() WHERE id = ?";
jdbcTemplate.update(sql, data.get("name"), data.get("notice"), data.get("status"), data.get("id"));
return CommonResult.success("更新成功");
}
@ApiOperation(value = "删除家族")
@RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
public CommonResult<String> delete(@PathVariable Integer id) {
// 先删除家族成员
jdbcTemplate.update("DELETE FROM eb_family_member WHERE family_id = ?", id);
// 再删除家族
jdbcTemplate.update("DELETE FROM eb_family WHERE id = ?", id);
return CommonResult.success("删除成功");
}
@ApiOperation(value = "批量删除家族")
@RequestMapping(value = "/batch-delete", method = RequestMethod.POST)
public CommonResult<String> batchDelete(@RequestBody Map<String, java.util.List<Integer>> request) {
java.util.List<Integer> ids = request.get("ids");
if (ids == null || ids.isEmpty()) {
return CommonResult.failed("请选择要删除的数据");
}
for (Integer id : ids) {
jdbcTemplate.update("DELETE FROM eb_family_member WHERE family_id = ?", id);
jdbcTemplate.update("DELETE FROM eb_family WHERE id = ?", id);
}
return CommonResult.success("批量删除成功");
}
}

View File

@ -46,12 +46,12 @@ public class FeedbackController {
StringBuilder countSql = new StringBuilder("SELECT COUNT(*) FROM eb_feedback WHERE 1=1");
if (userName != null && !userName.isEmpty()) {
sql.append(" AND user_name LIKE '%").append(userName).append("%'");
countSql.append(" AND user_name LIKE '%").append(userName).append("%'");
sql.append(" AND nickname LIKE '%").append(userName).append("%'");
countSql.append(" AND nickname LIKE '%").append(userName).append("%'");
}
if (phone != null && !phone.isEmpty()) {
sql.append(" AND user_phone LIKE '%").append(phone).append("%'");
countSql.append(" AND user_phone LIKE '%").append(phone).append("%'");
sql.append(" AND contact LIKE '%").append(phone).append("%'");
countSql.append(" AND contact LIKE '%").append(phone).append("%'");
}
if (startTime != null && !startTime.isEmpty()) {
sql.append(" AND create_time >= '").append(startTime).append("'");

View File

@ -34,25 +34,36 @@ public class GiftAdminController {
@GetMapping("/list")
public CommonResult<CommonPage<Map<String, Object>>> getGiftList(
@RequestParam(value = "keywords", required = false) String keywords,
@RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "status", required = false) String statusStr,
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "limit", defaultValue = "20") Integer limit) {
StringBuilder sql = new StringBuilder("SELECT * FROM eb_gift WHERE 1=1");
StringBuilder countSql = new StringBuilder("SELECT COUNT(*) FROM eb_gift WHERE 1=1");
if (keywords != null && !keywords.isEmpty()) {
String condition = " AND name LIKE '%" + keywords + "%'";
if (keywords != null && !keywords.trim().isEmpty()) {
String condition = " AND name LIKE '%" + keywords.trim() + "%'";
sql.append(condition);
countSql.append(condition);
}
// 处理status参数空字符串视为null
Integer status = null;
if (statusStr != null && !statusStr.trim().isEmpty()) {
try {
status = Integer.parseInt(statusStr.trim());
} catch (NumberFormatException e) {
// 忽略无效的status值
}
}
if (status != null) {
String condition = " AND status = " + status;
sql.append(condition);
countSql.append(condition);
}
sql.append(" ORDER BY sort DESC, id ASC");
sql.append(" ORDER BY id ASC");
Long total = jdbcTemplate.queryForObject(countSql.toString(), Long.class);
@ -105,7 +116,7 @@ public class GiftAdminController {
public CommonResult<Boolean> addGift(@RequestBody Map<String, Object> data) {
try {
String sql = "INSERT INTO eb_gift (name, image, diamond_price, intimacy, status, is_heartbeat, " +
"buy_type, belong, remark, effect_version, sort, create_time, update_time) " +
"buy_type, belong, remark, effect_version, effect_url, create_time, update_time) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";
jdbcTemplate.update(sql,
@ -119,7 +130,7 @@ public class GiftAdminController {
data.get("belong"),
data.get("remark"),
data.get("effectVersion"),
data.get("sort") != null ? data.get("sort") : 0
data.get("effectUrl") != null ? data.get("effectUrl") : ""
);
return CommonResult.success(true);
} catch (Exception e) {
@ -137,7 +148,7 @@ public class GiftAdminController {
try {
String sql = "UPDATE eb_gift SET name = ?, image = ?, diamond_price = ?, intimacy = ?, " +
"status = ?, is_heartbeat = ?, buy_type = ?, belong = ?, remark = ?, " +
"effect_version = ?, sort = ?, update_time = NOW() WHERE id = ?";
"effect_version = ?, effect_url = ?, update_time = NOW() WHERE id = ?";
jdbcTemplate.update(sql,
data.get("name"),
@ -150,7 +161,7 @@ public class GiftAdminController {
data.get("belong"),
data.get("remark"),
data.get("effectVersion"),
data.get("sort") != null ? data.get("sort") : 0,
data.get("effectUrl") != null ? data.get("effectUrl") : "",
id
);
return CommonResult.success(true);
@ -205,6 +216,28 @@ public class GiftAdminController {
}
}
/**
* 批量删除礼物
*/
@ApiOperation(value = "批量删除礼物")
@PostMapping("/batch-delete")
public CommonResult<Boolean> batchDeleteGift(@RequestBody Map<String, Object> data) {
try {
@SuppressWarnings("unchecked")
List<Integer> ids = (List<Integer>) data.get("ids");
if (ids == null || ids.isEmpty()) {
return CommonResult.failed("请选择要删除的礼物");
}
String placeholders = String.join(",", ids.stream().map(id -> "?").toArray(String[]::new));
String sql = "DELETE FROM eb_gift WHERE id IN (" + placeholders + ")";
jdbcTemplate.update(sql, ids.toArray());
return CommonResult.success(true);
} catch (Exception e) {
log.error("批量删除礼物失败: {}", e.getMessage());
return CommonResult.failed("批量删除失败: " + e.getMessage());
}
}
/**
* 礼物统计
*/

View File

@ -31,7 +31,7 @@ public class LotteryController {
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<CommonPage<Map<String, Object>>> getList(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "status", required = false) String statusStr,
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "limit", defaultValue = "10") Integer limit) {
@ -41,11 +41,21 @@ public class LotteryController {
List<Object> params = new ArrayList<>();
List<Object> countParams = new ArrayList<>();
if (name != null && !name.isEmpty()) {
if (name != null && !name.trim().isEmpty()) {
sql.append(" AND name LIKE ?");
countSql.append(" AND name LIKE ?");
params.add("%" + name + "%");
countParams.add("%" + name + "%");
params.add("%" + name.trim() + "%");
countParams.add("%" + name.trim() + "%");
}
// 处理status参数
Integer status = null;
if (statusStr != null && !statusStr.trim().isEmpty()) {
try {
status = Integer.parseInt(statusStr.trim());
} catch (NumberFormatException e) {
// 忽略无效值
}
}
if (status != null) {

View File

@ -37,36 +37,46 @@ public class MountOrderController {
@RequestParam(required = false) String userNickname,
@RequestParam(required = false) String userPhone,
@RequestParam(required = false) String type,
@RequestParam(required = false) Integer status,
@RequestParam(required = false) String statusStr,
@RequestParam(required = false) String startTime,
@RequestParam(required = false) String endTime) {
StringBuilder sql = new StringBuilder("SELECT * FROM eb_mount_order WHERE 1=1");
StringBuilder countSql = new StringBuilder("SELECT COUNT(*) FROM eb_mount_order WHERE 1=1");
if (userNickname != null && !userNickname.isEmpty()) {
sql.append(" AND user_nickname LIKE '%").append(userNickname).append("%'");
countSql.append(" AND user_nickname LIKE '%").append(userNickname).append("%'");
if (userNickname != null && !userNickname.trim().isEmpty()) {
sql.append(" AND user_nickname LIKE '%").append(userNickname.trim()).append("%'");
countSql.append(" AND user_nickname LIKE '%").append(userNickname.trim()).append("%'");
}
if (userPhone != null && !userPhone.isEmpty()) {
sql.append(" AND user_phone LIKE '%").append(userPhone).append("%'");
countSql.append(" AND user_phone LIKE '%").append(userPhone).append("%'");
if (userPhone != null && !userPhone.trim().isEmpty()) {
sql.append(" AND user_phone LIKE '%").append(userPhone.trim()).append("%'");
countSql.append(" AND user_phone LIKE '%").append(userPhone.trim()).append("%'");
}
if (type != null && !type.isEmpty() && !"全部".equals(type)) {
sql.append(" AND type = '").append(type).append("'");
countSql.append(" AND type = '").append(type).append("'");
if (type != null && !type.trim().isEmpty() && !"全部".equals(type.trim())) {
sql.append(" AND type = '").append(type.trim()).append("'");
countSql.append(" AND type = '").append(type.trim()).append("'");
}
// 处理status参数
Integer status = null;
if (statusStr != null && !statusStr.trim().isEmpty()) {
try {
status = Integer.parseInt(statusStr.trim());
} catch (NumberFormatException e) {
// 忽略无效值
}
}
if (status != null) {
sql.append(" AND status = ").append(status);
countSql.append(" AND status = ").append(status);
}
if (startTime != null && !startTime.isEmpty()) {
sql.append(" AND purchase_time >= '").append(startTime).append("'");
countSql.append(" AND purchase_time >= '").append(startTime).append("'");
if (startTime != null && !startTime.trim().isEmpty()) {
sql.append(" AND purchase_time >= '").append(startTime.trim()).append("'");
countSql.append(" AND purchase_time >= '").append(startTime.trim()).append("'");
}
if (endTime != null && !endTime.isEmpty()) {
sql.append(" AND purchase_time <= '").append(endTime).append("'");
countSql.append(" AND purchase_time <= '").append(endTime).append("'");
if (endTime != null && !endTime.trim().isEmpty()) {
sql.append(" AND purchase_time <= '").append(endTime.trim()).append("'");
countSql.append(" AND purchase_time <= '").append(endTime.trim()).append("'");
}
sql.append(" ORDER BY id DESC LIMIT ").append((page - 1) * limit).append(", ").append(limit);

View File

@ -46,28 +46,24 @@ public class ReportController {
StringBuilder countSql = new StringBuilder("SELECT COUNT(*) FROM eb_report WHERE 1=1");
if (userName != null && !userName.isEmpty()) {
sql.append(" AND user_name LIKE '%").append(userName).append("%'");
countSql.append(" AND user_name LIKE '%").append(userName).append("%'");
}
if (userPhone != null && !userPhone.isEmpty()) {
sql.append(" AND user_phone LIKE '%").append(userPhone).append("%'");
countSql.append(" AND user_phone LIKE '%").append(userPhone).append("%'");
sql.append(" AND nickname LIKE '%").append(userName).append("%'");
countSql.append(" AND nickname LIKE '%").append(userName).append("%'");
}
if (reportType != null && !reportType.isEmpty() && !"全部".equals(reportType)) {
sql.append(" AND report_type = '").append(reportType).append("'");
countSql.append(" AND report_type = '").append(reportType).append("'");
sql.append(" AND target_type = '").append(reportType).append("'");
countSql.append(" AND target_type = '").append(reportType).append("'");
}
if (status != null) {
sql.append(" AND status = ").append(status);
countSql.append(" AND status = ").append(status);
}
if (startTime != null && !startTime.isEmpty()) {
sql.append(" AND report_time >= '").append(startTime).append("'");
countSql.append(" AND report_time >= '").append(startTime).append("'");
sql.append(" AND create_time >= '").append(startTime).append("'");
countSql.append(" AND create_time >= '").append(startTime).append("'");
}
if (endTime != null && !endTime.isEmpty()) {
sql.append(" AND report_time <= '").append(endTime).append("'");
countSql.append(" AND report_time <= '").append(endTime).append("'");
sql.append(" AND create_time <= '").append(endTime).append("'");
countSql.append(" AND create_time <= '").append(endTime).append("'");
}
sql.append(" ORDER BY id DESC LIMIT ").append((page - 1) * limit).append(", ").append(limit);
@ -94,7 +90,7 @@ public class ReportController {
Integer id = (Integer) params.get("id");
String handleResult = (String) params.get("handleResult");
String sql = "UPDATE eb_report SET status = 1, handle_result = ?, handle_time = NOW() WHERE id = ?";
String sql = "UPDATE eb_report SET status = 2, result = ?, handle_time = NOW(), update_time = NOW() WHERE id = ?";
jdbcTemplate.update(sql, handleResult, id);
return CommonResult.success();

View File

@ -33,7 +33,7 @@ public class SystemMessageController {
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<CommonPage<Map<String, Object>>> getList(
@RequestParam(value = "title", required = false) String title,
@RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "status", required = false) String statusStr,
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "limit", defaultValue = "10") Integer limit) {
@ -43,6 +43,16 @@ public class SystemMessageController {
if (title != null && !title.trim().isEmpty()) {
sql.append(" AND title LIKE '%").append(title.replace("'", "''")).append("%'");
}
// 处理status参数
Integer status = null;
if (statusStr != null && !statusStr.trim().isEmpty()) {
try {
status = Integer.parseInt(statusStr.trim());
} catch (NumberFormatException e) {
// 忽略无效值
}
}
if (status != null) {
sql.append(" AND status = ").append(status);
}
@ -92,12 +102,12 @@ public class SystemMessageController {
@RequestMapping(value = "/create", method = RequestMethod.POST)
public CommonResult<String> create(@RequestBody Map<String, Object> params) {
String title = (String) params.get("title");
String image = (String) params.get("image");
String content = (String) params.get("content");
Integer type = params.get("type") != null ? (Integer) params.get("type") : 1;
Integer status = params.get("status") != null ? (Integer) params.get("status") : 1;
String sql = "INSERT INTO eb_system_message (title, image, content, status) VALUES (?, ?, ?, ?)";
int rows = jdbcTemplate.update(sql, title, image, content, status);
String sql = "INSERT INTO eb_system_message (title, content, type, status, send_time, create_time) VALUES (?, ?, ?, ?, NOW(), NOW())";
int rows = jdbcTemplate.update(sql, title, content, type, status);
return rows > 0 ? CommonResult.success("添加成功") : CommonResult.failed("添加失败");
}
@ -110,12 +120,12 @@ public class SystemMessageController {
public CommonResult<String> update(@RequestBody Map<String, Object> params) {
Integer id = (Integer) params.get("id");
String title = (String) params.get("title");
String image = (String) params.get("image");
String content = (String) params.get("content");
Integer type = (Integer) params.get("type");
Integer status = (Integer) params.get("status");
String sql = "UPDATE eb_system_message SET title = ?, image = ?, content = ?, status = ? WHERE id = ?";
int rows = jdbcTemplate.update(sql, title, image, content, status, id);
String sql = "UPDATE eb_system_message SET title = ?, content = ?, type = ?, status = ?, update_time = NOW() WHERE id = ?";
int rows = jdbcTemplate.update(sql, title, content, type, status, id);
return rows > 0 ? CommonResult.success("更新成功") : CommonResult.failed("更新失败");
}

View File

@ -0,0 +1,128 @@
package com.zbkj.admin.controller;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.wishtree.WishtreeBackground;
import com.zbkj.common.model.wishtree.WishtreeFestival;
import com.zbkj.common.request.AuditRequest;
import com.zbkj.common.request.WishtreeWishRequest;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.vo.WishtreeStatisticsVO;
import com.zbkj.common.vo.WishtreeWishVO;
import com.zbkj.service.service.WishtreeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 许愿树管理控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/wishtree")
@Api(tags = "许愿树管理")
public class WishtreeAdminController {
@Autowired
private WishtreeService wishtreeService;
// ==================== 节日管理 ====================
//@PreAuthorize("hasAuthority('admin:wishtree:festival')")
@ApiOperation("节日列表")
@GetMapping("/festival/list")
public CommonResult<List<WishtreeFestival>> festivalList() {
return CommonResult.success(wishtreeService.getFestivalList());
}
//@PreAuthorize("hasAuthority('admin:wishtree:festival')")
@ApiOperation("保存节日")
@PostMapping("/festival/save")
public CommonResult<String> festivalSave(@RequestBody WishtreeFestival festival) {
wishtreeService.saveFestival(festival);
return CommonResult.success("保存成功");
}
//@PreAuthorize("hasAuthority('admin:wishtree:festival')")
@ApiOperation("删除节日")
@DeleteMapping("/festival/delete/{id}")
public CommonResult<String> festivalDelete(@PathVariable Integer id) {
wishtreeService.deleteFestival(id);
return CommonResult.success("删除成功");
}
//@PreAuthorize("hasAuthority('admin:wishtree:festival')")
@ApiOperation("更新节日状态")
@PostMapping("/festival/status")
public CommonResult<String> festivalStatus(@RequestBody WishtreeFestival festival) {
wishtreeService.updateFestivalStatus(festival.getId(), festival.getStatus());
return CommonResult.success("更新成功");
}
// ==================== 心愿管理 ====================
//@PreAuthorize("hasAuthority('admin:wishtree:wish')")
@ApiOperation("心愿列表")
@PostMapping("/wish/list")
public CommonResult<PageInfo<WishtreeWishVO>> wishList(@RequestBody WishtreeWishRequest request) {
return CommonResult.success(wishtreeService.getWishList(request));
}
//@PreAuthorize("hasAuthority('admin:wishtree:wish')")
@ApiOperation("审核心愿")
@PostMapping("/wish/audit")
public CommonResult<String> wishAudit(@RequestBody AuditRequest request) {
wishtreeService.auditWish(request.getId(), request.getStatus(), request.getRemark());
return CommonResult.success("审核成功");
}
//@PreAuthorize("hasAuthority('admin:wishtree:wish')")
@ApiOperation("删除心愿")
@DeleteMapping("/wish/delete/{id}")
public CommonResult<String> wishDelete(@PathVariable Long id) {
wishtreeService.deleteWish(id);
return CommonResult.success("删除成功");
}
// ==================== 背景素材 ====================
//@PreAuthorize("hasAuthority('admin:wishtree:background')")
@ApiOperation("背景列表")
@GetMapping("/background/list")
public CommonResult<List<WishtreeBackground>> backgroundList() {
return CommonResult.success(wishtreeService.getBackgroundList());
}
//@PreAuthorize("hasAuthority('admin:wishtree:background')")
@ApiOperation("保存背景")
@PostMapping("/background/save")
public CommonResult<String> backgroundSave(@RequestBody WishtreeBackground background) {
wishtreeService.saveBackground(background);
return CommonResult.success("保存成功");
}
//@PreAuthorize("hasAuthority('admin:wishtree:background')")
@ApiOperation("删除背景")
@DeleteMapping("/background/delete/{id}")
public CommonResult<String> backgroundDelete(@PathVariable Integer id) {
wishtreeService.deleteBackground(id);
return CommonResult.success("删除成功");
}
// ==================== 数据统计 ====================
//@PreAuthorize("hasAuthority('admin:wishtree:statistics')")
@ApiOperation("获取统计数据")
@GetMapping("/statistics")
public CommonResult<WishtreeStatisticsVO> getStatistics(@RequestParam(defaultValue = "7") Integer days) {
return CommonResult.success(wishtreeService.getStatistics(days));
}
//@PreAuthorize("hasAuthority('admin:wishtree:statistics')")
@ApiOperation("获取心愿趋势")
@GetMapping("/statistics/trend")
public CommonResult<List<Map<String, Object>>> getWishTrend(@RequestParam(defaultValue = "7") Integer days) {
return CommonResult.success(wishtreeService.getWishTrend(days));
}
}

View File

@ -32,7 +32,7 @@ public class WithdrawController {
@ApiOperation(value = "提现列表")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<CommonPage<Map<String, Object>>> getList(
@RequestParam(value = "auditor_nickname", required = false) String auditorNickname,
@RequestParam(value = "nickname", required = false) String nickname,
@RequestParam(value = "status", required = false) String status,
@RequestParam(value = "start_time", required = false) String startTime,
@RequestParam(value = "end_time", required = false) String endTime,
@ -42,8 +42,8 @@ public class WithdrawController {
// 构建查询SQL
StringBuilder sql = new StringBuilder("SELECT * FROM eb_withdraw WHERE 1=1");
if (auditorNickname != null && !auditorNickname.trim().isEmpty()) {
sql.append(" AND auditor_nickname LIKE '%").append(auditorNickname.replace("'", "''")).append("%'");
if (nickname != null && !nickname.trim().isEmpty()) {
sql.append(" AND nickname LIKE '%").append(nickname.replace("'", "''")).append("%'");
}
if (status != null && !status.trim().isEmpty()) {
sql.append(" AND status = '").append(status.replace("'", "''")).append("'");
@ -52,7 +52,7 @@ public class WithdrawController {
sql.append(" AND create_time >= '").append(startTime.replace("'", "''")).append("'");
}
if (endTime != null && !endTime.trim().isEmpty()) {
sql.append(" AND audit_time <= '").append(endTime.replace("'", "''")).append("'");
sql.append(" AND create_time <= '").append(endTime.replace("'", "''")).append(" 23:59:59'");
}
// 查询总数
@ -99,11 +99,11 @@ public class WithdrawController {
@ApiOperation(value = "审核提现")
@RequestMapping(value = "/audit/{id}", method = RequestMethod.POST)
public CommonResult<String> audit(@PathVariable Integer id, @RequestBody Map<String, Object> params) {
String status = (String) params.get("status");
String auditorNickname = (String) params.get("auditor_nickname");
Integer status = (Integer) params.get("status");
String rejectReason = (String) params.get("reject_reason");
String sql = "UPDATE eb_withdraw SET status = ?, auditor_nickname = ?, audit_time = NOW() WHERE id = ?";
jdbcTemplate.update(sql, status, auditorNickname, id);
String sql = "UPDATE eb_withdraw SET status = ?, reject_reason = ?, audit_time = NOW(), update_time = NOW() WHERE id = ?";
jdbcTemplate.update(sql, status, rejectReason != null ? rejectReason : "", id);
return CommonResult.success("审核成功");
}

View File

@ -0,0 +1,54 @@
package com.zbkj.common.model.community;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 缘池板块实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_community_category")
@ApiModel(value = "CommunityCategory", description = "缘池板块")
public class CommunityCategory implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "板块ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "板块名称")
private String name;
@ApiModelProperty(value = "图标")
private String icon;
@ApiModelProperty(value = "类型 quick=快捷入口 card=功能卡片")
private String type;
@ApiModelProperty(value = "跳转页面")
private String jumpPage;
@ApiModelProperty(value = "排序(越大越靠前)")
private Integer sort;
@ApiModelProperty(value = "状态 0禁用 1启用")
private Integer status;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "更新时间")
private Date updateTime;
}

View File

@ -0,0 +1,51 @@
package com.zbkj.common.model.community;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 缘池匹配配置实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_community_match_config")
@ApiModel(value = "CommunityMatchConfig", description = "缘池匹配配置")
public class CommunityMatchConfig implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "配置ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "匹配半径(公里)")
private Integer matchRadius;
@ApiModelProperty(value = "推荐用户数")
private Integer recommendCount;
@ApiModelProperty(value = "优先在线用户 0否 1是")
private Integer priorityOnline;
@ApiModelProperty(value = "优先同城用户 0否 1是")
private Integer prioritySameCity;
@ApiModelProperty(value = "优先异性用户 0否 1是")
private Integer priorityOppositeSex;
@ApiModelProperty(value = "自动审核开关 0关 1开")
private Integer autoAudit;
@ApiModelProperty(value = "更新时间")
private Date updateTime;
}

View File

@ -0,0 +1,60 @@
package com.zbkj.common.model.community;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 缘池消息实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_community_message")
@ApiModel(value = "CommunityMessage", description = "缘池消息")
public class CommunityMessage implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "消息ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "用户ID")
private Integer uid;
@ApiModelProperty(value = "板块ID")
private Integer categoryId;
@ApiModelProperty(value = "消息内容")
private String content;
@ApiModelProperty(value = "图片(逗号分隔)")
private String images;
@ApiModelProperty(value = "状态 0待审核 1通过 2拒绝")
private Integer status;
@ApiModelProperty(value = "审核方式 0自动 1人工")
private Integer auditType;
@ApiModelProperty(value = "审核备注")
private String auditRemark;
@ApiModelProperty(value = "是否删除 0否 1是")
private Integer isDelete;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "更新时间")
private Date updateTime;
}

View File

@ -0,0 +1,48 @@
package com.zbkj.common.model.wishtree;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 许愿树背景素材实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_wishtree_background")
@ApiModel(value = "WishtreeBackground", description = "许愿树背景素材")
public class WishtreeBackground implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "背景ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "背景名称")
private String name;
@ApiModelProperty(value = "背景图片URL")
private String image;
@ApiModelProperty(value = "关联节日ID(0=通用)")
private Integer festivalId;
@ApiModelProperty(value = "排序(越大越靠前)")
private Integer sort;
@ApiModelProperty(value = "状态 0禁用 1启用")
private Integer status;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,51 @@
package com.zbkj.common.model.wishtree;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 许愿树评论实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_wishtree_comment")
@ApiModel(value = "WishtreeComment", description = "许愿树评论")
public class WishtreeComment implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "评论ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "心愿ID")
private Long wishId;
@ApiModelProperty(value = "用户ID")
private Integer uid;
@ApiModelProperty(value = "评论内容")
private String content;
@ApiModelProperty(value = "父评论ID(回复)")
private Long parentId;
@ApiModelProperty(value = "状态 0待审核 1通过 2拒绝")
private Integer status;
@ApiModelProperty(value = "是否删除 0否 1是")
private Integer isDelete;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,60 @@
package com.zbkj.common.model.wishtree;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 许愿树节日实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_wishtree_festival")
@ApiModel(value = "WishtreeFestival", description = "许愿树节日")
public class WishtreeFestival implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "节日ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "节日名称")
private String name;
@ApiModelProperty(value = "节日图标")
private String icon;
@ApiModelProperty(value = "开始日期(MM-DD或农历)")
private String startDate;
@ApiModelProperty(value = "结束日期")
private String endDate;
@ApiModelProperty(value = "是否农历 0否 1是")
private Integer isLunar;
@ApiModelProperty(value = "主题色")
private String themeColor;
@ApiModelProperty(value = "排序(越大越靠前)")
private Integer sort;
@ApiModelProperty(value = "状态 0禁用 1启用")
private Integer status;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "更新时间")
private Date updateTime;
}

View File

@ -0,0 +1,39 @@
package com.zbkj.common.model.wishtree;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 许愿树点赞实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_wishtree_like")
@ApiModel(value = "WishtreeLike", description = "许愿树点赞")
public class WishtreeLike implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "点赞ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "用户ID")
private Integer uid;
@ApiModelProperty(value = "心愿ID")
private Long wishId;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,66 @@
package com.zbkj.common.model.wishtree;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 许愿树心愿实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_wishtree_wish")
@ApiModel(value = "WishtreeWish", description = "许愿树心愿")
public class WishtreeWish implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "心愿ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "用户ID")
private Integer uid;
@ApiModelProperty(value = "节日ID")
private Integer festivalId;
@ApiModelProperty(value = "心愿内容")
private String content;
@ApiModelProperty(value = "背景ID")
private Integer backgroundId;
@ApiModelProperty(value = "状态 0待审核 1通过 2拒绝")
private Integer status;
@ApiModelProperty(value = "审核方式 0自动 1人工")
private Integer auditType;
@ApiModelProperty(value = "审核备注")
private String auditRemark;
@ApiModelProperty(value = "点赞数")
private Integer likeCount;
@ApiModelProperty(value = "评论数")
private Integer commentCount;
@ApiModelProperty(value = "是否删除 0否 1是")
private Integer isDelete;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "更新时间")
private Date updateTime;
}

View File

@ -0,0 +1,26 @@
package com.zbkj.common.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 审核请求
*/
@Data
@ApiModel(value = "AuditRequest", description = "审核请求")
public class AuditRequest implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID")
private Long id;
@ApiModelProperty(value = "状态 1通过 2拒绝")
private Integer status;
@ApiModelProperty(value = "审核备注")
private String remark;
}

View File

@ -0,0 +1,44 @@
package com.zbkj.common.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 缘池消息请求
*/
@Data
@ApiModel(value = "CommunityMessageRequest", description = "缘池消息请求")
public class CommunityMessageRequest implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "板块ID")
private Integer categoryId;
@ApiModelProperty(value = "消息内容")
private String content;
@ApiModelProperty(value = "图片(逗号分隔)")
private String images;
@ApiModelProperty(value = "状态筛选")
private Integer status;
@ApiModelProperty(value = "开始时间")
private String startTime;
@ApiModelProperty(value = "结束时间")
private String endTime;
@ApiModelProperty(value = "关键词搜索")
private String keywords;
@ApiModelProperty(value = "页码")
private Integer page = 1;
@ApiModelProperty(value = "每页数量")
private Integer limit = 20;
}

View File

@ -0,0 +1,23 @@
package com.zbkj.common.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 许愿树评论请求
*/
@Data
@ApiModel(value = "WishtreeCommentRequest", description = "许愿树评论请求")
public class WishtreeCommentRequest implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "评论内容")
private String content;
@ApiModelProperty(value = "父评论ID(回复时使用)")
private Long parentId;
}

View File

@ -0,0 +1,44 @@
package com.zbkj.common.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 许愿树心愿请求
*/
@Data
@ApiModel(value = "WishtreeWishRequest", description = "许愿树心愿请求")
public class WishtreeWishRequest implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "节日ID")
private Integer festivalId;
@ApiModelProperty(value = "心愿内容")
private String content;
@ApiModelProperty(value = "背景ID")
private Integer backgroundId;
@ApiModelProperty(value = "状态筛选")
private Integer status;
@ApiModelProperty(value = "开始时间")
private String startTime;
@ApiModelProperty(value = "结束时间")
private String endTime;
@ApiModelProperty(value = "关键词搜索")
private String keywords;
@ApiModelProperty(value = "页码")
private Integer page = 1;
@ApiModelProperty(value = "每页数量")
private Integer limit = 20;
}

View File

@ -0,0 +1,54 @@
package com.zbkj.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 缘池消息VO
*/
@Data
@ApiModel(value = "CommunityMessageVO", description = "缘池消息VO")
public class CommunityMessageVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "消息ID")
private Long id;
@ApiModelProperty(value = "用户ID")
private Integer uid;
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "用户头像")
private String avatar;
@ApiModelProperty(value = "板块ID")
private Integer categoryId;
@ApiModelProperty(value = "板块名称")
private String categoryName;
@ApiModelProperty(value = "消息内容")
private String content;
@ApiModelProperty(value = "图片列表")
private String images;
@ApiModelProperty(value = "状态 0待审核 1通过 2拒绝")
private Integer status;
@ApiModelProperty(value = "审核方式 0自动 1人工")
private Integer auditType;
@ApiModelProperty(value = "审核备注")
private String auditRemark;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,41 @@
package com.zbkj.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 附近用户VO
*/
@Data
@ApiModel(value = "NearbyUserVO", description = "附近用户VO")
public class NearbyUserVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户ID")
private Integer uid;
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "用户头像")
private String avatar;
@ApiModelProperty(value = "性别 0未知 1男 2女")
private Integer sex;
@ApiModelProperty(value = "年龄")
private Integer age;
@ApiModelProperty(value = "距离(米)")
private Double distance;
@ApiModelProperty(value = "是否在线")
private Boolean isOnline;
@ApiModelProperty(value = "个性签名")
private String signature;
}

View File

@ -0,0 +1,45 @@
package com.zbkj.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 许愿树评论VO
*/
@Data
@ApiModel(value = "WishtreeCommentVO", description = "许愿树评论VO")
public class WishtreeCommentVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "评论ID")
private Long id;
@ApiModelProperty(value = "心愿ID")
private Long wishId;
@ApiModelProperty(value = "用户ID")
private Integer uid;
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "用户头像")
private String avatar;
@ApiModelProperty(value = "评论内容")
private String content;
@ApiModelProperty(value = "父评论ID")
private Long parentId;
@ApiModelProperty(value = "回复用户昵称")
private String replyNickname;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,43 @@
package com.zbkj.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* 许愿树统计VO
*/
@Data
@ApiModel(value = "WishtreeStatisticsVO", description = "许愿树统计VO")
public class WishtreeStatisticsVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "总心愿数")
private Long totalWishes;
@ApiModelProperty(value = "今日新增")
private Long todayWishes;
@ApiModelProperty(value = "待审核数")
private Long pendingWishes;
@ApiModelProperty(value = "总点赞数")
private Long totalLikes;
@ApiModelProperty(value = "总评论数")
private Long totalComments;
@ApiModelProperty(value = "心愿趋势(日期->数量)")
private List<Map<String, Object>> wishTrend;
@ApiModelProperty(value = "节日分布(节日名->数量)")
private List<Map<String, Object>> festivalDistribution;
@ApiModelProperty(value = "热门心愿TOP10")
private List<WishtreeWishVO> hotWishes;
}

View File

@ -0,0 +1,69 @@
package com.zbkj.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 许愿树心愿VO
*/
@Data
@ApiModel(value = "WishtreeWishVO", description = "许愿树心愿VO")
public class WishtreeWishVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "心愿ID")
private Long id;
@ApiModelProperty(value = "用户ID")
private Integer uid;
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "用户头像")
private String avatar;
@ApiModelProperty(value = "节日ID")
private Integer festivalId;
@ApiModelProperty(value = "节日名称")
private String festivalName;
@ApiModelProperty(value = "节日图标")
private String festivalIcon;
@ApiModelProperty(value = "心愿内容")
private String content;
@ApiModelProperty(value = "背景ID")
private Integer backgroundId;
@ApiModelProperty(value = "背景图片")
private String backgroundImage;
@ApiModelProperty(value = "状态 0待审核 1通过 2拒绝")
private Integer status;
@ApiModelProperty(value = "审核方式 0自动 1人工")
private Integer auditType;
@ApiModelProperty(value = "审核备注")
private String auditRemark;
@ApiModelProperty(value = "点赞数")
private Integer likeCount;
@ApiModelProperty(value = "评论数")
private Integer commentCount;
@ApiModelProperty(value = "是否已点赞")
private Boolean isLiked;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,68 @@
package com.zbkj.front.controller;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.community.CommunityCategory;
import com.zbkj.common.model.community.CommunityMessage;
import com.zbkj.common.request.CommunityMessageRequest;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.vo.CommunityMessageVO;
import com.zbkj.common.vo.NearbyUserVO;
import com.zbkj.service.service.CommunityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 缘池移动端控制器
*/
@Slf4j
@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));
}
}

View File

@ -0,0 +1,122 @@
package com.zbkj.front.controller;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.wishtree.WishtreeBackground;
import com.zbkj.common.model.wishtree.WishtreeComment;
import com.zbkj.common.model.wishtree.WishtreeFestival;
import com.zbkj.common.model.wishtree.WishtreeWish;
import com.zbkj.common.request.WishtreeCommentRequest;
import com.zbkj.common.request.WishtreeWishRequest;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.vo.WishtreeCommentVO;
import com.zbkj.common.vo.WishtreeWishVO;
import com.zbkj.service.service.WishtreeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 许愿树移动端控制器
*/
@Slf4j
@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());
}
}

View File

@ -0,0 +1,12 @@
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.community.CommunityCategory;
import org.apache.ibatis.annotations.Mapper;
/**
* 缘池板块DAO
*/
@Mapper
public interface CommunityCategoryDao extends BaseMapper<CommunityCategory> {
}

View File

@ -0,0 +1,12 @@
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.community.CommunityMatchConfig;
import org.apache.ibatis.annotations.Mapper;
/**
* 缘池匹配配置DAO
*/
@Mapper
public interface CommunityMatchConfigDao extends BaseMapper<CommunityMatchConfig> {
}

View File

@ -0,0 +1,22 @@
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.community.CommunityMessage;
import com.zbkj.common.request.CommunityMessageRequest;
import com.zbkj.common.vo.CommunityMessageVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 缘池消息DAO
*/
@Mapper
public interface CommunityMessageDao extends BaseMapper<CommunityMessage> {
/**
* 查询消息列表(带用户信息和板块信息)
*/
List<CommunityMessageVO> selectMessageList(@Param("request") CommunityMessageRequest request);
}

View File

@ -0,0 +1,12 @@
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.wishtree.WishtreeBackground;
import org.apache.ibatis.annotations.Mapper;
/**
* 许愿树背景素材DAO
*/
@Mapper
public interface WishtreeBackgroundDao extends BaseMapper<WishtreeBackground> {
}

View File

@ -0,0 +1,21 @@
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.wishtree.WishtreeComment;
import com.zbkj.common.vo.WishtreeCommentVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 许愿树评论DAO
*/
@Mapper
public interface WishtreeCommentDao extends BaseMapper<WishtreeComment> {
/**
* 查询评论列表(带用户信息)
*/
List<WishtreeCommentVO> selectCommentList(@Param("wishId") Long wishId);
}

View File

@ -0,0 +1,12 @@
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.wishtree.WishtreeFestival;
import org.apache.ibatis.annotations.Mapper;
/**
* 许愿树节日DAO
*/
@Mapper
public interface WishtreeFestivalDao extends BaseMapper<WishtreeFestival> {
}

View File

@ -0,0 +1,12 @@
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.wishtree.WishtreeLike;
import org.apache.ibatis.annotations.Mapper;
/**
* 许愿树点赞DAO
*/
@Mapper
public interface WishtreeLikeDao extends BaseMapper<WishtreeLike> {
}

View File

@ -0,0 +1,58 @@
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.wishtree.WishtreeWish;
import com.zbkj.common.request.WishtreeWishRequest;
import com.zbkj.common.vo.WishtreeWishVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 许愿树心愿DAO
*/
@Mapper
public interface WishtreeWishDao extends BaseMapper<WishtreeWish> {
/**
* 查询心愿列表(带用户信息和节日信息)
*/
List<WishtreeWishVO> selectWishList(@Param("request") WishtreeWishRequest request);
/**
* 查询用户心愿列表
*/
List<WishtreeWishVO> selectMyWishList(@Param("uid") Integer uid);
/**
* 查询心愿详情
*/
WishtreeWishVO selectWishDetail(@Param("id") Long id, @Param("uid") Integer uid);
/**
* 统计今日心愿数
*/
Long countTodayWishes();
/**
* 统计待审核心愿数
*/
Long countPendingWishes();
/**
* 查询心愿趋势
*/
List<Map<String, Object>> selectWishTrend(@Param("days") Integer days);
/**
* 查询节日分布
*/
List<Map<String, Object>> selectFestivalDistribution();
/**
* 查询热门心愿
*/
List<WishtreeWishVO> selectHotWishes(@Param("limit") Integer limit);
}

View File

@ -0,0 +1,91 @@
package com.zbkj.service.service;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.community.CommunityCategory;
import com.zbkj.common.model.community.CommunityMatchConfig;
import com.zbkj.common.model.community.CommunityMessage;
import com.zbkj.common.request.CommunityMessageRequest;
import com.zbkj.common.vo.CommunityMessageVO;
import com.zbkj.common.vo.NearbyUserVO;
import java.util.List;
/**
* 缘池服务接口
*/
public interface CommunityService {
// ==================== 板块管理 ====================
/**
* 获取板块列表(管理端)
*/
List<CommunityCategory> getCategoryList();
/**
* 获取启用的板块列表(移动端)
*/
List<CommunityCategory> getEnabledCategories();
/**
* 保存板块
*/
void saveCategory(CommunityCategory category);
/**
* 删除板块
*/
void deleteCategory(Integer id);
/**
* 更新板块状态
*/
void updateCategoryStatus(Integer id, Integer status);
// ==================== 消息管理 ====================
/**
* 获取消息列表(管理端)
*/
PageInfo<CommunityMessageVO> getMessageList(CommunityMessageRequest request);
/**
* 获取消息列表(移动端)
*/
PageInfo<CommunityMessageVO> getFrontMessageList(Integer categoryId, Integer page, Integer limit);
/**
* 发布消息
*/
CommunityMessage publishMessage(CommunityMessageRequest request);
/**
* 删除我的消息
*/
void deleteMyMessage(Long id);
/**
* 审核消息
*/
void auditMessage(Long id, Integer status, String remark);
/**
* 删除消息(管理端)
*/
void deleteMessage(Long id);
// ==================== 匹配配置 ====================
/**
* 获取匹配配置
*/
CommunityMatchConfig getMatchConfig();
/**
* 保存匹配配置
*/
void saveMatchConfig(CommunityMatchConfig config);
// ==================== 用户匹配 ====================
/**
* 获取附近用户
*/
List<NearbyUserVO> getNearbyUsers(Double latitude, Double longitude, Integer radius, Integer limit);
}

View File

@ -0,0 +1,143 @@
package com.zbkj.service.service;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.wishtree.*;
import com.zbkj.common.request.WishtreeCommentRequest;
import com.zbkj.common.request.WishtreeWishRequest;
import com.zbkj.common.vo.WishtreeCommentVO;
import com.zbkj.common.vo.WishtreeStatisticsVO;
import com.zbkj.common.vo.WishtreeWishVO;
import java.util.List;
import java.util.Map;
/**
* 许愿树服务接口
*/
public interface WishtreeService {
// ==================== 节日管理 ====================
/**
* 获取节日列表(管理端)
*/
List<WishtreeFestival> getFestivalList();
/**
* 获取启用的节日列表(移动端)
*/
List<WishtreeFestival> getEnabledFestivals();
/**
* 获取当前进行中的节日
*/
WishtreeFestival getCurrentFestival();
/**
* 保存节日
*/
void saveFestival(WishtreeFestival festival);
/**
* 删除节日
*/
void deleteFestival(Integer id);
/**
* 更新节日状态
*/
void updateFestivalStatus(Integer id, Integer status);
// ==================== 心愿管理 ====================
/**
* 获取心愿列表(管理端)
*/
PageInfo<WishtreeWishVO> getWishList(WishtreeWishRequest request);
/**
* 获取心愿列表(移动端)
*/
PageInfo<WishtreeWishVO> getFrontWishList(Integer festivalId, Integer page, Integer limit);
/**
* 获取我的心愿列表
*/
PageInfo<WishtreeWishVO> getMyWishList(Integer page, Integer limit);
/**
* 发布心愿
*/
WishtreeWish publishWish(WishtreeWishRequest request);
/**
* 获取心愿详情
*/
WishtreeWishVO getWishDetail(Long id);
/**
* 删除我的心愿
*/
void deleteMyWish(Long id);
/**
* 审核心愿
*/
void auditWish(Long id, Integer status, String remark);
/**
* 删除心愿(管理端)
*/
void deleteWish(Long id);
// ==================== 互动相关 ====================
/**
* 点赞心愿
*/
void likeWish(Long wishId);
/**
* 取消点赞
*/
void unlikeWish(Long wishId);
/**
* 获取评论列表
*/
PageInfo<WishtreeCommentVO> getCommentList(Long wishId, Integer page, Integer limit);
/**
* 发表评论
*/
WishtreeComment addComment(Long wishId, WishtreeCommentRequest request);
// ==================== 背景素材 ====================
/**
* 获取背景列表(管理端)
*/
List<WishtreeBackground> getBackgroundList();
/**
* 获取启用的背景列表(移动端)
*/
List<WishtreeBackground> getEnabledBackgrounds();
/**
* 保存背景
*/
void saveBackground(WishtreeBackground background);
/**
* 删除背景
*/
void deleteBackground(Integer id);
// ==================== 数据统计 ====================
/**
* 获取统计数据
*/
WishtreeStatisticsVO getStatistics(Integer days);
/**
* 获取心愿趋势
*/
List<Map<String, Object>> getWishTrend(Integer days);
}

View File

@ -0,0 +1,211 @@
package com.zbkj.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.community.CommunityCategory;
import com.zbkj.common.model.community.CommunityMatchConfig;
import com.zbkj.common.model.community.CommunityMessage;
import com.zbkj.common.request.CommunityMessageRequest;
import com.zbkj.common.vo.CommunityMessageVO;
import com.zbkj.common.vo.NearbyUserVO;
import com.zbkj.service.dao.CommunityCategoryDao;
import com.zbkj.service.dao.CommunityMatchConfigDao;
import com.zbkj.service.dao.CommunityMessageDao;
import com.zbkj.service.service.CommunityService;
import com.zbkj.service.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 缘池服务实现
*/
@Service
public class CommunityServiceImpl implements CommunityService {
@Autowired
private CommunityCategoryDao categoryDao;
@Autowired
private CommunityMessageDao messageDao;
@Autowired
private CommunityMatchConfigDao matchConfigDao;
@Autowired
private UserService userService;
// ==================== 板块管理 ====================
@Override
public List<CommunityCategory> getCategoryList() {
return categoryDao.selectList(new LambdaQueryWrapper<CommunityCategory>()
.orderByDesc(CommunityCategory::getSort));
}
@Override
public List<CommunityCategory> getEnabledCategories() {
return categoryDao.selectList(new LambdaQueryWrapper<CommunityCategory>()
.eq(CommunityCategory::getStatus, 1)
.orderByDesc(CommunityCategory::getSort));
}
@Override
public void saveCategory(CommunityCategory category) {
if (category.getId() != null) {
category.setUpdateTime(new Date());
categoryDao.updateById(category);
} else {
category.setCreateTime(new Date());
category.setUpdateTime(new Date());
categoryDao.insert(category);
}
}
@Override
public void deleteCategory(Integer id) {
categoryDao.deleteById(id);
}
@Override
public void updateCategoryStatus(Integer id, Integer status) {
CommunityCategory category = new CommunityCategory();
category.setId(id);
category.setStatus(status);
category.setUpdateTime(new Date());
categoryDao.updateById(category);
}
// ==================== 消息管理 ====================
@Override
public PageInfo<CommunityMessageVO> getMessageList(CommunityMessageRequest request) {
PageHelper.startPage(request.getPage(), request.getLimit());
List<CommunityMessageVO> list = messageDao.selectMessageList(request);
return new PageInfo<>(list);
}
@Override
public PageInfo<CommunityMessageVO> getFrontMessageList(Integer categoryId, Integer page, Integer limit) {
CommunityMessageRequest request = new CommunityMessageRequest();
request.setCategoryId(categoryId);
request.setStatus(1); // 只显示已通过的
request.setPage(page);
request.setLimit(limit);
PageHelper.startPage(page, limit);
List<CommunityMessageVO> list = messageDao.selectMessageList(request);
return new PageInfo<>(list);
}
@Override
public CommunityMessage publishMessage(CommunityMessageRequest request) {
Integer uid = userService.getUserIdException();
CommunityMessage message = new CommunityMessage();
message.setUid(uid);
message.setCategoryId(request.getCategoryId());
message.setContent(request.getContent());
message.setImages(request.getImages());
message.setIsDelete(0);
message.setCreateTime(new Date());
message.setUpdateTime(new Date());
// 自动审核
autoAuditMessage(message);
messageDao.insert(message);
return message;
}
@Override
public void deleteMyMessage(Long id) {
Integer uid = userService.getUserIdException();
CommunityMessage message = messageDao.selectById(id);
if (message == null || !message.getUid().equals(uid)) {
throw new CrmebException("消息不存在或无权删除");
}
message.setIsDelete(1);
message.setUpdateTime(new Date());
messageDao.updateById(message);
}
@Override
public void auditMessage(Long id, Integer status, String remark) {
CommunityMessage message = new CommunityMessage();
message.setId(id);
message.setStatus(status);
message.setAuditType(1); // 人工审核
message.setAuditRemark(remark);
message.setUpdateTime(new Date());
messageDao.updateById(message);
}
@Override
public void deleteMessage(Long id) {
LambdaUpdateWrapper<CommunityMessage> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(CommunityMessage::getId, id)
.set(CommunityMessage::getIsDelete, 1)
.set(CommunityMessage::getUpdateTime, new Date());
messageDao.update(null, wrapper);
}
// ==================== 匹配配置 ====================
@Override
public CommunityMatchConfig getMatchConfig() {
CommunityMatchConfig config = matchConfigDao.selectById(1);
if (config == null) {
config = new CommunityMatchConfig();
config.setId(1);
config.setMatchRadius(5);
config.setRecommendCount(6);
config.setPriorityOnline(1);
config.setPrioritySameCity(1);
config.setPriorityOppositeSex(1);
config.setAutoAudit(1);
matchConfigDao.insert(config);
}
return config;
}
@Override
public void saveMatchConfig(CommunityMatchConfig config) {
config.setId(1);
config.setUpdateTime(new Date());
matchConfigDao.updateById(config);
}
// ==================== 用户匹配 ====================
@Override
public List<NearbyUserVO> getNearbyUsers(Double latitude, Double longitude, Integer radius, Integer limit) {
// TODO: 实现基于位置的用户匹配逻辑
// 这里需要根据用户表中的经纬度字段进行距离计算
return new ArrayList<>();
}
// ==================== 自动审核 ====================
private void autoAuditMessage(CommunityMessage message) {
CommunityMatchConfig config = getMatchConfig();
if (config.getAutoAudit() != 1) {
message.setStatus(0); // 待审核
return;
}
// 简单的敏感词检测(实际项目中应使用敏感词库)
String content = message.getContent();
if (content == null || content.trim().isEmpty()) {
message.setStatus(2); // 拒绝
message.setAuditRemark("内容不能为空");
message.setAuditType(0);
return;
}
// 默认通过
message.setStatus(1);
message.setAuditRemark("自动审核通过");
message.setAuditType(0);
}
}

View File

@ -0,0 +1,347 @@
package com.zbkj.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.wishtree.*;
import com.zbkj.common.request.WishtreeCommentRequest;
import com.zbkj.common.request.WishtreeWishRequest;
import com.zbkj.common.vo.WishtreeCommentVO;
import com.zbkj.common.vo.WishtreeStatisticsVO;
import com.zbkj.common.vo.WishtreeWishVO;
import com.zbkj.service.dao.*;
import com.zbkj.service.service.UserService;
import com.zbkj.service.service.WishtreeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 许愿树服务实现
*/
@Service
public class WishtreeServiceImpl implements WishtreeService {
@Autowired
private WishtreeFestivalDao festivalDao;
@Autowired
private WishtreeWishDao wishDao;
@Autowired
private WishtreeLikeDao likeDao;
@Autowired
private WishtreeCommentDao commentDao;
@Autowired
private WishtreeBackgroundDao backgroundDao;
@Autowired
private UserService userService;
// ==================== 节日管理 ====================
@Override
public List<WishtreeFestival> getFestivalList() {
return festivalDao.selectList(new LambdaQueryWrapper<WishtreeFestival>()
.orderByDesc(WishtreeFestival::getSort));
}
@Override
public List<WishtreeFestival> getEnabledFestivals() {
return festivalDao.selectList(new LambdaQueryWrapper<WishtreeFestival>()
.eq(WishtreeFestival::getStatus, 1)
.orderByDesc(WishtreeFestival::getSort));
}
@Override
public WishtreeFestival getCurrentFestival() {
// 简单实现返回第一个启用的节日
List<WishtreeFestival> list = getEnabledFestivals();
return list.isEmpty() ? null : list.get(0);
}
@Override
public void saveFestival(WishtreeFestival festival) {
if (festival.getId() != null) {
festival.setUpdateTime(new Date());
festivalDao.updateById(festival);
} else {
festival.setCreateTime(new Date());
festival.setUpdateTime(new Date());
festivalDao.insert(festival);
}
}
@Override
public void deleteFestival(Integer id) {
festivalDao.deleteById(id);
}
@Override
public void updateFestivalStatus(Integer id, Integer status) {
WishtreeFestival festival = new WishtreeFestival();
festival.setId(id);
festival.setStatus(status);
festival.setUpdateTime(new Date());
festivalDao.updateById(festival);
}
// ==================== 心愿管理 ====================
@Override
public PageInfo<WishtreeWishVO> getWishList(WishtreeWishRequest request) {
PageHelper.startPage(request.getPage(), request.getLimit());
List<WishtreeWishVO> list = wishDao.selectWishList(request);
return new PageInfo<>(list);
}
@Override
public PageInfo<WishtreeWishVO> getFrontWishList(Integer festivalId, Integer page, Integer limit) {
WishtreeWishRequest request = new WishtreeWishRequest();
request.setFestivalId(festivalId);
request.setStatus(1); // 只显示已通过的
request.setPage(page);
request.setLimit(limit);
PageHelper.startPage(page, limit);
List<WishtreeWishVO> list = wishDao.selectWishList(request);
return new PageInfo<>(list);
}
@Override
public PageInfo<WishtreeWishVO> getMyWishList(Integer page, Integer limit) {
Integer uid = userService.getUserIdException();
PageHelper.startPage(page, limit);
List<WishtreeWishVO> list = wishDao.selectMyWishList(uid);
return new PageInfo<>(list);
}
@Override
public WishtreeWish publishWish(WishtreeWishRequest request) {
Integer uid = userService.getUserIdException();
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);
wish.setCreateTime(new Date());
wish.setUpdateTime(new Date());
// 自动审核
autoAuditWish(wish);
wishDao.insert(wish);
return wish;
}
@Override
public WishtreeWishVO getWishDetail(Long id) {
Integer uid = userService.getUserId();
return wishDao.selectWishDetail(id, uid);
}
@Override
public void deleteMyWish(Long id) {
Integer uid = userService.getUserIdException();
WishtreeWish wish = wishDao.selectById(id);
if (wish == null || !wish.getUid().equals(uid)) {
throw new CrmebException("心愿不存在或无权删除");
}
wish.setIsDelete(1);
wish.setUpdateTime(new Date());
wishDao.updateById(wish);
}
@Override
public void auditWish(Long id, Integer status, String remark) {
WishtreeWish wish = new WishtreeWish();
wish.setId(id);
wish.setStatus(status);
wish.setAuditType(1); // 人工审核
wish.setAuditRemark(remark);
wish.setUpdateTime(new Date());
wishDao.updateById(wish);
}
@Override
public void deleteWish(Long id) {
LambdaUpdateWrapper<WishtreeWish> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(WishtreeWish::getId, id)
.set(WishtreeWish::getIsDelete, 1)
.set(WishtreeWish::getUpdateTime, new Date());
wishDao.update(null, wrapper);
}
// ==================== 互动相关 ====================
@Override
@Transactional
public void likeWish(Long wishId) {
Integer uid = userService.getUserIdException();
// 检查是否已点赞
LambdaQueryWrapper<WishtreeLike> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(WishtreeLike::getUid, uid).eq(WishtreeLike::getWishId, wishId);
if (likeDao.selectCount(wrapper) > 0) {
throw new CrmebException("已经点赞过了");
}
// 添加点赞记录
WishtreeLike like = new WishtreeLike();
like.setUid(uid);
like.setWishId(wishId);
like.setCreateTime(new Date());
likeDao.insert(like);
// 更新点赞数
WishtreeWish wish = wishDao.selectById(wishId);
if (wish != null) {
wish.setLikeCount(wish.getLikeCount() + 1);
wishDao.updateById(wish);
}
}
@Override
@Transactional
public void unlikeWish(Long wishId) {
Integer uid = userService.getUserIdException();
// 删除点赞记录
LambdaQueryWrapper<WishtreeLike> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(WishtreeLike::getUid, uid).eq(WishtreeLike::getWishId, wishId);
int deleted = likeDao.delete(wrapper);
// 更新点赞数
if (deleted > 0) {
WishtreeWish wish = wishDao.selectById(wishId);
if (wish != null && wish.getLikeCount() > 0) {
wish.setLikeCount(wish.getLikeCount() - 1);
wishDao.updateById(wish);
}
}
}
@Override
public PageInfo<WishtreeCommentVO> getCommentList(Long wishId, Integer page, Integer limit) {
PageHelper.startPage(page, limit);
List<WishtreeCommentVO> list = commentDao.selectCommentList(wishId);
return new PageInfo<>(list);
}
@Override
@Transactional
public WishtreeComment addComment(Long wishId, WishtreeCommentRequest request) {
Integer uid = userService.getUserIdException();
WishtreeComment comment = new WishtreeComment();
comment.setWishId(wishId);
comment.setUid(uid);
comment.setContent(request.getContent());
comment.setParentId(request.getParentId() != null ? request.getParentId() : 0L);
comment.setStatus(1); // 默认通过
comment.setIsDelete(0);
comment.setCreateTime(new Date());
commentDao.insert(comment);
// 更新评论数
WishtreeWish wish = wishDao.selectById(wishId);
if (wish != null) {
wish.setCommentCount(wish.getCommentCount() + 1);
wishDao.updateById(wish);
}
return comment;
}
// ==================== 背景素材 ====================
@Override
public List<WishtreeBackground> getBackgroundList() {
return backgroundDao.selectList(new LambdaQueryWrapper<WishtreeBackground>()
.orderByDesc(WishtreeBackground::getSort));
}
@Override
public List<WishtreeBackground> getEnabledBackgrounds() {
return backgroundDao.selectList(new LambdaQueryWrapper<WishtreeBackground>()
.eq(WishtreeBackground::getStatus, 1)
.orderByDesc(WishtreeBackground::getSort));
}
@Override
public void saveBackground(WishtreeBackground background) {
if (background.getId() != null) {
backgroundDao.updateById(background);
} else {
background.setCreateTime(new Date());
backgroundDao.insert(background);
}
}
@Override
public void deleteBackground(Integer id) {
backgroundDao.deleteById(id);
}
// ==================== 数据统计 ====================
@Override
public WishtreeStatisticsVO getStatistics(Integer days) {
WishtreeStatisticsVO vo = new WishtreeStatisticsVO();
// 总心愿数
vo.setTotalWishes(Long.valueOf(wishDao.selectCount(new LambdaQueryWrapper<WishtreeWish>()
.eq(WishtreeWish::getIsDelete, 0))));
// 今日新增
vo.setTodayWishes(wishDao.countTodayWishes());
// 待审核数
vo.setPendingWishes(wishDao.countPendingWishes());
// 总点赞数
vo.setTotalLikes(Long.valueOf(likeDao.selectCount(null)));
// 总评论数
vo.setTotalComments(Long.valueOf(commentDao.selectCount(new LambdaQueryWrapper<WishtreeComment>()
.eq(WishtreeComment::getIsDelete, 0))));
// 心愿趋势
vo.setWishTrend(wishDao.selectWishTrend(days));
// 节日分布
vo.setFestivalDistribution(wishDao.selectFestivalDistribution());
// 热门心愿
vo.setHotWishes(wishDao.selectHotWishes(10));
return vo;
}
@Override
public List<Map<String, Object>> getWishTrend(Integer days) {
return wishDao.selectWishTrend(days);
}
// ==================== 自动审核 ====================
private void autoAuditWish(WishtreeWish wish) {
String content = wish.getContent();
if (content == null || content.trim().isEmpty()) {
wish.setStatus(2); // 拒绝
wish.setAuditRemark("内容不能为空");
wish.setAuditType(0);
return;
}
// 默认通过
wish.setStatus(1);
wish.setAuditRemark("自动审核通过");
wish.setAuditType(0);
}
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zbkj.service.dao.CommunityMessageDao">
<select id="selectMessageList" resultType="com.zbkj.common.vo.CommunityMessageVO">
SELECT
m.id,
m.uid,
u.nickname,
u.avatar,
m.category_id AS categoryId,
c.name AS categoryName,
m.content,
m.images,
m.status,
m.audit_type AS auditType,
m.audit_remark AS auditRemark,
m.create_time AS createTime
FROM eb_community_message m
LEFT JOIN eb_user u ON m.uid = u.uid
LEFT JOIN eb_community_category c ON m.category_id = c.id
WHERE m.is_delete = 0
<if test="request.categoryId != null">
AND m.category_id = #{request.categoryId}
</if>
<if test="request.status != null">
AND m.status = #{request.status}
</if>
<if test="request.keywords != null and request.keywords != ''">
AND m.content LIKE CONCAT('%', #{request.keywords}, '%')
</if>
<if test="request.startTime != null and request.startTime != ''">
AND m.create_time &gt;= #{request.startTime}
</if>
<if test="request.endTime != null and request.endTime != ''">
AND m.create_time &lt;= #{request.endTime}
</if>
ORDER BY m.create_time DESC
</select>
</mapper>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zbkj.service.dao.WishtreeCommentDao">
<select id="selectCommentList" resultType="com.zbkj.common.vo.WishtreeCommentVO">
SELECT
c.id,
c.wish_id AS wishId,
c.uid,
u.nickname,
u.avatar,
c.content,
c.parent_id AS parentId,
pu.nickname AS replyNickname,
c.create_time AS createTime
FROM eb_wishtree_comment c
LEFT JOIN eb_user u ON c.uid = u.uid
LEFT JOIN eb_wishtree_comment pc ON c.parent_id = pc.id
LEFT JOIN eb_user pu ON pc.uid = pu.uid
WHERE c.wish_id = #{wishId} AND c.status = 1 AND c.is_delete = 0
ORDER BY c.create_time ASC
</select>
</mapper>

View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zbkj.service.dao.WishtreeWishDao">
<select id="selectWishList" resultType="com.zbkj.common.vo.WishtreeWishVO">
SELECT
w.id,
w.uid,
u.nickname,
u.avatar,
w.festival_id AS festivalId,
f.name AS festivalName,
f.icon AS festivalIcon,
w.content,
w.background_id AS backgroundId,
b.image AS backgroundImage,
w.status,
w.audit_type AS auditType,
w.audit_remark AS auditRemark,
w.like_count AS likeCount,
w.comment_count AS commentCount,
w.create_time AS createTime
FROM eb_wishtree_wish w
LEFT JOIN eb_user u ON w.uid = u.uid
LEFT JOIN eb_wishtree_festival f ON w.festival_id = f.id
LEFT JOIN eb_wishtree_background b ON w.background_id = b.id
WHERE w.is_delete = 0
<if test="request.festivalId != null">
AND w.festival_id = #{request.festivalId}
</if>
<if test="request.status != null">
AND w.status = #{request.status}
</if>
<if test="request.keywords != null and request.keywords != ''">
AND w.content LIKE CONCAT('%', #{request.keywords}, '%')
</if>
<if test="request.startTime != null and request.startTime != ''">
AND w.create_time &gt;= #{request.startTime}
</if>
<if test="request.endTime != null and request.endTime != ''">
AND w.create_time &lt;= #{request.endTime}
</if>
ORDER BY w.create_time DESC
</select>
<select id="selectMyWishList" resultType="com.zbkj.common.vo.WishtreeWishVO">
SELECT
w.id,
w.uid,
w.festival_id AS festivalId,
f.name AS festivalName,
f.icon AS festivalIcon,
w.content,
w.background_id AS backgroundId,
b.image AS backgroundImage,
w.status,
w.like_count AS likeCount,
w.comment_count AS commentCount,
w.create_time AS createTime
FROM eb_wishtree_wish w
LEFT JOIN eb_wishtree_festival f ON w.festival_id = f.id
LEFT JOIN eb_wishtree_background b ON w.background_id = b.id
WHERE w.uid = #{uid} AND w.is_delete = 0
ORDER BY w.create_time DESC
</select>
<select id="selectWishDetail" resultType="com.zbkj.common.vo.WishtreeWishVO">
SELECT
w.id,
w.uid,
u.nickname,
u.avatar,
w.festival_id AS festivalId,
f.name AS festivalName,
f.icon AS festivalIcon,
w.content,
w.background_id AS backgroundId,
b.image AS backgroundImage,
w.status,
w.like_count AS likeCount,
w.comment_count AS commentCount,
w.create_time AS createTime,
(SELECT COUNT(1) FROM eb_wishtree_like l WHERE l.wish_id = w.id AND l.uid = #{uid}) > 0 AS isLiked
FROM eb_wishtree_wish w
LEFT JOIN eb_user u ON w.uid = u.uid
LEFT JOIN eb_wishtree_festival f ON w.festival_id = f.id
LEFT JOIN eb_wishtree_background b ON w.background_id = b.id
WHERE w.id = #{id} AND w.is_delete = 0
</select>
<select id="countTodayWishes" resultType="java.lang.Long">
SELECT COUNT(1) FROM eb_wishtree_wish
WHERE DATE(create_time) = CURDATE() AND is_delete = 0
</select>
<select id="countPendingWishes" resultType="java.lang.Long">
SELECT COUNT(1) FROM eb_wishtree_wish
WHERE status = 0 AND is_delete = 0
</select>
<select id="selectWishTrend" resultType="java.util.Map">
SELECT
DATE(create_time) AS date,
COUNT(1) AS count
FROM eb_wishtree_wish
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL #{days} DAY) AND is_delete = 0
GROUP BY DATE(create_time)
ORDER BY date
</select>
<select id="selectFestivalDistribution" resultType="java.util.Map">
SELECT
f.name AS festivalName,
COUNT(w.id) AS count
FROM eb_wishtree_wish w
LEFT JOIN eb_wishtree_festival f ON w.festival_id = f.id
WHERE w.is_delete = 0
GROUP BY w.festival_id
ORDER BY count DESC
</select>
<select id="selectHotWishes" resultType="com.zbkj.common.vo.WishtreeWishVO">
SELECT
w.id,
w.uid,
u.nickname,
u.avatar,
w.content,
w.like_count AS likeCount,
w.comment_count AS commentCount,
w.create_time AS createTime
FROM eb_wishtree_wish w
LEFT JOIN eb_user u ON w.uid = u.uid
WHERE w.status = 1 AND w.is_delete = 0
ORDER BY w.like_count DESC
LIMIT #{limit}
</select>
</mapper>

View File

@ -0,0 +1,101 @@
-- ============================================
-- 检查管理端所有关键表的数据情况
-- 执行此脚本可查看各模块数据统计
-- ============================================
-- 1. 用户数据统计
SELECT '========== 用户数据 ==========' AS '模块';
SELECT 'eb_user (用户表)' AS '表名', COUNT(*) AS '数量' FROM eb_user;
SELECT 'eb_user_address (用户地址)' AS '表名', COUNT(*) AS '数量' FROM eb_user_address;
SELECT 'eb_user_bill (用户账单)' AS '表名', COUNT(*) AS '数量' FROM eb_user_bill;
SELECT 'eb_user_sign (签到记录)' AS '表名', COUNT(*) AS '数量' FROM eb_user_sign;
-- 2. 社交数据统计
SELECT '========== 社交数据 ==========' AS '模块';
SELECT 'eb_dynamic (动态)' AS '表名', COUNT(*) AS '数量' FROM eb_dynamic;
SELECT 'eb_dynamic_comment (动态评论)' AS '表名', COUNT(*) AS '数量' FROM eb_dynamic_comment;
SELECT 'eb_follow (关注记录)' AS '表名', COUNT(*) AS '数量' FROM eb_follow;
-- 3. 家族数据统计
SELECT '========== 家族数据 ==========' AS '模块';
SELECT 'eb_family (家族)' AS '表名', COUNT(*) AS '数量' FROM eb_family;
SELECT 'eb_family_member (家族成员)' AS '表名', COUNT(*) AS '数量' FROM eb_family_member;
-- 4. 粉丝团数据统计
SELECT '========== 粉丝团数据 ==========' AS '模块';
SELECT 'eb_fan_group (粉丝团)' AS '表名', COUNT(*) AS '数量' FROM eb_fan_group;
SELECT 'eb_fan_group_member (粉丝团成员)' AS '表名', COUNT(*) AS '数量' FROM eb_fan_group_member;
-- 5. 通话会话数据统计
SELECT '========== 通话会话数据 ==========' AS '模块';
SELECT 'eb_call (通话记录)' AS '表名', COUNT(*) AS '数量' FROM eb_call;
SELECT 'eb_session (会话记录)' AS '表名', COUNT(*) AS '数量' FROM eb_session;
-- 6. 运营数据统计
SELECT '========== 运营数据 ==========' AS '模块';
SELECT 'eb_banner (轮播图)' AS '表名', COUNT(*) AS '数量' FROM eb_banner;
SELECT 'eb_system_message (系统消息)' AS '表名', COUNT(*) AS '数量' FROM eb_system_message;
SELECT 'eb_novice_task (新手任务)' AS '表名', COUNT(*) AS '数量' FROM eb_novice_task;
SELECT 'eb_lottery (抽奖活动)' AS '表名', COUNT(*) AS '数量' FROM eb_lottery;
SELECT 'eb_lottery_prize (抽奖奖品)' AS '表名', COUNT(*) AS '数量' FROM eb_lottery_prize;
SELECT 'eb_lottery_record (抽奖记录)' AS '表名', COUNT(*) AS '数量' FROM eb_lottery_record;
SELECT 'eb_activity (平台活动)' AS '表名', COUNT(*) AS '数量' FROM eb_activity;
-- 7. 礼物数据统计
SELECT '========== 礼物数据 ==========' AS '模块';
SELECT 'eb_gift (礼物配置)' AS '表名', COUNT(*) AS '数量' FROM eb_gift;
SELECT 'eb_gift_record (礼物记录)' AS '表名', COUNT(*) AS '数量' FROM eb_gift_record;
-- 8. 财务数据统计
SELECT '========== 财务数据 ==========' AS '模块';
SELECT 'eb_withdraw (提现记录)' AS '表名', COUNT(*) AS '数量' FROM eb_withdraw;
SELECT 'eb_recharge_order (充值订单)' AS '表名', COUNT(*) AS '数量' FROM eb_recharge_order;
SELECT 'eb_exchange_record (兑换记录)' AS '表名', COUNT(*) AS '数量' FROM eb_exchange_record;
-- 9. 审核数据统计
SELECT '========== 审核数据 ==========' AS '模块';
SELECT 'eb_certification (认证申请)' AS '表名', COUNT(*) AS '数量' FROM eb_certification;
SELECT 'eb_appeal (申诉记录)' AS '表名', COUNT(*) AS '数量' FROM eb_appeal;
SELECT 'eb_report (举报记录)' AS '表名', COUNT(*) AS '数量' FROM eb_report;
SELECT 'eb_feedback (用户反馈)' AS '表名', COUNT(*) AS '数量' FROM eb_feedback;
-- 10. 安全数据统计
SELECT '========== 安全数据 ==========' AS '模块';
SELECT 'eb_sensitive_word (敏感词)' AS '表名', COUNT(*) AS '数量' FROM eb_sensitive_word;
SELECT 'eb_blacklist (黑名单)' AS '表名', COUNT(*) AS '数量' FROM eb_blacklist;
-- 11. 缘池数据统计
SELECT '========== 缘池数据 ==========' AS '模块';
SELECT 'eb_community_category (板块)' AS '表名', COUNT(*) AS '数量' FROM eb_community_category;
SELECT 'eb_community_message (消息)' AS '表名', COUNT(*) AS '数量' FROM eb_community_message WHERE is_delete = 0;
SELECT 'eb_community_match_config (匹配配置)' AS '表名', COUNT(*) AS '数量' FROM eb_community_match_config;
-- 12. 许愿树数据统计
SELECT '========== 许愿树数据 ==========' AS '模块';
SELECT 'eb_wishtree_festival (节日)' AS '表名', COUNT(*) AS '数量' FROM eb_wishtree_festival;
SELECT 'eb_wishtree_wish (心愿)' AS '表名', COUNT(*) AS '数量' FROM eb_wishtree_wish WHERE is_delete = 0;
SELECT 'eb_wishtree_like (点赞)' AS '表名', COUNT(*) AS '数量' FROM eb_wishtree_like;
SELECT 'eb_wishtree_comment (评论)' AS '表名', COUNT(*) AS '数量' FROM eb_wishtree_comment WHERE is_delete = 0;
SELECT 'eb_wishtree_background (背景)' AS '表名', COUNT(*) AS '数量' FROM eb_wishtree_background;
-- 13. 聊天数据统计
SELECT '========== 聊天数据 ==========' AS '模块';
SELECT 'eb_chat_phrase (聊天常用语)' AS '表名', COUNT(*) AS '数量' FROM eb_chat_phrase;
-- 14. 任务数据统计
SELECT '========== 任务数据 ==========' AS '模块';
SELECT 'eb_user_task (用户任务进度)' AS '表名', COUNT(*) AS '数量' FROM eb_user_task;
-- ============================================
-- 数据汇总
-- ============================================
SELECT '========== 数据汇总 ==========' AS '模块';
SELECT
(SELECT COUNT(*) FROM eb_user) AS '用户数',
(SELECT COUNT(*) FROM eb_dynamic) AS '动态数',
(SELECT COUNT(*) FROM eb_family) AS '家族数',
(SELECT COUNT(*) FROM eb_fan_group) AS '粉丝团数',
(SELECT COUNT(*) FROM eb_gift) AS '礼物数',
(SELECT COUNT(*) FROM eb_withdraw) AS '提现数',
(SELECT COUNT(*) FROM eb_certification) AS '认证数',
(SELECT COUNT(*) FROM eb_report) AS '举报数';

View File

@ -0,0 +1,59 @@
-- 检查数据是否正确插入
-- 1. 检查缘池板块
SELECT COUNT(*) AS category_count FROM eb_community_category;
-- 2. 检查缘池消息
SELECT COUNT(*) AS message_count FROM eb_community_message WHERE is_delete = 0;
-- 3. 检查许愿树节日
SELECT COUNT(*) AS festival_count FROM eb_wishtree_festival;
-- 4. 检查许愿树心愿
SELECT COUNT(*) AS wish_count FROM eb_wishtree_wish WHERE is_delete = 0;
-- 5. 检查心愿点赞
SELECT COUNT(*) AS like_count FROM eb_wishtree_like;
-- 6. 检查心愿评论
SELECT COUNT(*) AS comment_count FROM eb_wishtree_comment WHERE is_delete = 0;
-- 7. 检查背景素材
SELECT COUNT(*) AS background_count FROM eb_wishtree_background;
-- 8. 检查匹配配置
SELECT * FROM eb_community_match_config;
-- 9. 查看消息列表(带用户信息)
SELECT
m.id,
m.uid,
u.nickname,
c.name AS categoryName,
m.content,
m.status,
m.create_time
FROM eb_community_message m
LEFT JOIN eb_user u ON m.uid = u.uid
LEFT JOIN eb_community_category c ON m.category_id = c.id
WHERE m.is_delete = 0
ORDER BY m.create_time DESC
LIMIT 10;
-- 10. 查看心愿列表(带用户信息)
SELECT
w.id,
w.uid,
u.nickname,
f.name AS festivalName,
w.content,
w.status,
w.like_count,
w.comment_count,
w.create_time
FROM eb_wishtree_wish w
LEFT JOIN eb_user u ON w.uid = u.uid
LEFT JOIN eb_wishtree_festival f ON w.festival_id = f.id
WHERE w.is_delete = 0
ORDER BY w.create_time DESC
LIMIT 10;

View File

@ -0,0 +1,29 @@
-- ============================================
-- 检查虚拟道具相关表的数据
-- ============================================
-- 1. 检查坐骑表
SELECT '========== 坐骑表 eb_mount ==========' AS '模块';
SELECT COUNT(*) AS '坐骑数量' FROM eb_mount;
SELECT * FROM eb_mount LIMIT 5;
-- 2. 检查坐骑购买记录表
SELECT '========== 坐骑购买记录 eb_mount_order ==========' AS '模块';
SELECT COUNT(*) AS '购买记录数量' FROM eb_mount_order;
SELECT * FROM eb_mount_order LIMIT 5;
-- 3. 检查头饰表
SELECT '========== 头饰表 eb_headwear ==========' AS '模块';
SELECT COUNT(*) AS '头饰数量' FROM eb_headwear;
SELECT * FROM eb_headwear LIMIT 5;
-- 4. 检查礼物表
SELECT '========== 礼物表 eb_gift ==========' AS '模块';
SELECT COUNT(*) AS '礼物数量' FROM eb_gift;
SELECT * FROM eb_gift LIMIT 5;
-- 5. 检查表结构
SELECT '========== 表结构检查 ==========' AS '模块';
SHOW TABLES LIKE 'eb_mount%';
SHOW TABLES LIKE 'eb_headwear%';
SHOW TABLES LIKE 'eb_gift%';

View File

@ -0,0 +1,203 @@
-- ============================================
-- 缘池与许愿树数据库表
-- 版本: V2.0
-- 日期: 2025-12-30
-- ============================================
-- ============================================
-- 一、缘池相关表
-- ============================================
-- 1. 板块表
CREATE TABLE IF NOT EXISTS `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 COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缘池板块表';
-- 2. 消息表
CREATE TABLE IF NOT EXISTS `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 '是否删除 0否 1是',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
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 IF NOT EXISTS `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 '优先在线用户 0否 1是',
`priority_same_city` tinyint DEFAULT 1 COMMENT '优先同城用户 0否 1是',
`priority_opposite_sex` tinyint DEFAULT 1 COMMENT '优先异性用户 0否 1是',
`auto_audit` tinyint DEFAULT 1 COMMENT '自动审核开关 0关 1开',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缘池匹配配置表';
-- ============================================
-- 二、许愿树相关表
-- ============================================
-- 1. 节日表
CREATE TABLE IF NOT EXISTS `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 COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树节日表';
-- 2. 心愿表
CREATE TABLE IF NOT EXISTS `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 '是否删除 0否 1是',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_uid` (`uid`),
KEY `idx_festival` (`festival_id`),
KEY `idx_status` (`status`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树心愿表';
-- 3. 心愿点赞表
CREATE TABLE IF NOT EXISTS `eb_wishtree_like` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '点赞ID',
`uid` int NOT NULL COMMENT '用户ID',
`wish_id` bigint NOT NULL COMMENT '心愿ID',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
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 IF NOT EXISTS `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 '是否删除 0否 1是',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_wish` (`wish_id`),
KEY `idx_uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树评论表';
-- 5. 背景素材表
CREATE TABLE IF NOT EXISTS `eb_wishtree_background` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '背景ID',
`name` varchar(50) NOT NULL COMMENT '背景名称',
`image` varchar(255) NOT NULL COMMENT '背景图片URL',
`festival_id` int DEFAULT 0 COMMENT '关联节日ID(0=通用)',
`sort` int DEFAULT 0 COMMENT '排序(越大越靠前)',
`status` tinyint DEFAULT 1 COMMENT '状态 0禁用 1启用',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_festival` (`festival_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许愿树背景素材表';
-- ============================================
-- 三、初始化数据
-- ============================================
-- 初始化匹配配置
INSERT INTO `eb_community_match_config` (`id`, `match_radius`, `recommend_count`, `priority_online`, `priority_same_city`, `priority_opposite_sex`, `auto_audit`)
VALUES (1, 5, 6, 1, 1, 1, 1)
ON DUPLICATE KEY UPDATE `id` = `id`;
-- 初始化缘池板块
INSERT INTO `eb_community_category` (`name`, `icon`, `type`, `jump_page`, `sort`, `status`) VALUES
('语音匹配', 'el-icon-microphone', 'quick', 'VoiceMatchActivity', 100, 1),
('心动信号', 'el-icon-star-on', 'quick', 'HeartbeatSignalActivity', 99, 1),
('在线处对象', 'el-icon-user', 'card', 'OnlineDatingActivity', 90, 1),
('找人玩游戏', 'el-icon-video-play', 'card', 'FindGameActivity', 89, 1),
('一起KTV', 'el-icon-headset', 'card', 'KTVTogetherActivity', 88, 1),
('你画我猜', 'el-icon-edit', 'card', 'DrawGuessActivity', 87, 1),
('和平精英', 'el-icon-aim', 'card', 'PeaceEliteActivity', 86, 1),
('桌游', 'el-icon-s-grid', 'card', 'TableGamesActivity', 85, 1);
-- 初始化节日数据
INSERT INTO `eb_wishtree_festival` (`name`, `icon`, `start_date`, `end_date`, `is_lunar`, `theme_color`, `sort`, `status`) VALUES
('元旦', '🎉', '12-31', '01-03', 0, '#FF6B6B', 100, 1),
('春节', '🧧', '除夕', '正月十五', 1, '#E74C3C', 99, 1),
('情人节', '💕', '02-13', '02-15', 0, '#FF69B4', 98, 1),
('妇女节', '🌸', '03-07', '03-09', 0, '#FFB6C1', 97, 1),
('清明节', '🌿', '清明', '清明后2天', 1, '#90EE90', 96, 1),
('劳动节', '💪', '04-30', '05-03', 0, '#FFA500', 95, 1),
('母亲节', '🌹', '5月第2周日', '5月第2周日', 0, '#FF1493', 94, 1),
('儿童节', '🎈', '05-31', '06-02', 0, '#87CEEB', 93, 1),
('端午节', '🐲', '五月初五', '五月初七', 1, '#228B22', 92, 1),
('七夕', '🌙', '七月初七', '七月初七', 1, '#9370DB', 91, 1),
('中秋节', '🥮', '八月十五', '八月十七', 1, '#FFD700', 90, 1),
('国庆节', '🇨🇳', '09-30', '10-07', 0, '#FF0000', 89, 1),
('圣诞节', '🎄', '12-24', '12-26', 0, '#228B22', 88, 1),
('生日祝福', '🎂', '全年', '全年', 0, '#FF69B4', 50, 1),
('日常祝福', '', '全年', '全年', 0, '#9B59B6', 49, 1);
-- ============================================
-- 四、菜单配置
-- ============================================
-- 缘池管理菜单
INSERT INTO `eb_system_menu` (`pid`, `name`, `icon`, `perms`, `component`, `menu_type`, `sort`, `is_show`, `is_delte`, `create_time`, `update_time`) VALUES
(0, '缘池管理', 'el-icon-s-opportunity', '', '/community', 'M', 140, 1, 0, NOW(), NOW());
SET @community_id = LAST_INSERT_ID();
INSERT INTO `eb_system_menu` (`pid`, `name`, `icon`, `perms`, `component`, `menu_type`, `sort`, `is_show`, `is_delte`, `create_time`, `update_time`) VALUES
(@community_id, '板块管理', '', 'admin:community:category', '/community/category', 'C', 3, 1, 0, NOW(), NOW()),
(@community_id, '消息管理', '', 'admin:community:message', '/community/message', 'C', 2, 1, 0, NOW(), NOW()),
(@community_id, '匹配配置', '', 'admin:community:match', '/community/match-config', 'C', 1, 1, 0, NOW(), NOW());
-- 许愿树管理菜单
INSERT INTO `eb_system_menu` (`pid`, `name`, `icon`, `perms`, `component`, `menu_type`, `sort`, `is_show`, `is_delte`, `create_time`, `update_time`) VALUES
(0, '许愿树管理', 'el-icon-present', '', '/wishtree', 'M', 139, 1, 0, NOW(), NOW());
SET @wishtree_id = LAST_INSERT_ID();
INSERT INTO `eb_system_menu` (`pid`, `name`, `icon`, `perms`, `component`, `menu_type`, `sort`, `is_show`, `is_delte`, `create_time`, `update_time`) VALUES
(@wishtree_id, '节日管理', '', 'admin:wishtree:festival', '/wishtree/festival', 'C', 4, 1, 0, NOW(), NOW()),
(@wishtree_id, '心愿管理', '', 'admin:wishtree:wish', '/wishtree/wish', 'C', 3, 1, 0, NOW(), NOW()),
(@wishtree_id, '背景素材', '', 'admin:wishtree:background', '/wishtree/background', 'C', 2, 1, 0, NOW(), NOW()),
(@wishtree_id, '数据统计', '', 'admin:wishtree:statistics', '/wishtree/statistics', 'C', 1, 1, 0, NOW(), NOW());

View File

@ -0,0 +1,22 @@
-- ============================================
-- 礼物测试数据
-- ============================================
-- 清空现有数据(可选)
-- DELETE FROM eb_gift;
-- 插入礼物测试数据
INSERT INTO eb_gift (name, image, diamond_price, intimacy, status, is_heartbeat, buy_type, belong, remark, effect_version, effect_url) VALUES
('玫瑰花', 'https://example.com/gifts/rose.png', 10.00, 10, 1, 0, 'diamond', 'common', '浪漫玫瑰', 'v1.0', ''),
('爱心', 'https://example.com/gifts/heart.png', 20.00, 20, 1, 1, 'diamond', 'common', '心动礼物', 'v1.0', ''),
('火箭', 'https://example.com/gifts/rocket.png', 100.00, 100, 1, 0, 'diamond', 'live', '直播间专属', 'v2.0', 'https://example.com/effects/rocket.json'),
('皇冠', 'https://example.com/gifts/crown.png', 500.00, 500, 1, 1, 'diamond', 'common', '尊贵皇冠', 'v2.0', 'https://example.com/effects/crown.json'),
('跑车', 'https://example.com/gifts/car.png', 1000.00, 1000, 1, 0, 'diamond', 'live', '豪华跑车', 'v2.0', 'https://example.com/effects/car.json'),
('城堡', 'https://example.com/gifts/castle.png', 5000.00, 5000, 1, 1, 'diamond', 'common', '梦幻城堡', 'v3.0', 'https://example.com/effects/castle.json'),
('棒棒糖', 'https://example.com/gifts/lollipop.png', 5.00, 5, 1, 0, 'diamond', 'chat', '甜蜜棒棒糖', 'v1.0', ''),
('啤酒', 'https://example.com/gifts/beer.png', 15.00, 15, 1, 0, 'diamond', 'common', '干杯', 'v1.0', ''),
('蛋糕', 'https://example.com/gifts/cake.png', 50.00, 50, 1, 0, 'diamond', 'common', '生日蛋糕', 'v1.0', ''),
('钻戒', 'https://example.com/gifts/ring.png', 2000.00, 2000, 1, 1, 'diamond', 'common', '真爱钻戒', 'v2.0', 'https://example.com/effects/ring.json');
-- 查看插入结果
SELECT id, name, diamond_price, intimacy, status, is_heartbeat, buy_type, belong FROM eb_gift;

View File

@ -0,0 +1,505 @@
/*
19(uid: 100-118)
Date: 2025-12-30
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ============================================
-- 1. 缘池消息数据 (15条)
-- ============================================
INSERT INTO `eb_community_message` (`uid`, `category_id`, `content`, `images`, `status`, `audit_type`, `audit_remark`, `is_delete`, `create_time`) VALUES
-- 语音匹配板块 (category_id=1)
(100, 1, '有人一起语音聊天吗?声音好听的优先哦~', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 5 HOUR),
(102, 1, '无聊中,想找个人聊聊天,什么话题都可以', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 4 HOUR),
(109, 1, '晚上睡不着,有人陪我聊天吗?', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 2 HOUR),
-- 心动信号板块 (category_id=2)
(103, 2, '寻找有缘人,希望遇到一个温柔体贴的人', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 6 HOUR),
(112, 2, '单身中,想找个女朋友,真诚交友', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 3 HOUR),
(117, 2, '希望能在这里遇到对的人,认真交友', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 1 HOUR),
-- 在线处对象板块 (category_id=3)
(105, 3, '90后程序员工作稳定想找个女朋友', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 8 HOUR),
(114, 3, '喜欢旅游和美食,希望找到志同道合的另一半', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 7 HOUR),
-- 找人玩游戏板块 (category_id=4)
(108, 4, '王者荣耀开黑,需要辅助和打野,来吗?', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 10 HOUR),
(107, 4, '英雄联盟大乱斗,轻松娱乐局,欢迎加入', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 9 HOUR),
(100, 4, '原神一起探索,有没有小伙伴?', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 5 HOUR),
-- 一起KTV板块 (category_id=5)
(104, 5, '今晚想唱歌有人一起K歌吗', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 12 HOUR),
(115, 5, '周末约KTV喜欢唱歌的朋友来', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 11 HOUR),
-- 和平精英板块 (category_id=7)
(108, 7, '和平精英四排,差两个人,速来!', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 6 HOUR),
(113, 7, '吃鸡大神带飞,萌新也欢迎', '', 1, 0, '自动审核通过', 0, NOW() - INTERVAL 4 HOUR);
-- ============================================
-- 2. 许愿树心愿数据 (20条)
-- ============================================
INSERT INTO `eb_wishtree_wish` (`uid`, `festival_id`, `content`, `background_id`, `status`, `audit_type`, `audit_remark`, `like_count`, `comment_count`, `is_delete`, `create_time`) VALUES
-- 元旦心愿 (festival_id=1)
(100, 1, '新的一年,希望家人身体健康,万事如意!', 0, 1, 0, '自动审核通过', 15, 3, 0, NOW() - INTERVAL 2 DAY),
(101, 1, '2026年希望事业更上一层楼加油', 0, 1, 0, '自动审核通过', 12, 2, 0, NOW() - INTERVAL 2 DAY + INTERVAL 1 HOUR),
(104, 1, '新年新气象,希望直播间人气越来越旺!', 0, 1, 0, '自动审核通过', 28, 5, 0, NOW() - INTERVAL 2 DAY + INTERVAL 2 HOUR),
-- 春节心愿 (festival_id=2)
(103, 2, '春节快乐!希望全家团团圆圆,幸福美满', 0, 1, 0, '自动审核通过', 20, 4, 0, NOW() - INTERVAL 3 DAY),
(115, 2, '新春大吉!愿所有粉丝都能心想事成', 0, 1, 0, '自动审核通过', 35, 8, 0, NOW() - INTERVAL 3 DAY + INTERVAL 3 HOUR),
-- 情人节心愿 (festival_id=3)
(102, 3, '希望今年能遇到那个对的人,脱单成功!', 0, 1, 0, '自动审核通过', 18, 6, 0, NOW() - INTERVAL 4 DAY),
(112, 3, '情人节快乐,愿天下有情人终成眷属', 0, 1, 0, '自动审核通过', 10, 2, 0, NOW() - INTERVAL 4 DAY + INTERVAL 2 HOUR),
(117, 3, '希望和喜欢的人一起度过每一个情人节', 0, 1, 0, '自动审核通过', 22, 4, 0, NOW() - INTERVAL 4 DAY + INTERVAL 4 HOUR),
-- 生日祝福 (festival_id=14)
(109, 14, '祝自己生日快乐!新的一岁要更加努力', 0, 1, 0, '自动审核通过', 25, 10, 0, NOW() - INTERVAL 5 DAY),
(107, 14, '生日愿望:希望能实现自己的梦想', 0, 1, 0, '自动审核通过', 16, 5, 0, NOW() - INTERVAL 6 DAY),
(114, 14, '又长大一岁啦,感谢所有的祝福', 0, 1, 0, '自动审核通过', 19, 7, 0, NOW() - INTERVAL 7 DAY),
-- 日常祝福 (festival_id=15)
(105, 15, '希望每天都能开开心心的', 0, 1, 0, '自动审核通过', 8, 2, 0, NOW() - INTERVAL 1 DAY),
(106, 15, '愿所有美好都如期而至', 0, 1, 0, '自动审核通过', 11, 3, 0, NOW() - INTERVAL 1 DAY + INTERVAL 5 HOUR),
(110, 15, '希望工作顺利,生活美满', 0, 1, 0, '自动审核通过', 14, 4, 0, NOW() - INTERVAL 8 HOUR),
(111, 15, '愿世界和平,人人幸福', 0, 1, 0, '自动审核通过', 9, 2, 0, NOW() - INTERVAL 6 HOUR),
(113, 15, '希望能遇到更多志同道合的朋友', 0, 1, 0, '自动审核通过', 13, 3, 0, NOW() - INTERVAL 4 HOUR),
(116, 15, '新的一天,新的开始,加油!', 0, 1, 0, '自动审核通过', 7, 1, 0, NOW() - INTERVAL 3 HOUR),
(118, 15, '希望家人朋友都平安健康', 0, 1, 0, '自动审核通过', 17, 5, 0, NOW() - INTERVAL 2 HOUR),
-- 待审核的心愿
(108, 1, '新年愿望:希望游戏技术更上一层楼', 0, 0, 0, '', 0, 0, 0, NOW() - INTERVAL 30 MINUTE),
(103, 15, '希望每天都能进步一点点', 0, 0, 0, '', 0, 0, 0, NOW() - INTERVAL 15 MINUTE);
-- ============================================
-- 3. 许愿树点赞数据 (30条)
-- ============================================
INSERT INTO `eb_wishtree_like` (`uid`, `wish_id`, `create_time`) VALUES
-- 对心愿1的点赞
(101, 1, NOW() - INTERVAL 1 DAY),
(102, 1, NOW() - INTERVAL 1 DAY + INTERVAL 1 HOUR),
(103, 1, NOW() - INTERVAL 1 DAY + INTERVAL 2 HOUR),
(104, 1, NOW() - INTERVAL 23 HOUR),
(108, 1, NOW() - INTERVAL 20 HOUR),
-- 对心愿2的点赞
(100, 2, NOW() - INTERVAL 1 DAY),
(103, 2, NOW() - INTERVAL 22 HOUR),
(105, 2, NOW() - INTERVAL 18 HOUR),
-- 对心愿3的点赞
(100, 3, NOW() - INTERVAL 1 DAY + INTERVAL 3 HOUR),
(101, 3, NOW() - INTERVAL 1 DAY + INTERVAL 4 HOUR),
(102, 3, NOW() - INTERVAL 1 DAY + INTERVAL 5 HOUR),
(103, 3, NOW() - INTERVAL 20 HOUR),
(108, 3, NOW() - INTERVAL 15 HOUR),
(109, 3, NOW() - INTERVAL 10 HOUR),
-- 对心愿4的点赞
(100, 4, NOW() - INTERVAL 2 DAY),
(104, 4, NOW() - INTERVAL 2 DAY + INTERVAL 2 HOUR),
(115, 4, NOW() - INTERVAL 2 DAY + INTERVAL 4 HOUR),
-- 对心愿5的点赞
(100, 5, NOW() - INTERVAL 2 DAY + INTERVAL 5 HOUR),
(101, 5, NOW() - INTERVAL 2 DAY + INTERVAL 6 HOUR),
(102, 5, NOW() - INTERVAL 2 DAY + INTERVAL 7 HOUR),
(103, 5, NOW() - INTERVAL 2 DAY + INTERVAL 8 HOUR),
(104, 5, NOW() - INTERVAL 2 DAY + INTERVAL 9 HOUR),
-- 对心愿9的点赞生日祝福
(100, 9, NOW() - INTERVAL 4 DAY),
(101, 9, NOW() - INTERVAL 4 DAY + INTERVAL 1 HOUR),
(102, 9, NOW() - INTERVAL 4 DAY + INTERVAL 2 HOUR),
(103, 9, NOW() - INTERVAL 4 DAY + INTERVAL 3 HOUR),
(104, 9, NOW() - INTERVAL 4 DAY + INTERVAL 4 HOUR),
(105, 9, NOW() - INTERVAL 4 DAY + INTERVAL 5 HOUR),
(108, 9, NOW() - INTERVAL 3 DAY),
(115, 9, NOW() - INTERVAL 3 DAY + INTERVAL 2 HOUR);
-- ============================================
-- 4. 许愿树评论数据 (25条)
-- ============================================
INSERT INTO `eb_wishtree_comment` (`wish_id`, `uid`, `content`, `parent_id`, `status`, `is_delete`, `create_time`) VALUES
-- 对心愿1的评论
(1, 101, '新年快乐!祝你心想事成!', 0, 1, 0, NOW() - INTERVAL 1 DAY + INTERVAL 30 MINUTE),
(1, 104, '同祝!希望大家都能实现愿望', 0, 1, 0, NOW() - INTERVAL 1 DAY + INTERVAL 1 HOUR),
(1, 108, '加油加油!', 0, 1, 0, NOW() - INTERVAL 20 HOUR),
-- 对心愿3的评论
(3, 100, '主播加油!我们一直支持你', 0, 1, 0, NOW() - INTERVAL 1 DAY + INTERVAL 3 HOUR),
(3, 101, '直播间见!', 0, 1, 0, NOW() - INTERVAL 1 DAY + INTERVAL 4 HOUR),
(3, 109, '最喜欢看你直播了', 0, 1, 0, NOW() - INTERVAL 18 HOUR),
(3, 117, '冲冲冲!', 0, 1, 0, NOW() - INTERVAL 12 HOUR),
(3, 102, '新年第一个愿望送给你', 0, 1, 0, NOW() - INTERVAL 8 HOUR),
-- 对心愿5的评论
(5, 100, '新春快乐!', 0, 1, 0, NOW() - INTERVAL 2 DAY + INTERVAL 4 HOUR),
(5, 101, '恭喜发财!', 0, 1, 0, NOW() - INTERVAL 2 DAY + INTERVAL 5 HOUR),
(5, 102, '万事如意!', 0, 1, 0, NOW() - INTERVAL 2 DAY + INTERVAL 6 HOUR),
(5, 103, '心想事成!', 0, 1, 0, NOW() - INTERVAL 2 DAY + INTERVAL 7 HOUR),
(5, 107, '大吉大利!', 0, 1, 0, NOW() - INTERVAL 2 DAY + INTERVAL 8 HOUR),
(5, 108, '阖家幸福!', 0, 1, 0, NOW() - INTERVAL 2 DAY + INTERVAL 9 HOUR),
(5, 109, '身体健康!', 0, 1, 0, NOW() - INTERVAL 2 DAY + INTERVAL 10 HOUR),
(5, 110, '财源广进!', 0, 1, 0, NOW() - INTERVAL 1 DAY),
-- 对心愿9的评论生日祝福
(9, 100, '生日快乐!🎂', 0, 1, 0, NOW() - INTERVAL 4 DAY + INTERVAL 1 HOUR),
(9, 101, '祝你生日快乐,天天开心!', 0, 1, 0, NOW() - INTERVAL 4 DAY + INTERVAL 2 HOUR),
(9, 102, 'Happy Birthday!', 0, 1, 0, NOW() - INTERVAL 4 DAY + INTERVAL 3 HOUR),
(9, 103, '愿你所有愿望都能实现', 0, 1, 0, NOW() - INTERVAL 4 DAY + INTERVAL 4 HOUR),
(9, 104, '生日快乐永远18岁', 0, 1, 0, NOW() - INTERVAL 4 DAY + INTERVAL 5 HOUR),
(9, 105, '祝福送给你', 0, 1, 0, NOW() - INTERVAL 4 DAY + INTERVAL 6 HOUR),
(9, 108, '生快!', 0, 1, 0, NOW() - INTERVAL 3 DAY + INTERVAL 1 HOUR),
(9, 115, '生日快乐呀~', 0, 1, 0, NOW() - INTERVAL 3 DAY + INTERVAL 3 HOUR),
(9, 117, '又长大一岁啦,开心!', 0, 1, 0, NOW() - INTERVAL 3 DAY + INTERVAL 5 HOUR),
(9, 118, '祝你越来越好!', 0, 1, 0, NOW() - INTERVAL 2 DAY);
-- ============================================
-- 5. 许愿树背景素材数据 (8条)
-- ============================================
INSERT INTO `eb_wishtree_background` (`name`, `image`, `festival_id`, `sort`, `status`, `create_time`) VALUES
('新年红色背景', 'https://picsum.photos/400/600?random=bg1', 1, 100, 1, NOW()),
('春节喜庆背景', 'https://picsum.photos/400/600?random=bg2', 2, 99, 1, NOW()),
('情人节粉色背景', 'https://picsum.photos/400/600?random=bg3', 3, 98, 1, NOW()),
('生日蛋糕背景', 'https://picsum.photos/400/600?random=bg4', 14, 97, 1, NOW()),
('星空梦幻背景', 'https://picsum.photos/400/600?random=bg5', 0, 50, 1, NOW()),
('简约白色背景', 'https://picsum.photos/400/600?random=bg6', 0, 49, 1, NOW()),
('温馨暖色背景', 'https://picsum.photos/400/600?random=bg7', 0, 48, 1, NOW()),
('清新绿色背景', 'https://picsum.photos/400/600?random=bg8', 0, 47, 1, NOW());
-- ============================================
-- 6. 用户签到记录数据 (30条)
-- ============================================
INSERT INTO `eb_user_sign` (`uid`, `sign_date`, `continuous_days`, `reward_type`, `reward_amount`, `create_time`) VALUES
-- 张吉惟的签到记录
(100, '2025-12-25', 1, 1, 10, '2025-12-25 08:30:00'),
(100, '2025-12-26', 2, 1, 15, '2025-12-26 09:15:00'),
(100, '2025-12-27', 3, 1, 20, '2025-12-27 08:45:00'),
(100, '2025-12-28', 4, 1, 25, '2025-12-28 10:00:00'),
(100, '2025-12-29', 5, 1, 30, '2025-12-29 08:20:00'),
(100, '2025-12-30', 6, 1, 35, '2025-12-30 09:00:00'),
-- 林国瑞的签到记录
(101, '2025-12-27', 1, 1, 10, '2025-12-27 07:30:00'),
(101, '2025-12-28', 2, 1, 15, '2025-12-28 08:00:00'),
(101, '2025-12-29', 3, 1, 20, '2025-12-29 07:45:00'),
(101, '2025-12-30', 4, 1, 25, '2025-12-30 08:15:00'),
-- 江奕云的签到记录
(104, '2025-12-20', 1, 1, 10, '2025-12-20 10:00:00'),
(104, '2025-12-21', 2, 1, 15, '2025-12-21 09:30:00'),
(104, '2025-12-22', 3, 1, 20, '2025-12-22 11:00:00'),
(104, '2025-12-23', 4, 1, 25, '2025-12-23 10:15:00'),
(104, '2025-12-24', 5, 1, 30, '2025-12-24 09:45:00'),
(104, '2025-12-25', 6, 1, 35, '2025-12-25 10:30:00'),
(104, '2025-12-26', 7, 1, 50, '2025-12-26 09:00:00'),
(104, '2025-12-27', 8, 1, 10, '2025-12-27 10:20:00'),
(104, '2025-12-28', 9, 1, 15, '2025-12-28 09:15:00'),
(104, '2025-12-29', 10, 1, 20, '2025-12-29 10:00:00'),
(104, '2025-12-30', 11, 1, 25, '2025-12-30 09:30:00'),
-- 其他用户签到
(102, '2025-12-30', 1, 1, 10, '2025-12-30 08:00:00'),
(103, '2025-12-29', 1, 1, 10, '2025-12-29 09:00:00'),
(103, '2025-12-30', 2, 1, 15, '2025-12-30 08:30:00'),
(108, '2025-12-28', 1, 1, 10, '2025-12-28 11:00:00'),
(108, '2025-12-29', 2, 1, 15, '2025-12-29 10:30:00'),
(108, '2025-12-30', 3, 1, 20, '2025-12-30 11:15:00'),
(115, '2025-12-30', 1, 1, 10, '2025-12-30 07:45:00'),
(117, '2025-12-29', 1, 1, 10, '2025-12-29 08:15:00'),
(117, '2025-12-30', 2, 1, 15, '2025-12-30 08:45:00');
-- ============================================
-- 7. 用户地址数据 (15条)
-- ============================================
INSERT INTO `eb_user_address` (`uid`, `real_name`, `phone`, `province`, `city`, `city_id`, `district`, `detail`, `post_code`, `longitude`, `latitude`, `is_default`, `is_del`, `create_time`, `update_time`) VALUES
(100, '张吉惟', '13800100001', '上海市', '上海市', 310100, '浦东新区', '张江高科技园区', '201203', '121.5908', '31.2047', 1, 0, NOW(), NOW()),
(101, '林国瑞', '13800100002', '北京市', '北京市', 110100, '朝阳区', '望京SOHO', '100102', '116.4716', '40.0017', 1, 0, NOW(), NOW()),
(102, '林玟书', '13800100003', '广东省', '深圳市', 440300, '南山区', '科技园南区', '518057', '113.9436', '22.5329', 1, 0, NOW(), NOW()),
(103, '林雅南', '13800100004', '浙江省', '杭州市', 330100, '西湖区', '西溪湿地', '310013', '120.0621', '30.2741', 1, 0, NOW(), NOW()),
(104, '江奕云', '13800100005', '上海市', '上海市', 310100, '静安区', '南京西路', '200040', '121.4484', '31.2286', 1, 0, NOW(), NOW()),
(105, '刘柏宏', '13800100006', '四川省', '成都市', 510100, '武侯区', '天府软件园', '610041', '104.0633', '30.5728', 1, 0, NOW(), NOW()),
(106, '阮建安', '13800100007', '福建省', '厦门市', 350200, '思明区', '软件园二期', '361008', '118.1175', '24.4897', 1, 0, NOW(), NOW()),
(107, '林子帆', '13800100008', '江苏省', '南京市', 320100, '鼓楼区', '新街口', '210005', '118.7778', '32.0617', 1, 0, NOW(), NOW()),
(108, '夏志豪', '13800100009', '广东省', '广州市', 440100, '天河区', '珠江新城', '510623', '113.3218', '23.1195', 1, 0, NOW(), NOW()),
(109, '吉茹定', '13800100010', '湖北省', '武汉市', 420100, '洪山区', '光谷广场', '430074', '114.3975', '30.5052', 1, 0, NOW(), NOW()),
(110, '李中冰', '13800100011', '陕西省', '西安市', 610100, '雁塔区', '高新区', '710065', '108.9402', '34.2266', 1, 0, NOW(), NOW()),
(115, '刘姿婷', '13800100016', '北京市', '北京市', 110100, '海淀区', '中关村', '100080', '116.3103', '39.9929', 1, 0, NOW(), NOW()),
(117, '吕致盈', '13800100018', '浙江省', '杭州市', 330100, '滨江区', '网易大厦', '310052', '120.2052', '30.2084', 1, 0, NOW(), NOW()),
(118, '方一强', '13800100019', '江苏省', '苏州市', 320500, '工业园区', '金鸡湖', '215021', '120.7194', '31.3116', 1, 0, NOW(), NOW()),
(113, '傅智翔', '13800100014', '湖南省', '长沙市', 430100, '岳麓区', '麓谷', '410205', '112.8891', '28.2278', 1, 0, NOW(), NOW());
-- ============================================
-- 8. 用户账单数据 (20条)
-- ============================================
INSERT INTO `eb_user_bill` (`uid`, `link_id`, `pm`, `title`, `category`, `type`, `number`, `balance`, `mark`, `status`, `create_time`, `update_time`) VALUES
-- 充值记录
(100, 'R202512280001', 1, '充值', 'now_money', 'recharge', 100.00, 5780.00, '充值100元', 1, '2025-12-28 15:00:00', '2025-12-28 15:00:00'),
(101, 'R202512280002', 1, '充值', 'now_money', 'recharge', 500.00, 13000.00, '充值500元', 1, '2025-12-28 16:30:00', '2025-12-28 16:30:00'),
(104, 'R202512270001', 1, '充值', 'now_money', 'recharge', 1000.00, 26600.00, '充值1000元', 1, '2025-12-27 20:00:00', '2025-12-27 20:00:00'),
(108, 'R202512290001', 1, '充值', 'now_money', 'recharge', 200.00, 18400.00, '充值200元', 1, '2025-12-29 10:15:00', '2025-12-29 10:15:00'),
(115, 'R202512290002', 1, '充值', 'now_money', 'recharge', 500.00, 22500.00, '充值500元', 1, '2025-12-29 11:00:00', '2025-12-29 11:00:00'),
-- 送礼消费记录
(100, 'G202512280001', 0, '送礼物', 'now_money', 'gift', 100.00, 5680.00, '送出100个小心心', 1, '2025-12-28 20:15:00', '2025-12-28 20:15:00'),
(101, 'G202512280002', 0, '送礼物', 'now_money', 'gift', 500.00, 12500.00, '送出50朵玫瑰花', 1, '2025-12-28 20:20:00', '2025-12-28 20:20:00'),
(108, 'G202512280003', 0, '送礼物', 'now_money', 'gift', 1000.00, 17200.00, '送出2个火箭', 1, '2025-12-28 20:25:00', '2025-12-28 20:25:00'),
(117, 'G202512290001', 0, '送礼物', 'now_money', 'gift', 500.00, 13000.00, '送出5个皇冠', 1, '2025-12-29 19:10:00', '2025-12-29 19:10:00'),
-- 收礼收入记录
(104, 'G202512280001', 1, '收到礼物', 'now_money', 'gift_income', 70.00, 25670.00, '收到礼物分成', 1, '2025-12-28 20:15:00', '2025-12-28 20:15:00'),
(104, 'G202512280002', 1, '收到礼物', 'now_money', 'gift_income', 350.00, 26020.00, '收到礼物分成', 1, '2025-12-28 20:20:00', '2025-12-28 20:20:00'),
(104, 'G202512280003', 1, '收到礼物', 'now_money', 'gift_income', 700.00, 26720.00, '收到礼物分成', 1, '2025-12-28 20:25:00', '2025-12-28 20:25:00'),
(115, 'G202512290001', 1, '收到礼物', 'now_money', 'gift_income', 350.00, 22350.00, '收到礼物分成', 1, '2025-12-29 19:10:00', '2025-12-29 19:10:00'),
-- 签到奖励
(100, 'S202512300001', 1, '签到奖励', 'integral', 'sign', 35.00, 2385.00, '连续签到6天奖励', 1, '2025-12-30 09:00:00', '2025-12-30 09:00:00'),
(101, 'S202512300002', 1, '签到奖励', 'integral', 'sign', 25.00, 5705.00, '连续签到4天奖励', 1, '2025-12-30 08:15:00', '2025-12-30 08:15:00'),
(104, 'S202512300003', 1, '签到奖励', 'integral', 'sign', 25.00, 8925.00, '连续签到11天奖励', 1, '2025-12-30 09:30:00', '2025-12-30 09:30:00'),
-- 抽奖消费
(100, 'L202512280001', 0, '抽奖消费', 'integral', 'lottery', 10.00, 2340.00, '新年大转盘抽奖', 1, '2025-12-28 15:30:00', '2025-12-28 15:30:00'),
(101, 'L202512270001', 0, '抽奖消费', 'integral', 'lottery', 10.00, 5670.00, '新年大转盘抽奖', 1, '2025-12-27 20:00:00', '2025-12-27 20:00:00'),
-- 抽奖奖励
(100, 'L202512280001', 1, '抽奖奖励', 'integral', 'lottery_win', 18.00, 2358.00, '获得18钻石', 1, '2025-12-28 15:30:00', '2025-12-28 15:30:00'),
(101, 'L202512270001', 1, '抽奖奖励', 'integral', 'lottery_win', 88.00, 5758.00, '获得88钻石', 1, '2025-12-27 20:00:00', '2025-12-27 20:00:00');
-- ============================================
-- 9. 直播间数据 (5个直播间)
-- ============================================
INSERT INTO `eb_live_room` (`id`, `uid`, `title`, `cover`, `category_id`, `status`, `viewer_count`, `like_count`, `gift_value`, `start_time`, `end_time`, `create_time`) VALUES
(1001, 104, '江奕云的直播间', 'https://picsum.photos/400/300?random=room1', 1, 1, 1580, 25600, 125000, '2025-12-30 19:00:00', NULL, '2025-06-08 08:30:00'),
(1002, 115, '姿婷宝贝直播间', 'https://picsum.photos/400/300?random=room2', 1, 1, 1120, 18900, 98000, '2025-12-30 20:00:00', NULL, '2025-06-25 11:30:00'),
(1003, 110, '中冰老师直播间', 'https://picsum.photos/400/300?random=room3', 2, 0, 890, 15200, 85000, '2025-12-29 19:00:00', '2025-12-29 22:00:00', '2025-05-18 09:25:00'),
(1004, 108, '志豪Gaming', 'https://picsum.photos/400/300?random=room4', 3, 0, 650, 12800, 45000, '2025-12-28 20:00:00', '2025-12-28 23:30:00', '2025-07-22 17:55:00'),
(1005, 117, '致盈小仙女', 'https://picsum.photos/400/300?random=room5', 1, 0, 420, 8500, 32000, '2025-12-27 19:30:00', '2025-12-27 22:00:00', '2025-08-02 10:45:00');
-- ============================================
-- 10. 直播间弹幕数据 (20条)
-- ============================================
INSERT INTO `eb_live_danmu` (`room_id`, `uid`, `nickname`, `content`, `type`, `color`, `create_time`) VALUES
(1001, 100, '张吉惟', '主播好棒!', 1, '#FFFFFF', NOW() - INTERVAL 30 MINUTE),
(1001, 101, '林国瑞', '来了来了', 1, '#FFFFFF', NOW() - INTERVAL 28 MINUTE),
(1001, 103, '林雅南', '支持主播!', 1, '#FFD700', NOW() - INTERVAL 25 MINUTE),
(1001, 108, '夏志豪', '666', 1, '#FFFFFF', NOW() - INTERVAL 22 MINUTE),
(1001, 109, '吉茹定', '主播唱得真好听', 1, '#FF69B4', NOW() - INTERVAL 20 MINUTE),
(1001, 107, '林子帆', '冲冲冲', 1, '#FFFFFF', NOW() - INTERVAL 18 MINUTE),
(1001, 112, '谢彦文', '太棒了', 1, '#FFFFFF', NOW() - INTERVAL 15 MINUTE),
(1002, 102, '林玟书', '姐姐好美', 1, '#FF69B4', NOW() - INTERVAL 25 MINUTE),
(1002, 114, '洪振霞', '来支持啦', 1, '#FFFFFF', NOW() - INTERVAL 22 MINUTE),
(1002, 117, '吕致盈', '互相支持', 1, '#FFD700', NOW() - INTERVAL 20 MINUTE),
(1002, 116, '荣姿康', '主播加油', 1, '#FFFFFF', NOW() - INTERVAL 18 MINUTE),
(1003, 105, '刘柏宏', '老师讲得好', 1, '#FFFFFF', NOW() - INTERVAL 1 DAY),
(1003, 113, '傅智翔', '学到了', 1, '#FFFFFF', NOW() - INTERVAL 1 DAY + INTERVAL 5 MINUTE),
(1003, 118, '方一强', '感谢分享', 1, '#FFD700', NOW() - INTERVAL 1 DAY + INTERVAL 10 MINUTE),
(1003, 111, '黄文隆', '干货满满', 1, '#FFFFFF', NOW() - INTERVAL 1 DAY + INTERVAL 15 MINUTE),
(1004, 100, '张吉惟', '带我一个', 1, '#FFFFFF', NOW() - INTERVAL 2 DAY),
(1004, 107, '林子帆', '一起开黑', 1, '#FFFFFF', NOW() - INTERVAL 2 DAY + INTERVAL 3 MINUTE),
(1004, 106, '阮建安', '大神带飞', 1, '#FFD700', NOW() - INTERVAL 2 DAY + INTERVAL 8 MINUTE),
(1005, 102, '林玟书', '小仙女来了', 1, '#FF69B4', NOW() - INTERVAL 3 DAY),
(1005, 114, '洪振霞', '好看', 1, '#FFFFFF', NOW() - INTERVAL 3 DAY + INTERVAL 5 MINUTE);
-- ============================================
-- 11. 私信消息数据 (25条)
-- ============================================
INSERT INTO `eb_private_message` (`sender_id`, `sender_name`, `receiver_id`, `receiver_name`, `content`, `type`, `is_read`, `create_time`) VALUES
-- 张吉惟和江奕云的对话
(100, '张吉惟', 104, '江奕云', '主播你好,很喜欢你的直播!', 1, 1, NOW() - INTERVAL 2 DAY),
(104, '江奕云', 100, '张吉惟', '谢谢支持!欢迎常来直播间哦~', 1, 1, NOW() - INTERVAL 2 DAY + INTERVAL 10 MINUTE),
(100, '张吉惟', 104, '江奕云', '一定会的!', 1, 1, NOW() - INTERVAL 2 DAY + INTERVAL 15 MINUTE),
-- 林国瑞和林雅南的对话
(101, '林国瑞', 103, '林雅南', '在吗?', 1, 1, NOW() - INTERVAL 1 DAY),
(103, '林雅南', 101, '林国瑞', '在的,怎么了?', 1, 1, NOW() - INTERVAL 1 DAY + INTERVAL 5 MINUTE),
(101, '林国瑞', 103, '林雅南', '明天一起吃饭吗?', 1, 1, NOW() - INTERVAL 1 DAY + INTERVAL 8 MINUTE),
(103, '林雅南', 101, '林国瑞', '好呀,几点?', 1, 1, NOW() - INTERVAL 1 DAY + INTERVAL 12 MINUTE),
(101, '林国瑞', 103, '林雅南', '中午12点怎么样', 1, 1, NOW() - INTERVAL 1 DAY + INTERVAL 15 MINUTE),
(103, '林雅南', 101, '林国瑞', '可以,到时候见', 1, 0, NOW() - INTERVAL 1 DAY + INTERVAL 18 MINUTE),
-- 吕致盈和刘姿婷的对话
(117, '吕致盈', 115, '刘姿婷', '姐姐今晚直播吗?', 1, 1, NOW() - INTERVAL 8 HOUR),
(115, '刘姿婷', 117, '吕致盈', '直播的8点开始', 1, 1, NOW() - INTERVAL 8 HOUR + INTERVAL 3 MINUTE),
(117, '吕致盈', 115, '刘姿婷', '好的,我准时来看', 1, 1, NOW() - INTERVAL 8 HOUR + INTERVAL 5 MINUTE),
(115, '刘姿婷', 117, '吕致盈', '好的,明天见~', 1, 0, NOW() - INTERVAL 8 HOUR + INTERVAL 8 MINUTE),
-- 傅智翔和李中冰的对话
(113, '傅智翔', 110, '李中冰', '老师,上次讲的内容我还有些不懂', 1, 1, NOW() - INTERVAL 3 DAY),
(110, '李中冰', 113, '傅智翔', '哪里不懂?可以具体说说', 1, 1, NOW() - INTERVAL 3 DAY + INTERVAL 30 MINUTE),
(113, '傅智翔', 110, '李中冰', '就是关于那个算法的部分', 1, 1, NOW() - INTERVAL 3 DAY + INTERVAL 35 MINUTE),
(110, '李中冰', 113, '傅智翔', '好的,我下次直播详细讲一下', 1, 1, NOW() - INTERVAL 3 DAY + INTERVAL 40 MINUTE),
(113, '傅智翔', 110, '李中冰', '好的老师,谢谢!', 1, 0, NOW() - INTERVAL 3 DAY + INTERVAL 45 MINUTE),
-- 林玟书和洪振霞的对话
(102, '林玟书', 114, '洪振霞', '那个链接发我一下', 1, 1, NOW() - INTERVAL 12 HOUR),
(114, '洪振霞', 102, '林玟书', 'https://example.com/xxx', 1, 1, NOW() - INTERVAL 12 HOUR + INTERVAL 2 MINUTE),
(102, '林玟书', 114, '洪振霞', '收到,谢谢', 1, 0, NOW() - INTERVAL 12 HOUR + INTERVAL 5 MINUTE),
-- 夏志豪和江奕云的对话
(108, '夏志豪', 104, '江奕云', '下次一起连麦打游戏吧', 1, 1, NOW() - INTERVAL 2 DAY + INTERVAL 2 HOUR),
(104, '江奕云', 108, '夏志豪', '好呀,什么时候?', 1, 1, NOW() - INTERVAL 2 DAY + INTERVAL 2 HOUR + INTERVAL 10 MINUTE),
(108, '夏志豪', 104, '江奕云', '周末晚上怎么样?', 1, 1, NOW() - INTERVAL 2 DAY + INTERVAL 2 HOUR + INTERVAL 15 MINUTE),
(104, '江奕云', 108, '夏志豪', '可以,到时候联系', 1, 0, NOW() - INTERVAL 2 DAY + INTERVAL 2 HOUR + INTERVAL 20 MINUTE);
-- ============================================
-- 12. 动态点赞数据 (20条)
-- ============================================
INSERT INTO `eb_dynamic_like` (`dynamic_id`, `uid`, `nickname`, `create_time`) VALUES
-- 对动态1的点赞
(1, 100, '张吉惟', NOW() - INTERVAL 1 DAY + INTERVAL 1 HOUR),
(1, 101, '林国瑞', NOW() - INTERVAL 1 DAY + INTERVAL 2 HOUR),
(1, 103, '林雅南', NOW() - INTERVAL 1 DAY + INTERVAL 3 HOUR),
(1, 108, '夏志豪', NOW() - INTERVAL 1 DAY + INTERVAL 4 HOUR),
(1, 109, '吉茹定', NOW() - INTERVAL 20 HOUR),
-- 对动态2的点赞
(2, 104, '江奕云', NOW() - INTERVAL 18 HOUR),
(2, 117, '吕致盈', NOW() - INTERVAL 17 HOUR),
(2, 102, '林玟书', NOW() - INTERVAL 16 HOUR),
-- 对动态4的点赞
(4, 115, '刘姿婷', NOW() - INTERVAL 10 HOUR),
(4, 117, '吕致盈', NOW() - INTERVAL 9 HOUR),
(4, 102, '林玟书', NOW() - INTERVAL 8 HOUR),
(4, 103, '林雅南', NOW() - INTERVAL 7 HOUR),
(4, 109, '吉茹定', NOW() - INTERVAL 6 HOUR),
-- 对动态6的点赞
(6, 110, '李中冰', NOW() - INTERVAL 2 DAY),
(6, 113, '傅智翔', NOW() - INTERVAL 2 DAY + INTERVAL 1 HOUR),
(6, 118, '方一强', NOW() - INTERVAL 2 DAY + INTERVAL 2 HOUR),
-- 对动态8的点赞
(8, 102, '林玟书', NOW() - INTERVAL 3 DAY),
(8, 114, '洪振霞', NOW() - INTERVAL 3 DAY + INTERVAL 1 HOUR),
(8, 103, '林雅南', NOW() - INTERVAL 3 DAY + INTERVAL 2 HOUR),
(8, 117, '吕致盈', NOW() - INTERVAL 3 DAY + INTERVAL 3 HOUR);
-- ============================================
-- 13. 好友关系数据 (15条)
-- ============================================
INSERT INTO `eb_friend` (`uid`, `friend_uid`, `friend_name`, `friend_avatar`, `remark`, `status`, `create_time`) VALUES
-- 张吉惟的好友
(100, 101, '林国瑞', 'https://api.dicebear.com/7.x/avataaars/svg?seed=2', '国瑞哥', 1, NOW() - INTERVAL 30 DAY),
(100, 107, '林子帆', 'https://api.dicebear.com/7.x/avataaars/svg?seed=8', '子帆', 1, NOW() - INTERVAL 25 DAY),
(100, 108, '夏志豪', 'https://api.dicebear.com/7.x/avataaars/svg?seed=9', '游戏搭子', 1, NOW() - INTERVAL 20 DAY),
-- 林国瑞的好友
(101, 100, '张吉惟', 'https://api.dicebear.com/7.x/avataaars/svg?seed=1', '吉惟', 1, NOW() - INTERVAL 30 DAY),
(101, 103, '林雅南', 'https://api.dicebear.com/7.x/avataaars/svg?seed=4', '雅南', 1, NOW() - INTERVAL 60 DAY),
(101, 104, '江奕云', 'https://api.dicebear.com/7.x/avataaars/svg?seed=5', '奕云', 1, NOW() - INTERVAL 90 DAY),
-- 江奕云的好友
(104, 101, '林国瑞', 'https://api.dicebear.com/7.x/avataaars/svg?seed=2', '', 1, NOW() - INTERVAL 90 DAY),
(104, 108, '夏志豪', 'https://api.dicebear.com/7.x/avataaars/svg?seed=9', '志豪', 1, NOW() - INTERVAL 85 DAY),
(104, 103, '林雅南', 'https://api.dicebear.com/7.x/avataaars/svg?seed=4', '', 1, NOW() - INTERVAL 80 DAY),
-- 刘姿婷的好友
(115, 102, '林玟书', 'https://api.dicebear.com/7.x/avataaars/svg?seed=3', '玟书', 1, NOW() - INTERVAL 45 DAY),
(115, 114, '洪振霞', 'https://api.dicebear.com/7.x/avataaars/svg?seed=15', '振霞', 1, NOW() - INTERVAL 40 DAY),
(115, 117, '吕致盈', 'https://api.dicebear.com/7.x/avataaars/svg?seed=18', '致盈', 1, NOW() - INTERVAL 50 DAY),
-- 李中冰的好友
(110, 113, '傅智翔', 'https://api.dicebear.com/7.x/avataaars/svg?seed=14', '智翔', 1, NOW() - INTERVAL 70 DAY),
(110, 118, '方一强', 'https://api.dicebear.com/7.x/avataaars/svg?seed=19', '一强', 1, NOW() - INTERVAL 65 DAY),
(110, 105, '刘柏宏', 'https://api.dicebear.com/7.x/avataaars/svg?seed=6', '柏宏', 1, NOW() - INTERVAL 55 DAY);
-- ============================================
-- 14. 礼物配置数据 (10种礼物)
-- ============================================
INSERT INTO `eb_gift` (`id`, `name`, `icon`, `price`, `experience`, `category`, `animation`, `sort`, `status`, `create_time`) VALUES
(1, '小心心', 'https://picsum.photos/100/100?random=gift1', 1, 1, 1, '', 100, 1, NOW()),
(2, '棒棒糖', 'https://picsum.photos/100/100?random=gift2', 5, 5, 1, '', 99, 1, NOW()),
(3, '玫瑰花', 'https://picsum.photos/100/100?random=gift3', 10, 10, 1, '', 98, 1, NOW()),
(4, '皇冠', 'https://picsum.photos/100/100?random=gift4', 100, 100, 2, 'crown.json', 97, 1, NOW()),
(5, '火箭', 'https://picsum.photos/100/100?random=gift5', 500, 500, 2, 'rocket.json', 96, 1, NOW()),
(6, '跑车', 'https://picsum.photos/100/100?random=gift6', 1000, 1000, 3, 'car.json', 95, 1, NOW()),
(7, '游艇', 'https://picsum.photos/100/100?random=gift7', 2000, 2000, 3, 'yacht.json', 94, 1, NOW()),
(8, '城堡', 'https://picsum.photos/100/100?random=gift8', 5000, 5000, 3, 'castle.json', 93, 1, NOW()),
(9, '么么哒', 'https://picsum.photos/100/100?random=gift9', 20, 20, 1, '', 92, 1, NOW()),
(10, '啤酒', 'https://picsum.photos/100/100?random=gift10', 50, 50, 1, '', 91, 1, NOW())
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`);
-- ============================================
-- 15. 签到配置数据 (7天)
-- ============================================
INSERT INTO `eb_sign_config` (`day`, `reward_type`, `reward_value`, `is_double`, `status`, `create_time`) VALUES
(1, 1, 10, 0, 1, NOW()),
(2, 1, 15, 0, 1, NOW()),
(3, 1, 20, 0, 1, NOW()),
(4, 1, 25, 0, 1, NOW()),
(5, 1, 30, 0, 1, NOW()),
(6, 1, 35, 0, 1, NOW()),
(7, 1, 50, 1, 1, NOW())
ON DUPLICATE KEY UPDATE `reward_value` = VALUES(`reward_value`);
-- ============================================
-- 16. 直播分类数据 (5个分类)
-- ============================================
INSERT INTO `eb_live_category` (`id`, `name`, `icon`, `sort`, `status`, `create_time`) VALUES
(1, '娱乐', 'https://picsum.photos/100/100?random=cat1', 100, 1, NOW()),
(2, '教育', 'https://picsum.photos/100/100?random=cat2', 99, 1, NOW()),
(3, '游戏', 'https://picsum.photos/100/100?random=cat3', 98, 1, NOW()),
(4, '音乐', 'https://picsum.photos/100/100?random=cat4', 97, 1, NOW()),
(5, '户外', 'https://picsum.photos/100/100?random=cat5', 96, 1, NOW())
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`);
-- ============================================
-- 17. 用户等级配置数据 (10级)
-- ============================================
INSERT INTO `eb_user_level` (`id`, `level`, `name`, `icon`, `experience`, `discount`, `privileges`, `status`, `create_time`) VALUES
(1, 1, '青铜', 'https://picsum.photos/50/50?random=lv1', 0, 100, '基础权益', 1, NOW()),
(2, 2, '白银', 'https://picsum.photos/50/50?random=lv2', 1000, 98, '专属标识', 1, NOW()),
(3, 3, '黄金', 'https://picsum.photos/50/50?random=lv3', 3000, 95, '专属标识,入场特效', 1, NOW()),
(4, 4, '铂金', 'https://picsum.photos/50/50?random=lv4', 8000, 92, '专属标识,入场特效,弹幕颜色', 1, NOW()),
(5, 5, '钻石', 'https://picsum.photos/50/50?random=lv5', 15000, 90, '专属标识,入场特效,弹幕颜色,专属客服', 1, NOW()),
(6, 6, '星耀', 'https://picsum.photos/50/50?random=lv6', 30000, 88, '专属标识,入场特效,弹幕颜色,专属客服,生日礼物', 1, NOW()),
(7, 7, '王者', 'https://picsum.photos/50/50?random=lv7', 60000, 85, '专属标识,入场特效,弹幕颜色,专属客服,生日礼物,专属座驾', 1, NOW()),
(8, 8, '至尊', 'https://picsum.photos/50/50?random=lv8', 120000, 82, '全部权益', 1, NOW()),
(9, 9, '传说', 'https://picsum.photos/50/50?random=lv9', 250000, 80, '全部权益,定制服务', 1, NOW()),
(10, 10, '神话', 'https://picsum.photos/50/50?random=lv10', 500000, 75, '全部权益,定制服务,专属活动', 1, NOW())
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`);
-- ============================================
-- 18. 魅力等级配置数据 (10级)
-- ============================================
INSERT INTO `eb_charm_level` (`id`, `level`, `name`, `icon`, `charm_value`, `privileges`, `status`, `create_time`) VALUES
(1, 1, '萌新主播', 'https://picsum.photos/50/50?random=charm1', 0, '基础权益', 1, NOW()),
(2, 2, '人气主播', 'https://picsum.photos/50/50?random=charm2', 5000, '专属标识', 1, NOW()),
(3, 3, '明星主播', 'https://picsum.photos/50/50?random=charm3', 20000, '专属标识,推荐位', 1, NOW()),
(4, 4, '金牌主播', 'https://picsum.photos/50/50?random=charm4', 50000, '专属标识,推荐位,分成提升', 1, NOW()),
(5, 5, '钻石主播', 'https://picsum.photos/50/50?random=charm5', 100000, '专属标识,推荐位,分成提升,专属客服', 1, NOW()),
(6, 6, '皇冠主播', 'https://picsum.photos/50/50?random=charm6', 200000, '全部权益', 1, NOW()),
(7, 7, '女神主播', 'https://picsum.photos/50/50?random=charm7', 500000, '全部权益,专属活动', 1, NOW()),
(8, 8, '天王主播', 'https://picsum.photos/50/50?random=charm8', 1000000, '全部权益,专属活动,定制服务', 1, NOW()),
(9, 9, '传奇主播', 'https://picsum.photos/50/50?random=charm9', 2000000, '全部权益,专属活动,定制服务,专属运营', 1, NOW()),
(10, 10, '神级主播', 'https://picsum.photos/50/50?random=charm10', 5000000, '最高权益', 1, NOW())
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`);
SET FOREIGN_KEY_CHECKS = 1;
-- ============================================
-- 补充测试数据统计
-- ============================================
/*
SQL文件为19个测试用户(uid: 100-118):
- 15
- 20
- 30
- 25
- 8
- 30
- 15
- 20
- 5
- 20
- 25
- 20
- 15
- 10
- 7
- 5
- 10
- 10
使:
1. zhibo_test_data.sql
2.
3. INSERT使用ON DUPLICATE KEY UPDATE避免重复插入
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,915 @@
# 缘池管理端设计文档
> 版本V1.0
> 更新日期2025-12-30
> 功能范围:板块管理 + 消息管理 + 自动审核
---
## 一、功能概述
缘池是直播平台的社交社区模块,用户可在不同板块发布消息进行交流。管理端提供板块配置、消息审核、自动审核规则设置等功能。
### 1.1 功能结构
```
缘池管理 (/community)
├── 板块管理 - 配置社区板块分类
├── 消息管理 - 查看/审核/管理用户消息
└── 审核配置 - 自动审核规则设置
```
### 1.2 自动审核机制
```
用户发布消息 → 敏感词检测 → 自动判定
┌──────────┼──────────┐
↓ ↓ ↓
无敏感词 轻度敏感 重度敏感
↓ ↓ ↓
自动通过 待人工审核 自动拒绝
```
---
## 二、前端设计
### 2.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: '板块管理', icon: '' },
},
{
path: 'message',
component: () => import('@/views/community/message/index'),
name: 'CommunityMessage',
meta: { title: '消息管理', icon: '' },
},
{
path: 'audit-config',
component: () => import('@/views/community/auditConfig/index'),
name: 'CommunityAuditConfig',
meta: { title: '审核配置', icon: '' },
},
],
};
export default communityManageRouter;
```
### 2.2 API接口
文件:`Zhibo/admin/src/api/community.js`
```javascript
import request from '@/utils/request';
// ==================== 板块管理 ====================
// 获取板块列表
export function categoryList(params) {
return request({
url: '/admin/community/category/list',
method: 'get',
params,
});
}
// 保存板块(新增/编辑)
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 getAuditConfig() {
return request({
url: '/admin/community/audit/config',
method: 'get',
});
}
// 保存审核配置
export function saveAuditConfig(data) {
return request({
url: '/admin/community/audit/config/save',
method: 'post',
data,
});
}
```
### 2.3 页面设计
#### 2.3.1 板块管理页面
文件:`Zhibo/admin/src/views/community/category/index.vue`
```
┌─────────────────────────────────────────────────────────────┐
│ [+ 新增板块] │
├─────────────────────────────────────────────────────────────┤
│ 图标 │ 名称 │ 排序 │ 状态 │ 创建时间 │ 操作 │
├──────┼────────┼──────┼────────┼────────────┼───────────────┤
│ 🎮 │ 游戏 │ 100 │ ●启用 │ 2025-01-01 │ [编辑][删除] │
│ 🎵 │ 音乐 │ 90 │ ●启用 │ 2025-01-01 │ [编辑][删除] │
│ 💬 │ 交友 │ 80 │ ○禁用 │ 2025-01-01 │ [编辑][删除] │
└─────────────────────────────────────────────────────────────┘
```
**功能说明:**
- 新增板块:弹窗表单,填写名称、图标、排序
- 编辑板块:弹窗表单,修改板块信息
- 删除板块:确认弹窗后删除
- 状态切换:开关组件,启用/禁用板块
#### 2.3.2 消息管理页面
文件:`Zhibo/admin/src/views/community/message/index.vue`
```
┌─────────────────────────────────────────────────────────────────────┐
│ 板块[全部▼] 状态[全部▼] 审核方式[全部▼] 时间[起始-结束] [搜索] │
├─────────────────────────────────────────────────────────────────────┤
│ 用户 │ 板块 │ 内容 │ 图片 │ 状态 │ 审核方式│ 操作 │
├──────────┼──────┼──────────────┼──────┼────────┼─────────┼─────────┤
│ 👤张三 │ 游戏 │ 今天开黑吗.. │ 🖼x2 │ 已通过 │ 自动 │ [删除] │
│ 👤李四 │ 交友 │ 有人一起.. │ 🖼x1 │ 待审核 │ - │ [✓][✗] │
│ 👤王五 │ 音乐 │ 推荐一首.. │ - │ 已拒绝 │ 自动 │ [删除] │
└─────────────────────────────────────────────────────────────────────┘
```
**筛选条件:**
- 板块:下拉选择板块
- 状态:全部/待审核/已通过/已拒绝
- 审核方式:全部/自动/人工
- 时间范围:日期选择器
**操作说明:**
- 待审核消息:显示[通过][拒绝]按钮
- 已审核消息:显示[删除]按钮
- 点击内容可展开查看完整内容和图片
#### 2.3.3 审核配置页面
文件:`Zhibo/admin/src/views/community/auditConfig/index.vue`
```
┌─────────────────────────────────────────────────────────────┐
│ 自动审核配置 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 开启自动审核 [========●] │
│ 说明:开启后系统自动检测敏感词并审核 │
│ │
│ 无敏感词自动通过 [========●] │
│ 说明:消息不含敏感词时自动通过审核 │
│ │
│ 重度敏感词自动拒绝 [========●] │
│ 说明:消息含违禁词时自动拒绝 │
│ │
│ [保存配置] │
└─────────────────────────────────────────────────────────────┘
```
---
## 三、数据库设计
### 3.1 板块表 (eb_community_category)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | int | 板块ID主键自增 |
| name | varchar(50) | 板块名称 |
| icon | varchar(255) | 板块图标URL |
| sort | int | 排序(越大越靠前) |
| status | tinyint | 状态 0禁用 1启用 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
### 3.2 消息表 (eb_community_message)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 消息ID主键自增 |
| uid | int | 用户ID |
| category_id | int | 板块ID |
| content | text | 消息内容 |
| images | varchar(1000) | 图片URL(逗号分隔) |
| status | tinyint | 状态 0待审核 1通过 2拒绝 |
| audit_type | tinyint | 审核方式 0自动 1人工 |
| audit_remark | varchar(255) | 审核备注 |
| is_delete | tinyint | 是否删除 0否 1是 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
### 3.3 审核配置表 (eb_community_audit_config)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | int | 配置ID固定为1 |
| auto_audit | tinyint | 开启自动审核 0关闭 1开启 |
| auto_pass | tinyint | 无敏感词自动通过 0否 1是 |
| auto_reject | tinyint | 重度敏感词自动拒绝 0否 1是 |
| update_time | datetime | 更新时间 |
### 3.4 建表SQL
```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 '板块图标URL',
`sort` int DEFAULT 0 COMMENT '排序(越大越靠前)',
`status` tinyint DEFAULT 1 COMMENT '状态 0禁用 1启用',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
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 '图片URL(逗号分隔)',
`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 '是否删除 0否 1是',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
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_audit_config` (
`id` int NOT NULL AUTO_INCREMENT,
`auto_audit` tinyint DEFAULT 1 COMMENT '开启自动审核 0关闭 1开启',
`auto_pass` tinyint DEFAULT 1 COMMENT '无敏感词自动通过 0否 1是',
`auto_reject` tinyint DEFAULT 1 COMMENT '重度敏感词自动拒绝 0否 1是',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缘池审核配置表';
-- 初始化审核配置
INSERT INTO `eb_community_audit_config` (`id`, `auto_audit`, `auto_pass`, `auto_reject`)
VALUES (1, 1, 1, 1);
-- 初始化默认板块
INSERT INTO `eb_community_category` (`name`, `icon`, `sort`, `status`) VALUES
('交友', 'el-icon-user', 100, 1),
('游戏', 'el-icon-video-play', 90, 1),
('音乐', 'el-icon-headset', 80, 1),
('运动', 'el-icon-football', 70, 1),
('美食', 'el-icon-food', 60, 1);
```
---
## 四、后端设计
### 4.1 实体类
#### CommunityCategory.java
文件:`crmeb-common/src/main/java/com/zbkj/common/model/community/CommunityCategory.java`
```java
package com.zbkj.common.model.community;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("eb_community_category")
public class CommunityCategory {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String icon;
private Integer sort;
private Integer status;
private Date createTime;
private Date updateTime;
}
```
#### CommunityMessage.java
文件:`crmeb-common/src/main/java/com/zbkj/common/model/community/CommunityMessage.java`
```java
package com.zbkj.common.model.community;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@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; // 0待审核 1通过 2拒绝
private Integer auditType; // 0自动 1人工
private String auditRemark;
private Integer isDelete;
private Date createTime;
private Date updateTime;
}
```
#### CommunityAuditConfig.java
文件:`crmeb-common/src/main/java/com/zbkj/common/model/community/CommunityAuditConfig.java`
```java
package com.zbkj.common.model.community;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("eb_community_audit_config")
public class CommunityAuditConfig {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer autoAudit; // 开启自动审核
private Integer autoPass; // 无敏感词自动通过
private Integer autoReject; // 重度敏感词自动拒绝
private Date updateTime;
}
```
### 4.2 Controller
文件:`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.CommunityMessageRequest;
import com.zbkj.common.request.CommunityAuditRequest;
import com.zbkj.common.response.CommunityMessageVO;
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 CommunityAuditRequest 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("/audit/config")
public CommonResult<CommunityAuditConfig> getAuditConfig() {
return CommonResult.success(communityService.getAuditConfig());
}
@ApiOperation("保存审核配置")
@PostMapping("/audit/config/save")
public CommonResult<String> saveAuditConfig(@RequestBody CommunityAuditConfig config) {
communityService.saveAuditConfig(config);
return CommonResult.success("保存成功");
}
}
```
### 4.3 Service
文件:`crmeb-service/src/main/java/com/zbkj/service/service/CommunityService.java`
```java
package com.zbkj.service.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.community.*;
import com.zbkj.common.request.CommunityMessageRequest;
import com.zbkj.common.response.CommunityMessageVO;
import com.zbkj.service.dao.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CommunityService {
@Autowired
private CommunityCategoryDao categoryDao;
@Autowired
private CommunityMessageDao messageDao;
@Autowired
private CommunityAuditConfigDao auditConfigDao;
@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 void deleteCategory(Integer id) {
categoryDao.deleteById(id);
}
public void updateCategoryStatus(Integer id, Integer status) {
CommunityCategory category = new CommunityCategory();
category.setId(id);
category.setStatus(status);
categoryDao.updateById(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 auditMessage(Long id, Integer status, String remark) {
CommunityMessage message = new CommunityMessage();
message.setId(id);
message.setStatus(status);
message.setAuditType(1); // 人工审核
message.setAuditRemark(remark != null ? remark : (status == 1 ? "人工审核通过" : "人工审核拒绝"));
messageDao.updateById(message);
}
public void deleteMessage(Long id) {
CommunityMessage message = new CommunityMessage();
message.setId(id);
message.setIsDelete(1);
messageDao.updateById(message);
}
// ==================== 自动审核(移动端发布时调用) ====================
public void autoAuditMessage(CommunityMessage message) {
CommunityAuditConfig config = getAuditConfig();
// 未开启自动审核,待人工审核
if (config.getAutoAudit() != 1) {
message.setStatus(0);
return;
}
// 敏感词检测
String content = message.getContent();
List<String> sensitiveWords = sensitiveWordService.findAll(content);
if (sensitiveWords.isEmpty()) {
// 无敏感词
if (config.getAutoPass() == 1) {
message.setStatus(1);
message.setAuditRemark("自动审核通过");
} else {
message.setStatus(0);
}
message.setAuditType(0);
} else if (sensitiveWordService.hasSevereWord(sensitiveWords)) {
// 重度敏感词
if (config.getAutoReject() == 1) {
message.setStatus(2);
message.setAuditRemark("含违禁词自动拒绝");
} else {
message.setStatus(0);
message.setAuditRemark("含敏感词:" + String.join(",", sensitiveWords));
}
message.setAuditType(0);
} else {
// 轻度敏感词,待人工审核
message.setStatus(0);
message.setAuditRemark("含敏感词:" + String.join(",", sensitiveWords));
message.setAuditType(0);
}
}
// ==================== 审核配置 ====================
public CommunityAuditConfig getAuditConfig() {
return auditConfigDao.selectById(1);
}
public void saveAuditConfig(CommunityAuditConfig config) {
config.setId(1);
auditConfigDao.updateById(config);
}
}
```
### 4.4 DAO层
#### CommunityCategoryDao.java
文件:`crmeb-service/src/main/java/com/zbkj/service/dao/CommunityCategoryDao.java`
```java
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.community.CommunityCategory;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CommunityCategoryDao extends BaseMapper<CommunityCategory> {
}
```
#### CommunityMessageDao.java
文件:`crmeb-service/src/main/java/com/zbkj/service/dao/CommunityMessageDao.java`
```java
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.community.CommunityMessage;
import com.zbkj.common.request.CommunityMessageRequest;
import com.zbkj.common.response.CommunityMessageVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface CommunityMessageDao extends BaseMapper<CommunityMessage> {
List<CommunityMessageVO> selectMessageList(@Param("req") CommunityMessageRequest request);
}
```
#### CommunityAuditConfigDao.java
文件:`crmeb-service/src/main/java/com/zbkj/service/dao/CommunityAuditConfigDao.java`
```java
package com.zbkj.service.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.model.community.CommunityAuditConfig;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CommunityAuditConfigDao extends BaseMapper<CommunityAuditConfig> {
}
```
### 4.5 Mapper XML
文件:`crmeb-service/src/main/resources/mapper/community/CommunityMessageMapper.xml`
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zbkj.service.dao.CommunityMessageDao">
<select id="selectMessageList" resultType="com.zbkj.common.response.CommunityMessageVO">
SELECT
m.id, m.uid, m.category_id, m.content, m.images,
m.status, m.audit_type, m.audit_remark, m.create_time,
u.nickname, u.avatar,
c.name as category_name
FROM eb_community_message m
LEFT JOIN eb_user u ON m.uid = u.uid
LEFT JOIN eb_community_category c ON m.category_id = c.id
WHERE m.is_delete = 0
<if test="req.categoryId != null">
AND m.category_id = #{req.categoryId}
</if>
<if test="req.status != null">
AND m.status = #{req.status}
</if>
<if test="req.auditType != null">
AND m.audit_type = #{req.auditType}
</if>
<if test="req.startTime != null and req.endTime != null">
AND m.create_time BETWEEN #{req.startTime} AND #{req.endTime}
</if>
ORDER BY m.create_time DESC
</select>
</mapper>
```
### 4.6 Request/Response类
#### CommunityMessageRequest.java
文件:`crmeb-common/src/main/java/com/zbkj/common/request/CommunityMessageRequest.java`
```java
package com.zbkj.common.request;
import lombok.Data;
@Data
public class CommunityMessageRequest {
private Integer page = 1;
private Integer limit = 20;
private Integer categoryId; // 板块ID
private Integer status; // 状态
private Integer auditType; // 审核方式
private String startTime; // 开始时间
private String endTime; // 结束时间
}
```
#### CommunityAuditRequest.java
文件:`crmeb-common/src/main/java/com/zbkj/common/request/CommunityAuditRequest.java`
```java
package com.zbkj.common.request;
import lombok.Data;
@Data
public class CommunityAuditRequest {
private Long id; // 消息ID
private Integer status; // 审核状态 1通过 2拒绝
private String remark; // 审核备注
}
```
#### CommunityMessageVO.java
文件:`crmeb-common/src/main/java/com/zbkj/common/response/CommunityMessageVO.java`
```java
package com.zbkj.common.response;
import lombok.Data;
import java.util.Date;
@Data
public class CommunityMessageVO {
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 Date createTime;
// 关联字段
private String nickname; // 用户昵称
private String avatar; // 用户头像
private String categoryName; // 板块名称
}
```
---
## 五、文件清单
### 5.1 前端文件
```
Zhibo/admin/src/
├── api/
│ └── community.js # API接口
├── router/modules/
│ └── communityManage.js # 路由配置
└── views/community/
├── category/
│ └── index.vue # 板块管理页面
├── message/
│ └── index.vue # 消息管理页面
└── auditConfig/
└── index.vue # 审核配置页面
```
### 5.2 后端文件
```
Zhibo/zhibo-h/
├── crmeb-admin/src/main/java/com/zbkj/admin/controller/
│ └── CommunityAdminController.java # 控制器
├── crmeb-service/src/main/java/com/zbkj/service/
│ ├── service/
│ │ └── CommunityService.java # 服务层
│ └── dao/
│ ├── CommunityCategoryDao.java # 板块DAO
│ ├── CommunityMessageDao.java # 消息DAO
│ └── CommunityAuditConfigDao.java # 配置DAO
├── crmeb-service/src/main/resources/mapper/community/
│ └── CommunityMessageMapper.xml # Mapper XML
└── crmeb-common/src/main/java/com/zbkj/common/
├── model/community/
│ ├── CommunityCategory.java # 板块实体
│ ├── CommunityMessage.java # 消息实体
│ └── CommunityAuditConfig.java # 配置实体
├── request/
│ ├── CommunityMessageRequest.java # 消息查询请求
│ └── CommunityAuditRequest.java # 审核请求
└── response/
└── CommunityMessageVO.java # 消息响应VO
```
### 5.3 数据库
```
eb_community_category # 板块表
eb_community_message # 消息表
eb_community_audit_config # 审核配置表
```
---
## 六、菜单配置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`, `icon`, `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:audit', '/community/audit-config', 'C', 1, 1);
```
---
## 七、开发顺序
1. **数据库** - 执行建表SQL
2. **后端实体类** - 创建Model类
3. **后端DAO** - 创建DAO接口和Mapper
4. **后端Service** - 实现业务逻辑
5. **后端Controller** - 实现API接口
6. **前端API** - 创建接口文件
7. **前端路由** - 配置路由
8. **前端页面** - 实现三个管理页面
9. **菜单配置** - 执行菜单SQL