Commit Graph

271 Commits

Author SHA1 Message Date
bd1e247fcf 优化:浮漂下沉动画延长至 1.5s,视觉更自然 2026-03-01 16:22:42 +08:00
03e7f260b2 功能:自动钓鱼卡新增 72小时卡(15000金币) 2026-03-01 16:20:34 +08:00
63679a622f 功能:随机浮漂钓鱼防挂机 + 商店自动钓鱼卡
核心变更:
1. FishingController 重写
   - cast(): 生成随机浮漂坐标(x/y%) + 一次性 token
   - reel(): 必须携带 token 才能收竿(防脚本绕过)
   - 检测自动钓鱼卡剩余时间并返回给前端

2. 前端钓鱼逻辑重写
   - 抛竿后显示随机位置 🪝 浮漂动画(全屏飘动)
   - 鱼上钩时浮漂「下沉」动画,8秒内点击浮漂才能收竿
   - 超时未点击:鱼跑了,token 也失效
   - 持有自动钓鱼卡:自动点击,紫色提示剩余时间

3. 商店新增「🎣 自动钓鱼卡」分组
   - 3档:2h(800金)/8h(2500金)/24h(6000金)
   - 图标徽章显示剩余有效时间(紫色)
   - 购买后即时激活,无需手动操作

4. 数据库
   - shop_items.type 加 auto_fishing 枚举
   - shop_items.duration_minutes 新字段(分钟精度)
   - Seeder 写入 3 张卡数据

防挂机原理:按钮 → 浮漂随机位置,脚本无法固定坐标点击
2026-03-01 16:19:45 +08:00
e0c15b437e 修复:求婚按钮异性判断 - 统一 sex 字段格式
根因:sex 字段数据库存整数(0/1/2),但前后端判断混用了
字符串('男'/'女')导致比较永远错误。

修复三处:
1. UserController::show() - sex 返回统一转字符串(1→'男' 2→'女' 其他→'')
2. frame.blade.php - chatContext.userSex 注入时同样转字符串
3. MarriageService::propose() - 后端性别校验改用整数(1/2)比较

逻辑链路:
- 未设置性别(sex=0) → '' → x-show && userInfo.sex 为'' falsy → 按钮隐藏 ✓
- 同性(如两个男) → '男'==='男' → !== 为false → 按钮隐藏 ✓
- 异性(男+女) → '男'!=='女' → 按钮显示 ✓
2026-03-01 16:04:32 +08:00
954a078d63 修复:自动存点不再覆盖有职务用户的等级
AutoSaveExp::processUser() 第3步升降级逻辑重构:
- 有在职职务的用户:等级强制锁定为 position.level
  (防止自动存点按经验值降低/覆盖职务对应等级)
- 管理员(>= superLevel):不变动
- 普通用户:照旧按经验自动升降级

同时在 refresh() 后加 load('activePosition.position')
确保职务关联数据已就绪。
2026-03-01 16:00:10 +08:00
9139108744 修复:求婚按钮异性判断,mySex 存入 Alpine data 避免 x-show 内 window 访问失效 2026-03-01 15:56:12 +08:00
5cf87391b6 优化:商店分组排序调整,改名卡(道具)移至戒指后面 2026-03-01 15:52:26 +08:00
f9312475d0 优化:商店浮窗宽度 520→800px,网格 2列→4列 2026-03-01 15:49:38 +08:00
3132f013b7 修复:无戒指时点确定改为打开商店浮窗而非新标签页 2026-03-01 15:47:01 +08:00
4a9730c38d 功能:浮窗商店同步加「💍 求婚戒指」分组
toolbar.blade.php renderShop 补充:
- ring 类型分组(存入背包,求婚时消耗)
- 图标持有数量红色徽章
- 卡片下方亲密度/魅力加成标注
- 购买按钮走现有 buyItem 流程(后端 buyRing 处理)
2026-03-01 15:45:13 +08:00
29e43507ac 功能:商店完善戒指板块
迁移:
- 2026_03_01_153959:shop_items 增加 intimacy_bonus/charm_bonus 字段

