Files
henan-backend/bin/checks/set-known-audit-logs.js
2026-09-21 19:21:35 +08:00

406 lines
32 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 按「方法名 → 注解」显式白名单写入 @Log(不做 URL 猜配,避免错位)
//
// node bin/checks/set-known-audit-logs.js 干跑
// node bin/checks/set-known-audit-logs.js --apply 落盘
//
// 按钮文案全部取自页面源码原文(每条的来源写在本表注释里,格式:views/xxx.vue:行号):
// 工具条按钮(生成招商账号/一键上架/发放CDK)优先于弹窗里的通用【确 定】——
// 运营的心智是"我点了那颗有名字的按钮",【确 定】记进日志等于没信息。
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '..', '..');
const apply = process.argv.includes('--apply');
const A = 'skins-service/service-admin/src/main/java/com/ruoyi/admin/controller/';
const W = 'skins-service/game-wheel-service/src/main/java/com/ruoyi/game/wheel/controller/';
const O = 'skins-service/game-olympus-service/src/main/java/com/ruoyi/game/olympus/controller/';
const TARGETS = [
// ---- 用户列表(ttuser/index.vue:工具条 113/121/129,行内 86/96,下拉 212/218/224)----
[A + 'TtUserController.java', 'generateAccount', { menu: '用户列表', action: '生成招商账号', type: 'INSERT' }],
[A + 'TtUserController.java', 'generateRobot', { menu: '用户列表', action: '生成机器人', type: 'INSERT' }],
[A + 'TtUserController.java', 'generateBlankAccount', { menu: '用户列表', action: '生成白号', type: 'INSERT' }],
[A + 'TtUserController.java', 'generateCardMerchant', { menu: '用户列表', action: '生成卡商账号', type: 'INSERT' }],
[A + 'TtUserController.java', 'edit', { menu: '用户列表', action: '修改', type: 'UPDATE', entity: 'TtUser', mapper: 'TtUserMapper' }],
[A + 'TtUserController.java', 'editInvitationCode', { menu: '用户列表', action: '修改邀请码', type: 'UPDATE', entity: 'TtUser', mapper: 'TtUserMapper' }],
[A + 'TtUserController.java', 'remove', { menu: '用户列表', action: '删除', type: 'DELETE' }],
[A + 'TtUserController.java', 'removeUserPackSackData', { menu: '背包列表', action: '删除', type: 'DELETE' }],
[A + 'TtUserController.java', 'resetUserBalance', { menu: '用户列表', action: '重置余额积分', type: 'CLEAN', entity: 'TtUser', mapper: 'TtUserMapper', idField: 'userId' }],
[A + 'TtUserController.java', 'forceDelete', { menu: '用户列表', action: '真删除', type: 'FORCE' }],
// ---- 亏损返水(ttredPacket/lossRebate.vue:31 保存上限 / 112 发放CDK)----
[A + 'LossRebateController.java', 'grant', { menu: '亏损返水', action: '发放CDK', type: 'GRANT', entity: 'TtLossRebate', mapper: 'TtLossRebateMapper', idField: 'id' }],
[A + 'LossRebateController.java', 'saveConfig', { menu: '亏损返水', action: '保存上限', type: 'UPDATE' }],
// ---- 卡商充值(ttCardMerchantRecharge/index.vue:126 确认充值 / 160 确认修改)----
[A + 'TtCardMerchantController.java', 'cardMerchantRecharge', { menu: '卡商充值', action: '确认充值', type: 'GRANT', entity: 'TtUser', mapper: 'TtUserMapper', idField: 'userId' }],
[A + 'TtCardMerchantController.java', 'cardMerchantUpdateBalance', { menu: '卡商充值', action: '确认修改', type: 'UPDATE', entity: 'TtUser', mapper: 'TtUserMapper', idField: 'userId' }],
// ---- 生成空白卡密(blankCardKey/index.vue:5 生成空白卡密 开弹窗)----
[A + 'AdminBlankCardKeyController.java', 'generate', { menu: '生成空白卡密', action: '生成空白卡密', type: 'INSERT' }],
// ---- 疯狂转盘 游戏配置(game/wheel/config/index.vue:8 重置奖池 / 44 调整奖池 / 241 保存)----
[W + 'AdminWheelController.java', 'resetPool', { menu: '游戏配置', action: '重置奖池', type: 'CLEAN' }],
[W + 'AdminWheelController.java', 'adjustPool', { menu: '游戏配置', action: '调整奖池', type: 'GRANT' }],
[W + 'AdminWheelController.java', 'updateGameConfig', { menu: '游戏配置', action: '保存', type: 'UPDATE' }],
// ---- 疯狂转盘 奖励矩阵(game/wheel/prize/index.vue:79 保存 / 89 全部保存 → saveMatrix)----
[W + 'AdminWheelController.java', 'matrixSave', { menu: '奖励矩阵', action: '保存', type: 'UPDATE' }],
// ---- 商城列表(ttShopping/index.vue:75 一键下架 / 82 一键上架)----
[A + 'ShoppingController.java', 'putAwayAll', { menu: '商城列表', action: '一键上架', type: 'UPDATE' }],
[A + 'ShoppingController.java', 'soldOutAll', { menu: '商城列表', action: '一键下架', type: 'UPDATE' }],
// ---- Roll房列表(ttRoll/index.vue:222 新 增 / 223 修 改 / 120 删除)----
[A + 'TtRollController.java', 'add', { menu: 'Roll房列表', action: '新增', type: 'INSERT', entity: 'TtRoll', mapper: 'TtRollMapper' }],
[A + 'TtRollController.java', 'edit', { menu: 'Roll房列表', action: '修改', type: 'UPDATE', entity: 'TtRoll', mapper: 'TtRollMapper' }],
[A + 'TtRollController.java', 'remove', { menu: 'Roll房列表', action: '删除', type: 'DELETE' }],
// ---- 抽奖活动(turnoverLottery/list.vue:43 新增抽奖活动 / 86 修改 / 92 删除)----
[A + 'TurnoverLotteryAdminController.java', 'create', { menu: '抽奖活动', action: '新增抽奖活动', type: 'INSERT' }],
[A + 'TurnoverLotteryAdminController.java', 'update', { menu: '抽奖活动', action: '修改', type: 'UPDATE' }],
[A + 'TurnoverLotteryAdminController.java', 'delete', { menu: '抽奖活动', action: '删除', type: 'DELETE' }],
// ---- 奥林匹斯 奖池水位(game/olympus/rewardPool/index.vue:101/106 批量注水|抽水、111 重置调整、172/175 行内图标→弹窗 213 确定注水|抽水)----
[O + 'OlympusAdminController.java', 'rewardPoolAdjust', { menu: '奖池水位', action: '注水/抽水', type: 'GRANT' }],
[O + 'OlympusAdminController.java', 'rewardPoolAdjustBatch', { menu: '奖池水位', action: '批量注水/抽水', type: 'GRANT' }],
[O + 'OlympusAdminController.java', 'rewardPoolAdjustReset', { menu: '奖池水位', action: '重置调整', type: 'CLEAN' }],
// ---- 宝箱列表(ttBox/index.vue:48 新增 / 59 修改 / 70 删除 / 282 重置宝箱)----
[A + 'TtBoxController.java', 'add', { menu: '宝箱列表', action: '新增', type: 'INSERT', entity: 'TtBox', mapper: 'TtBoxMapper' }],
[A + 'TtBoxController.java', 'edit', { menu: '宝箱列表', action: '修改', type: 'UPDATE' }],
[A + 'TtBoxController.java', 'remove', { menu: '宝箱列表', action: '删除', type: 'DELETE' }],
// 注意:resetBox 是 @GetMapping,但它改数据(GET 不在常规扫描范围内,这里显式补上)
[A + 'TtBoxController.java', 'resetBox', { menu: '宝箱列表', action: '重置宝箱', type: 'CLEAN', entity: 'TtBox', mapper: 'TtBoxMapper', idField: 'boxId' }],
// ---- Roll 奖品/房间(awarddetali.vue:22 指定获奖者 / 23 取消奖品;rollUser.vue:10 加入机器人 / 18 加入用户)----
[A + 'TtRollController.java', 'namedWinner', { menu: '装备列表', action: '指定获奖者', type: 'INSERT' }],
[A + 'TtRollController.java', 'cancelNamedWinner', { menu: '装备列表', action: '取消奖品', type: 'DELETE' }],
[A + 'TtRollController.java', 'addRobot', { menu: '房间用户', action: '加入机器人', type: 'INSERT' }],
[A + 'TtRollController.java', 'addUser', { menu: '房间用户', action: '加入用户', type: 'INSERT' }],
// ---- 奥林匹斯 箱子配置(game/olympus/box/index.vue:53 编辑 / 180 保存 / 15+141 一键重算分布 / 179 保存为模板 / 214 应用选中模板 / 207 删除模板)----
[O + 'OlympusAdminController.java', 'boxSave', { menu: '箱子配置', action: '编辑', type: 'UPDATE' }],
[O + 'OlympusAdminController.java', 'boxOrnamentsSave', { menu: '箱子配置', action: '保存', type: 'UPDATE' }],
[O + 'OlympusAdminController.java', 'recalcBatch', { menu: '箱子配置', action: '一键重算分布', type: 'CLEAN' }],
[O + 'OlympusAdminController.java', 'templateSave', { menu: '箱子配置', action: '保存为模板', type: 'INSERT' }],
[O + 'OlympusAdminController.java', 'templateApply', { menu: '箱子配置', action: '应用选中模板', type: 'UPDATE' }],
[O + 'OlympusAdminController.java', 'templateDelete', { menu: '箱子配置', action: '删除', type: 'DELETE' }],
// ---- 奥林匹斯 奖品管理(game/olympus/prize/index.vue:44 编辑 → 87 确定 → prizeSave)----
[O + 'OlympusAdminController.java', 'prizeSave', { menu: '奖品管理', action: '编辑', type: 'UPDATE' }],
// ---- 消费排行榜奖励(rechargeRankingReward.vue:5 生成消费奖励 / 23 修改 / 8 重置→handleReset:165)----
[A + 'TtRechargeRankingRewardController.java', 'generatePromotionLevel', { menu: '消费排行榜奖励', action: '生成消费奖励', type: 'UPDATE' }],
[A + 'TtRechargeRankingRewardController.java', 'edit', { menu: '消费排行榜奖励', action: '修改', type: 'UPDATE' }],
[A + 'TtRechargeRankingRewardController.java', 'truncateRankingReward', { menu: '消费排行榜奖励', action: '重置', type: 'CLEAN' }],
// ---- 对战排行榜奖励(fightRankingReward.vue:5 生成排名奖励 / 23 修改 / 8 重置→handleReset:167)----
[A + 'TtFightRankingRewardController.java', 'generatePromotionLevel', { menu: '对战排行榜奖励', action: '生成排名奖励', type: 'UPDATE' }],
[A + 'TtFightRankingRewardController.java', 'edit', { menu: '对战排行榜奖励', action: '修改', type: 'UPDATE' }],
[A + 'TtFightRankingRewardController.java', 'truncateRankingReward', { menu: '对战排行榜奖励', action: '重置', type: 'CLEAN' }],
// ---- 饰品列表(ttOrnaments/index.vue:58 新增饰品 / 123 编辑 / 125=77 删除 / 117 发放饰品)----
[A + 'TtOrnamentsController.java', 'add', { menu: '饰品列表', action: '新增饰品', type: 'INSERT', entity: 'TtOrnament', mapper: 'TtOrnamentMapper' }],
[A + 'TtOrnamentsController.java', 'edit', { menu: '饰品列表', action: '编辑', type: 'UPDATE', entity: 'TtOrnament', mapper: 'TtOrnamentMapper' }],
[A + 'TtOrnamentsController.java', 'delete', { menu: '饰品列表', action: '删除', type: 'DELETE' }],
[A + 'TtOrnamentsController.java', 'grantOrnaments', { menu: '饰品列表', action: '发放饰品', type: 'GRANT' }],
// ================= 以下为"存量旧 JSON 格式"转人话(按钮文案已逐页核实:都是标准 新增/修改/删除)=================
// ---- 福利列表 / 福利开箱记录(ttWelfare/index.vue、welfareBoxRecords.vue)----
[A + 'TtWelfareController.java', 'add', { menu: '福利列表', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtWelfareController.java', 'edit', { menu: '福利列表', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtWelfareController.java', 'remove', { menu: '福利列表', action: '删除', type: 'DELETE' }],
[A + 'TtWelfareController.java', 'removeBoxRecords', { menu: '福利开箱记录', action: '删除', type: 'DELETE' }],
[A + 'TtWelfareController.java', 'clearBoxRecords', { menu: '福利开箱记录', action: '清空全部记录', type: 'CLEAN' }],
// ---- 每月充值福利(monthlyRecharges.vue)----
[A + 'TtWelfareMonthlyRechargesController.java', 'add', { menu: '每月充值福利', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtWelfareMonthlyRechargesController.java', 'edit', { menu: '每月充值福利', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtWelfareMonthlyRechargesController.java', 'remove', { menu: '每月充值福利', action: '删除', type: 'DELETE' }],
// ---- 首充赠送(ttBonus/firstRecharge.vue)----
[A + 'TtFirstRechargeController.java', 'add', { menu: '首充赠送', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtFirstRechargeController.java', 'edit', { menu: '首充赠送', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtFirstRechargeController.java', 'remove', { menu: '首充赠送', action: '删除', type: 'DELETE' }],
// ---- CDK管理(ttRedPack/index.vue)----
[A + 'TtRedPackController.java', 'add', { menu: 'CDK管理', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRedPackController.java', 'edit', { menu: 'CDK管理', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRedPackController.java', 'remove', { menu: 'CDK管理', action: '删除', type: 'DELETE' }],
// ---- 汰换记录(ttReplacementRecord/index.vue)----
[A + 'TtReplacementRecordController.java', 'add', { menu: '汰换记录', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtReplacementRecordController.java', 'edit', { menu: '汰换记录', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtReplacementRecordController.java', 'remove', { menu: '汰换记录', action: '删除', type: 'DELETE' }],
// ---- 机器人对战分组(ttFight/robotFightGroup.vue)----
[A + 'TtRobotFightGroupController.java', 'add', { menu: '机器人对战分组', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRobotFightGroupController.java', 'edit', { menu: '机器人对战分组', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRobotFightGroupController.java', 'remove', { menu: '机器人对战分组', action: '删除', type: 'DELETE' }],
// ---- 机器人对战分组宝箱(ttFight/robotFightGroupBox.vue)----
[A + 'TtRobotFightGroupBoxController.java', 'add', { menu: '机器人对战分组宝箱', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRobotFightGroupBoxController.java', 'edit', { menu: '机器人对战分组宝箱', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRobotFightGroupBoxController.java', 'remove', { menu: '机器人对战分组宝箱', action: '删除', type: 'DELETE' }],
// ---- 机器人对战配置(ttFight/robotFightConfig.vue,两个 controller 共用一页)----
[A + 'TtRobotFightJoinConfigController.java', 'add', { menu: '机器人对战配置', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRobotFightJoinConfigController.java', 'edit', { menu: '机器人对战配置', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRobotFightJoinConfigController.java', 'remove', { menu: '机器人对战配置', action: '删除', type: 'DELETE' }],
[A + 'TtRobotFightPriceConfigController.java', 'add', { menu: '机器人对战配置', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRobotFightPriceConfigController.java', 'edit', { menu: '机器人对战配置', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRobotFightPriceConfigController.java', 'remove', { menu: '机器人对战配置', action: '删除', type: 'DELETE' }],
// ---- 转赠申请(delivery/transferApply.vue:同意 / 驳回 / 确定同意)----
[A + 'TtTransferApplyController.java', 'approve', { menu: '转赠申请', action: '同意', type: 'GRANT' }],
[A + 'TtTransferApplyController.java', 'reject', { menu: '转赠申请', action: '驳回', type: 'GRANT' }],
[A + 'TtTransferApplyController.java', 'approveBatch', { menu: '转赠申请', action: '确定同意', type: 'GRANT' }],
[A + 'TtTransferApplyController.java', 'rejectBatch', { menu: '转赠申请', action: '驳回', type: 'GRANT' }],
// ---- 任务列表(ttTaskCenter/index.vue)----
[A + 'TtTaskCenterController.java', 'add', { menu: '任务列表', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtTaskCenterController.java', 'edit', { menu: '任务列表', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtTaskCenterController.java', 'remove', { menu: '任务列表', action: '删除', type: 'DELETE' }],
// ---- 开箱机会(ttOrnaments/boxOpenChance.vue;库里无同名菜单,用页面功能名)----
[A + 'TtBoxOpenChanceController.java', 'add', { menu: '开箱机会', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtBoxOpenChanceController.java', 'edit', { menu: '开箱机会', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtBoxOpenChanceController.java', 'remove', { menu: '开箱机会', action: '删除', type: 'DELETE' }],
// ================= 其余有按钮证据的页面(标签来自 evidence.js:直接调用方的按钮文案,CRUD 页按工具条 新增/修改/删除)=================
// ---- 公告(ttSetting/announcement.vue)----
[A + 'TtAnnouncementController.java', 'addAnnouncement', { menu: '公告', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtAnnouncementController.java', 'editAnnouncement', { menu: '公告', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtAnnouncementController.java', 'removeAnnouncementByAnnouncementId', { menu: '公告', action: '删除', type: 'DELETE' }],
// ---- Banner设置 / 彩金 / 文章 / 文章类型 / 宝箱分类(ttSetting/banner.vue, ttBonus/index.vue, contentList, contentType, ttBox/boxType)----
[A + 'TtBannerController.java', 'add', { menu: 'Banner设置', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtBannerController.java', 'edit', { menu: 'Banner设置', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtBannerController.java', 'remove', { menu: 'Banner设置', action: '删除', type: 'DELETE' }],
[A + 'TtBonusController.java', 'add', { menu: '彩金', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtBonusController.java', 'edit', { menu: '彩金', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtBonusController.java', 'remove', { menu: '彩金', action: '删除', type: 'DELETE' }],
[A + 'TtContentController.java', 'add', { menu: '文章', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtContentController.java', 'edit', { menu: '文章', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtContentController.java', 'remove', { menu: '文章', action: '删除', type: 'DELETE' }],
[A + 'TtContentTypeController.java', 'add', { menu: '文章类型', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtContentTypeController.java', 'edit', { menu: '文章类型', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtContentTypeController.java', 'remove', { menu: '文章类型', action: '删除', type: 'DELETE' }],
[A + 'TtBoxTypeController.java', 'add', { menu: '宝箱分类', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtBoxTypeController.java', 'edit', { menu: '宝箱分类', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtBoxTypeController.java', 'remove', { menu: '宝箱分类', action: '删除', type: 'DELETE' }],
// ---- 宝箱饰品(挂在宝箱列表下;批量填货按钮见 ttBox/index.vue:283)----
[A + 'TtBoxOrnamentsController.java', 'add', { menu: '宝箱列表', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtBoxOrnamentsController.java', 'edit', { menu: '宝箱列表', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtBoxOrnamentsController.java', 'remove', { menu: '宝箱列表', action: '删除', type: 'DELETE' }],
[A + 'TtBoxOrnamentsController.java', 'batchAdd', { menu: '宝箱列表', action: '批量填货', type: 'INSERT' }],
// ---- 等级类(ttOrnamentsLevel/index.vue, ttSetting/promotionLevel.vue, ttSetting/vips.vue)----
[A + 'TtOrnamentsLevelController.java', 'edit', { menu: '饰品等级', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtOrnamentsLevelController.java', 'generateOrnamentsLevel', { menu: '饰品等级', action: '新增', type: 'INSERT' }],
[A + 'TtPromotionLevelController.java', 'edit', { menu: '推广等级设置', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtPromotionLevelController.java', 'generatePromotionLevel', { menu: '推广等级设置', action: '生成推广列表', type: 'INSERT' }],
[A + 'TtPromotionLevelController.java', 'truncateVipLevel', { menu: '推广等级设置', action: '重置', type: 'CLEAN' }],
[A + 'TtVipLevelController.java', 'edit', { menu: 'VIP等级设置', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtVipLevelController.java', 'generateVipLevel', { menu: 'VIP等级设置', action: '生成VIP等级', type: 'INSERT' }],
[A + 'TtVipLevelController.java', 'truncateVipLevel', { menu: 'VIP等级设置', action: '重置', type: 'CLEAN' }],
// ---- 充值/卡密(ttRechargeList/index.vue, ttRechargeRecord? , ttGenerateCard/index.vue:135)----
[A + 'TtRechargeListController.java', 'add', { menu: '货币列表', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRechargeListController.java', 'edit', { menu: '货币列表', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRechargeListController.java', 'remove', { menu: '货币列表', action: '删除', type: 'DELETE' }],
[A + 'TtRechargeConfigController.java', 'add', { menu: '网站货币管理', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRechargeConfigController.java', 'edit', { menu: '网站货币管理', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRechargeConfigController.java', 'remove', { menu: '网站货币管理', action: '删除', type: 'DELETE' }],
[A + 'TtRechargeCardController.java', 'generateCard', { menu: '卡密', action: '生成卡密', type: 'INSERT' }],
[A + 'TtRechargeCardController.java', 'generateBlankCard', { menu: '卡密', action: '生成空白卡密', type: 'INSERT' }],
// ---- CDK口令 / Roll奖池 / 限时Roll / 官方周期Roll配置 / 奖项配置 ----
[A + 'TtRedPacketController.java', 'add', { menu: 'CDK口令', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRedPacketController.java', 'edit', { menu: 'CDK口令', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRedPacketController.java', 'remove', { menu: 'CDK口令', action: '删除', type: 'DELETE' }],
[A + 'TtRollJackpotController.java', 'add', { menu: '奖池列表', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRollJackpotController.java', 'edit', { menu: '奖池列表', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRollJackpotController.java', 'remove', { menu: '奖池列表', action: '删除', type: 'DELETE' }],
[A + 'TtRollJackpotOrnamentsController.java', 'add', { menu: '奖池列表', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtRollJackpotOrnamentsController.java', 'edit', { menu: '奖池列表', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtRollJackpotOrnamentsController.java', 'remove', { menu: '奖池列表', action: '删除', type: 'DELETE' }],
[A + 'TtTimeRollController.java', 'add', { menu: '时间roll房', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtTimeRollController.java', 'edit', { menu: '时间roll房', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtTimeRollController.java', 'remove', { menu: '时间roll房', action: '删除', type: 'DELETE' }],
[A + 'TtOfficialRollConfigController.java', 'add', { menu: '官方周期Roll配置', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtOfficialRollConfigController.java', 'edit', { menu: '官方周期Roll配置', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtOfficialRollConfigController.java', 'remove', { menu: '官方周期Roll配置', action: '删除', type: 'DELETE' }],
[A + 'TurnoverLotteryPrizeController.java', 'add', { menu: '奖项配置', action: '新增', type: 'INSERT', auto: true }],
[A + 'TurnoverLotteryPrizeController.java', 'edit', { menu: '奖项配置', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TurnoverLotteryPrizeController.java', 'remove', { menu: '奖项配置', action: '删除', type: 'DELETE' }],
// ---- 升级饰品 / 失败奖励(ttUpgrade/index.vue, upgradeFall.vue)----
[A + 'TtUpgradeOrnamentsController.java', 'batchAdd', { menu: '饰品列表', action: '新增', type: 'INSERT' }],
[A + 'TtUpgradeOrnamentsController.java', 'edit', { menu: '饰品列表', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtUpgradeOrnamentsController.java', 'remove', { menu: '饰品列表', action: '删除', type: 'DELETE' }],
[A + 'TtUpgradeFailOrnamentsController.java', 'batchAdd', { menu: '失败奖励', action: '新增', type: 'INSERT' }],
[A + 'TtUpgradeFailOrnamentsController.java', 'edit', { menu: '失败奖励', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtUpgradeFailOrnamentsController.java', 'remove', { menu: '失败奖励', action: '删除', type: 'DELETE' }],
// ---- 头像设置 / 网站道具 / 发货记录 / 商城上下架 / 站点参数 ----
[A + 'TtUserAvatarController.java', 'add', { menu: '头像设置', action: '新增', type: 'INSERT', auto: true }],
[A + 'TtUserAvatarController.java', 'edit', { menu: '头像设置', action: '修改', type: 'UPDATE', auto: true }],
[A + 'TtUserAvatarController.java', 'remove', { menu: '头像设置', action: '删除', type: 'DELETE' }],
[A + 'WebsitePropertyController.java', 'add', { menu: '网站道具', action: '新增', type: 'INSERT', auto: true }],
[A + 'WebsitePropertyController.java', 'edit', { menu: '网站道具', action: '修改', type: 'UPDATE', auto: true }],
[A + 'WebsitePropertyController.java', 'remove', { menu: '网站道具', action: '删除', type: 'DELETE' }],
[A + 'TtDeliveryRecordController.java', 'deliveryApprove', { menu: '发货记录', action: '确认发货', type: 'GRANT' }],
[A + 'ShoppingController.java', 'batchPutAwayOrSoldOut', { menu: '商城列表', action: '上架/下架', type: 'UPDATE' }],
[A + 'WebsiteSetupController.java', 'updateParameterSetting', { menu: '网站设置', action: '保存', type: 'UPDATE' }],
// ---- 疯狂转盘 奖励矩阵删除 ----
[W + 'AdminWheelController.java', 'matrixDelete', { menu: '奖励矩阵', action: '删除', type: 'DELETE' }],
];
const IMPORTS = {
TtUser: 'com.ruoyi.domain.entity.sys.TtUser',
TtUserMapper: 'com.ruoyi.admin.mapper.TtUserMapper',
TtLossRebate: 'com.ruoyi.domain.entity.TtLossRebate',
TtLossRebateMapper: 'com.ruoyi.admin.mapper.TtLossRebateMapper',
TtRoll: 'com.ruoyi.domain.entity.roll.TtRoll',
TtRollMapper: 'com.ruoyi.admin.mapper.TtRollMapper',
TtBox: 'com.ruoyi.domain.other.TtBox',
TtBoxMapper: 'com.ruoyi.admin.mapper.TtBoxMapper',
TtOrnament: 'com.ruoyi.domain.entity.TtOrnament',
TtOrnamentMapper: 'com.ruoyi.admin.mapper.TtOrnamentMapper',
};
const isBlockMember = (l) =>
/^\s*(\/\/|\*|\/\*|@)/.test(l) || (/^\s*[\w.]+\s*=/.test(l) && /[,)]\s*$/.test(l));
// ---- 自动解析实体/Mapper:attrs.auto = true 时,按方法入参里的实体类型去认 ----
function collectFiles(dir, out, suffix) {
if (!fs.existsSync(dir)) return out;
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
const p = path.join(dir, e.name);
if (e.isDirectory()) collectFiles(p, out, suffix);
else if (e.isFile() && e.name.endsWith(suffix)) out.push(p);
}
return out;
}
const ENTITY = new Map(); // simpleName -> fqn(skins-model 全部类;真正用的时候还要求有 Mapper)
for (const f of collectFiles(path.join(ROOT, 'skins-model'), [], '.java')) {
const src = fs.readFileSync(f, 'utf8');
const cls = (src.match(/public\s+class\s+(\w+)/) || [, null])[1];
const pkg = (src.match(/^package\s+([\w.]+);/m) || [, ''])[1];
if (cls && !ENTITY.has(cls)) ENTITY.set(cls, `${pkg}.${cls}`);
}
const MAPPER = new Map(); // entitySimple -> {simple, fqn}(BaseMapper 与普通 MyBatis 接口都要认)
for (const f of collectFiles(path.join(ROOT, 'skins-service'), [], 'Mapper.java')) {
const simple = path.basename(f, '.java');
const entityName = simple.endsWith('Mapper') ? simple.slice(0, -6) : null;
if (!entityName || !ENTITY.has(entityName) || MAPPER.has(entityName)) continue;
const pkg = (fs.readFileSync(f, 'utf8').match(/^package\s+([\w.]+);/m) || [, ''])[1];
MAPPER.set(entityName, { simple, fqn: `${pkg}.${simple}` });
}
/** 取方法参数里的类型名(优先 @RequestBody 那个) */
function methodTypes(lines, sig) {
let text = '';
for (let i = sig; i < Math.min(sig + 10, lines.length); i++) {
text += lines[i] + ' ';
if (/\)\s*\{/.test(lines[i]) || /\)\s*$/.test(lines[i])) break;
}
const inner = (text.match(/\(([\s\S]*?)\)/) || [, ''])[1];
const types = [];
const rb = inner.match(/@RequestBody\s+(?:@\w+(?:\([^)]*\))?\s+)*(\w+)/);
if (rb) types.push(rb[1]);
for (const m of inner.matchAll(/(?:^|,)\s*(?:final\s+)?([A-Z]\w+)\s+\w+/g)) if (!types.includes(m[1])) types.push(m[1]);
return types;
}
function render(a, indent) {
const parts = [`title = "${a.menu}"`, `action = "${a.action}"`, `businessType = BusinessType.${a.type}`];
if (a.entity) parts.push(`entityClass = ${a.entity}.class`);
if (a.mapper) parts.push(`mapperClass = ${a.mapper}.class`);
if (a.idField) parts.push(`idField = "${a.idField}"`);
const one = `${indent}@Log(${parts.join(', ')})`;
if (one.length <= 130) return [one];
return [`${indent}@Log(${parts.slice(0, 3).join(', ')},`, `${indent} ${parts.slice(3).join(', ')})`];
}
function insertImports(lines, entries) {
for (const e of entries) {
// 集合里既有全限定名(com.ruoyi...),也有短名(TtUser),分开处理
const fqn = e.includes('.') ? e : IMPORTS[e];
if (!fqn) continue;
const simple = fqn.split('.').pop();
if (lines.some((l) => new RegExp(`^import\\s+[\\w.]*\\b${simple};`).test(l.trim()))) continue;
let at = lines.findIndex((l) => /^import com\.ruoyi\./.test(l));
if (at < 0) at = lines.findIndex((l) => /^import /.test(l));
if (at >= 0) lines.splice(at, 0, `import ${fqn};`);
}
}
const byFile = new Map();
for (const [file, method, attrs] of TARGETS) {
if (!byFile.has(file)) byFile.set(file, []);
byFile.get(file).push({ method, attrs });
}
if (process.argv.includes('--debug')) {
console.log(`实体索引 ${ENTITY.size},Mapper 索引 ${MAPPER.size}`);
for (const t of ['TtWelfare', 'TtRedPack', 'TtTaskCenter', 'TtBox']) {
console.log(` ${t}: entity=${ENTITY.get(t) || '无'} mapper=${MAPPER.has(t) ? MAPPER.get(t).fqn : '无'}`);
}
}
let done = 0, skipped = 0;
for (const [rel, list] of byFile) {
const abs = path.join(ROOT, rel);
const lines = fs.readFileSync(abs, 'utf8').split(/\r?\n/);
const edits = [];
const imports = new Set(['com.ruoyi.common.annotation.Log', 'com.ruoyi.common.enums.BusinessType']);
for (const { method, attrs } of list) {
// 找方法签名
let sig = -1;
for (let i = 0; i < lines.length; i++) {
if (new RegExp(`^\\s*(?:public|protected|private)\\s+[\\w<>\\[\\],\\.\\? ]+\\s+${method}\\s*\\(`).test(lines[i])) { sig = i; break; }
}
if (sig < 0) { console.log(` [跳过] 找不到方法 ${path.basename(rel)}.${method}`); skipped++; continue; }
// 注解块顶部
let top = sig;
for (let j = sig - 1; j >= 0; j--) {
if (lines[j].trim() === '' || !isBlockMember(lines[j])) break;
top = j;
}
// 已有 @Log 就整块删掉(支持多行)
let start = -1, end = -1;
for (let j = top; j < sig; j++) {
if (/^\s*@Log\(/.test(lines[j])) {
start = j;
let depth = 0;
outer:
for (let k = j; k < sig; k++) {
for (const ch of lines[k]) {
if (ch === '(') depth++;
else if (ch === ')') { depth--; if (depth === 0) { end = k; break outer; } }
}
}
break;
}
}
const indent = (lines[top].match(/^\s*/) || [' '])[0];
// 自动认实体:入参里第一个"有 @TableName 且有对应 Mapper"的类型
if (attrs.auto && !attrs.entity)
{
for (const t of methodTypes(lines, sig))
{
if (ENTITY.has(t) && MAPPER.has(t)) { attrs.entity = t; attrs.mapper = MAPPER.get(t).simple; break; }
}
}
edits.push({ start, end, top, newLines: render(attrs, indent), method, attrs });
if (attrs.entity && ENTITY.has(attrs.entity)) imports.add(ENTITY.get(attrs.entity));
if (attrs.entity && MAPPER.has(attrs.entity)) imports.add(MAPPER.get(attrs.entity).fqn);
if (attrs.mapper && IMPORTS[attrs.mapper]) imports.add(IMPORTS[attrs.mapper]);
}
for (const ed of edits.sort((a, b) => b.top - a.top)) {
if (ed.start >= 0) lines.splice(ed.start, ed.end - ed.start + 1, ...ed.newLines);
else lines.splice(ed.top, 0, ...ed.newLines);
console.log(` ${path.basename(rel)}.${ed.method} → ${ed.attrs.menu} / ${ed.attrs.action}` +
`${ed.attrs.entity ? ' diff=' + ed.attrs.entity : ''}${ed.attrs.idField ? ' idField=' + ed.attrs.idField : ''}`);
done++;
}
insertImports(lines, imports);
if (apply) fs.writeFileSync(abs, lines.join('\r\n'), 'utf8');
}
console.log(`\n${apply ? 'APPLIED' : 'DRY-RUN'}: 写入 ${done} 个方法,跳过 ${skipped}`);