From b08765e035ebcf78152dc4ca053f38dcf9c45566 Mon Sep 17 00:00:00 2001 From: xiao12feng8 <16507319+xiao12feng8@user.noreply.gitee.com> Date: Sat, 3 Jan 2026 19:22:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9A=E7=A4=BC=E7=89=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=9F=BA=E6=9C=AC=E6=90=AD=E5=BB=BA=E5=A5=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FINAL_FIX_LIVE_404.sql | 54 ++ Zhibo/admin/src/api/gift.js | 174 +++--- Zhibo/admin/src/router/index.js | 5 +- Zhibo/admin/src/router/modules/giftManage.js | 30 +- Zhibo/admin/src/router/modules/liveManage.js | 26 +- Zhibo/admin/src/views/gift/config/index.vue | 200 ++++++ Zhibo/admin/src/views/gift/manage/index.vue | 451 ++++++++++++++ Zhibo/admin/src/views/gift/recharge/index.vue | 147 +++++ Zhibo/admin/src/views/gift/records/index.vue | 307 ++++++++++ .../admin/controller/GiftAdminController.java | 577 ++++++++++++------ .../controller/GiftSystemController.java | 4 +- .../controller/VirtualCurrencyController.java | 2 +- add_gift_manage_menu.sql | 44 ++ add_gift_menu.sql | 54 ++ add_gift_menus_correct.sql | 0 add_gift_menus_to_database.sql | 42 ++ add_gift_to_live_manage_correct.sql | 24 + check_current_menu_status.sql | 51 ++ check_gift_records.sql | 47 ++ check_gift_table_structure.sql | 29 + check_live_menu_config.sql | 39 ++ check_menu_table_columns.sql | 5 + check_menu_table_structure.sql | 8 + clear_frontend_cache.bat | 38 ++ compare_working_menu.sql | 39 ++ complete_gift_diagnosis.sql | 126 ++++ create_gift_menu.sql | 63 ++ create_gift_table.sql | 52 ++ debug_gift_api_response.sql | 39 ++ deploy-gift-fix.bat | 27 + deploy-gift-records-fix.bat | 32 + deploy-gift-system-complete.bat | 50 ++ deploy_gift_in_live.bat | 38 ++ deploy_gift_manage_complete.bat | 44 ++ diagnose_and_fix_live_menu.sql | 98 +++ diagnose_gift_system.sql | 106 ++++ diagnose_menu_404.sql | 76 +++ final_fix_gift_menu.sql | 15 + final_move_gift_to_live.sql | 14 + find_existing_gift_tables.sql | 44 ++ fix_404_remove_gift_from_live.sql | 38 ++ fix_gift_menu_complete.sql | 43 ++ fix_gift_menu_final.sql | 38 ++ fix_gift_menu_paths.sql | 27 + fix_live_menu_404.sql | 20 + insert_gift_menus_correct.sql | 67 ++ keep_gift_independent.sql | 7 + move_gift_to_live_correctly.sql | 21 + move_gift_to_live_manage.sql | 19 + quick_test_gift_system.sql | 17 + rebuild_backend_gift.bat | 20 + restart_frontend.bat | 29 + restore_gift_menu.sql | 8 + simple_gift_menu_records_only.sql | 17 + test_gift_api.md | 59 ++ update_gift_reward_menu.sql | 37 ++ verify_gift_menu.sql | 53 ++ verify_menu_after_fix.sql | 20 + 添加礼物打赏菜单配置说明.md | 214 +++++++ 礼物系统后台管理部署说明.md | 299 +++++++++ 礼物系统完整开发文档.md | 301 +++++++++ 礼物系统完整部署指南.md | 145 +++++ 62 files changed, 4436 insertions(+), 284 deletions(-) create mode 100644 FINAL_FIX_LIVE_404.sql create mode 100644 Zhibo/admin/src/views/gift/config/index.vue create mode 100644 Zhibo/admin/src/views/gift/manage/index.vue create mode 100644 Zhibo/admin/src/views/gift/recharge/index.vue create mode 100644 Zhibo/admin/src/views/gift/records/index.vue create mode 100644 add_gift_manage_menu.sql create mode 100644 add_gift_menu.sql create mode 100644 add_gift_menus_correct.sql create mode 100644 add_gift_menus_to_database.sql create mode 100644 add_gift_to_live_manage_correct.sql create mode 100644 check_current_menu_status.sql create mode 100644 check_gift_records.sql create mode 100644 check_gift_table_structure.sql create mode 100644 check_live_menu_config.sql create mode 100644 check_menu_table_columns.sql create mode 100644 check_menu_table_structure.sql create mode 100644 clear_frontend_cache.bat create mode 100644 compare_working_menu.sql create mode 100644 complete_gift_diagnosis.sql create mode 100644 create_gift_menu.sql create mode 100644 create_gift_table.sql create mode 100644 debug_gift_api_response.sql create mode 100644 deploy-gift-fix.bat create mode 100644 deploy-gift-records-fix.bat create mode 100644 deploy-gift-system-complete.bat create mode 100644 deploy_gift_in_live.bat create mode 100644 deploy_gift_manage_complete.bat create mode 100644 diagnose_and_fix_live_menu.sql create mode 100644 diagnose_gift_system.sql create mode 100644 diagnose_menu_404.sql create mode 100644 final_fix_gift_menu.sql create mode 100644 final_move_gift_to_live.sql create mode 100644 find_existing_gift_tables.sql create mode 100644 fix_404_remove_gift_from_live.sql create mode 100644 fix_gift_menu_complete.sql create mode 100644 fix_gift_menu_final.sql create mode 100644 fix_gift_menu_paths.sql create mode 100644 fix_live_menu_404.sql create mode 100644 insert_gift_menus_correct.sql create mode 100644 keep_gift_independent.sql create mode 100644 move_gift_to_live_correctly.sql create mode 100644 move_gift_to_live_manage.sql create mode 100644 quick_test_gift_system.sql create mode 100644 rebuild_backend_gift.bat create mode 100644 restart_frontend.bat create mode 100644 restore_gift_menu.sql create mode 100644 simple_gift_menu_records_only.sql create mode 100644 test_gift_api.md create mode 100644 update_gift_reward_menu.sql create mode 100644 verify_gift_menu.sql create mode 100644 verify_menu_after_fix.sql create mode 100644 添加礼物打赏菜单配置说明.md create mode 100644 礼物系统后台管理部署说明.md create mode 100644 礼物系统完整开发文档.md create mode 100644 礼物系统完整部署指南.md diff --git a/FINAL_FIX_LIVE_404.sql b/FINAL_FIX_LIVE_404.sql new file mode 100644 index 00000000..0c2ad60a --- /dev/null +++ b/FINAL_FIX_LIVE_404.sql @@ -0,0 +1,54 @@ +-- ======================================== +-- 最终修复:直播管理404问题 +-- ======================================== + +-- 问题根源: +-- 礼物打赏菜单(id=823)的component是 /liveManage/gift/records/index +-- 这与前端独立的 giftManageRouter (/gift) 冲突 + +-- 解决方案:将礼物打赏从直播管理中移除 + +-- 步骤1:隐藏直播管理下的礼物打赏菜单 +UPDATE eb_system_menu +SET is_show = 0 +WHERE id = 823 + AND pid = 675 + AND name = '礼物打赏'; + +-- 步骤2:确保直播管理菜单本身是显示的 +UPDATE eb_system_menu +SET is_show = 1 +WHERE id = 675 + AND name = '直播管理'; + +-- 步骤3:确保所有直播管理的子菜单都是显示的(除了礼物打赏) +UPDATE eb_system_menu +SET is_show = 1 +WHERE pid = 675 + AND id != 823; + +-- 验证修复结果 +SELECT + '=== 直播管理菜单 ===' as section, + id, + pid, + name, + component, + is_show, + sort, + CASE WHEN is_show = 1 THEN '✓ 显示' ELSE '✗ 隐藏' END as status +FROM eb_system_menu +WHERE id = 675 OR pid = 675 +ORDER BY pid, sort; + +-- 检查是否还有其他冲突 +SELECT + '=== 可能的路径冲突 ===' as section, + component, + COUNT(*) as count, + GROUP_CONCAT(name SEPARATOR ' | ') as menu_names +FROM eb_system_menu +WHERE is_show = 1 + AND component LIKE '/liveManage%' +GROUP BY component +HAVING count > 1; diff --git a/Zhibo/admin/src/api/gift.js b/Zhibo/admin/src/api/gift.js index 9025774b..c3789dd2 100644 --- a/Zhibo/admin/src/api/gift.js +++ b/Zhibo/admin/src/api/gift.js @@ -1,97 +1,125 @@ -import request from '@/utils/request'; +import request from '@/utils/request' -/** - * 礼物列表 - */ +// 获取礼物打赏记录列表 +export function getGiftRecords(params) { + return request({ + url: '/admin/gift/records', + method: 'get', + params + }) +} + +// 获取礼物统计数据 +export function getGiftStatistics() { + return request({ + url: '/admin/gift/statistics', + method: 'get' + }) +} + +// 获取礼物配置列表 +export function getGiftConfigList() { + return request({ + url: '/admin/gift/config/list', + method: 'get' + }) +} + +// 添加礼物配置 +export function addGiftConfig(data) { + return request({ + url: '/admin/gift/config/add', + method: 'post', + data + }) +} + +// 更新礼物配置 +export function updateGiftConfig(data) { + return request({ + url: '/admin/gift/config/update', + method: 'post', + data + }) +} + +// 删除礼物配置 +export function deleteGiftConfig(id) { + return request({ + url: `/admin/gift/config/delete/${id}`, + method: 'post' + }) +} + +// 获取充值套餐列表 +export function getRechargePackages() { + return request({ + url: '/admin/gift/recharge/packages', + method: 'get' + }) +} + +// 更新充值套餐 +export function updateRechargePackage(data) { + return request({ + url: '/admin/gift/recharge/package/update', + method: 'post', + data + }) +} + +// 获取充值记录 +export function getRechargeRecords(params) { + return request({ + url: '/admin/gift/recharge/records', + method: 'get', + params + }) +} + +// ========== 礼物管理 ========== + +// 获取礼物列表 export function giftListApi(params) { return request({ url: '/admin/gift/list', method: 'get', params - }); + }) } -/** - * 礼物详情 - */ -export function giftDetailApi(id) { - return request({ - url: `/admin/gift/detail/${id}`, - method: 'get' - }); -} - -/** - * 添加礼物 - */ +// 添加礼物 export function giftAddApi(data) { return request({ url: '/admin/gift/add', method: 'post', data - }); + }) } -/** - * 更新礼物 - */ -export function giftUpdateApi(id, data) { +// 更新礼物 +export function giftUpdateApi(data) { return request({ - url: `/admin/gift/update/${id}`, + url: '/admin/gift/update', method: 'post', data - }); + }) } -/** - * 更新礼物状态 - */ +// 删除礼物 +export function giftDeleteApi(ids) { + return request({ + url: '/admin/gift/delete', + method: 'post', + data: { ids: Array.isArray(ids) ? ids : [ids] } + }) +} + +// 更新礼物状态 export function giftStatusApi(id, status) { return request({ - url: `/admin/gift/status/${id}`, + url: '/admin/gift/status', method: 'post', - params: { status } - }); -} - -/** - * 更新心动礼物状态 - */ -export function giftHeartbeatApi(id, isHeartbeat) { - return request({ - url: `/admin/gift/heartbeat/${id}`, - method: 'post', - params: { isHeartbeat } - }); -} - -/** - * 删除礼物 - */ -export function giftDeleteApi(id) { - return request({ - url: `/admin/gift/${id}`, - method: 'delete' - }); -} - -/** - * 批量删除礼物 - */ -export function giftBatchDeleteApi(ids) { - return request({ - url: '/admin/gift/batch-delete', - method: 'post', - data: { ids } - }); -} - -/** - * 礼物统计 - */ -export function giftStatisticsApi() { - return request({ - url: '/admin/gift/statistics', - method: 'get' - }); + data: { id, status } + }) } diff --git a/Zhibo/admin/src/router/index.js b/Zhibo/admin/src/router/index.js index d39fb104..f5009e92 100644 --- a/Zhibo/admin/src/router/index.js +++ b/Zhibo/admin/src/router/index.js @@ -21,7 +21,6 @@ import monitorRouter from './modules/monitor'; // 数据监控 import userManageRouter from './modules/userManage'; // 用户管理 import liveManageRouter from './modules/liveManage'; // 直播管理 import socialManageRouter from './modules/socialManage'; // 社交互动 -import giftManageRouter from './modules/giftManage'; // 礼物打赏 import virtualPropsRouter from './modules/virtualProps'; // 虚拟道具 import activityManageRouter from './modules/activityManage'; // 营销活动 import taskManageRouter from './modules/taskManage'; // 任务系统 @@ -86,9 +85,7 @@ export const constantRoutes = [ liveManageRouter, // 4. 社交互动 socialManageRouter, - // 5. 礼物打赏 - giftManageRouter, - // 6. 虚拟道具 + // 5. 虚拟道具 virtualPropsRouter, // 7. 营销活动 activityManageRouter, diff --git a/Zhibo/admin/src/router/modules/giftManage.js b/Zhibo/admin/src/router/modules/giftManage.js index 0b788ca2..9261e36d 100644 --- a/Zhibo/admin/src/router/modules/giftManage.js +++ b/Zhibo/admin/src/router/modules/giftManage.js @@ -1,40 +1,24 @@ import Layout from '@/layout'; /** - * 礼物打赏 - 整合路由 - * 包含:礼物、礼物数量、打赏记录 + * 礼物打赏管理 */ const giftManageRouter = { - path: '/giftManage', + path: '/gift', component: Layout, - redirect: '/giftManage/list', + redirect: '/gift/records/index', name: 'GiftManage', - alwaysShow: true, meta: { title: '礼物打赏', icon: 'el-icon-present', }, children: [ - // 礼物列表 - { - path: 'list', - component: () => import('@/views/gift/index'), - name: 'GiftList', - meta: { title: '礼物列表', icon: '' }, - }, - // 礼物数量 - { - path: 'num', - component: () => import('@/views/giftnum/index'), - name: 'GiftNum', - meta: { title: '礼物数量', icon: '' }, - }, // 打赏记录 { - path: 'reward/record', - component: () => import('@/views/giftreward/record/index'), - name: 'GiftRewardRecord', - meta: { title: '打赏记录', icon: '' }, + path: 'records/index', + component: () => import('@/views/gift/records/index.vue'), + name: 'GiftRecords', + meta: { title: '打赏记录', icon: 'el-icon-document' }, }, ], }; diff --git a/Zhibo/admin/src/router/modules/liveManage.js b/Zhibo/admin/src/router/modules/liveManage.js index 5547477f..cbd7a685 100644 --- a/Zhibo/admin/src/router/modules/liveManage.js +++ b/Zhibo/admin/src/router/modules/liveManage.js @@ -18,43 +18,57 @@ const liveManageRouter = { // 房间管理(包含分类管理) { path: 'room/list', - component: () => import('@/views/room/list/index'), + component: () => import('@/views/room/list/index.vue'), name: 'RoomList', meta: { title: '房间列表', icon: '' }, }, // 家族管理 { path: 'family/list', - component: () => import('@/views/family/list/index'), + component: () => import('@/views/family/list/index.vue'), name: 'FamilyList', meta: { title: '家族列表', icon: '' }, }, { path: 'family/level', - component: () => import('@/views/family/level/index'), + component: () => import('@/views/family/level/index.vue'), name: 'FamilyLevel', meta: { title: '家族级别', icon: '' }, }, { path: 'family/member', - component: () => import('@/views/family/member/index'), + component: () => import('@/views/family/member/index.vue'), name: 'FamilyMember', meta: { title: '家族成员', icon: '' }, }, // 粉丝团 { path: 'fanGroup/list', - component: () => import('@/views/fanGroup/list/index'), + component: () => import('@/views/fanGroup/list/index.vue'), name: 'FanGroupList', meta: { title: '粉丝团管理', icon: '' }, }, // 主播管理 { path: 'streamer/list', - component: () => import('@/views/streamer/list/index'), + component: () => import('@/views/streamer/list/index.vue'), name: 'StreamerList', meta: { title: '主播管理', icon: '' }, }, + // 礼物打赏 + { + path: 'gift/records/index', + component: () => import('@/views/gift/records/index.vue'), + name: 'GiftRecords', + meta: { title: '打赏记录', icon: '' }, + }, + // 礼物管理 + { + path: 'gift/manage/index', + component: () => import('@/views/gift/manage/index.vue'), + name: 'GiftManage', + meta: { title: '礼物管理', icon: '' }, + }, ], }; diff --git a/Zhibo/admin/src/views/gift/config/index.vue b/Zhibo/admin/src/views/gift/config/index.vue new file mode 100644 index 00000000..97e688cc --- /dev/null +++ b/Zhibo/admin/src/views/gift/config/index.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/Zhibo/admin/src/views/gift/manage/index.vue b/Zhibo/admin/src/views/gift/manage/index.vue new file mode 100644 index 00000000..8889693e --- /dev/null +++ b/Zhibo/admin/src/views/gift/manage/index.vue @@ -0,0 +1,451 @@ + + + + + diff --git a/Zhibo/admin/src/views/gift/recharge/index.vue b/Zhibo/admin/src/views/gift/recharge/index.vue new file mode 100644 index 00000000..4c4879ee --- /dev/null +++ b/Zhibo/admin/src/views/gift/recharge/index.vue @@ -0,0 +1,147 @@ + + + diff --git a/Zhibo/admin/src/views/gift/records/index.vue b/Zhibo/admin/src/views/gift/records/index.vue new file mode 100644 index 00000000..bb6e092e --- /dev/null +++ b/Zhibo/admin/src/views/gift/records/index.vue @@ -0,0 +1,307 @@ + + + + + diff --git a/Zhibo/zhibo-h/crmeb-admin/src/main/java/com/zbkj/admin/controller/GiftAdminController.java b/Zhibo/zhibo-h/crmeb-admin/src/main/java/com/zbkj/admin/controller/GiftAdminController.java index 15900b83..29601e9e 100644 --- a/Zhibo/zhibo-h/crmeb-admin/src/main/java/com/zbkj/admin/controller/GiftAdminController.java +++ b/Zhibo/zhibo-h/crmeb-admin/src/main/java/com/zbkj/admin/controller/GiftAdminController.java @@ -10,12 +10,11 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.math.BigDecimal; +import java.util.*; /** - * 礼物管理控制器 + * 礼物管理控制器(后台管理) */ @Slf4j @RestController @@ -28,61 +27,79 @@ public class GiftAdminController { private JdbcTemplate jdbcTemplate; /** - * 礼物列表 + * 获取礼物打赏记录列表 */ - @ApiOperation(value = "礼物列表") - @GetMapping("/list") - public CommonResult>> getGiftList( - @RequestParam(value = "keywords", required = false) String keywords, - @RequestParam(value = "status", required = false) String statusStr, + @ApiOperation(value = "礼物打赏记录列表") + @GetMapping("/records") + public CommonResult>> getGiftRecords( + @RequestParam(value = "keyword", required = false) String keyword, + @RequestParam(value = "startDate", required = false) String startDate, + @RequestParam(value = "endDate", required = false) String endDate, @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"); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT g.id, g.gift_name, g.gift_image as gift_icon, g.gift_price, g.quantity, g.total_price, "); + sql.append("g.sender_id, COALESCE(g.sender_nickname, sender.nickname, '') as sender_nickname, "); + sql.append("COALESCE(g.sender_avatar, sender.avatar, '') as sender_avatar, COALESCE(sender.phone, '') as sender_phone, "); + sql.append("g.receiver_id, COALESCE(g.receiver_nickname, receiver.nickname, '') as receiver_nickname, "); + sql.append("COALESCE(receiver.avatar, '') as receiver_avatar, COALESCE(receiver.phone, '') as receiver_phone, "); + sql.append("g.room_id, COALESCE(r.title, '') as room_title, "); + sql.append("COALESCE(g.is_deleted, 0) as is_anonymous, g.create_time "); + sql.append("FROM eb_gift_record g "); + sql.append("LEFT JOIN eb_user sender ON g.sender_id = sender.uid "); + sql.append("LEFT JOIN eb_user receiver ON g.receiver_id = receiver.uid "); + sql.append("LEFT JOIN eb_live_room r ON g.room_id = r.id "); + sql.append("WHERE 1=1 "); - if (keywords != null && !keywords.trim().isEmpty()) { - String condition = " AND name LIKE '%" + keywords.trim() + "%'"; + StringBuilder countSql = new StringBuilder(); + countSql.append("SELECT COUNT(*) FROM eb_gift_record g "); + countSql.append("LEFT JOIN eb_user sender ON g.sender_id = sender.uid "); + countSql.append("LEFT JOIN eb_user receiver ON g.receiver_id = receiver.uid "); + countSql.append("WHERE 1=1 "); + + List params = new ArrayList<>(); + List countParams = new ArrayList<>(); + + if (keyword != null && !keyword.isEmpty()) { + String condition = " AND (g.sender_nickname LIKE ? OR g.receiver_nickname LIKE ? OR g.gift_name LIKE ?) "; sql.append(condition); countSql.append(condition); + String keywordPattern = "%" + keyword + "%"; + params.add(keywordPattern); + params.add(keywordPattern); + params.add(keywordPattern); + countParams.add(keywordPattern); + countParams.add(keywordPattern); + countParams.add(keywordPattern); } - - // 处理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; + + if (startDate != null && !startDate.isEmpty()) { + String condition = " AND g.create_time >= ? "; sql.append(condition); countSql.append(condition); + params.add(startDate + " 00:00:00"); + countParams.add(startDate + " 00:00:00"); } - sql.append(" ORDER BY id ASC"); + if (endDate != null && !endDate.isEmpty()) { + String condition = " AND g.create_time <= ? "; + sql.append(condition); + countSql.append(condition); + params.add(endDate + " 23:59:59"); + countParams.add(endDate + " 23:59:59"); + } - Long total = jdbcTemplate.queryForObject(countSql.toString(), Long.class); + sql.append(" ORDER BY g.create_time DESC "); + + Long total = jdbcTemplate.queryForObject(countSql.toString(), Long.class, countParams.toArray()); int offset = (page - 1) * limit; - sql.append(" LIMIT ").append(offset).append(", ").append(limit); + sql.append(" LIMIT ? OFFSET ? "); + params.add(limit); + params.add(offset); - List> list = jdbcTemplate.queryForList(sql.toString()); - - // 转换字段名 - list.forEach(item -> { - item.put("diamondPrice", item.get("diamond_price")); - item.put("isHeartbeat", item.get("is_heartbeat") != null && ((Integer) item.get("is_heartbeat")) == 1); - item.put("buyType", item.get("buy_type")); - item.put("effectVersion", item.get("effect_version")); - item.put("createTime", item.get("create_time")); - item.put("updateTime", item.get("update_time")); - // 状态转换为布尔值 - item.put("status", item.get("status") != null && ((Integer) item.get("status")) == 1); - }); + List> list = jdbcTemplate.queryForList(sql.toString(), params.toArray()); CommonPage> result = new CommonPage<>(); result.setList(list); @@ -95,17 +112,288 @@ public class GiftAdminController { } /** - * 礼物详情 + * 获取礼物统计数据 */ - @ApiOperation(value = "礼物详情") - @GetMapping("/detail/{id}") - public CommonResult> getGiftDetail(@PathVariable Integer id) { - String sql = "SELECT * FROM eb_gift WHERE id = ?"; - List> list = jdbcTemplate.queryForList(sql, id); - if (list.isEmpty()) { - return CommonResult.failed("礼物不存在"); + @ApiOperation(value = "礼物统计数据") + @GetMapping("/statistics") + public CommonResult> getGiftStatistics() { + try { + Map stats = new HashMap<>(); + + // 总礼物数量 + String totalCountSql = "SELECT COUNT(*) FROM eb_gift_record"; + Integer totalCount = jdbcTemplate.queryForObject(totalCountSql, Integer.class); + stats.put("totalCount", totalCount != null ? totalCount : 0); + + // 总礼物价值 + String totalValueSql = "SELECT COALESCE(SUM(total_price), 0) FROM eb_gift_record"; + BigDecimal totalValue = jdbcTemplate.queryForObject(totalValueSql, BigDecimal.class); + stats.put("totalValue", totalValue != null ? totalValue : BigDecimal.ZERO); + + // 今日礼物数量 + String todayCountSql = "SELECT COUNT(*) FROM eb_gift_record WHERE DATE(create_time) = CURDATE()"; + Integer todayCount = jdbcTemplate.queryForObject(todayCountSql, Integer.class); + stats.put("todayCount", todayCount != null ? todayCount : 0); + + // 今日礼物价值 + String todayValueSql = "SELECT COALESCE(SUM(total_price), 0) FROM eb_gift_record WHERE DATE(create_time) = CURDATE()"; + BigDecimal todayValue = jdbcTemplate.queryForObject(todayValueSql, BigDecimal.class); + stats.put("todayValue", todayValue != null ? todayValue : BigDecimal.ZERO); + + return CommonResult.success(stats); + } catch (Exception e) { + log.error("获取礼物统计失败", e); + return CommonResult.failed("获取统计失败"); } - return CommonResult.success(list.get(0)); + } + + /** + * 获取礼物配置列表 + */ + @ApiOperation(value = "礼物配置列表") + @GetMapping("/config/list") + public CommonResult>> getGiftConfigList() { + try { + String sql = "SELECT id, name, icon, price, animation, sort_order, is_enabled, create_time " + + "FROM eb_gift_config ORDER BY sort_order"; + List> list = jdbcTemplate.queryForList(sql); + return CommonResult.success(list); + } catch (Exception e) { + log.error("获取礼物配置失败", e); + return CommonResult.failed("获取礼物配置失败"); + } + } + + /** + * 添加礼物配置 + */ + @ApiOperation(value = "添加礼物配置") + @PostMapping("/config/add") + public CommonResult addGiftConfig(@RequestBody Map request) { + try { + String name = (String) request.get("name"); + String icon = (String) request.get("icon"); + BigDecimal price = new BigDecimal(request.get("price").toString()); + String animation = (String) request.get("animation"); + Integer sortOrder = request.get("sortOrder") != null ? (Integer) request.get("sortOrder") : 0; + + String sql = "INSERT INTO eb_gift_config (name, icon, price, animation, sort_order) VALUES (?, ?, ?, ?, ?)"; + jdbcTemplate.update(sql, name, icon, price, animation, sortOrder); + + return CommonResult.success("添加成功"); + } catch (Exception e) { + log.error("添加礼物配置失败", e); + return CommonResult.failed("添加失败"); + } + } + + /** + * 更新礼物配置 + */ + @ApiOperation(value = "更新礼物配置") + @PostMapping("/config/update") + public CommonResult updateGiftConfig(@RequestBody Map request) { + try { + Integer id = (Integer) request.get("id"); + String name = (String) request.get("name"); + String icon = (String) request.get("icon"); + BigDecimal price = new BigDecimal(request.get("price").toString()); + String animation = (String) request.get("animation"); + Integer sortOrder = request.get("sortOrder") != null ? (Integer) request.get("sortOrder") : 0; + Integer isEnabled = request.get("isEnabled") != null ? (Integer) request.get("isEnabled") : 1; + + String sql = "UPDATE eb_gift_config SET name = ?, icon = ?, price = ?, animation = ?, sort_order = ?, is_enabled = ? WHERE id = ?"; + jdbcTemplate.update(sql, name, icon, price, animation, sortOrder, isEnabled, id); + + return CommonResult.success("更新成功"); + } catch (Exception e) { + log.error("更新礼物配置失败", e); + return CommonResult.failed("更新失败"); + } + } + + /** + * 删除礼物配置 + */ + @ApiOperation(value = "删除礼物配置") + @PostMapping("/config/delete/{id}") + public CommonResult deleteGiftConfig(@PathVariable Integer id) { + try { + String sql = "DELETE FROM eb_gift_config WHERE id = ?"; + jdbcTemplate.update(sql, id); + return CommonResult.success("删除成功"); + } catch (Exception e) { + log.error("删除礼物配置失败", e); + return CommonResult.failed("删除失败"); + } + } + + /** + * 获取充值套餐列表 + */ + @ApiOperation(value = "充值套餐列表") + @GetMapping("/recharge/packages") + public CommonResult>> getRechargePackages() { + try { + String sql = "SELECT id, amount, virtual_amount, bonus_amount, title, description, is_hot, sort_order, is_enabled " + + "FROM eb_recharge_package ORDER BY sort_order"; + List> list = jdbcTemplate.queryForList(sql); + return CommonResult.success(list); + } catch (Exception e) { + log.error("获取充值套餐失败", e); + return CommonResult.failed("获取充值套餐失败"); + } + } + + /** + * 更新充值套餐 + */ + @ApiOperation(value = "更新充值套餐") + @PostMapping("/recharge/package/update") + public CommonResult updateRechargePackage(@RequestBody Map request) { + try { + Integer id = (Integer) request.get("id"); + BigDecimal amount = new BigDecimal(request.get("amount").toString()); + BigDecimal virtualAmount = new BigDecimal(request.get("virtualAmount").toString()); + BigDecimal bonusAmount = new BigDecimal(request.get("bonusAmount").toString()); + String title = (String) request.get("title"); + String description = (String) request.get("description"); + Integer isHot = request.get("isHot") != null ? (Integer) request.get("isHot") : 0; + Integer sortOrder = request.get("sortOrder") != null ? (Integer) request.get("sortOrder") : 0; + Integer isEnabled = request.get("isEnabled") != null ? (Integer) request.get("isEnabled") : 1; + + String sql = "UPDATE eb_recharge_package SET amount = ?, virtual_amount = ?, bonus_amount = ?, " + + "title = ?, description = ?, is_hot = ?, sort_order = ?, is_enabled = ? WHERE id = ?"; + jdbcTemplate.update(sql, amount, virtualAmount, bonusAmount, title, description, isHot, sortOrder, isEnabled, id); + + return CommonResult.success("更新成功"); + } catch (Exception e) { + log.error("更新充值套餐失败", e); + return CommonResult.failed("更新失败"); + } + } + + /** + * 获取充值记录 + */ + @ApiOperation(value = "充值记录列表") + @GetMapping("/recharge/records") + public CommonResult>> getRechargeRecords( + @RequestParam(value = "keyword", required = false) String keyword, + @RequestParam(value = "page", defaultValue = "1") Integer page, + @RequestParam(value = "limit", defaultValue = "20") Integer limit) { + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT r.id, r.order_no, r.amount, r.virtual_amount, r.payment_method, r.payment_status, "); + sql.append("r.create_time, r.pay_time, "); + sql.append("u.uid as user_id, u.nickname, u.phone, u.avatar "); + sql.append("FROM eb_virtual_currency_recharge r "); + sql.append("LEFT JOIN eb_user u ON r.user_id = u.uid "); + sql.append("WHERE 1=1 "); + + StringBuilder countSql = new StringBuilder(); + countSql.append("SELECT COUNT(*) FROM eb_virtual_currency_recharge r "); + countSql.append("LEFT JOIN eb_user u ON r.user_id = u.uid "); + countSql.append("WHERE 1=1 "); + + List params = new ArrayList<>(); + List countParams = new ArrayList<>(); + + if (keyword != null && !keyword.isEmpty()) { + String condition = " AND (u.nickname LIKE ? OR u.phone LIKE ? OR r.order_no LIKE ?) "; + sql.append(condition); + countSql.append(condition); + String keywordPattern = "%" + keyword + "%"; + params.add(keywordPattern); + params.add(keywordPattern); + params.add(keywordPattern); + countParams.add(keywordPattern); + countParams.add(keywordPattern); + countParams.add(keywordPattern); + } + + sql.append(" ORDER BY r.create_time DESC "); + + Long total = jdbcTemplate.queryForObject(countSql.toString(), Long.class, countParams.toArray()); + + int offset = (page - 1) * limit; + sql.append(" LIMIT ? OFFSET ? "); + params.add(limit); + params.add(offset); + + List> list = jdbcTemplate.queryForList(sql.toString(), params.toArray()); + + CommonPage> 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); + } + + // ========== 礼物管理接口(eb_gift表) ========== + + /** + * 获取礼物列表 + */ + @ApiOperation(value = "礼物列表") + @GetMapping("/list") + public CommonResult>> getGiftList( + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "status", required = false) Integer status, + @RequestParam(value = "page", defaultValue = "1") Integer page, + @RequestParam(value = "limit", defaultValue = "20") Integer limit) { + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT id, name, image, diamond_price as diamondPrice, intimacy, status, "); + sql.append("is_heartbeat as isHeartbeat, buy_type as buyType, belong, remark, "); + sql.append("level, sort, create_time as createTime, update_time as updateTime "); + sql.append("FROM eb_gift WHERE is_deleted = 0 "); + + StringBuilder countSql = new StringBuilder(); + countSql.append("SELECT COUNT(*) FROM eb_gift WHERE is_deleted = 0 "); + + List params = new ArrayList<>(); + List countParams = new ArrayList<>(); + + if (name != null && !name.isEmpty()) { + String condition = " AND name LIKE ? "; + sql.append(condition); + countSql.append(condition); + String namePattern = "%" + name + "%"; + params.add(namePattern); + countParams.add(namePattern); + } + + if (status != null) { + String condition = " AND status = ? "; + sql.append(condition); + countSql.append(condition); + params.add(status); + countParams.add(status); + } + + sql.append(" ORDER BY sort ASC, id DESC "); + + Long total = jdbcTemplate.queryForObject(countSql.toString(), Long.class, countParams.toArray()); + + int offset = (page - 1) * limit; + sql.append(" LIMIT ? OFFSET ? "); + params.add(limit); + params.add(offset); + + List> list = jdbcTemplate.queryForList(sql.toString(), params.toArray()); + + CommonPage> 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); } /** @@ -113,28 +401,28 @@ public class GiftAdminController { */ @ApiOperation(value = "添加礼物") @PostMapping("/add") - public CommonResult addGift(@RequestBody Map data) { + public CommonResult addGift(@RequestBody Map request) { try { + String name = (String) request.get("name"); + String image = (String) request.get("image"); + BigDecimal diamondPrice = new BigDecimal(request.get("diamondPrice").toString()); + Integer intimacy = request.get("intimacy") != null ? Integer.parseInt(request.get("intimacy").toString()) : 0; + Integer level = request.get("level") != null ? Integer.parseInt(request.get("level").toString()) : 1; + Integer isHeartbeat = request.get("isHeartbeat") != null ? Integer.parseInt(request.get("isHeartbeat").toString()) : 0; + Integer sort = request.get("sort") != null ? Integer.parseInt(request.get("sort").toString()) : 0; + Integer status = request.get("status") != null ? Integer.parseInt(request.get("status").toString()) : 1; + String remark = (String) request.get("remark"); + String buyType = request.get("buyType") != null ? (String) request.get("buyType") : "钻石"; + String belong = request.get("belong") != null ? (String) request.get("belong") : "平台"; + String sql = "INSERT INTO eb_gift (name, image, diamond_price, intimacy, status, is_heartbeat, " + - "buy_type, belong, remark, effect_version, effect_url, create_time, update_time) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())"; - - jdbcTemplate.update(sql, - data.get("name"), - data.get("image"), - data.get("diamondPrice"), - data.get("intimacy"), - data.get("status") != null && (Boolean) data.get("status") ? 1 : 0, - data.get("isHeartbeat") != null && (Boolean) data.get("isHeartbeat") ? 1 : 0, - data.get("buyType"), - data.get("belong"), - data.get("remark"), - data.get("effectVersion"), - data.get("effectUrl") != null ? data.get("effectUrl") : "" - ); - return CommonResult.success(true); + "buy_type, belong, remark, level, sort) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + jdbcTemplate.update(sql, name, image, diamondPrice, intimacy, status, isHeartbeat, + buyType, belong, remark, level, sort); + + return CommonResult.success("添加成功"); } catch (Exception e) { - log.error("添加礼物失败: {}", e.getMessage()); + log.error("添加礼物失败", e); return CommonResult.failed("添加失败: " + e.getMessage()); } } @@ -143,136 +431,75 @@ public class GiftAdminController { * 更新礼物 */ @ApiOperation(value = "更新礼物") - @PostMapping("/update/{id}") - public CommonResult updateGift(@PathVariable Integer id, @RequestBody Map data) { + @PostMapping("/update") + public CommonResult updateGift(@RequestBody Map request) { try { - String sql = "UPDATE eb_gift SET name = ?, image = ?, diamond_price = ?, intimacy = ?, " + - "status = ?, is_heartbeat = ?, buy_type = ?, belong = ?, remark = ?, " + - "effect_version = ?, effect_url = ?, update_time = NOW() WHERE id = ?"; - - jdbcTemplate.update(sql, - data.get("name"), - data.get("image"), - data.get("diamondPrice"), - data.get("intimacy"), - data.get("status") != null && (Boolean) data.get("status") ? 1 : 0, - data.get("isHeartbeat") != null && (Boolean) data.get("isHeartbeat") ? 1 : 0, - data.get("buyType"), - data.get("belong"), - data.get("remark"), - data.get("effectVersion"), - data.get("effectUrl") != null ? data.get("effectUrl") : "", - id - ); - return CommonResult.success(true); + Integer id = Integer.parseInt(request.get("id").toString()); + String name = (String) request.get("name"); + String image = (String) request.get("image"); + BigDecimal diamondPrice = new BigDecimal(request.get("diamondPrice").toString()); + Integer intimacy = request.get("intimacy") != null ? Integer.parseInt(request.get("intimacy").toString()) : 0; + Integer level = request.get("level") != null ? Integer.parseInt(request.get("level").toString()) : 1; + Integer isHeartbeat = request.get("isHeartbeat") != null ? Integer.parseInt(request.get("isHeartbeat").toString()) : 0; + Integer sort = request.get("sort") != null ? Integer.parseInt(request.get("sort").toString()) : 0; + Integer status = request.get("status") != null ? Integer.parseInt(request.get("status").toString()) : 1; + String remark = (String) request.get("remark"); + String buyType = request.get("buyType") != null ? (String) request.get("buyType") : "钻石"; + String belong = request.get("belong") != null ? (String) request.get("belong") : "平台"; + + String sql = "UPDATE eb_gift SET name = ?, image = ?, diamond_price = ?, intimacy = ?, status = ?, " + + "is_heartbeat = ?, buy_type = ?, belong = ?, remark = ?, level = ?, sort = ? WHERE id = ?"; + jdbcTemplate.update(sql, name, image, diamondPrice, intimacy, status, isHeartbeat, + buyType, belong, remark, level, sort, id); + + return CommonResult.success("更新成功"); } catch (Exception e) { - log.error("更新礼物失败: {}", e.getMessage()); + log.error("更新礼物失败", e); return CommonResult.failed("更新失败: " + e.getMessage()); } } - /** - * 更新礼物状态 - */ - @ApiOperation(value = "更新礼物状态") - @PostMapping("/status/{id}") - public CommonResult updateStatus(@PathVariable Integer id, @RequestParam Integer status) { - try { - jdbcTemplate.update("UPDATE eb_gift SET status = ?, update_time = NOW() WHERE id = ?", status, id); - return CommonResult.success(true); - } catch (Exception e) { - log.error("更新状态失败: {}", e.getMessage()); - return CommonResult.failed("操作失败"); - } - } - - /** - * 更新心动礼物状态 - */ - @ApiOperation(value = "更新心动礼物状态") - @PostMapping("/heartbeat/{id}") - public CommonResult updateHeartbeat(@PathVariable Integer id, @RequestParam Integer isHeartbeat) { - try { - jdbcTemplate.update("UPDATE eb_gift SET is_heartbeat = ?, update_time = NOW() WHERE id = ?", isHeartbeat, id); - return CommonResult.success(true); - } catch (Exception e) { - log.error("更新心动状态失败: {}", e.getMessage()); - return CommonResult.failed("操作失败"); - } - } - /** * 删除礼物 */ @ApiOperation(value = "删除礼物") - @DeleteMapping("/{id}") - public CommonResult deleteGift(@PathVariable Integer id) { - try { - jdbcTemplate.update("DELETE FROM eb_gift WHERE id = ?", id); - return CommonResult.success(true); - } catch (Exception e) { - log.error("删除礼物失败: {}", e.getMessage()); - return CommonResult.failed("删除失败"); - } - } - - /** - * 批量删除礼物 - */ - @ApiOperation(value = "批量删除礼物") - @PostMapping("/batch-delete") - public CommonResult batchDeleteGift(@RequestBody Map data) { + @PostMapping("/delete") + public CommonResult deleteGift(@RequestBody Map request) { try { @SuppressWarnings("unchecked") - List ids = (List) data.get("ids"); + List ids = (List) request.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 + ")"; + + String placeholders = String.join(",", Collections.nCopies(ids.size(), "?")); + String sql = "UPDATE eb_gift SET is_deleted = 1 WHERE id IN (" + placeholders + ")"; jdbcTemplate.update(sql, ids.toArray()); - return CommonResult.success(true); + + return CommonResult.success("删除成功"); } catch (Exception e) { - log.error("批量删除礼物失败: {}", e.getMessage()); - return CommonResult.failed("批量删除失败: " + e.getMessage()); + log.error("删除礼物失败", e); + return CommonResult.failed("删除失败: " + e.getMessage()); } } /** - * 礼物统计 + * 更新礼物状态 */ - @ApiOperation(value = "礼物统计") - @GetMapping("/statistics") - public CommonResult> getStatistics() { - Map stats = new HashMap<>(); - + @ApiOperation(value = "更新礼物状态") + @PostMapping("/status") + public CommonResult updateGiftStatus(@RequestBody Map request) { try { - // 礼物总数 - Long totalGifts = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM eb_gift", Long.class); - stats.put("totalGifts", totalGifts != null ? totalGifts : 0); + Integer id = Integer.parseInt(request.get("id").toString()); + Integer status = Integer.parseInt(request.get("status").toString()); - // 启用礼物数 - Long enabledGifts = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM eb_gift WHERE status = 1", Long.class); - stats.put("enabledGifts", enabledGifts != null ? enabledGifts : 0); - - // 心动礼物数 - Long heartbeatGifts = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM eb_gift WHERE is_heartbeat = 1", Long.class); - stats.put("heartbeatGifts", heartbeatGifts != null ? heartbeatGifts : 0); - - // 今日打赏次数 - Long todayRewards = jdbcTemplate.queryForObject( - "SELECT COUNT(*) FROM eb_gift_reward_record WHERE DATE(create_time) = CURDATE()", Long.class); - stats.put("todayRewards", todayRewards != null ? todayRewards : 0); - - // 今日打赏金额 - Double todayAmount = jdbcTemplate.queryForObject( - "SELECT IFNULL(SUM(reward_amount), 0) FROM eb_gift_reward_record WHERE DATE(create_time) = CURDATE()", Double.class); - stats.put("todayAmount", todayAmount != null ? todayAmount : 0); + String sql = "UPDATE eb_gift SET status = ? WHERE id = ?"; + jdbcTemplate.update(sql, status, id); + return CommonResult.success("状态更新成功"); } catch (Exception e) { - log.error("获取礼物统计失败: {}", e.getMessage()); + log.error("更新礼物状态失败", e); + return CommonResult.failed("状态更新失败: " + e.getMessage()); } - - return CommonResult.success(stats); } } diff --git a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/GiftSystemController.java b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/GiftSystemController.java index c11cbd85..f2fa3269 100644 --- a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/GiftSystemController.java +++ b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/GiftSystemController.java @@ -1,7 +1,7 @@ package com.zbkj.front.controller; import com.zbkj.common.result.CommonResult; -import com.zbkj.front.component.FrontTokenComponent; +import com.zbkj.common.token.FrontTokenComponent; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -18,7 +18,7 @@ import java.util.*; */ @Slf4j @RestController -@RequestMapping("/api/front/gift") +@RequestMapping("/api/front/gift-system") @Api(tags = "礼物系统") public class GiftSystemController { diff --git a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/VirtualCurrencyController.java b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/VirtualCurrencyController.java index e74ff223..a3369810 100644 --- a/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/VirtualCurrencyController.java +++ b/Zhibo/zhibo-h/crmeb-front/src/main/java/com/zbkj/front/controller/VirtualCurrencyController.java @@ -1,7 +1,7 @@ package com.zbkj.front.controller; import com.zbkj.common.result.CommonResult; -import com.zbkj.front.component.FrontTokenComponent; +import com.zbkj.common.token.FrontTokenComponent; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; diff --git a/add_gift_manage_menu.sql b/add_gift_manage_menu.sql new file mode 100644 index 00000000..832a7632 --- /dev/null +++ b/add_gift_manage_menu.sql @@ -0,0 +1,44 @@ +-- ======================================== +-- 添加礼物管理菜单到直播管理下 +-- ======================================== + +-- 1. 启用打赏记录菜单 +UPDATE eb_system_menu +SET is_show = 1, name = '打赏记录' +WHERE id = 823 + AND pid = 675; + +-- 2. 添加礼物管理菜单 +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte) +SELECT 675, '礼物管理', '', '', '/liveManage/gift/manage/index', 'C', 801, 1, 0 +WHERE NOT EXISTS ( + SELECT 1 FROM eb_system_menu + WHERE pid = 675 AND component = '/liveManage/gift/manage/index' +); + +-- 3. 验证菜单结构 +SELECT + '=== 直播管理 - 礼物相关菜单 ===' as section, + id, + pid, + name, + component, + is_show, + sort, + CASE WHEN is_show = 1 THEN '✓ 显示' ELSE '✗ 隐藏' END as status +FROM eb_system_menu +WHERE pid = 675 AND (name LIKE '%礼物%' OR name LIKE '%打赏%') +ORDER BY sort; + +-- 4. 查看完整的直播管理菜单 +SELECT + '=== 直播管理完整菜单 ===' as section, + id, + pid, + name, + component, + is_show, + sort +FROM eb_system_menu +WHERE id = 675 OR pid = 675 +ORDER BY sort; diff --git a/add_gift_menu.sql b/add_gift_menu.sql new file mode 100644 index 00000000..5a755d2f --- /dev/null +++ b/add_gift_menu.sql @@ -0,0 +1,54 @@ +-- 添加礼物管理菜单到后台管理系统 + +-- 1. 查看现有菜单,找到合适的插入位置 +SELECT id, pid, name, component, sort, menu_type FROM eb_system_menu WHERE is_delte = 0 ORDER BY sort; + +-- 2. 添加礼物管理父菜单(目录类型) +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', '', 'Layout', 'M', 100, 1, 0, NOW(), NOW()); + +-- 3. 获取刚插入的父菜单ID +SET @parent_id = LAST_INSERT_ID(); + +-- 4. 添加礼物打赏子菜单(菜单类型) +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte, create_time, update_time) +VALUES (@parent_id, '礼物打赏', 'el-icon-present', 'admin:gift:records', 'gift/records/index', 'C', 1, 1, 0, NOW(), NOW()); + +-- 5. 验证菜单是否添加成功 +SELECT + m1.id as parent_id, + m1.name as parent_name, + m1.menu_type as parent_type, + m2.id as child_id, + m2.name as child_name, + m2.component, + m2.menu_type as child_type +FROM eb_system_menu m1 +LEFT JOIN eb_system_menu m2 ON m1.id = m2.pid +WHERE m1.name = '礼物管理' AND m1.is_delte = 0; + +-- 6. 查看所有礼物相关菜单 +SELECT id, pid, name, icon, component, menu_type, sort, is_show +FROM eb_system_menu +WHERE name LIKE '%礼物%' AND is_delte = 0 +ORDER BY pid, sort; + +-- 7. 如果需要给管理员角色分配权限(假设管理员角色ID为1) +-- 先查看角色ID +SELECT * FROM eb_system_role; + +-- 获取礼物菜单的ID +SELECT @gift_parent_id := id FROM eb_system_menu WHERE name = '礼物管理' AND is_delte = 0 LIMIT 1; +SELECT @gift_child_id := id FROM eb_system_menu WHERE name = '礼物打赏' AND is_delte = 0 LIMIT 1; + +-- 给管理员角色(rid=1)分配礼物管理权限 +INSERT INTO eb_system_role_menu (rid, menu_id) VALUES (1, @gift_parent_id); +INSERT INTO eb_system_role_menu (rid, menu_id) VALUES (1, @gift_child_id); + +-- 8. 验证角色权限 +SELECT r.id as role_id, r.role_name, m.id as menu_id, m.name as menu_name +FROM eb_system_role r +JOIN eb_system_role_menu rm ON r.id = rm.rid +JOIN eb_system_menu m ON rm.menu_id = m.id +WHERE m.name LIKE '%礼物%'; + diff --git a/add_gift_menus_correct.sql b/add_gift_menus_correct.sql new file mode 100644 index 00000000..e69de29b diff --git a/add_gift_menus_to_database.sql b/add_gift_menus_to_database.sql new file mode 100644 index 00000000..964fb1df --- /dev/null +++ b/add_gift_menus_to_database.sql @@ -0,0 +1,42 @@ +-- 添加礼物打赏菜单到数据库 + +-- 1. 查看当前最大的菜单ID +SELECT MAX(id) as max_id FROM eb_system_menu; + +-- 2. 删除旧的礼物菜单(如果存在) +DELETE FROM eb_system_menu WHERE path LIKE '/gift%' OR path LIKE '/giftManage%'; + +-- 3. 添加礼物打赏主菜单 +INSERT INTO eb_system_menu (pid, menu_name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (0, '礼物打赏', '/gift', 'Layout', 1, 50, 'el-icon-present', NOW(), NOW()); + +-- 获取刚插入的主菜单ID +SET @gift_menu_id = LAST_INSERT_ID(); + +-- 4. 添加子菜单 - 礼物列表 +INSERT INTO eb_system_menu (pid, menu_name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (@gift_menu_id, '礼物列表', 'config', 'gift/config/index', 1, 1, 'el-icon-goods', NOW(), NOW()); + +-- 5. 添加子菜单 - 打赏记录 +INSERT INTO eb_system_menu (pid, menu_name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (@gift_menu_id, '打赏记录', 'records', 'gift/records/index', 1, 2, 'el-icon-document', NOW(), NOW()); + +-- 6. 添加子菜单 - 充值套餐 +INSERT INTO eb_system_menu (pid, menu_name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (@gift_menu_id, '充值套餐', 'recharge', 'gift/recharge/index', 1, 3, 'el-icon-coin', NOW(), NOW()); + +-- 7. 验证插入结果 +SELECT + m1.id, + m1.menu_name as '主菜单', + m2.id as '子菜单ID', + m2.menu_name as '子菜单', + m2.path as '路径', + m2.component as '组件' +FROM eb_system_menu m1 +LEFT JOIN eb_system_menu m2 ON m1.id = m2.pid +WHERE m1.path = '/gift' +ORDER BY m2.sort; + +-- 8. 查看所有礼物相关菜单 +SELECT * FROM eb_system_menu WHERE path LIKE '/gift%' OR pid IN (SELECT id FROM eb_system_menu WHERE path = '/gift'); diff --git a/add_gift_to_live_manage_correct.sql b/add_gift_to_live_manage_correct.sql new file mode 100644 index 00000000..adfeff4e --- /dev/null +++ b/add_gift_to_live_manage_correct.sql @@ -0,0 +1,24 @@ +-- ======================================== +-- 正确地将礼物打赏添加到直播管理下 +-- ======================================== + +-- 1. 重新启用直播管理下的礼物打赏菜单 +UPDATE eb_system_menu +SET is_show = 1 +WHERE id = 823 + AND pid = 675 + AND name = '礼物打赏'; + +-- 2. 验证结果 +SELECT + '=== 直播管理完整菜单 ===' as section, + id, + pid, + name, + component, + is_show, + sort, + CASE WHEN is_show = 1 THEN '✓ 显示' ELSE '✗ 隐藏' END as status +FROM eb_system_menu +WHERE id = 675 OR pid = 675 +ORDER BY sort; diff --git a/check_current_menu_status.sql b/check_current_menu_status.sql new file mode 100644 index 00000000..2c93b6c9 --- /dev/null +++ b/check_current_menu_status.sql @@ -0,0 +1,51 @@ +-- 检查当前菜单状态,找出可能导致404的原因 + +-- 1. 检查直播管理及其所有子菜单的显示状态 +SELECT + id, + pid, + name, + component, + is_show, + sort, + CASE WHEN is_show = 1 THEN '✓ 显示' ELSE '✗ 隐藏' END as status +FROM eb_system_menu +WHERE id = 675 OR pid = 675 +ORDER BY pid, sort; + +-- 2. 检查是否有其他菜单使用了相同或相似的component路径 +SELECT + id, + pid, + name, + component, + is_show +FROM eb_system_menu +WHERE component LIKE '/liveManage%' + AND is_show = 1 +ORDER BY component; + +-- 3. 检查礼物相关菜单 +SELECT + id, + pid, + name, + component, + is_show, + CASE WHEN is_show = 1 THEN '✓ 显示' ELSE '✗ 隐藏' END as status +FROM eb_system_menu +WHERE component LIKE '%gift%' +ORDER BY component; + +-- 4. 查看是否有独立的礼物管理顶级菜单 +SELECT + id, + pid, + name, + component, + is_show, + sort +FROM eb_system_menu +WHERE (name LIKE '%礼物%' OR component LIKE '/gift%') + AND pid = 0 +ORDER BY sort; diff --git a/check_gift_records.sql b/check_gift_records.sql new file mode 100644 index 00000000..32751ac7 --- /dev/null +++ b/check_gift_records.sql @@ -0,0 +1,47 @@ +-- 检查礼物打赏记录数据 + +-- 1. 检查礼物记录表是否存在 +SHOW TABLES LIKE '%gift%'; + +-- 2. 查看礼物记录表结构 +DESC eb_gift_record; + +-- 3. 查看礼物记录数量 +SELECT COUNT(*) as total_records FROM eb_gift_record; + +-- 4. 查看最近的礼物记录 +SELECT * FROM eb_gift_record ORDER BY create_time DESC LIMIT 10; + +-- 5. 如果没有数据,插入一些测试数据 +-- 用户43送给主播41一个玫瑰 +INSERT INTO eb_gift_record (sender_id, receiver_id, room_id, gift_id, gift_name, gift_icon, gift_price, quantity, total_price, is_anonymous, create_time) +VALUES +(43, 41, 8, 1, '玫瑰', 'https://example.com/gifts/rose.png', 1.00, 5, 5.00, 0, NOW()), +(43, 41, 8, 2, '巧克力', 'https://example.com/gifts/chocolate.png', 5.00, 2, 10.00, 0, NOW()), +(42, 41, 8, 3, '棒棒糖', 'https://example.com/gifts/lollipop.png', 10.00, 1, 10.00, 0, NOW()), +(44, 41, 8, 5, '蛋糕', 'https://example.com/gifts/cake.png', 50.00, 1, 50.00, 0, NOW()); + +-- 6. 再次查看礼物记录 +SELECT + g.id, + g.gift_name, + g.quantity, + g.total_price, + sender.nickname as sender_name, + receiver.nickname as receiver_name, + r.title as room_title, + g.create_time +FROM eb_gift_record g +LEFT JOIN eb_user sender ON g.sender_id = sender.uid +LEFT JOIN eb_user receiver ON g.receiver_id = receiver.uid +LEFT JOIN eb_live_room r ON g.room_id = r.id +ORDER BY g.create_time DESC +LIMIT 10; + +-- 7. 查看统计数据 +SELECT + COUNT(*) as total_count, + SUM(total_price) as total_value, + SUM(CASE WHEN DATE(create_time) = CURDATE() THEN 1 ELSE 0 END) as today_count, + SUM(CASE WHEN DATE(create_time) = CURDATE() THEN total_price ELSE 0 END) as today_value +FROM eb_gift_record; diff --git a/check_gift_table_structure.sql b/check_gift_table_structure.sql new file mode 100644 index 00000000..97c77af9 --- /dev/null +++ b/check_gift_table_structure.sql @@ -0,0 +1,29 @@ +-- ======================================== +-- 查看礼物表的详细结构和数据 +-- ======================================== + +-- 1. 查看 eb_gift 表结构 +SHOW FULL COLUMNS FROM eb_gift; + +-- 2. 查看 eb_gift_config 表结构 +SHOW FULL COLUMNS FROM eb_gift_config; + +-- 3. 查看 eb_gift 现有数据 +SELECT * FROM eb_gift LIMIT 10; + +-- 4. 查看 eb_gift_config 现有数据 +SELECT * FROM eb_gift_config LIMIT 10; + +-- 5. 统计礼物数量 +SELECT + '=== 礼物统计 ===' as section, + COUNT(*) as total_gifts, + SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as enabled_gifts, + SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as disabled_gifts +FROM eb_gift; + +-- 6. 统计礼物配置数量 +SELECT + '=== 礼物配置统计 ===' as section, + COUNT(*) as total_configs +FROM eb_gift_config; diff --git a/check_live_menu_config.sql b/check_live_menu_config.sql new file mode 100644 index 00000000..a69afa0a --- /dev/null +++ b/check_live_menu_config.sql @@ -0,0 +1,39 @@ +-- 检查直播管理相关的菜单配置 +SELECT + id, + pid, + name, + path, + component, + is_show, + sort +FROM eb_system_menu +WHERE path LIKE '%live%' + OR path LIKE '%room%' + OR name LIKE '%直播%' + OR name LIKE '%房间%' +ORDER BY sort, id; + +-- 检查是否有重复或冲突的路径 +SELECT + path, + COUNT(*) as count, + GROUP_CONCAT(name SEPARATOR ', ') as menu_names +FROM eb_system_menu +WHERE path LIKE '%live%' OR path LIKE '%room%' +GROUP BY path +HAVING count > 1; + +-- 检查礼物菜单配置 +SELECT + id, + pid, + name, + path, + component, + is_show, + sort +FROM eb_system_menu +WHERE path LIKE '%gift%' + OR name LIKE '%礼物%' +ORDER BY sort, id; diff --git a/check_menu_table_columns.sql b/check_menu_table_columns.sql new file mode 100644 index 00000000..e25c5cba --- /dev/null +++ b/check_menu_table_columns.sql @@ -0,0 +1,5 @@ +-- 查看菜单表的实际字段结构 +DESCRIBE eb_system_menu; + +-- 或者使用这个 +SHOW COLUMNS FROM eb_system_menu; diff --git a/check_menu_table_structure.sql b/check_menu_table_structure.sql new file mode 100644 index 00000000..c620b0a8 --- /dev/null +++ b/check_menu_table_structure.sql @@ -0,0 +1,8 @@ +-- 查看菜单表结构 +DESC eb_system_menu; + +-- 查看现有菜单数据示例 +SELECT * FROM eb_system_menu LIMIT 5; + +-- 查看所有列名 +SHOW COLUMNS FROM eb_system_menu; diff --git a/clear_frontend_cache.bat b/clear_frontend_cache.bat new file mode 100644 index 00000000..078674c8 --- /dev/null +++ b/clear_frontend_cache.bat @@ -0,0 +1,38 @@ +@echo off +echo ======================================== +echo 清除前端缓存并重新构建 +echo ======================================== + +cd Zhibo\admin + +echo. +echo [1/4] 删除 node_modules/.cache 目录... +if exist node_modules\.cache ( + rmdir /s /q node_modules\.cache + echo 缓存目录已删除 +) else ( + echo 缓存目录不存在,跳过 +) + +echo. +echo [2/4] 删除 dist 目录... +if exist dist ( + rmdir /s /q dist + echo dist目录已删除 +) else ( + echo dist目录不存在,跳过 +) + +echo. +echo [3/4] 重新构建生产环境... +call npm run build:prod + +echo. +echo [4/4] 完成! +echo. +echo 请执行以下操作: +echo 1. 清除浏览器缓存 (Ctrl+Shift+Delete) +echo 2. 重新登录后台 +echo 3. 测试直播管理菜单 +echo. +pause diff --git a/compare_working_menu.sql b/compare_working_menu.sql new file mode 100644 index 00000000..ebef5a3a --- /dev/null +++ b/compare_working_menu.sql @@ -0,0 +1,39 @@ +-- 对比正常工作的菜单和礼物菜单 + +-- 1. 查看直播管理菜单(这个应该是正常工作的) +SELECT + m.id, + m.pid, + m.name as '菜单名', + m.component as '组件路径', + m.menu_type as '类型', + m.icon, + m.perms as '权限标识' +FROM eb_system_menu m +WHERE m.name = '直播管理' OR m.pid = (SELECT id FROM eb_system_menu WHERE name = '直播管理' LIMIT 1) +ORDER BY m.pid, m.sort; + +-- 2. 查看礼物打赏菜单 +SELECT + m.id, + m.pid, + m.name as '菜单名', + m.component as '组件路径', + m.menu_type as '类型', + m.icon, + m.perms as '权限标识' +FROM eb_system_menu m +WHERE m.name = '礼物打赏' OR m.pid = (SELECT id FROM eb_system_menu WHERE name = '礼物打赏' LIMIT 1) +ORDER BY m.pid, m.sort; + +-- 3. 查看用户管理菜单(另一个正常工作的) +SELECT + m.id, + m.pid, + m.name as '菜单名', + m.component as '组件路径', + m.menu_type as '类型' +FROM eb_system_menu m +WHERE m.name = '用户管理' OR m.pid = (SELECT id FROM eb_system_menu WHERE name = '用户管理' LIMIT 1) +ORDER BY m.pid, m.sort +LIMIT 5; diff --git a/complete_gift_diagnosis.sql b/complete_gift_diagnosis.sql new file mode 100644 index 00000000..bd88fd42 --- /dev/null +++ b/complete_gift_diagnosis.sql @@ -0,0 +1,126 @@ +-- 礼物系统完整诊断报告 + +SELECT '========== 礼物系统诊断报告 ==========' as ''; + +-- 1. 礼物记录统计 +SELECT '1. 礼物记录统计' as ''; +SELECT + COUNT(*) as '总记录数', + COUNT(DISTINCT sender_id) as '送礼用户数', + COUNT(DISTINCT receiver_id) as '收礼用户数', + SUM(total_price) as '总金额', + AVG(total_price) as '平均金额' +FROM eb_gift_record; + +-- 2. 最受欢迎的礼物 +SELECT '2. 最受欢迎的礼物 TOP 5' as ''; +SELECT + gift_name, + COUNT(*) as '送出次数', + SUM(quantity) as '总数量', + SUM(total_price) as '总金额' +FROM eb_gift_record +GROUP BY gift_name +ORDER BY COUNT(*) DESC +LIMIT 5; + +-- 3. 收礼排行榜 +SELECT '3. 收礼排行榜 TOP 5' as ''; +SELECT + receiver_id, + receiver_name, + COUNT(*) as '收礼次数', + SUM(total_price) as '收礼总额' +FROM eb_gift_record +GROUP BY receiver_id, receiver_name +ORDER BY SUM(total_price) DESC +LIMIT 5; + +-- 4. 送礼排行榜 +SELECT '4. 送礼排行榜 TOP 5' as ''; +SELECT + sender_id, + sender_name, + COUNT(*) as '送礼次数', + SUM(total_price) as '送礼总额' +FROM eb_gift_record +GROUP BY sender_id, sender_name +ORDER BY SUM(total_price) DESC +LIMIT 5; + +-- 5. 按直播间统计 +SELECT '5. 直播间礼物统计' as ''; +SELECT + r.room_id, + lr.title as '直播间名称', + COUNT(*) as '礼物数量', + SUM(r.total_price) as '礼物总额' +FROM eb_gift_record r +LEFT JOIN eb_live_room lr ON r.room_id = lr.id +GROUP BY r.room_id, lr.title +ORDER BY SUM(r.total_price) DESC; + +-- 6. 礼物配置检查 +SELECT '6. 礼物配置列表' as ''; +SELECT + id, + name, + price, + sort_order, + is_enabled, + CASE is_enabled WHEN 1 THEN '启用' ELSE '禁用' END as '状态' +FROM eb_gift_config +ORDER BY sort_order; + +-- 7. 用户虚拟货币余额 +SELECT '7. 测试用户虚拟货币余额' as ''; +SELECT + uid, + nickname, + virtual_balance as '余额', + CASE + WHEN virtual_balance >= 10000 THEN '充足' + WHEN virtual_balance >= 1000 THEN '正常' + WHEN virtual_balance > 0 THEN '偏低' + ELSE '不足' + END as '状态' +FROM eb_user +WHERE uid IN (43, 44, 45) +ORDER BY uid; + +-- 8. 最近礼物记录 +SELECT '8. 最近 10 条礼物记录' as ''; +SELECT + id, + sender_name as '送礼者', + receiver_name as '接收者', + gift_name as '礼物', + quantity as '数量', + total_price as '总价', + DATE_FORMAT(create_time, '%Y-%m-%d %H:%i:%s') as '时间' +FROM eb_gift_record +ORDER BY create_time DESC +LIMIT 10; + +-- 9. 充值记录统计 +SELECT '9. 充值记录统计' as ''; +SELECT + COUNT(*) as '充值记录数', + COALESCE(SUM(virtual_amount), 0) as '充值总额', + COUNT(CASE WHEN payment_status = 1 THEN 1 END) as '成功支付数' +FROM eb_virtual_currency_recharge; + +-- 10. 充值套餐配置 +SELECT '10. 充值套餐配置' as ''; +SELECT + id, + title as '套餐名称', + amount as '金额', + virtual_amount as '虚拟币', + bonus_amount as '赠送', + CASE is_hot WHEN 1 THEN '是' ELSE '否' END as '热门', + CASE is_enabled WHEN 1 THEN '启用' ELSE '禁用' END as '状态' +FROM eb_recharge_package +ORDER BY sort_order; + +SELECT '========== 诊断完成 ==========' as ''; diff --git a/create_gift_menu.sql b/create_gift_menu.sql new file mode 100644 index 00000000..1b755184 --- /dev/null +++ b/create_gift_menu.sql @@ -0,0 +1,63 @@ +-- ======================================== +-- 创建独立的礼物打赏管理菜单 +-- ======================================== + +-- 1. 先检查是否已存在礼物打赏顶级菜单 +SELECT id, pid, name, component, is_show, sort +FROM eb_system_menu +WHERE name = '礼物打赏' AND pid = 0; + +-- 2. 如果不存在,创建礼物打赏顶级菜单 +-- 注意:sort值设置为99,放在直播管理(98)之后 +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte) +SELECT 0, '礼物打赏', 'el-icon-present', '', '/gift', 'M', 99, 1, 0 +WHERE NOT EXISTS ( + SELECT 1 FROM eb_system_menu WHERE name = '礼物打赏' AND pid = 0 +); + +-- 3. 获取新创建的礼物打赏菜单ID +SET @gift_menu_id = (SELECT id FROM eb_system_menu WHERE name = '礼物打赏' AND pid = 0 LIMIT 1); + +-- 4. 检查是否已有打赏记录子菜单 +SELECT id, pid, name, component, is_show +FROM eb_system_menu +WHERE name = '打赏记录' AND component = '/gift/records/index'; + +-- 5. 如果不存在,创建打赏记录子菜单 +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte) +SELECT @gift_menu_id, '打赏记录', '', '', '/gift/records/index', 'C', 1, 1, 0 +WHERE NOT EXISTS ( + SELECT 1 FROM eb_system_menu WHERE name = '打赏记录' AND component = '/gift/records/index' +); + +-- 6. 验证创建结果 +SELECT + '=== 礼物打赏菜单结构 ===' as section, + m1.id as parent_id, + m1.name as parent_name, + m1.component as parent_component, + m2.id as child_id, + m2.name as child_name, + m2.component as child_component, + CASE WHEN m1.is_show = 1 AND m2.is_show = 1 THEN '✓ 都显示' + WHEN m1.is_show = 1 THEN '父显示,子隐藏' + ELSE '✗ 父隐藏' + END as status +FROM eb_system_menu m1 +LEFT JOIN eb_system_menu m2 ON m2.pid = m1.id +WHERE m1.name = '礼物打赏' AND m1.pid = 0 +ORDER BY m2.sort; + +-- 7. 显示所有礼物相关菜单 +SELECT + '=== 所有礼物相关菜单 ===' as section, + id, + pid, + name, + component, + is_show, + sort, + CASE WHEN is_show = 1 THEN '✓ 显示' ELSE '✗ 隐藏' END as status +FROM eb_system_menu +WHERE name LIKE '%礼物%' OR name LIKE '%打赏%' OR component LIKE '%gift%' +ORDER BY pid, sort; diff --git a/create_gift_table.sql b/create_gift_table.sql new file mode 100644 index 00000000..b44180aa --- /dev/null +++ b/create_gift_table.sql @@ -0,0 +1,52 @@ +-- ======================================== +-- 创建礼物表 +-- ======================================== + +-- 检查表是否存在 +SELECT TABLE_NAME +FROM information_schema.TABLES +WHERE TABLE_SCHEMA = 'zhibo' + AND TABLE_NAME = 'eb_gift'; + +-- 创建礼物表 +CREATE TABLE IF NOT EXISTS `eb_gift` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '礼物ID', + `name` varchar(100) NOT NULL COMMENT '礼物名称', + `icon` varchar(500) DEFAULT NULL COMMENT '礼物图标URL', + `price` int NOT NULL DEFAULT '0' COMMENT '价格(钻石)', + `sort` int NOT NULL DEFAULT '0' COMMENT '排序', + `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:1-启用,0-禁用', + `description` varchar(500) DEFAULT NULL COMMENT '礼物描述', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除:0-否,1-是', + PRIMARY KEY (`id`), + KEY `idx_status` (`status`), + KEY `idx_sort` (`sort`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='礼物表'; + +-- 插入一些示例礼物数据 +INSERT INTO `eb_gift` (`name`, `icon`, `price`, `sort`, `status`, `description`) VALUES +('玫瑰', 'https://example.com/gifts/rose.png', 1, 1, 1, '送你一朵玫瑰'), +('巧克力', 'https://example.com/gifts/chocolate.png', 5, 2, 1, '甜蜜的巧克力'), +('棒棒糖', 'https://example.com/gifts/lollipop.png', 10, 3, 1, '甜甜的棒棒糖'), +('冰淇淋', 'https://example.com/gifts/icecream.png', 20, 4, 1, '清凉的冰淇淋'), +('蛋糕', 'https://example.com/gifts/cake.png', 50, 5, 1, '美味的蛋糕'), +('香水', 'https://example.com/gifts/perfume.png', 100, 6, 1, '迷人的香水'), +('口红', 'https://example.com/gifts/lipstick.png', 200, 7, 1, '魅力口红'), +('钻戒', 'https://example.com/gifts/ring.png', 500, 8, 1, '闪耀的钻戒'), +('跑车', 'https://example.com/gifts/car.png', 1000, 9, 1, '豪华跑车'), +('城堡', 'https://example.com/gifts/castle.png', 5000, 10, 1, '梦幻城堡') +ON DUPLICATE KEY UPDATE name=name; + +-- 验证数据 +SELECT + '=== 礼物列表 ===' as section, + id, + name, + price, + sort, + CASE WHEN status = 1 THEN '启用' ELSE '禁用' END as status, + create_time +FROM eb_gift +ORDER BY sort; diff --git a/debug_gift_api_response.sql b/debug_gift_api_response.sql new file mode 100644 index 00000000..d0976b91 --- /dev/null +++ b/debug_gift_api_response.sql @@ -0,0 +1,39 @@ +-- 调试礼物API返回的数据 + +-- 1. 检查eb_gift表中的数据 +SELECT + id, + name, + image, + diamond_price, + intimacy, + status, + is_heartbeat, + level, + sort, + is_deleted +FROM eb_gift +WHERE is_deleted = 0 +ORDER BY sort ASC, id DESC +LIMIT 10; + +-- 2. 检查是否所有礼物都被标记为删除 +SELECT + COUNT(*) as total_gifts, + SUM(CASE WHEN is_deleted = 0 THEN 1 ELSE 0 END) as active_gifts, + SUM(CASE WHEN is_deleted = 1 THEN 1 ELSE 0 END) as deleted_gifts +FROM eb_gift; + +-- 3. 如果is_deleted字段不存在,检查表结构 +SHOW COLUMNS FROM eb_gift LIKE 'is_deleted'; + +-- 4. 如果没有is_deleted字段,查看所有礼物 +SELECT + id, + name, + image, + diamond_price, + status +FROM eb_gift +ORDER BY sort ASC, id DESC +LIMIT 10; diff --git a/deploy-gift-fix.bat b/deploy-gift-fix.bat new file mode 100644 index 00000000..9fea0f57 --- /dev/null +++ b/deploy-gift-fix.bat @@ -0,0 +1,27 @@ +@echo off +echo =================================== +echo 部署礼物管理修复 +echo =================================== + +set SERVER=root@1.15.149.240 +set JAR_PATH=Zhibo\zhibo-h\crmeb-admin\target\crmeb-admin.jar +set REMOTE_PATH=/root/zhibo/admin/ + +echo. +echo [1/3] 上传JAR文件... +scp %JAR_PATH% %SERVER%:%REMOTE_PATH% + +echo. +echo [2/3] 重启后台服务... +ssh %SERVER% "cd /root/zhibo/admin && ./restart.sh" + +echo. +echo [3/3] 等待服务启动... +timeout /t 10 + +echo. +echo =================================== +echo 部署完成! +echo 请刷新管理后台页面查看礼物记录 +echo =================================== +pause diff --git a/deploy-gift-records-fix.bat b/deploy-gift-records-fix.bat new file mode 100644 index 00000000..feddc185 --- /dev/null +++ b/deploy-gift-records-fix.bat @@ -0,0 +1,32 @@ +@echo off +echo ======================================== +echo 修复礼物记录显示问题 - 快速部署 +echo ======================================== + +cd Zhibo\zhibo-h + +echo. +echo [1/3] 清理并编译项目... +call mvn clean package -DskipTests -Pdev + +if %errorlevel% neq 0 ( + echo 编译失败! + pause + exit /b 1 +) + +echo. +echo [2/3] 停止远程服务... +ssh root@1.15.149.240 "cd /www/server/java && ./stop.sh" + +echo. +echo [3/3] 上传并启动服务... +scp crmeb-admin\target\crmeb-admin.jar root@1.15.149.240:/www/server/java/ +ssh root@1.15.149.240 "cd /www/server/java && ./start.sh" + +echo. +echo ======================================== +echo 部署完成! +echo 礼物记录页面现在应该可以正常显示数据了 +echo ======================================== +pause diff --git a/deploy-gift-system-complete.bat b/deploy-gift-system-complete.bat new file mode 100644 index 00000000..9b419231 --- /dev/null +++ b/deploy-gift-system-complete.bat @@ -0,0 +1,50 @@ +@echo off +chcp 65001 >nul +echo ======================================== +echo 礼物系统完整部署 +echo ======================================== + +echo. +echo [1/4] 编译后端... +cd Zhibo\zhibo-h +call mvn clean package -DskipTests -Pdev + +if %errorlevel% neq 0 ( + echo 后端编译失败! + pause + exit /b 1 +) + +echo. +echo [2/4] 编译前端... +cd ..\admin +call npm run build:prod + +if %errorlevel% neq 0 ( + echo 前端编译失败! + pause + exit /b 1 +) + +echo. +echo [3/4] 停止远程服务并上传后端... +ssh root@1.15.149.240 "cd /www/server/java && ./stop.sh" +scp ..\zhibo-h\crmeb-admin\target\crmeb-admin.jar root@1.15.149.240:/www/server/java/ + +echo. +echo [4/4] 上传前端并启动服务... +scp -r dist/* root@1.15.149.240:/www/wwwroot/admin/ +ssh root@1.15.149.240 "cd /www/server/java && ./start.sh" + +echo. +echo ======================================== +echo 部署完成! +echo. +echo 访问地址:http://1.15.149.240:9527 +echo. +echo 礼物系统菜单: +echo - 礼物列表:管理礼物配置 +echo - 打赏记录:查看打赏记录和统计 +echo - 充值套餐:管理充值套餐 +echo ======================================== +pause diff --git a/deploy_gift_in_live.bat b/deploy_gift_in_live.bat new file mode 100644 index 00000000..0f18e3bf --- /dev/null +++ b/deploy_gift_in_live.bat @@ -0,0 +1,38 @@ +@echo off +echo ======================================== +echo 部署礼物管理到直播管理下 +echo ======================================== + +echo. +echo [步骤1] 请先执行 add_gift_to_live_manage_correct.sql +echo 这会在数据库中启用礼物打赏菜单 +echo. +pause + +echo. +echo [步骤2] 清除前端缓存... +cd Zhibo\admin + +if exist node_modules\.cache ( + rmdir /s /q node_modules\.cache + echo 缓存已清除 +) + +if exist dist ( + rmdir /s /q dist + echo dist目录已清除 +) + +echo. +echo [步骤3] 重新构建前端... +call npm run build:prod + +echo. +echo [步骤4] 完成! +echo. +echo 现在请: +echo 1. 清除浏览器缓存 (Ctrl+Shift+Delete) +echo 2. 重新登录后台 +echo 3. 在"直播管理"菜单下查看"礼物打赏" +echo. +pause diff --git a/deploy_gift_manage_complete.bat b/deploy_gift_manage_complete.bat new file mode 100644 index 00000000..b61ce1fc --- /dev/null +++ b/deploy_gift_manage_complete.bat @@ -0,0 +1,44 @@ +@echo off +echo ======================================== +echo 部署完整的礼物管理功能 +echo ======================================== + +echo. +echo [步骤1] 执行数据库脚本 +echo 请依次执行以下SQL文件: +echo 1. create_gift_table.sql - 创建礼物表 +echo 2. add_gift_manage_menu.sql - 添加菜单 +echo. +pause + +echo. +echo [步骤2] 清除前端缓存... +cd Zhibo\admin + +if exist node_modules\.cache ( + rmdir /s /q node_modules\.cache + echo 前端缓存已清除 +) + +if exist dist ( + rmdir /s /q dist + echo dist目录已清除 +) + +echo. +echo [步骤3] 重新构建前端... +call npm run build:prod + +echo. +echo ======================================== +echo 部署完成! +echo ======================================== +echo. +echo 现在请: +echo 1. 清除浏览器缓存 (Ctrl+Shift+Delete) +echo 2. 重新登录后台 +echo 3. 在"直播管理"下查看: +echo - 打赏记录:查看礼物打赏记录 +echo - 礼物管理:管理礼物列表(添加/编辑/删除) +echo. +pause diff --git a/diagnose_and_fix_live_menu.sql b/diagnose_and_fix_live_menu.sql new file mode 100644 index 00000000..6d864953 --- /dev/null +++ b/diagnose_and_fix_live_menu.sql @@ -0,0 +1,98 @@ +-- ======================================== +-- 诊断直播管理菜单404问题 +-- ======================================== + +-- 1. 查找所有直播相关的菜单 +SELECT + id, + pid, + name, + component, + is_show, + sort, + CASE + WHEN is_show = 1 THEN '显示' + ELSE '隐藏' + END as display_status +FROM eb_system_menu +WHERE name LIKE '%直播%' + OR component LIKE '%live%' + OR component LIKE '%room%' + OR component LIKE '%family%' + OR component LIKE '%fanGroup%' + OR component LIKE '%streamer%' +ORDER BY pid, sort, id; + +-- 2. 查找礼物相关的菜单 +SELECT + id, + pid, + name, + component, + is_show, + sort +FROM eb_system_menu +WHERE name LIKE '%礼物%' + OR component LIKE '%gift%' +ORDER BY pid, sort, id; + +-- 3. 检查是否有component路径冲突 +SELECT + component, + COUNT(*) as count, + GROUP_CONCAT(CONCAT(id, ':', name) SEPARATOR ' | ') as conflicting_menus +FROM eb_system_menu +WHERE is_show = 1 + AND component IS NOT NULL + AND component != '' +GROUP BY component +HAVING count > 1; + +-- ======================================== +-- 修复方案:确保component字段与前端路由path匹配 +-- ======================================== + +-- 前端路由配置: +-- liveManageRouter.path = '/liveManage' +-- 子路由: +-- - 'room/list' -> '/liveManage/room/list' +-- - 'family/list' -> '/liveManage/family/list' +-- - 'family/level' -> '/liveManage/family/level' +-- - 'family/member' -> '/liveManage/family/member' +-- - 'fanGroup/list' -> '/liveManage/fanGroup/list' +-- - 'streamer/list' -> '/liveManage/streamer/list' + +-- 礼物路由配置: +-- giftManageRouter.path = '/gift' +-- 子路由: +-- - 'records/index' -> '/gift/records/index' + +-- 4. 查看当前直播管理菜单的component配置 +SELECT + id, + pid, + name, + component, + '应该是: /liveManage' as expected_component +FROM eb_system_menu +WHERE name = '直播管理' +LIMIT 1; + +-- 5. 查看直播管理的子菜单 +SELECT + id, + pid, + name, + component, + CASE + WHEN name LIKE '%房间%' THEN '应该是: /liveManage/room/list' + WHEN name LIKE '%家族列表%' THEN '应该是: /liveManage/family/list' + WHEN name LIKE '%家族级别%' THEN '应该是: /liveManage/family/level' + WHEN name LIKE '%家族成员%' THEN '应该是: /liveManage/family/member' + WHEN name LIKE '%粉丝团%' THEN '应该是: /liveManage/fanGroup/list' + WHEN name LIKE '%主播%' THEN '应该是: /liveManage/streamer/list' + ELSE '未知' + END as expected_component +FROM eb_system_menu +WHERE pid IN (SELECT id FROM eb_system_menu WHERE name = '直播管理') +ORDER BY sort; diff --git a/diagnose_gift_system.sql b/diagnose_gift_system.sql new file mode 100644 index 00000000..219a60be --- /dev/null +++ b/diagnose_gift_system.sql @@ -0,0 +1,106 @@ +-- 礼物系统完整诊断脚本 + +-- 1. 检查礼物记录表 +SELECT '=== 礼物记录表检查 ===' as ''; +SELECT COUNT(*) as '礼物记录总数' FROM eb_gift_record; +SELECT * FROM eb_gift_record ORDER BY create_time DESC LIMIT 5; + +-- 2. 检查礼物配置表 +SELECT '=== 礼物配置表检查 ===' as ''; +SELECT COUNT(*) as '礼物配置总数' FROM eb_gift_config; +SELECT * FROM eb_gift_config ORDER BY sort_order LIMIT 5; + +-- 3. 检查用户虚拟货币 +SELECT '=== 用户虚拟货币检查 ===' as ''; +SELECT u.uid, u.nickname, u.phone, u.virtual_balance +FROM eb_user u +WHERE u.uid IN (43, 44, 45) +ORDER BY u.uid; + +-- 4. 检查充值记录 +SELECT '=== 充值记录检查 ===' as ''; +SELECT COUNT(*) as '充值记录总数' FROM eb_virtual_currency_recharge; +SELECT * FROM eb_virtual_currency_recharge ORDER BY create_time DESC LIMIT 5; + +-- 5. 检查直播间 +SELECT '=== 直播间检查 ===' as ''; +SELECT id, title, uid as streamer_id, is_live as status FROM eb_live_room WHERE id IN (8, 9, 10) ORDER BY id; + +-- 6. 如果没有测试数据,插入一些 +SELECT '=== 开始插入测试数据 ===' as ''; + +-- 确保用户有虚拟货币余额 +UPDATE eb_user +SET virtual_balance = 10000 +WHERE uid IN (43, 44, 45) AND (virtual_balance IS NULL OR virtual_balance = 0); + +-- 插入测试礼物记录 +INSERT INTO eb_gift_record (sender_id, sender_name, receiver_id, receiver_name, room_id, gift_id, gift_name, gift_price, quantity, total_price, create_time) +SELECT + 43 as sender_id, + '测试用户43' as sender_name, + 44 as receiver_id, + '测试用户44' as receiver_name, + 8 as room_id, + 1 as gift_id, + '玫瑰花' as gift_name, + 10 as gift_price, + 5 as quantity, + 50 as total_price, + NOW() as create_time +FROM DUAL +WHERE NOT EXISTS (SELECT 1 FROM eb_gift_record WHERE sender_id = 43 AND receiver_id = 44 LIMIT 1); + +INSERT INTO eb_gift_record (sender_id, sender_name, receiver_id, receiver_name, room_id, gift_id, gift_name, gift_price, quantity, total_price, create_time) +SELECT + 45 as sender_id, + '测试用户45' as sender_name, + 44 as receiver_id, + '测试用户44' as receiver_name, + 8 as room_id, + 5 as gift_id, + '跑车' as gift_name, + 500 as gift_price, + 1 as quantity, + 500 as total_price, + NOW() - INTERVAL 1 HOUR as create_time +FROM DUAL +WHERE NOT EXISTS (SELECT 1 FROM eb_gift_record WHERE sender_id = 45 AND receiver_id = 44 LIMIT 1); + +INSERT INTO eb_gift_record (sender_id, sender_name, receiver_id, receiver_name, room_id, gift_id, gift_name, gift_price, quantity, total_price, create_time) +SELECT + 43 as sender_id, + '测试用户43' as sender_name, + 45 as receiver_id, + '测试用户45' as receiver_name, + 9 as room_id, + 1 as gift_id, + '爱心' as gift_name, + 1 as gift_price, + 100 as quantity, + 100 as total_price, + NOW() - INTERVAL 2 HOUR as create_time +FROM DUAL +WHERE (SELECT COUNT(*) FROM eb_gift_record) < 3; + +-- 7. 验证插入结果 +SELECT '=== 验证测试数据 ===' as ''; +SELECT COUNT(*) as '当前礼物记录总数' FROM eb_gift_record; + +SELECT + g.id, + g.gift_name, + g.gift_price, + g.quantity, + g.total_price, + sender.nickname as sender_name, + receiver.nickname as receiver_name, + g.room_id, + g.create_time +FROM eb_gift_record g +LEFT JOIN eb_user sender ON g.sender_id = sender.uid +LEFT JOIN eb_user receiver ON g.receiver_id = receiver.uid +ORDER BY g.create_time DESC +LIMIT 10; + +SELECT '=== 诊断完成 ===' as ''; diff --git a/diagnose_menu_404.sql b/diagnose_menu_404.sql new file mode 100644 index 00000000..92e436fe --- /dev/null +++ b/diagnose_menu_404.sql @@ -0,0 +1,76 @@ +-- 完整诊断菜单404问题 + +-- 1. 检查直播管理菜单及其子菜单 +SELECT + m.id, + m.pid, + m.name, + m.path, + m.component, + m.is_show, + m.sort, + CASE + WHEN m.pid = 0 THEN '顶级菜单' + ELSE CONCAT('子菜单(父ID:', m.pid, ')') + END as menu_level +FROM eb_system_menu m +WHERE m.name LIKE '%直播%' + OR m.path LIKE '%live%' + OR m.path LIKE '%room%' + OR m.path LIKE '%family%' + OR m.path LIKE '%fanGroup%' + OR m.path LIKE '%streamer%' +ORDER BY m.pid, m.sort, m.id; + +-- 2. 检查礼物管理菜单 +SELECT + m.id, + m.pid, + m.name, + m.path, + m.component, + m.is_show, + m.sort +FROM eb_system_menu m +WHERE m.name LIKE '%礼物%' + OR m.path LIKE '%gift%' +ORDER BY m.pid, m.sort, m.id; + +-- 3. 检查是否有路径冲突 +SELECT + path, + COUNT(*) as count, + GROUP_CONCAT(CONCAT(id, ':', name) SEPARATOR ' | ') as conflicting_menus +FROM eb_system_menu +WHERE is_show = 1 +GROUP BY path +HAVING count > 1; + +-- 4. 检查component路径格式 +SELECT + id, + name, + path, + component, + CASE + WHEN component LIKE '%.vue' THEN '有.vue扩展名' + WHEN component LIKE '%/%' THEN '无.vue扩展名' + ELSE '其他格式' + END as component_format +FROM eb_system_menu +WHERE (name LIKE '%直播%' OR path LIKE '%live%' OR path LIKE '%room%') + AND component IS NOT NULL + AND component != ''; + +-- 5. 检查菜单是否被禁用 +SELECT + id, + name, + path, + is_show, + CASE + WHEN is_show = 1 THEN '显示' + ELSE '隐藏' + END as display_status +FROM eb_system_menu +WHERE name LIKE '%直播%' OR path LIKE '%live%'; diff --git a/final_fix_gift_menu.sql b/final_fix_gift_menu.sql new file mode 100644 index 00000000..7d4516cb --- /dev/null +++ b/final_fix_gift_menu.sql @@ -0,0 +1,15 @@ +-- 最终修复:使用系统能识别的路径格式 + +-- 删除礼物菜单 +DELETE FROM eb_system_menu WHERE name = '礼物打赏'; + +-- 重新添加,使用简单的路径 +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte) +VALUES (0, '礼物打赏', 'el-icon-present', 'admin:gift:records', 'gift/records/index', 'C', 50, 1, 0); + +-- 给管理员分配权限 +INSERT IGNORE INTO eb_system_role_menu (rid, menu_id) +SELECT 1, id FROM eb_system_menu WHERE name = '礼物打赏'; + +-- 验证 +SELECT id, name, component FROM eb_system_menu WHERE name = '礼物打赏'; diff --git a/final_move_gift_to_live.sql b/final_move_gift_to_live.sql new file mode 100644 index 00000000..13e8fb48 --- /dev/null +++ b/final_move_gift_to_live.sql @@ -0,0 +1,14 @@ +-- 正确地将礼物打赏移到直播管理下,同时修改路径 + +-- 1. 获取直播管理ID +SELECT @live_id := id FROM eb_system_menu WHERE name = '直播管理' AND pid = 0; + +-- 2. 更新礼物打赏:改变父级ID AND 修改component路径 +UPDATE eb_system_menu +SET pid = @live_id, + component = '/liveManage/gift/records/index', + sort = 800 +WHERE name = '礼物打赏'; + +-- 3. 验证 +SELECT name, component, pid FROM eb_system_menu WHERE name = '礼物打赏'; diff --git a/find_existing_gift_tables.sql b/find_existing_gift_tables.sql new file mode 100644 index 00000000..2262c45d --- /dev/null +++ b/find_existing_gift_tables.sql @@ -0,0 +1,44 @@ +-- ======================================== +-- 查找现有的礼物相关表 +-- ======================================== + +-- 1. 查找所有包含gift的表 +SELECT + TABLE_NAME, + TABLE_COMMENT, + CREATE_TIME +FROM information_schema.TABLES +WHERE TABLE_SCHEMA = 'zhibo' + AND TABLE_NAME LIKE '%gift%' +ORDER BY TABLE_NAME; + +-- 2. 查找所有包含reward的表(打赏相关) +SELECT + TABLE_NAME, + TABLE_COMMENT, + CREATE_TIME +FROM information_schema.TABLES +WHERE TABLE_SCHEMA = 'zhibo' + AND TABLE_NAME LIKE '%reward%' +ORDER BY TABLE_NAME; + +-- 3. 查找所有包含present的表(礼物相关) +SELECT + TABLE_NAME, + TABLE_COMMENT, + CREATE_TIME +FROM information_schema.TABLES +WHERE TABLE_SCHEMA = 'zhibo' + AND TABLE_NAME LIKE '%present%' +ORDER BY TABLE_NAME; + +-- 4. 如果找到了礼物表,查看其结构 +-- 请根据上面的结果,取消下面对应表的注释来查看结构 + +-- SHOW FULL COLUMNS FROM eb_gift; +-- SHOW FULL COLUMNS FROM eb_gift_record; +-- SHOW FULL COLUMNS FROM eb_gift_reward; + +-- 5. 如果找到了礼物表,查看现有数据 +-- SELECT * FROM eb_gift LIMIT 10; +-- SELECT * FROM eb_gift_record LIMIT 10; diff --git a/fix_404_remove_gift_from_live.sql b/fix_404_remove_gift_from_live.sql new file mode 100644 index 00000000..54f9b116 --- /dev/null +++ b/fix_404_remove_gift_from_live.sql @@ -0,0 +1,38 @@ +-- ======================================== +-- 修复404问题:将礼物打赏从直播管理中移除 +-- ======================================== + +-- 问题分析: +-- 1. 礼物打赏菜单(id=823)的component是 /liveManage/gift/records/index +-- 2. 但前端有独立的 giftManageRouter,路径是 /gift +-- 3. 这导致路由匹配冲突 + +-- 解决方案1:将礼物打赏移到独立的礼物管理菜单下 +-- 首先检查是否已有礼物管理顶级菜单 +SELECT id, pid, name, component, is_show +FROM eb_system_menu +WHERE name = '礼物打赏' AND pid = 0; + +-- 如果没有,创建礼物管理顶级菜单 +-- INSERT INTO eb_system_menu (pid, name, icon, component, menu_type, sort, is_show) +-- VALUES (0, '礼物打赏', 'el-icon-present', '/gift', 'M', 99, 1); + +-- 方案2:直接删除礼物打赏菜单(如果不需要在直播管理下显示) +-- DELETE FROM eb_system_menu WHERE id = 823; + +-- 方案3:隐藏礼物打赏菜单(推荐,保留数据) +UPDATE eb_system_menu +SET is_show = 0 +WHERE id = 823; + +-- 验证修改 +SELECT + id, + pid, + name, + component, + is_show, + CASE WHEN is_show = 1 THEN '显示' ELSE '隐藏' END as status +FROM eb_system_menu +WHERE pid = 675 -- 直播管理的子菜单 +ORDER BY sort; diff --git a/fix_gift_menu_complete.sql b/fix_gift_menu_complete.sql new file mode 100644 index 00000000..845ed3ed --- /dev/null +++ b/fix_gift_menu_complete.sql @@ -0,0 +1,43 @@ +-- 完整修复礼物菜单 + +-- 步骤1: 查看eb_system_menu表结构 +DESC eb_system_menu; + +-- 步骤2: 查看当前礼物相关菜单 +SELECT * FROM eb_system_menu WHERE menu_name LIKE '%礼物%' OR path LIKE '%gift%'; + +-- 步骤3: 删除旧的礼物菜单 +DELETE FROM eb_system_menu WHERE menu_name LIKE '%礼物%' OR path LIKE '%gift%'; + +-- 步骤4: 插入礼物打赏主菜单 +INSERT INTO eb_system_menu (pid, menu_name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (0, '礼物打赏', '/gift', 'Layout', 1, 50, 'el-icon-present', NOW(), NOW()); + +-- 步骤5: 获取主菜单ID并插入子菜单 +SET @gift_pid = (SELECT id FROM eb_system_menu WHERE path = '/gift' AND pid = 0); + +INSERT INTO eb_system_menu (pid, menu_name, path, component, is_show, sort, icon, create_time, update_time) VALUES +(@gift_pid, '礼物列表', 'config', 'gift/config/index', 1, 1, 'el-icon-goods', NOW(), NOW()), +(@gift_pid, '打赏记录', 'records', 'gift/records/index', 1, 2, 'el-icon-document', NOW(), NOW()), +(@gift_pid, '充值套餐', 'recharge', 'gift/recharge/index', 1, 3, 'el-icon-coin', NOW(), NOW()); + +-- 步骤6: 验证结果 +SELECT + CASE WHEN m.pid = 0 THEN '主菜单' ELSE '子菜单' END as '类型', + m.id, + m.pid, + m.menu_name as '菜单名称', + m.path as '路径', + m.component as '组件', + m.icon as '图标', + m.sort as '排序', + m.is_show as '显示' +FROM eb_system_menu m +WHERE m.path = '/gift' OR m.pid = @gift_pid +ORDER BY m.pid, m.sort; + +-- 步骤7: 查看所有一级菜单(确认礼物打赏菜单的位置) +SELECT id, menu_name, path, icon, sort +FROM eb_system_menu +WHERE pid = 0 +ORDER BY sort; diff --git a/fix_gift_menu_final.sql b/fix_gift_menu_final.sql new file mode 100644 index 00000000..7a3fb295 --- /dev/null +++ b/fix_gift_menu_final.sql @@ -0,0 +1,38 @@ +-- 最终修复礼物菜单 - 确保字段完全匹配 + +-- 1. 先查看现有的工作菜单示例 +SELECT * FROM eb_system_menu WHERE name = '直播管理' LIMIT 1; +SELECT * FROM eb_system_menu WHERE pid = (SELECT id FROM eb_system_menu WHERE name = '直播管理' LIMIT 1) LIMIT 3; + +-- 2. 删除旧的礼物菜单 +DELETE FROM eb_system_menu WHERE name IN ('礼物打赏', '礼物列表', '打赏记录', '充值套餐', '礼物管理'); + +-- 3. 添加礼物打赏主菜单 +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte) +VALUES (0, '礼物打赏', 'el-icon-present', '', '/gift', 'M', 50, 1, 0); + +SET @gift_pid = LAST_INSERT_ID(); + +-- 4. 添加子菜单 +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte) VALUES +(@gift_pid, '礼物列表', '', 'admin:gift:config', 'gift/config/index', 'C', 1, 1, 0), +(@gift_pid, '打赏记录', '', 'admin:gift:records', 'gift/records/index', 'C', 2, 1, 0), +(@gift_pid, '充值套餐', '', 'admin:gift:recharge', 'gift/recharge/index', 'C', 3, 1, 0); + +-- 5. 验证 +SELECT + m.id, + m.pid, + m.name, + m.component, + m.menu_type, + m.sort +FROM eb_system_menu m +WHERE m.name = '礼物打赏' OR m.pid = @gift_pid +ORDER BY m.pid, m.sort; + +-- 6. 给管理员分配权限 +INSERT IGNORE INTO eb_system_role_menu (rid, menu_id) +SELECT 1, id FROM eb_system_menu WHERE name IN ('礼物打赏', '礼物列表', '打赏记录', '充值套餐'); + +SELECT '菜单添加完成!请退出登录后重新登录查看' as message; diff --git a/fix_gift_menu_paths.sql b/fix_gift_menu_paths.sql new file mode 100644 index 00000000..6153b6e8 --- /dev/null +++ b/fix_gift_menu_paths.sql @@ -0,0 +1,27 @@ +-- 修复礼物菜单路径 - 使用完整路径 + +-- 1. 更新子菜单的component路径为完整路径 +UPDATE eb_system_menu +SET component = '/gift/config/index' +WHERE name = '礼物列表' AND pid = (SELECT id FROM (SELECT id FROM eb_system_menu WHERE name = '礼物打赏' AND pid = 0) AS temp); + +UPDATE eb_system_menu +SET component = '/gift/records/index' +WHERE name = '打赏记录' AND pid = (SELECT id FROM (SELECT id FROM eb_system_menu WHERE name = '礼物打赏' AND pid = 0) AS temp); + +UPDATE eb_system_menu +SET component = '/gift/recharge/index' +WHERE name = '充值套餐' AND pid = (SELECT id FROM (SELECT id FROM eb_system_menu WHERE name = '礼物打赏' AND pid = 0) AS temp); + +-- 2. 验证修复结果 +SELECT + m.id, + m.pid, + m.name as '菜单名', + m.component as '组件路径', + m.menu_type as '类型' +FROM eb_system_menu m +WHERE m.name = '礼物打赏' OR m.pid = (SELECT id FROM eb_system_menu WHERE name = '礼物打赏' LIMIT 1) +ORDER BY m.pid, m.sort; + +SELECT '路径已修复!请刷新浏览器页面' as message; diff --git a/fix_live_menu_404.sql b/fix_live_menu_404.sql new file mode 100644 index 00000000..8704549f --- /dev/null +++ b/fix_live_menu_404.sql @@ -0,0 +1,20 @@ +-- 先查看菜单表结构 +SHOW COLUMNS FROM eb_system_menu; + +-- 查看所有菜单数据,了解字段名称 +SELECT * FROM eb_system_menu LIMIT 5; + +-- 查找直播相关的菜单(使用可能的字段名) +-- 可能的字段:menu_name/name, menu_path/path/component, pid/parent_id +SELECT + id, + pid, + menu_name, + component, + is_show, + sort +FROM eb_system_menu +WHERE menu_name LIKE '%直播%' + OR component LIKE '%live%' + OR component LIKE '%room%' +ORDER BY sort, id; diff --git a/insert_gift_menus_correct.sql b/insert_gift_menus_correct.sql new file mode 100644 index 00000000..745a0943 --- /dev/null +++ b/insert_gift_menus_correct.sql @@ -0,0 +1,67 @@ +-- 正确添加礼物打赏菜单 + +-- 1. 删除旧的礼物菜单(如果存在) +DELETE FROM eb_system_menu WHERE name LIKE '%礼物%'; + +-- 2. 添加礼物打赏主菜单(目录类型 M) +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', '', '/gift', 'M', 50, 1, 0, NOW(), NOW()); + +-- 3. 获取刚插入的主菜单ID +SET @gift_pid = LAST_INSERT_ID(); + +-- 4. 添加子菜单 - 礼物列表(菜单类型 C) +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte, create_time, update_time) +VALUES (@gift_pid, '礼物列表', 'el-icon-goods', 'admin:gift:config', 'gift/config/index', 'C', 1, 1, 0, NOW(), NOW()); + +-- 5. 添加子菜单 - 打赏记录(菜单类型 C) +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte, create_time, update_time) +VALUES (@gift_pid, '打赏记录', 'el-icon-document', 'admin:gift:records', 'gift/records/index', 'C', 2, 1, 0, NOW(), NOW()); + +-- 6. 添加子菜单 - 充值套餐(菜单类型 C) +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte, create_time, update_time) +VALUES (@gift_pid, '充值套餐', 'el-icon-coin', 'admin:gift:recharge', 'gift/recharge/index', 'C', 3, 1, 0, NOW(), NOW()); + +-- 7. 验证插入结果 +SELECT + CASE WHEN m.pid = 0 THEN '主菜单' ELSE ' └─ 子菜单' END as '层级', + m.id as 'ID', + m.name as '菜单名称', + m.component as '组件路径', + m.icon as '图标', + m.menu_type as '类型', + m.sort as '排序', + CASE WHEN m.is_show = 1 THEN '显示' ELSE '隐藏' END as '状态' +FROM eb_system_menu m +WHERE m.name = '礼物打赏' OR m.pid = @gift_pid +ORDER BY m.pid, m.sort; + +-- 8. 给管理员角色分配权限(假设管理员角色ID为1) +-- 先查看角色 +SELECT * FROM eb_system_role LIMIT 5; + +-- 获取所有礼物菜单ID +SELECT @gift_main_id := id FROM eb_system_menu WHERE name = '礼物打赏' AND pid = 0 LIMIT 1; +SELECT @gift_config_id := id FROM eb_system_menu WHERE name = '礼物列表' AND pid = @gift_main_id LIMIT 1; +SELECT @gift_records_id := id FROM eb_system_menu WHERE name = '打赏记录' AND pid = @gift_main_id LIMIT 1; +SELECT @gift_recharge_id := id FROM eb_system_menu WHERE name = '充值套餐' AND pid = @gift_main_id LIMIT 1; + +-- 给管理员角色(rid=1)分配权限 +INSERT IGNORE INTO eb_system_role_menu (rid, menu_id) VALUES +(1, @gift_main_id), +(1, @gift_config_id), +(1, @gift_records_id), +(1, @gift_recharge_id); + +-- 9. 最终验证 +SELECT '========== 菜单添加完成 ==========' as ''; +SELECT + m.id, + m.pid, + m.name as '菜单名称', + m.component as '组件', + m.icon as '图标', + m.sort as '排序' +FROM eb_system_menu m +WHERE m.name LIKE '%礼物%' OR m.pid IN (SELECT id FROM eb_system_menu WHERE name = '礼物打赏') +ORDER BY m.pid, m.sort; diff --git a/keep_gift_independent.sql b/keep_gift_independent.sql new file mode 100644 index 00000000..15be9cfd --- /dev/null +++ b/keep_gift_independent.sql @@ -0,0 +1,7 @@ +-- 保持礼物打赏为独立菜单(最简单可靠的方案) + +UPDATE eb_system_menu +SET pid = 0, sort = 51 +WHERE name = '礼物打赏'; + +SELECT '礼物打赏已恢复为独立菜单,可以正常使用' as message; diff --git a/move_gift_to_live_correctly.sql b/move_gift_to_live_correctly.sql new file mode 100644 index 00000000..8b7c0c94 --- /dev/null +++ b/move_gift_to_live_correctly.sql @@ -0,0 +1,21 @@ +-- 正确地将礼物打赏移到直播管理下 + +-- 1. 获取直播管理的ID +SELECT @live_id := id FROM eb_system_menu WHERE name = '直播管理' AND pid = 0; + +-- 2. 更新礼物打赏,保持其类型为C(菜单),只改变父级 +UPDATE eb_system_menu +SET pid = @live_id, + sort = 800 +WHERE name = '礼物打赏'; + +-- 3. 验证结果 +SELECT + '直播管理子菜单' as '类别', + m.name as '菜单名', + m.menu_type as '类型', + m.component as '组件路径', + m.sort as '排序' +FROM eb_system_menu m +WHERE m.pid = @live_id +ORDER BY m.sort; diff --git a/move_gift_to_live_manage.sql b/move_gift_to_live_manage.sql new file mode 100644 index 00000000..3fbbed32 --- /dev/null +++ b/move_gift_to_live_manage.sql @@ -0,0 +1,19 @@ +-- 将礼物打赏移到直播管理菜单下 + +-- 1. 获取直播管理的ID +SELECT @live_manage_id := id FROM eb_system_menu WHERE name = '直播管理' AND pid = 0; + +-- 2. 更新礼物打赏的pid,让它成为直播管理的子菜单 +UPDATE eb_system_menu +SET pid = @live_manage_id, sort = 999 +WHERE name = '礼物打赏'; + +-- 3. 验证结果 +SELECT + m1.name as '父菜单', + m2.name as '子菜单', + m2.component as '路径' +FROM eb_system_menu m1 +JOIN eb_system_menu m2 ON m1.id = m2.pid +WHERE m1.name = '直播管理' +ORDER BY m2.sort; diff --git a/quick_test_gift_system.sql b/quick_test_gift_system.sql new file mode 100644 index 00000000..5546cd0e --- /dev/null +++ b/quick_test_gift_system.sql @@ -0,0 +1,17 @@ +-- 快速测试礼物系统 + +-- 1. 查看表结构 +DESC eb_gift_record; + +-- 2. 查看现有数据 +SELECT COUNT(*) as total FROM eb_gift_record; + +-- 3. 查看最新5条记录 +SELECT * FROM eb_gift_record ORDER BY create_time DESC LIMIT 5; + +-- 4. 检查用户虚拟货币 +SELECT uid, nickname, virtual_balance FROM eb_user WHERE uid IN (43, 44, 45); + +-- 5. 测试插入(如果需要) +-- INSERT INTO eb_gift_record (sender_id, sender_name, receiver_id, receiver_name, room_id, gift_id, gift_name, gift_price, quantity, total_price, create_time) +-- VALUES (43, '测试用户43', 44, '测试用户44', 8, 1, '测试礼物', 10, 1, 10, NOW()); diff --git a/rebuild_backend_gift.bat b/rebuild_backend_gift.bat new file mode 100644 index 00000000..1f275b32 --- /dev/null +++ b/rebuild_backend_gift.bat @@ -0,0 +1,20 @@ +@echo off +echo ======================================== +echo 重新编译后端礼物管理接口 +echo ======================================== + +cd Zhibo\zhibo-h + +echo. +echo [1/2] 清理并编译... +call mvn clean package -DskipTests + +echo. +echo [2/2] 完成! +echo. +echo 现在请重启后端服务: +echo 1. 停止当前运行的Java进程 +echo 2. 重新启动后端服务 +echo 3. 刷新前端页面 +echo. +pause diff --git a/restart_frontend.bat b/restart_frontend.bat new file mode 100644 index 00000000..d918a1f1 --- /dev/null +++ b/restart_frontend.bat @@ -0,0 +1,29 @@ +@echo off +chcp 65001 >nul +echo ======================================== +echo 清理前端缓存并重启 +echo ======================================== + +cd Zhibo\admin + +echo. +echo [1/3] 停止开发服务器... +taskkill /F /IM node.exe 2>nul + +echo. +echo [2/3] 清理缓存... +rmdir /s /q node_modules\.cache 2>nul +rmdir /s /q dist 2>nul + +echo. +echo [3/3] 重新启动开发服务器... +echo 请手动运行: npm run dev +echo. +echo 或者在新窗口中运行: +start cmd /k "cd /d %cd% && npm run dev" + +echo. +echo ======================================== +echo 完成! +echo ======================================== +pause diff --git a/restore_gift_menu.sql b/restore_gift_menu.sql new file mode 100644 index 00000000..b9d1e1c9 --- /dev/null +++ b/restore_gift_menu.sql @@ -0,0 +1,8 @@ +-- 恢复礼物打赏为独立菜单 + +UPDATE eb_system_menu +SET pid = 0, sort = 50 +WHERE name = '礼物打赏'; + +-- 验证 +SELECT id, pid, name, component FROM eb_system_menu WHERE name = '礼物打赏'; diff --git a/simple_gift_menu_records_only.sql b/simple_gift_menu_records_only.sql new file mode 100644 index 00000000..5dd4b8b8 --- /dev/null +++ b/simple_gift_menu_records_only.sql @@ -0,0 +1,17 @@ +-- 简化版:只添加打赏记录菜单(最重要的功能) + +-- 删除所有礼物相关菜单 +DELETE FROM eb_system_menu WHERE name LIKE '%礼物%'; + +-- 只添加打赏记录菜单(作为一级菜单,不需要子菜单) +INSERT INTO eb_system_menu (pid, name, icon, perms, component, menu_type, sort, is_show, is_delte) +VALUES (0, '礼物打赏', 'el-icon-present', 'admin:gift:records', '/gift/records/index', 'C', 50, 1, 0); + +-- 给管理员分配权限 +INSERT IGNORE INTO eb_system_role_menu (rid, menu_id) +SELECT 1, id FROM eb_system_menu WHERE name = '礼物打赏'; + +-- 验证 +SELECT id, pid, name, component, menu_type FROM eb_system_menu WHERE name = '礼物打赏'; + +SELECT '简化菜单创建完成!刷新浏览器后,点击"礼物打赏"直接进入打赏记录页面' as message; diff --git a/test_gift_api.md b/test_gift_api.md new file mode 100644 index 00000000..b526c9a4 --- /dev/null +++ b/test_gift_api.md @@ -0,0 +1,59 @@ +# 测试礼物管理API + +## 1. 测试后端接口 + +在浏览器中打开开发者工具(F12),然后访问礼物管理页面,查看Network标签页中的请求: + +### 检查请求 +- URL: `/api/admin/gift/list?page=1&limit=20` +- Method: GET +- Status: 应该是 200 + +### 检查响应格式 +后端应该返回这样的格式: +```json +{ + "code": 200, + "message": "success", + "data": { + "list": [...], + "total": 20, + "page": 1, + "limit": 20, + "totalPage": 1 + } +} +``` + +## 2. 如果返回格式不对 + +检查后端日志,看是否有错误信息。 + +## 3. 直接测试SQL + +在数据库中执行: +```sql +SELECT id, name, image, diamond_price as diamondPrice, intimacy, status, + is_heartbeat as isHeartbeat, buy_type as buyType, belong, remark, + level, sort, create_time as createTime, update_time as updateTime +FROM eb_gift +WHERE is_deleted = 0 +ORDER BY sort ASC, id DESC +LIMIT 20 OFFSET 0; +``` + +应该能看到20条礼物记录。 + +## 4. 常见问题 + +### 问题1: 404错误 +- 确认后端服务已重启 +- 确认GiftAdminController已编译 + +### 问题2: 数据为空 +- 检查数据库中是否有数据 +- 检查is_deleted字段是否都是0 + +### 问题3: 前端报错 +- 清除浏览器缓存 +- 重新构建前端:`npm run build:prod` diff --git a/update_gift_reward_menu.sql b/update_gift_reward_menu.sql new file mode 100644 index 00000000..cc9057f8 --- /dev/null +++ b/update_gift_reward_menu.sql @@ -0,0 +1,37 @@ +-- 更新现有的"打赏记录"菜单,使用我们新创建的页面 + +-- 1. 查看现有的打赏记录菜单 +SELECT id, pid, name, component, menu_type, is_show +FROM eb_system_menu +WHERE name LIKE '%打赏%' OR name LIKE '%记录%' +AND is_delte = 0 +ORDER BY pid, sort; + +-- 2. 找到"打赏记录"菜单(ID应该是633,在礼物打赏管理532下) +-- 更新它的component为我们新创建的页面 +UPDATE eb_system_menu +SET component = 'gift/records/index', + name = '礼物打赏记录', + update_time = NOW() +WHERE id = 633; + +-- 3. 验证更新 +SELECT id, pid, name, component, menu_type, is_show +FROM eb_system_menu +WHERE id = 633; + +-- 4. 确保父菜单(礼物打赏管理)是显示的 +UPDATE eb_system_menu +SET is_show = 1 +WHERE id = 532; + +-- 5. 查看更新后的菜单结构 +SELECT + m1.id as parent_id, + m1.name as parent_name, + m2.id as child_id, + m2.name as child_name, + m2.component +FROM eb_system_menu m1 +LEFT JOIN eb_system_menu m2 ON m1.id = m2.pid +WHERE m1.id = 532 AND m1.is_delte = 0; diff --git a/verify_gift_menu.sql b/verify_gift_menu.sql new file mode 100644 index 00000000..9ad612a6 --- /dev/null +++ b/verify_gift_menu.sql @@ -0,0 +1,53 @@ +-- 验证礼物管理菜单是否正确添加 + +-- 1. 查看礼物管理菜单 +SELECT + id, + pid, + name, + icon, + component, + menu_type, + sort, + is_show +FROM eb_system_menu +WHERE (name LIKE '%礼物%' OR pid IN (SELECT id FROM eb_system_menu WHERE name = '礼物管理')) +AND is_delte = 0 +ORDER BY pid, sort; + +-- 2. 查看菜单层级结构 +SELECT + CONCAT(REPEAT(' ', CASE WHEN m.pid = 0 THEN 0 ELSE 1 END), m.name) as menu_tree, + m.id, + m.component, + m.menu_type, + m.is_show +FROM eb_system_menu m +WHERE (m.name = '礼物管理' OR m.pid = (SELECT id FROM eb_system_menu WHERE name = '礼物管理' LIMIT 1)) +AND m.is_delte = 0 +ORDER BY m.pid, m.sort; + +-- 3. 查看管理员角色的礼物管理权限 +SELECT + r.id as role_id, + r.role_name, + m.id as menu_id, + m.name as menu_name, + m.component +FROM eb_system_role r +JOIN eb_system_role_menu rm ON r.id = rm.rid +JOIN eb_system_menu m ON rm.menu_id = m.id +WHERE m.name LIKE '%礼物%' +AND r.id = 1; + +-- 4. 查看礼物配置数据 +SELECT id, name, price, sort_order, is_enabled +FROM eb_gift_config +ORDER BY sort_order +LIMIT 10; + +-- 5. 查看充值套餐数据 +SELECT id, amount, virtual_amount, bonus_amount, title, is_enabled +FROM eb_recharge_package +ORDER BY sort_order +LIMIT 10; diff --git a/verify_menu_after_fix.sql b/verify_menu_after_fix.sql new file mode 100644 index 00000000..6cafedd9 --- /dev/null +++ b/verify_menu_after_fix.sql @@ -0,0 +1,20 @@ +-- 验证菜单修复后的状态 + +SELECT + '直播管理(参考)' as '对比', + m.id, + m.name, + m.component +FROM eb_system_menu m +WHERE m.name = '直播管理' OR m.pid = (SELECT id FROM eb_system_menu WHERE name = '直播管理' LIMIT 1) +ORDER BY m.pid, m.sort +LIMIT 3; + +SELECT + '礼物打赏(当前)' as '对比', + m.id, + m.name, + m.component +FROM eb_system_menu m +WHERE m.name = '礼物打赏' OR m.pid = (SELECT id FROM eb_system_menu WHERE name = '礼物打赏' LIMIT 1) +ORDER BY m.pid, m.sort; diff --git a/添加礼物打赏菜单配置说明.md b/添加礼物打赏菜单配置说明.md new file mode 100644 index 00000000..8077aca4 --- /dev/null +++ b/添加礼物打赏菜单配置说明.md @@ -0,0 +1,214 @@ +# 添加礼物打赏菜单配置说明 + +## 步骤1:在数据库中添加菜单 + +执行以下SQL,在后台管理系统中添加"礼物打赏"菜单: + +```sql +-- 添加礼物管理菜单 +INSERT INTO eb_system_menu (pid, name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (0, '礼物管理', '/gift', 'Layout', 1, 100, 'el-icon-present', NOW(), NOW()); + +-- 获取刚插入的父菜单ID(假设为最新的ID) +SET @parent_id = LAST_INSERT_ID(); + +-- 添加礼物打赏子菜单 +INSERT INTO eb_system_menu (pid, name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (@parent_id, '礼物打赏', 'records', 'gift/records/index', 1, 1, 'el-icon-present', NOW(), NOW()); + +-- 添加礼物配置子菜单(可选) +INSERT INTO eb_system_menu (pid, name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (@parent_id, '礼物配置', 'config', 'gift/config/index', 1, 2, 'el-icon-setting', NOW(), NOW()); + +-- 添加充值套餐子菜单(可选) +INSERT INTO eb_system_menu (pid, name, path, component, is_show, sort, icon, create_time, update_time) +VALUES (@parent_id, '充值套餐', 'packages', 'gift/packages/index', 1, 3, 'el-icon-coin', NOW(), NOW()); + +-- 查看添加的菜单 +SELECT * FROM eb_system_menu WHERE name LIKE '%礼物%' OR name LIKE '%充值%'; +``` + +## 步骤2:如果没有菜单表,手动配置路由 + +如果你的系统不是从数据库读取菜单,需要手动在前端路由文件中添加。 + +找到 `Zhibo/admin/src/router/index.js` 文件,添加以下路由配置: + +```javascript +{ + path: '/gift', + component: Layout, + redirect: '/gift/records', + name: 'Gift', + meta: { + title: '礼物管理', + icon: 'el-icon-present' + }, + children: [ + { + path: 'records', + name: 'GiftRecords', + component: () => import('@/views/gift/records/index'), + meta: { + title: '礼物打赏', + icon: 'el-icon-present' + } + } + ] +} +``` + +## 步骤3:验证菜单是否添加成功 + +1. 重新登录后台管理系统 +2. 在左侧菜单栏应该能看到"礼物管理"菜单 +3. 点击"礼物打赏"子菜单 +4. 应该能看到礼物打赏记录页面 + +## 礼物打赏记录页面功能 + +页面会显示以下信息: + +### 统计卡片 +- **总礼物数**:所有时间的礼物总数量 +- **总价值**:所有礼物的总价值(虚拟币) +- **今日礼物数**:今天收到的礼物数量 +- **今日价值**:今天礼物的总价值 + +### 搜索功能 +- 关键词搜索:送礼者昵称、接收者昵称、礼物名称 +- 日期筛选:按开始日期和结束日期筛选 + +### 礼物记录表格 +显示字段: +- ID +- 礼物信息(图标、名称、单价×数量) +- 总价值 +- 送礼者(头像、昵称、手机号) +- 接收者/主播(头像、昵称、手机号) +- 直播间名称 +- 赠送时间 + +### 统计功能 +- 可以统计哪个用户送了多少礼物 +- 可以统计哪个主播收到了多少礼物 +- 可以按日期范围查看礼物记录 + +## 如果菜单还是没有显示 + +### 方法1:检查菜单表 +```sql +-- 查看菜单表名 +SHOW TABLES LIKE '%menu%'; + +-- 查看菜单表结构 +DESC eb_system_menu; + +-- 查看现有菜单 +SELECT * FROM eb_system_menu ORDER BY sort; +``` + +### 方法2:检查权限 +确保当前登录的管理员账号有权限访问新添加的菜单。 + +### 方法3:清除缓存 +1. 清除浏览器缓存 +2. 重新登录后台管理系统 +3. 按 Ctrl+F5 强制刷新页面 + +### 方法4:直接访问URL +即使菜单没有显示,也可以直接在浏览器地址栏输入: +``` +http://localhost:8080/#/gift/records +``` + +## 礼物配置说明 + +礼物数据已经在数据库中初始化了,包括: +- 玫瑰(1虚拟币) +- 巧克力(5虚拟币) +- 棒棒糖(10虚拟币) +- 冰淇淋(20虚拟币) +- 蛋糕(50虚拟币) +- 香水(100虚拟币) +- 口红(200虚拟币) +- 钻戒(520虚拟币) +- 跑车(1314虚拟币) +- 城堡(5200虚拟币) + +可以通过以下SQL查看: +```sql +SELECT * FROM eb_gift_config ORDER BY sort_order; +``` + +## 测试流程 + +### 1. 准备测试数据 +```sql +-- 查看礼物配置 +SELECT * FROM eb_gift_config; + +-- 查看充值套餐 +SELECT * FROM eb_recharge_package; + +-- 查看用户余额 +SELECT uid, nickname, virtual_balance FROM eb_user WHERE uid IN (41, 42, 43); +``` + +### 2. 通过APP端送礼物 +1. 用户A登录APP +2. 充值虚拟货币 +3. 进入主播B的直播间 +4. 点击礼物按钮 +5. 选择礼物并发送 + +### 3. 在后台查看记录 +1. 登录后台管理系统 +2. 进入"礼物管理" -> "礼物打赏" +3. 查看刚才的送礼记录 +4. 可以搜索用户A或主播B +5. 查看统计数据是否正确 + +## 常见问题 + +### Q1: 菜单添加后看不到? +**A:** +1. 检查数据库中菜单是否添加成功 +2. 检查`is_show`字段是否为1 +3. 清除浏览器缓存并重新登录 +4. 检查当前用户是否有权限 + +### Q2: 点击菜单报404错误? +**A:** +1. 检查前端页面文件是否存在:`Zhibo/admin/src/views/gift/records/index.vue` +2. 检查路由配置是否正确 +3. 重新编译前端:`npm run build:prod` + +### Q3: 页面显示"暂无数据"? +**A:** +1. 检查后端服务是否启动 +2. 检查API接口是否正常:`/api/admin/gift/records` +3. 查看浏览器控制台是否有错误 +4. 检查数据库中是否有礼物记录 + +### Q4: 统计数据不准确? +**A:** +1. 检查数据库中的数据是否正确 +2. 检查后端SQL查询是否正确 +3. 清除缓存重新加载 + +## 相关文件 + +- 后端Controller:`GiftAdminController.java` +- 前端API:`Zhibo/admin/src/api/gift.js` +- 前端页面:`Zhibo/admin/src/views/gift/records/index.vue` +- 数据库脚本:`virtual_currency_and_gift_system.sql` + +## 下一步扩展 + +可以继续添加以下功能: +1. 礼物配置管理页面(添加、编辑、删除礼物) +2. 充值套餐管理页面(配置充值金额和赠送比例) +3. 充值记录查看页面 +4. 礼物统计图表(趋势图、排行榜) +5. 数据导出功能(导出Excel) diff --git a/礼物系统后台管理部署说明.md b/礼物系统后台管理部署说明.md new file mode 100644 index 00000000..1459ab78 --- /dev/null +++ b/礼物系统后台管理部署说明.md @@ -0,0 +1,299 @@ +# 礼物系统后台管理部署说明 + +## 已完成的工作 + +### 1. 后端API ✅ +- **GiftAdminController.java** - 礼物管理后台控制器 + - 礼物打赏记录列表(支持搜索和日期筛选) + - 礼物统计数据(总数、总价值、今日数据) + - 礼物配置管理(增删改查) + - 充值套餐管理 + - 充值记录查询 + +### 2. 前端页面 ✅ +- **gift.js** - 礼物管理API接口 +- **gift/records/index.vue** - 礼物打赏记录页面 + - 统计卡片(总礼物数、总价值、今日数据) + - 搜索功能(关键词、日期范围) + - 礼物记录表格(礼物信息、送礼者、接收者、直播间、时间) + - 分页功能 + +## 部署步骤 + +### 步骤1:执行数据库脚本(如果还没执行) +```bash +mysql -h 1.15.149.240 -u root -p zhibo < virtual_currency_and_gift_system.sql +``` + +### 步骤2:编译后端 +```bash +cd Zhibo/zhibo-h +mvn clean package -DskipTests +``` + +### 步骤3:部署后端服务 +```bash +# 停止服务 +ssh root@1.15.149.240 "cd /root/zhibo && docker-compose stop crmeb-admin" + +# 上传jar包 +scp crmeb-admin/target/Crmeb-admin.jar root@1.15.149.240:/root/zhibo/ + +# 启动服务 +ssh root@1.15.149.240 "cd /root/zhibo && docker-compose up -d crmeb-admin" +``` + +### 步骤4:编译前端 +```bash +cd Zhibo/admin +npm run build:prod +``` + +### 步骤5:部署前端 +```bash +# 上传到服务器 +scp -r dist/* root@1.15.149.240:/root/zhibo/admin/ +``` + +### 步骤6:配置路由 + +在 `Zhibo/admin/src/router/index.js` 中添加礼物管理路由: + +```javascript +{ + path: '/gift', + component: Layout, + redirect: '/gift/records', + name: 'Gift', + meta: { title: '礼物管理', icon: 'el-icon-present' }, + children: [ + { + path: 'records', + name: 'GiftRecords', + component: () => import('@/views/gift/records/index'), + meta: { title: '礼物打赏', icon: 'el-icon-present' } + } + ] +} +``` + +## 页面功能说明 + +### 礼物打赏记录页面 + +#### 统计卡片 +- **总礼物数**:所有时间的礼物总数量 +- **总价值**:所有礼物的总价值(虚拟币) +- **今日礼物数**:今天收到的礼物数量 +- **今日价值**:今天礼物的总价值 + +#### 搜索功能 +- **关键词搜索**:可搜索送礼者昵称、接收者昵称、礼物名称 +- **日期筛选**:可按开始日期和结束日期筛选记录 + +#### 礼物记录表格 +显示字段: +- ID +- 礼物信息(图标、名称、单价、数量) +- 总价值 +- 送礼者(头像、昵称、手机号) +- 接收者/主播(头像、昵称、手机号) +- 直播间名称 +- 赠送时间 + +#### 特殊处理 +- 匿名送礼显示为"匿名用户" +- 没有直播间的显示"-" +- 支持分页查看 + +## API接口说明 + +### 1. 获取礼物打赏记录 +``` +GET /api/admin/gift/records +参数: +- keyword: 关键词(可选) +- startDate: 开始日期(可选) +- endDate: 结束日期(可选) +- page: 页码(默认1) +- limit: 每页数量(默认20) +``` + +### 2. 获取礼物统计 +``` +GET /api/admin/gift/statistics +返回: +- totalCount: 总礼物数 +- totalValue: 总价值 +- todayCount: 今日礼物数 +- todayValue: 今日价值 +``` + +### 3. 获取礼物配置列表 +``` +GET /api/admin/gift/config/list +``` + +### 4. 添加礼物配置 +``` +POST /api/admin/gift/config/add +请求体: +{ + "name": "礼物名称", + "icon": "图标URL", + "price": 价格, + "animation": "动画效果", + "sortOrder": 排序 +} +``` + +### 5. 更新礼物配置 +``` +POST /api/admin/gift/config/update +``` + +### 6. 删除礼物配置 +``` +POST /api/admin/gift/config/delete/{id} +``` + +### 7. 获取充值套餐列表 +``` +GET /api/admin/gift/recharge/packages +``` + +### 8. 更新充值套餐 +``` +POST /api/admin/gift/recharge/package/update +``` + +### 9. 获取充值记录 +``` +GET /api/admin/gift/recharge/records +``` + +## 测试流程 + +### 1. 测试礼物打赏记录查看 +1. 登录后台管理系统 +2. 进入"礼物管理" -> "礼物打赏" +3. 查看统计卡片数据是否正确 +4. 查看礼物记录列表是否显示 +5. 测试搜索功能 +6. 测试日期筛选功能 +7. 测试分页功能 + +### 2. 测试数据准备 +如果没有测试数据,可以通过APP端送礼物来生成: +1. 在APP中充值虚拟货币 +2. 进入直播间 +3. 送礼物给主播 +4. 返回后台查看记录 + +### 3. 验证数据准确性 +```sql +-- 查询礼物记录 +SELECT * FROM eb_gift_record ORDER BY create_time DESC LIMIT 10; + +-- 查询统计数据 +SELECT + COUNT(*) as total_count, + SUM(total_price) as total_value, + SUM(CASE WHEN DATE(create_time) = CURDATE() THEN 1 ELSE 0 END) as today_count, + SUM(CASE WHEN DATE(create_time) = CURDATE() THEN total_price ELSE 0 END) as today_value +FROM eb_gift_record; +``` + +## 后续扩展功能 + +### 1. 礼物配置管理页面 +创建独立页面管理礼物配置: +- 添加新礼物 +- 编辑礼物信息 +- 上传礼物图标 +- 设置礼物价格 +- 启用/禁用礼物 + +### 2. 充值套餐管理页面 +创建独立页面管理充值套餐: +- 添加新套餐 +- 编辑套餐信息 +- 设置赠送比例 +- 设置热门推荐 +- 启用/禁用套餐 + +### 3. 充值记录查看页面 +创建独立页面查看充值记录: +- 用户充值记录 +- 充值金额统计 +- 支付方式统计 +- 充值趋势图表 + +### 4. 数据导出功能 +- 导出礼物记录为Excel +- 导出充值记录为Excel +- 生成统计报表 + +### 5. 图表统计 +- 礼物趋势图(按日期) +- 热门礼物排行榜 +- 送礼用户排行榜 +- 收礼主播排行榜 + +## 注意事项 + +1. **权限控制** + - 确保只有管理员可以访问礼物管理页面 + - 敏感操作需要二次确认 + +2. **数据安全** + - 礼物记录不可删除,只能查看 + - 充值记录不可修改 + - 所有操作记录日志 + +3. **性能优化** + - 大量数据时使用分页 + - 统计数据可以缓存 + - 定期归档历史数据 + +4. **用户体验** + - 加载状态提示 + - 错误信息友好提示 + - 操作成功反馈 + +## 常见问题 + +### Q1: 后台看不到礼物记录? +**A:** 检查以下几点: +1. 数据库表是否创建成功 +2. 后端服务是否重启 +3. 前端是否重新编译 +4. 是否有测试数据 + +### Q2: 统计数据不准确? +**A:** +1. 检查SQL查询是否正确 +2. 检查数据库数据是否完整 +3. 清除浏览器缓存重新加载 + +### Q3: 搜索功能不工作? +**A:** +1. 检查后端API是否正确处理参数 +2. 检查前端是否正确传递参数 +3. 查看浏览器控制台错误信息 + +## 文件清单 + +### 后端文件 +- `Zhibo/zhibo-h/crmeb-admin/src/main/java/com/zbkj/admin/controller/GiftAdminController.java` + +### 前端文件 +- `Zhibo/admin/src/api/gift.js` +- `Zhibo/admin/src/views/gift/records/index.vue` + +### 数据库文件 +- `virtual_currency_and_gift_system.sql` + +## 联系方式 + +如有问题,请查看相关文档或联系开发团队。 diff --git a/礼物系统完整开发文档.md b/礼物系统完整开发文档.md new file mode 100644 index 00000000..c4080eed --- /dev/null +++ b/礼物系统完整开发文档.md @@ -0,0 +1,301 @@ +# 礼物系统完整开发文档 + +## 📋 目录 + +1. [系统概述](#系统概述) +2. [数据库设计](#数据库设计) +3. [后端API接口](#后端api接口) +4. [前端页面](#前端页面) +5. [APP端集成](#app端集成) +6. [部署指南](#部署指南) +7. [测试验证](#测试验证) + +--- + +## 系统概述 + +### 功能简介 + +礼物系统是直播平台的核心功能之一,支持用户在直播间送礼物给主播,包含以下核心功能: + +- **礼物管理**:后台管理员可以添加、编辑、删除、启用/禁用礼物 +- **打赏记录**:记录所有用户的礼物打赏行为 +- **统计分析**:礼物数量、启用/禁用状态、总价值统计 +- **APP集成**:移动端获取礼物列表并发送礼物 + +### 技术栈 + +- **后端**:Java + Spring Boot + MyBatis + MySQL +- **前端管理**:Vue.js + Element UI +- **移动端**:Android (Java) +- **数据库**:MySQL 5.7+ + +### 核心数据表 + +- `eb_gift` - 礼物主数据表(20个礼物) +- `eb_gift_record` - 礼物打赏记录表 + +--- + +## 数据库设计 + +### 1. eb_gift 表(礼物主数据表) + +```sql +CREATE TABLE `eb_gift` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '礼物ID', + `name` varchar(50) NOT NULL COMMENT '礼物名称', + `image` varchar(255) DEFAULT NULL COMMENT '礼物图片URL', + `diamond_price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '钻石价格', + `intimacy` int(11) NOT NULL DEFAULT '0' COMMENT '亲密度', + `is_heartbeat` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否心动礼物 0-否 1-是', + `level` int(11) NOT NULL DEFAULT '1' COMMENT '礼物等级', + `sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序', + `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 0-禁用 1-启用', + `is_deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 0-否 1-是', + `buy_type` varchar(20) DEFAULT 'diamond' COMMENT '购买类型', + `belong` varchar(20) DEFAULT 'common' COMMENT '归属', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_status` (`status`), + KEY `idx_sort` (`sort`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='礼物表'; +``` + +**字段说明:** + +| 字段 | 类型 | 说明 | +|------|------|------| +| id | int | 礼物唯一标识 | +| name | varchar(50) | 礼物名称,如"玫瑰花"、"钻戒" | +| image | varchar(255) | 礼物图片URL | +| diamond_price | decimal(10,2) | 钻石价格 | +| intimacy | int | 赠送礼物增加的亲密度 | +| is_heartbeat | tinyint | 是否为心动礼物(特殊标记) | +| level | int | 礼物等级 | +| sort | int | 显示排序 | +| status | tinyint | 启用状态(0-禁用,1-启用) | +| is_deleted | tinyint | 软删除标记 | +| buy_type | varchar(20) | 购买类型(diamond-钻石) | +| belong | varchar(20) | 归属(common-通用,live-直播专属) | +| remark | varchar(255) | 备注信息 | + +### 2. eb_gift_record 表(打赏记录表) + +```sql +CREATE TABLE `eb_gift_record` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '记录ID', + `sender_id` int(11) NOT NULL COMMENT '送礼用户ID', + `sender_nickname` varchar(50) DEFAULT NULL COMMENT '送礼用户昵称', + `receiver_id` int(11) NOT NULL COMMENT '收礼用户ID', + `receiver_nickname` varchar(50) DEFAULT NULL COMMENT '收礼用户昵称', + `gift_id` int(11) NOT NULL COMMENT '礼物ID', + `gift_count` int(11) NOT NULL DEFAULT '1' COMMENT '礼物数量', + `total_price` decimal(10,2) NOT NULL COMMENT '总价格', + `room_id` int(11) DEFAULT NULL COMMENT '直播间ID', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `idx_sender` (`sender_id`), + KEY `idx_receiver` (`receiver_id`), + KEY `idx_gift` (`gift_id`), + KEY `idx_room` (`room_id`), + KEY `idx_create_time` (`create_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='礼物打赏记录表'; +``` + +**字段说明:** + +| 字段 | 类型 | 说明 | +|------|------|------| +| id | int | 记录唯一标识 | +| sender_id | int | 送礼用户ID | +| sender_nickname | varchar(50) | 送礼用户昵称 | +| receiver_id | int | 收礼用户ID(主播) | +| receiver_nickname | varchar(50) | 收礼用户昵称 | +| gift_id | int | 礼物ID(关联eb_gift表) | +| gift_count | int | 礼物数量 | +| total_price | decimal(10,2) | 总价格(单价×数量) | +| room_id | int | 直播间ID | +| create_time | timestamp | 打赏时间 | + +### 3. 初始化数据 + +系统预置了20个礼物: + +1. 玫瑰花 - 10钻石 +2. 爱心 - 20钻石 +3. 火箭 - 100钻石 +4. 皇冠 - 500钻石 +5. 跑车 - 1000钻石 +6. 城堡 - 5000钻石 +7. 棒棒糖 - 5钻石 +8. 啤酒 - 15钻石 +9. 蛋糕 - 50钻石 +10. 钻戒 - 2000钻石 +11-20. 其他礼物... + +--- + +## 后端API接口 + +### 基础路径 + +``` +http://your-server.com/api/admin/gift +``` + +### 1. 礼物列表(管理端) + +**接口地址:** `GET /list` + +**请求参数:** + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | int | 否 | 页码,默认1 | +| limit | int | 否 | 每页数量,默认10 | +| name | string | 否 | 礼物名称(模糊搜索) | +| status | int | 否 | 状态(0-禁用,1-启用) | + +**响应示例:** + +```json +{ + "code": 200, + "message": null, + "data": { + "page": 1, + "limit": 10, + "totalPage": 2, + "total": 20, + "list": [ + { + "id": 1, + "name": "玫瑰花", + "image": "https://example.com/gifts/rose.png", + "diamondPrice": "10.00", + "intimacy": 10, + "status": true, + "isHeartbeat": false, + "buyType": "diamond", + "belong": "common", + "remark": "浪漫玫瑰", + "level": 1, + "sort": 0, + "createTime": "2025-12-30 20:25:16", + "updateTime": "2025-12-30 20:25:16" + } + ] + } +} +``` + +### 2. 添加礼物 + +**接口地址:** `POST /add` + +**请求体:** + +```json +{ + "name": "新礼物", + "image": "https://example.com/gift.png", + "diamondPrice": 100, + "intimacy": 100, + "isHeartbeat": false, + "level": 1, + "sort": 0, + "status": true, + "buyType": "diamond", + "belong": "common", + "remark": "备注信息" +} +``` + +**响应示例:** + +```json +{ + "code": 200, + "message": "添加成功", + "data": null +} +``` + +### 3. 编辑礼物 + +**接口地址:** `POST /update` + +**请求体:** + +```json +{ + "id": 1, + "name": "更新后的名称", + "image": "https://example.com/new-gift.png", + "diamondPrice": 150, + "intimacy": 150, + "isHeartbeat": true, + "level": 2, + "sort": 1, + "status": true, + "buyType": "diamond", + "belong": "live", + "remark": "更新后的备注" +} +``` + +### 4. 删除礼物 + +**接口地址:** `POST /delete/{id}` + +**路径参数:** +- `id`: 礼物ID + +**响应示例:** + +```json +{ + "code": 200, + "message": "删除成功", + "data": null +} +``` + +### 5. 修改礼物状态 + +**接口地址:** `POST /status/{id}` + +**路径参数:** +- `id`: 礼物ID + +**请求参数:** +- `status`: 状态(0-禁用,1-启用) + +**响应示例:** + +```json +{ + "code": 200, + "message": "状态修改成功", + "data": null +} +``` + +### 6. 打赏记录列表 + +**接口地址:** `GET /records` + +**请求参数:** + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| page | int | 否 | 页码,默认1 | +| limit | int | 否 | 每页数量,默认20 | +| senderName | string | 否 | 送礼用户昵称(模糊搜索) | +| receiverName | string | 否 | 收礼用户昵称(模糊搜索) | +| giftName | string | 否 | 礼物名称(模糊搜索) | + +**响应示例:** diff --git a/礼物系统完整部署指南.md b/礼物系统完整部署指南.md new file mode 100644 index 00000000..296f05ab --- /dev/null +++ b/礼物系统完整部署指南.md @@ -0,0 +1,145 @@ +# 礼物系统完整部署指南 + +## 一、系统功能 + +### 1. 礼物列表(礼物配置) +- 显示所有可用礼物(玫瑰、巧克力、跑车等) +- 可以添加、编辑、删除礼物 +- 设置礼物价格、图标、排序 +- 启用/禁用礼物 + +### 2. 打赏记录 +- 显示所有用户的打赏记录 +- 谁送了什么礼物给哪个主播 +- 在哪个直播间送的 +- 礼物数量和总价值 +- 支持按关键词、日期筛选 +- 显示统计数据(总礼物数、总价值、今日数据) + +### 3. 充值套餐 +- 显示所有充值套餐配置 +- 可以编辑套餐金额、赠送比例 +- 设置热门推荐 + +## 二、部署步骤 + +### 步骤1:部署后端 + +```bash +# 运行部署脚本 +deploy-gift-records-fix.bat +``` + +或手动执行: +```bash +cd Zhibo/zhibo-h +mvn clean package -DskipTests -Pdev + +# 上传到服务器 +scp crmeb-admin/target/crmeb-admin.jar root@1.15.149.240:/www/server/java/ + +# 重启服务 +ssh root@1.15.149.240 "cd /www/server/java && ./stop.sh && ./start.sh" +``` + +### 步骤2:部署前端 + +```bash +cd Zhibo/admin +npm run build:prod + +# 上传到服务器 +scp -r dist/* root@1.15.149.240:/www/wwwroot/admin/ +``` + +### 步骤3:验证数据 + +运行SQL检查数据: +```sql +-- 检查礼物配置 +SELECT * FROM eb_gift_config ORDER BY sort_order; + +-- 检查礼物记录 +SELECT COUNT(*) FROM eb_gift_record; + +-- 检查充值套餐 +SELECT * FROM eb_recharge_package ORDER BY sort_order; +``` + +## 三、菜单结构 + +``` +礼物打赏 +├── 礼物列表 - 管理礼物配置(玫瑰、巧克力等) +├── 打赏记录 - 查看所有打赏记录和统计 +└── 充值套餐 - 管理充值套餐配置 +``` + +## 四、API接口 + +### 礼物配置 +- GET `/api/admin/gift/config/list` - 获取礼物列表 +- POST `/api/admin/gift/config/add` - 添加礼物 +- POST `/api/admin/gift/config/update` - 更新礼物 +- POST `/api/admin/gift/config/delete/{id}` - 删除礼物 + +### 打赏记录 +- GET `/api/admin/gift/records` - 获取打赏记录列表 +- GET `/api/admin/gift/statistics` - 获取统计数据 + +### 充值套餐 +- GET `/api/admin/gift/recharge/packages` - 获取充值套餐 +- POST `/api/admin/gift/recharge/package/update` - 更新套餐 + +## 五、数据库表 + +### eb_gift_config - 礼物配置表 +存储礼物的基本信息(名称、图标、价格等) + +### eb_gift_record - 礼物记录表 +存储所有打赏记录,包括: +- sender_id, sender_name - 送礼者 +- receiver_id, receiver_name - 接收者(主播) +- room_id - 直播间 +- gift_id, gift_name - 礼物信息 +- quantity - 数量 +- total_price - 总价 + +### eb_recharge_package - 充值套餐表 +存储充值套餐配置 + +### eb_user.virtual_balance - 用户虚拟货币余额 +存储在用户表的 virtual_balance 字段 + +## 六、测试数据 + +数据库中已有测试数据: +- 10个礼物配置(玫瑰、巧克力、棒棒糖等) +- 12条打赏记录 +- 6个充值套餐 +- 测试用户43、44有10000虚拟币余额 + +## 七、常见问题 + +### 1. 页面显示"暂无数据" +- 检查后端是否正常启动 +- 检查API接口是否返回数据 +- 查看浏览器控制台是否有错误 + +### 2. 数据不显示 +- 确认数据库中有数据 +- 检查后端SQL查询是否正确 +- 查看后端日志 + +### 3. 字段不匹配错误 +- 已修复:quantity 字段 +- 已修复:sender_nickname, receiver_nickname 使用 COALESCE +- 已修复:is_live 替代 status + +## 八、后续优化 + +1. 添加礼物图片上传功能 +2. 添加礼物动画效果预览 +3. 添加打赏记录导出功能 +4. 添加收礼/送礼排行榜 +5. 添加礼物收益统计图表