Seeder(RingItemsSeeder):
- 银质戒指 500金  亲密+10 魅力+30
- 黄金戒指 2000金 亲密+30 魅力+80
- 红宝石戒指 8000金 亲密+80 魅力+200
- 钻石戒指 30000金 亲密+200 魅力+500
- 传说神戒 100000金 亲密+500 魅力+1000

ShopService:
- buyItem() 分支加 ring 类型
- buyRing():扣金币 + 写入 active UserPurchase(背包持有)

ShopController::items():
- 返回 intimacy_bonus/charm_bonus
- 统计 ring_counts(各戒指持有数量)

shop-panel.blade.php:
- 新增「💍 求婚戒指」分组(排在最后)
- 图标右上角红色数字徽章(持有时)
- 卡片下方显示亲密度/魅力加成
- 购买按钮与现有逻辑复用
2026-03-01 15:42:25 +08:00
1f33013216 优化:求婚前先检查戒指库存,无戒指则引导购买
openProposeModal() 改为 async:
1. 先调 /marriage/rings 检查背包
2. 无戒指 → 弹确认框 → 同意则新窗口打开 /shop
3. 有戒指 → 直接传入弹窗(openWithRings),避免二次请求

marriageProposeModal 新增 openWithRings(username, rings)
方法,接收预加载列表,无 loading 状态直接展示。
2026-03-01 15:38:52 +08:00
e5a35779f8 修复:UserPurchase 模型补充 item() 关联别名
婚姻系统 whereHas('item') / with('item') 需要此方法,
原模型只有 shopItem(),现在加 item() 作为别名指向同一外键。
2026-03-01 15:36:22 +08:00
e20f94fe17 修复:求婚限制异性(前端隐藏按钮 + 后端拦截校验)
前端(user-actions.blade.php):
- 求婚按钮增加三重条件:对方未婚 + 双方性别均已填写 + 性别不同

后端(MarriageService::propose):
- 增加异性校验:两方性别必须为「男/女」且不同
- 报错:只有男女双方才能互相求婚

frame.blade.php:
- chatContext 注入 userSex(当前用户性别)供前端判断
2026-03-01 15:34:36 +08:00
877fd1935f 功能:婚姻系统第12步(前端交互)
chat.js:
- 监听婚姻全局广播(MarriageAccepted/Divorced/WeddingCelebration)
- initMarriagePrivateChannel() 监听私人频道
  (求婚/拒绝/过期/离婚申请/红包领取)

frame.blade.php:
- chatContext.marriage 注入所有婚姻 API URL
- 引入 marriage-modals.blade.php 弹窗组件

marriage-modals.blade.php(新建):
- 求婚弹窗(选戒指→求婚)
- 收到求婚弹窗(接受/拒绝)
- 结婚成功公告弹窗(可跳转婚礼设置)
- 婚礼设置弹窗(档位/支付方式/立即OR定时)
- 婚礼红包领取弹窗
- 所有 WebSocket 事件处理

user-actions.blade.php:
- 名片加「💍 求婚」按钮(对方未婚时)
- 名片加「💑 已婚状态」标签(对方已婚时)
- fetchUser 同步拉取对方婚姻状态

MarriageController:
- targetStatus 返回增加 status/partner_name/marriage_id
- myRings 返回增加 status/intimacy_bonus/charm_bonus
2026-03-01 15:31:07 +08:00
37af4ba975 修复:婚姻管理总览页 Tailwind v4 动态类无法构建问题
- 「婚礼档位」按钮改用 style 内联颜色(bg-pink-600 未被扫描)
- 快捷入口4张卡片 hover 颜色改为完整静态类名
  (Tailwind v4 无法扫描动态拼接 bg-xx / text-xx)
