- 完成对 scripts.blade.php 中非核心业务逻辑(钓鱼游戏、AI机器人、系统全局公告)的深度抽象隔离 - 修复抢红包逻辑中 setInterval 缺失时间参数(1000)引发浏览器前端主线程挂起的重度阻塞问题 - 修复 lottery-panel 组件结尾漏写 </div> 导致的连锁级渲染树崩溃(该崩溃导致红包节点被意外当作隐藏后代节点渲染,造成彻底不可见) - 对相关模板规范代码结构,执行 Laravel Pint 格式化并提交
129 lines
6.0 KiB
PHP
129 lines
6.0 KiB
PHP
<script>
|
||
// ══════════════════════════════════════════
|
||
// 任命公告:复用现有礼花特效 + 隆重弹窗
|
||
// ══════════════════════════════════════════
|
||
|
||
/**
|
||
* 显示任命公告弹窗(居中,5 秒后淡出)
|
||
*/
|
||
/**
|
||
* 显示任命公告弹窗(改用 chatBanner 公共组件)。
|
||
*
|
||
* @param {Object} data 任命数据:type, target_username, position_icon, position_name, department_name, operator_name
|
||
*/
|
||
function showAppointmentBanner(data) {
|
||
const dept = data.department_name ? escapeHtml(data.department_name) + ' · ' : '';
|
||
const isRevoke = data.type === 'revoke';
|
||
|
||
if (isRevoke) {
|
||
window.chatBanner.show({
|
||
id: 'appointment-banner',
|
||
icon: '📋',
|
||
title: '职务撤销',
|
||
name: `${escapeHtml(data.position_icon)} ${escapeHtml(data.target_username)}`,
|
||
body: `<strong style="color:#f3f4f6;">${dept}${escapeHtml(data.position_name)}</strong> 职务已被撤销`,
|
||
sub: `由 ${escapeHtml(data.operator_name)} 执行`,
|
||
gradient: ['#374151', '#4b5563', '#6b7280'],
|
||
titleColor: '#d1d5db',
|
||
autoClose: 4500,
|
||
});
|
||
} else {
|
||
window.chatBanner.show({
|
||
id: 'appointment-banner',
|
||
icon: '🎊🎖️🎊',
|
||
title: '任命公告',
|
||
name: `${escapeHtml(data.position_icon)} ${escapeHtml(data.target_username)}`,
|
||
body: `荣任 <strong style="color:#fde68a;">${dept}${escapeHtml(data.position_name)}</strong>`,
|
||
sub: `由 ${escapeHtml(data.operator_name)} 任命`,
|
||
gradient: ['#4f46e5', '#7c3aed', '#db2777'],
|
||
titleColor: '#fde68a',
|
||
autoClose: 4500,
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 监听任命公告事件:根据 type 区分任命(礼花+紫色弹窗)和撤销(灰色弹窗)
|
||
*/
|
||
window.addEventListener('chat:appointment-announced', (e) => {
|
||
const data = e.detail;
|
||
const isRevoke = data.type === 'revoke';
|
||
const dept = data.department_name ? escapeHtml(data.department_name) + ' · ' : '';
|
||
|
||
// ── 任命才有礼花 ──
|
||
if (!isRevoke && typeof EffectManager !== 'undefined') {
|
||
EffectManager.play('fireworks');
|
||
}
|
||
|
||
showAppointmentBanner(data);
|
||
|
||
// ── 聊天区系统消息:操作者/被操作者 → 私聊面板;其余人 → 公屏 ──
|
||
const now = new Date();
|
||
const timeStr = now.getHours().toString().padStart(2, '0') + ':' +
|
||
now.getMinutes().toString().padStart(2, '0') + ':' +
|
||
now.getSeconds().toString().padStart(2, '0');
|
||
|
||
const myName = window.chatContext?.username ?? '';
|
||
const isInvolved = myName === data.operator_name || myName === data.target_username;
|
||
|
||
// 随机鼓励语库
|
||
const appointPhrases = [
|
||
'望再接再厉,大展宏图,为大家服务!',
|
||
'期待在任期间带领大家更上一层楼!',
|
||
'众望所归,任重道远,加油!',
|
||
'新官上任,一展风采,前程似锦!',
|
||
'相信你能胜任,期待你的精彩表现!',
|
||
];
|
||
const revokePhrases = [
|
||
'感谢在任期间的辛勤付出,辛苦了!',
|
||
'江湖路长,愿前程似锦,未来可期!',
|
||
'感谢您为大家的奉献,一路顺风!',
|
||
'在任一场,情谊长存,感谢付出!',
|
||
'相信以后还有更多精彩,继续加油!',
|
||
];
|
||
const randomPhrase = isRevoke ?
|
||
revokePhrases[Math.floor(Math.random() * revokePhrases.length)] :
|
||
appointPhrases[Math.floor(Math.random() * appointPhrases.length)];
|
||
|
||
// 构建消息 DOM(内容相同,分配到不同面板)
|
||
function buildSysMsg() {
|
||
const sysDiv = document.createElement('div');
|
||
sysDiv.className = 'msg-line';
|
||
if (isRevoke) {
|
||
sysDiv.style.cssText =
|
||
'background:#f3f4f6; border-left:3px solid #9ca3af; border-radius:4px; padding:4px 10px; margin:2px 0;';
|
||
sysDiv.innerHTML =
|
||
`<span style="color:#6b7280;">📋 </span>` +
|
||
`<span style="color:#374151;"><b>${escapeHtml(data.target_username)}</b> 的 ${escapeHtml(data.position_icon)} ${dept}${escapeHtml(data.position_name)} 职务已被 <b>${escapeHtml(data.operator_name)}</b> 撤销。${randomPhrase}</span>` +
|
||
`<span class="msg-time">(${timeStr})</span>`;
|
||
} else {
|
||
sysDiv.style.cssText =
|
||
'background:#f5f3ff; border-left:3px solid #7c3aed; border-radius:4px; padding:4px 10px; margin:2px 0;';
|
||
sysDiv.innerHTML =
|
||
`<span style="color:#7c3aed;">🎖️ </span>` +
|
||
`<span style="color:#3730a3;">恭喜 <b>${escapeHtml(data.target_username)}</b> 荣任 ${escapeHtml(data.position_icon)} ${dept}<b>${escapeHtml(data.position_name)}</b>,由 <b>${escapeHtml(data.operator_name)}</b> 任命。${randomPhrase}</span>` +
|
||
`<span class="msg-time">(${timeStr})</span>`;
|
||
}
|
||
return sysDiv;
|
||
}
|
||
|
||
const say1 = document.getElementById('chat-messages-container');
|
||
const say2 = document.getElementById('chat-messages-container2');
|
||
|
||
if (isInvolved) {
|
||
// 操作者 / 被操作者:消息进私聊面板(包厢窗口)
|
||
if (say2) {
|
||
say2.appendChild(buildSysMsg());
|
||
say2.scrollTop = say2.scrollHeight;
|
||
}
|
||
} else {
|
||
// 其他人:消息进公屏
|
||
if (say1) {
|
||
say1.appendChild(buildSysMsg());
|
||
say1.scrollTop = say1.scrollHeight;
|
||
}
|
||
}
|
||
});
|
||
</script>
|