- npm run build 验证已生效
2026-03-01 15:23:35 +08:00
143601c251 功能:婚姻系统第11步(Horizon Jobs + 定时任务)
5个 Job:
- ExpireMarriageProposals:每5分钟扫描超时求婚(广播通知)
- TriggerScheduledWeddings:每5分钟触发定时婚礼(广播庆典)
- AutoExpireDivorces:每小时处理离婚超时自动解除
- ExpireWeddingEnvelopes:每小时清理过期红包
- ProcessMarriageIntimacy:每日00:05全量亲密度时间奖励

console.php 注册5个 Schedule
2026-03-01 15:16:46 +08:00
d2797d5b59 功能:婚姻系统第9步(后台管理页面)
Admin/MarriageManagerController:
- index() 总览统计卡片
- list() 婚姻列表(筛选/强制离婚/取消求婚)
- proposals() 求婚记录
- ceremonies() 婚礼红包记录
- claimDetail() 红包领取明细
- intimacyLogs() 亲密度日志(来源筛选)
- configs/updateConfigs 参数配置(批量保存)
- tiers/updateTier 婚礼档位管理

Views(7个页面):admin/marriages/{index|list|configs|tiers|ceremonies|claim-detail|proposals|intimacy-logs}
侧边栏:superlevel 区块新增「💒 婚姻管理」入口
2026-03-01 15:15:03 +08:00
4f49fb7ce8 功能:婚姻系统第8&10步(Controllers + Events + 路由)
- MarriageController:propose/accept/reject/divorce/confirmDivorce/status
- WeddingController:tiers/setup(立即触发)/claim/envelopeStatus
- 8个 WebSocket Events:
  Marriage{Proposed|Accepted|Rejected|Expired|Divorced|DivorceRequested}
  WeddingCelebration / EnvelopeClaimed
- 前台路由:marriage.* + wedding.*
- 后台路由:admin.marriages.*(superlevel 层)
2026-03-01 15:09:33 +08:00
384cf8e078 功能:婚姻系统第7步(WeddingService)
- setup():验证余额、立即/定时扣款或冻结
- trigger():获取在线用户、随机红包分配、写入 claims
- claim():领取红包、金币入账(乐观锁防并发重复领)
- distributeRedPacket():二倍均值算法,总和精确等于 total
- refundCeremony():在线为0时退还冻结金币
2026-03-01 15:04:49 +08:00
2d07b032d9 功能:婚姻系统第4-6步(Services + Models)
Step 4 - MarriageConfigService:
- 带60min Cache 的配置读取/写入
- 支持单项/分组/全量读取,管理员保存后自动清缓存

Step 5 - MarriageIntimacyService:
- 亲密度增加 + 日志写入 + 等级自动更新
- Redis 每日上限计数器(各来源独立控制)
- onFlowerSent/onPrivateChat/onlineTick 接入点方法
- dailyBatch 批量处理(Horizon Job 用)

Step 6 - MarriageService(核心业务):
- propose/accept/reject/divorce/confirmDivorce/forceDissolve
- 所有金币魅力通过 UserCurrencyService 统一记账
- 冷静期检查/超时处理/强制离婚金币全转对方

Models 改良(Marriage/MarriageConfig/MarriageIntimacyLog)
2026-03-01 15:03:34 +08:00
11dcb03924 功能:婚姻系统第1-3步(枚举/迁移/Seeder)
Step 1 - 枚举扩展:
- 新增 IntimacySource 枚举(7种亲密度来源)
- CurrencySource 追加7个婚姻相关来源

Step 2 - 数据库迁移(6张表):
- marriage_configs(约30条可配置参数)
- marriage_intimacy_logs(亲密度变更日志)
- wedding_tiers(5档婚礼配置)
- wedding_ceremonies(婚礼仪式记录)
- wedding_envelope_claims(红包领取记录)
- marriages 表改良(新增全部业务字段)
- users.frozen_jjb(定时婚礼金币冻结)
- shop_items.type 枚举添加 ring 类型

Step 3 - Seeder:
- 28条婚姻参数默认配置
- 5个婚礼档位
- 3种戒指道具(银/金/钻)
2026-03-01 14:56:47 +08:00
73badefcc5 文档:用户名禁词管理标记为已完成 2026-03-01 14:17:20 +08:00
477bba3003 修复:批量添加禁用词 UTF-8 编码错误
- 新增 sanitizeUtf8() 私有方法:
  去除 BOM、零宽字符、非法 UTF-8 字节、控制字符
  防止从聊天/文档复制时混入隐藏字符导致 json_encode 失败
- batchStore() 先净化 words 和 reason 输入
- preg_split 加 /u 修饰符(完整 Unicode 支持)
- 响应加 JSON_UNESCAPED_UNICODE 防中文被转义
2026-03-01 14:10:13 +08:00
f114c6b168 修复:新增独立迁移将 reserved_until 改为 nullable
上次 add_type_reason 迁移已在生产跑过(无 change),
导致 permanent 类型插入 NULL 时报 1048 错误。
新建专用迁移用 DB::statement ALTER TABLE 直接生效,
绕过 doctrine/dbal ->change() 的潜在兼容问题。
2026-03-01 14:07:42 +08:00
211075b77c 修复:reserved_until 列允许 NULL(permanent 禁用词无到期时间)
- 迁移文件补充 ->nullable()->change() 使 reserved_until 兼容 permanent 类型
- Tinker 直接执行 ALTER TABLE 修复已运行的迁移(无需回滚)
2026-03-01 14:06:35 +08:00
632a4240c4 功能:禁用词管理支持批量添加
- 新增 ForbiddenUsernameController::batchStore()
  支持换行、逗号、中文逗号、空格多种分隔格式
  自动去重、跳过已存在词语、忽略超长词
  返回成功数/跳过数详细提示
- 新增路由 POST /admin/forbidden-usernames/batch
- View 新增卡片加「单个/批量」两 Tab 切换
  批量 Tab 使用 textarea 多行输入
2026-03-01 14:04:28 +08:00
fc495ccceb 功能:禁用用户名管理(永久禁词列表)
数据库:
- 新增迁移 username_blacklist 表加 type/reason 列
  type: temp(改名30天保留)| permanent(管理员永久禁用)
  reason: 禁用原因备注(最长100字符)

核心逻辑:
- UsernameBlacklist::isBlocked() 同时拦截两种类型
  也包含 isReserved() 兼容旧调用
  增加 scopePermanent()/scopeTemp() 查询作用域
- AuthController 注册时加 isBlocked() 拦截
  禁词/保留期内均不可注册
- ShopService::useRenameCard() 已有 isReserved() 调用
  因已改用 isBlocked() 别名,无需修改

后台:
- ForbiddenUsernameController:index/store/update/destroy
- 路由:/admin/forbidden-usernames(chat.site_owner 中间件)
- 视图:admin/forbidden-usernames/index.blade.php
  新增表单、关键词搜索、分页、行内编辑原因、删除
- 侧边栏加「🚫 禁用用户名」入口(仅站长可见)
2026-03-01 14:00:38 +08:00
312b92a81d 文档/调整:好友面板完成,更新 DEVELOPMENT.md
- DEVELOPMENT.md:好友系统 [ ] → [x],补充功能细节
- toolbar.blade.php:好友按钮移至「呼叫」后(用户调整位置)
2026-03-01 13:51:27 +08:00
8120058948 重构:好友面板独立为 friend-panel.blade.php
- 新建 resources/views/chat/partials/friend-panel.blade.php
  包含完整的 style / HTML / JS
  结构完全干净,无嵌套错误
- toolbar.blade.php:
  恢复至干净基础版本(回滚损坏内容)
  添加「好友」按钮(openFriendPanel)
  通过 @include('chat.partials.friend-panel') 引入面板
- FriendController::index() 返回 sub_time 和 pending 列表
2026-03-01 13:47:51 +08:00
4ced484419 功能:好友列表面板
后端(FriendController::index):
- 返回 sub_time 添加时间
- 新增 pending 列表(对方加了我但我未回加)
  包含用户信息 + added_at(对方添加我的时间)

前端(toolbar.blade.php):
- 工具栏顶部加「好友」按钮(openFriendPanel)
- 好友弹窗面板(#friend-panel):
  ① 搜索栏:输入用户名 Enter/按钮添加好友
  ② 「我关注的好友」列表:头像/用户名/互相徽章/
     添加时间/删除按钮
  ③ 「对方已加我,待我回加」列表:头像/用户名/
     对方添加时间/回加按钮
  ④ 面板顶部提示区(成功/失败消息)
- 所有添加/删除调用与双击用户卡片完全相同的接口
  (/friend/{username}/add、/friend/{username}/remove)
2026-03-01 13:38:30 +08:00
48b31e7cff 修复:管理员进房烟花无声问题(AudioContext suspended)
根本原因:管理员进房特效在 800ms 后自动触发,
此时用户尚未与新页面交互,浏览器的 AudioContext
处于 suspended 状态,之前代码同步调用 resume()
但未 await 其 Promise,导致音频节点创建后无法出声。

修复方式:
- play() 和 ding() 均改为先检查 ctx.state
- 若为 suspended,用 ctx.resume().then(...) 链式执行
- resolver 成功后真正创建音频节点并播放
- 若浏览器拒绝 resume(无用户手势),catch 静默处理

此修复使所有自动触发的音效(进房烟花、任命公告等)
在 AudioContext 未激活时也能正确播放。
2026-03-01 13:32:00 +08:00
58b63fa8d3 功能:大卡片/小卡片弹出时播放叮咚通知音
effect-sounds.js:
- 新增 ding() 函数:A5(880Hz) + E5(659Hz) 两音叮咚
  每音含基音×2.76铃铛泛音,快冲击+铃铛式衰减
  自动检查 chat_sound_muted 禁音标志
- 导出 ding 至返回对象,底部暴露 window.chatSound = {ding}

toast-notification.blade.php:
- chatToast.show() 中 appendChild 后调用 window.chatSound.ding()

scripts.blade.php:
- chatBanner.show() 开头调用 window.chatSound.ding()
2026-03-01 13:28:19 +08:00
dac7750fe1 功能:特效音效三项优化 + 禁音开关
音效改进(effect-sounds.js):
1. 雷电 - 三层合成更贴近真实:
   ①放电啪声(带通噪声 ~50ms)
   ②低频轰鸣(120→38Hz 扫频,快冲击 2s 衰减)
   ③极低频滚动余韵(55→22Hz,缓慢堆积 3.6s 长衰减)
2. 下雨 - 音量 0.40→0.15,时长与视觉效果统一(8000ms)
3. 下雪 - 移除风声,只保留五声音阶铃音(C/E/G/C)
   铃音加第二泛音(×2.76倍频)模拟真实铃铛共鸣感
   8次随机铃声分布在 10 秒内

禁音开关:
- input-bar.blade.php:悄悄话旁新增「🔇 禁音」复选框
- scripts.blade.php:toggleSoundMute() 函数,
  localStorage chat_sound_muted 持久化,
  DOMContentLoaded 恢复复选框状态
- effect-sounds.js:play() 先检查 chat_sound_muted 标志
2026-03-01 13:19:24 +08:00
1d7aa636a0 功能:4种全屏特效增加 Web Audio API 实时合成音效
新建 public/js/effects/effect-sounds.js:
- 雷电:低频白噪声爆裂 + 雷鸣渐衰(10次,与视觉同步)
- 烟花:发射滑音(200→700Hz)+ 带通噪声爆炸(9轮)
- 下雨:双层带通白噪声(1200Hz+3500Hz)持续淡入淡出
- 下雪:4000Hz+高频风声 + 五声音阶轻柔铃音(5次随机)
- 所有音效纯 Web Audio API 合成,无外部音频文件
- 旧 AudioContext 若被 suspended 自动 resume

effect-manager.js:
- play() 调用 EffectSounds.play(type) 同步触发音效
- _cleanup() 调用 EffectSounds.stop() 兜底停止

frame.blade.php:effect-sounds.js 在 effect-manager 前引入
2026-03-01 13:07:36 +08:00
2947f0f741 功能:用户列表增加在线状态列,支持点击排序
- UserManagerController 注入 ChatStateService,从 Redis 聚合
  所有活跃房间在线用户名(跨房间去重)
- 排序白名单加入 'online',在线排序用 orderByRaw CASE WHEN 虚拟列
  desc = 在线用户优先显示,asc = 离线用户优先
- 视图表头加「在线 ↕」可排序列(绿色高亮箭头)
- 每行显示绿色实心点+「在线」/灰点+「离线」小徽章
- my-duty-logs 分页已有 paginate(30)+withQueryString+links(),无需改动
2026-03-01 12:54:34 +08:00
0dff79dd51 修复:6列统计卡片改用 inline style,规避 Tailwind 未编译 grid-cols-6 2026-03-01 12:26:23 +08:00
769632dea8 优化:履职记录统计卡片改为固定6列一行,紧凑尺寸 2026-03-01 12:24:15 +08:00
855f169516 功能:后台「我的履职记录」页面
- 侧边栏「我的履职记录」链接,位于「任命管理」上方
- 路由:GET /admin/my-duty-logs → appointments.my-duty-logs
- 控制器:AppointmentController::myDutyLogs()
  支持按操作类型、日期范围筛选,分页,withQueryString()
- 视图:admin/appointments/my-duty-logs.blade.php
  顶部 6 格汇总统计(奖励/踢出/禁言/警告/任命/撤职)
  每张卡片可点击快速按类型筛选
  表格显示:操作时间、类型 Badge、操作对象、所属部门·职务、金币金额、备注
2026-03-01 12:22:13 +08:00
f4de31f92b 优化:奖励消息发送者显示「部门·职务」
$positionName 由单一职务名改为「部门名 · 职务名」格式,
例如:「生产部 · 系长」,无部门时退化为仅显示职务名,
超管保持「超级管理员」不变。
公告文案、私信、Toast 通知均同步更新。
2026-03-01 12:17:16 +08:00
3d7b86f06d 功能:奖励发放聊天室公告 + 右下角 Toast 通知卡片
后端(AdminCommandController::reward):
- 新增聊天室公开公告消息(系统公告,所有在场用户可见)
- 接收者私信附带 toast_notification 字段触发前端小卡片
- 公告文案:「🪙 [职务人] 向 [目标] 发放了 [N] 枚奖励金币!」

前端:
- 新建 chat/partials/toast-notification.blade.php:
  全局右下角 Toast 组件,window.chatToast.show() API
  支持 title/message/icon/color/duration/action 配置
  多条 Toast 从右下角向上堆叠,独立计时、独立关闭
- chat:message 事件监听中检测 toast_notification 字段,
  自动弹出右下角通知卡片(仅接收方可见)
- showFriendToast 迁移至 window.chatToast.show(),
  删除 80 行旧实现,代码量净减
- frame.blade.php 引入新 partial

DEVELOPMENT.md:
- 新增 §7.9 chatToast 完整文档(API、使用场景、迁移说明)
- 原 chatBanner 章节编号改为 §7.10
2026-03-01 12:15:18 +08:00
2ae3d83349 优化:确认发放按钮圆角 6px→20px,视觉更圆润 2026-03-01 12:08:05 +08:00
9da0d83914 优化:确认发放按钮风格改为与全局弹窗一致
- 输入框+按钮回到同一行(align-items:stretch)
- 按钮完全复刻 global-dialog 确认按钮样式:
  padding:9px, border-radius:6px, font-size:13px, font-weight:bold
- 背景色 #f59e0b(与弹窗标题栏橙色对应)
- :style 仅控制 opacity,background 两分支都明确写入
2026-03-01 12:07:12 +08:00
5180526821 优化:确认发放按钮改为全宽独立一行,风格同弹窗按钮
输入框独占一行,按钮在输入框下方全宽显示:
- 宽度 100%,高度 48px,字号 16px,字间距 2px
- 琥珀橙色 #f59e0b,与弹窗头部色调呼应
- 禁用时 opacity:0.45,启用时 box-shadow 投影
- 符合截图中弹窗确定按钮的视觉风格
2026-03-01 12:04:05 +08:00
0d693eef5f 优化:输入框与确认按钮等高(align-items:stretch)
flex 容器改为 align-items:stretch,按钮去掉固定 height
改为 align-self:stretch,自动撑满与输入框相同高度,
视觉上两者完全对齐。
2026-03-01 12:01:53 +08:00
4207528043 修复:确认发放按钮背景色始终通过 :style 注入
将 background 从 static style 移入 :style 绑定,
两种状态(启用/禁用)均显式包含 background,
彻底避免 Alpine :style 动态绑定覆盖静态 style background 的问题。

按钮颜色:橙红渐变 #ea580c→#dc2626
- 启用:opacity:1 + box-shadow 投影
- 禁用:opacity:0.4 + no-shadow(未输入金额时)
2026-03-01 12:00:03 +08:00
96c472bfb9 修复:弹窗额度4列布局+确认按钮背景色
1. 4列布局:x-show 与 display:grid 分离到两层 div,
   避免 Alpine x-show 显示时把 display:grid 覆盖为 block

2. 确认按钮::style 改为始终返回 opacity 值而非空字符串,
   避免 Alpine :style 绑定空值时清除静态 style 的 background,
   按钮现为橙红渐变(#ea580c→#dc2626)+红色投影,
   禁用状态 opacity:0.45 降亮+cursor:not-allowed
2026-03-01 11:58:08 +08:00
4ba5a88fc2 优化:奖励弹窗加宽+4列额度+最近10条记录+确认按钮醒目
- 弹窗宽度 320→520px(max-width:95vw 自适应)
- 额度四格改为一行4列(单次上限/单日上限/今日已发/剩余额度)
- 确认按钮改为橙红渐变+投影,视觉更突出
- 输入框下方显示最近10条发放记录(目标/金额/时间)
- 发放成功后实时在历史列表头部插入新纪录
- rewardQuota 接口统一返回 recent_rewards(最近10条)
2026-03-01 11:55:29 +08:00
21cabb08c9 功能:奖励金币改为独立弹窗(展示额度信息)
- 点击「送金币」按钮打开独立弹窗,不再内联在用户名片中
- 弹窗展示 4 格额度信息:单次上限、单日上限、今日已发、剩余额度
- 新增 GET /command/reward-quota 接口(rewardQuota 方法)
  返回当前操作人实时额度,超管返回全部不限
- 发放成功后页面内实时更新今日已发/剩余额度,无需刷新
- 移除原内联奖励面板,action 改为调用全局 openRewardModal()
2026-03-01 11:50:12 +08:00
3d30d7e811 功能:id=1 超管无需职务即可发放奖励金币
前端(frame.blade.php):
- Auth::id()===1 时 myMaxReward=-1(不限),送金币按钮始终显示

后端(AdminCommandController::reward):
- isSuperAdmin=true 时跳过职务检查和①②③④限额校验
- 全局接收次数⑤对超管同样生效(防止刷奖励)
- 履职记录 user_position_id 允许 null(超管无职务时)
- 发放备注改用 positionName 变量(超管显示「超级管理员」)

顺带修复:②操作人单日累计统计之前误查 target_user_id,
已改为正确的 user_id(操作人自己今日已发总额)
2026-03-01 11:43:51 +08:00