Files
chatroom/resources/views/chat/partials/layout/input-bar.blade.php

358 lines
21 KiB
PHP
Raw 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.
{{--
文件功能:聊天室底部输入工具栏(两行结构)
第一行:发送对象、动作、字色、悄悄话、滚屏、分屏、管理操作
第二行:输入框 + 发送按钮
frame.blade.php 拆分,便于独立维护
依赖变量:$user, $room, $levelKick, $levelMute, $levelBan, $levelBanip
--}}
<div class="input-bar">
<form id="chat-form" onsubmit="sendMessage(event)">
{{-- 第一行:工具选项 --}}
<div class="input-row">
<label>
<select id="to_user" name="to_user" style="color: #224466;">
<option value="大家" selected>大家</option>
</select>
:
</label>
<label>动作:
<select id="action" name="action">
<option value=""></option>
<option value="微笑">微笑</option>
<option value="大笑">大笑</option>
<option value="愤怒">愤怒</option>
<option value="哭泣">哭泣</option>
<option value="害羞">害羞</option>
<option value="鄙视">鄙视</option>
<option value="得意">得意</option>
<option value="疑惑">疑惑</option>
<option value="同情">同情</option>
<option value="无奈">无奈</option>
<option value="拳打">拳打</option>
<option value="飞吻">飞吻</option>
<option value="偷看">偷看</option>
{{-- 欢迎语专用 action隐藏不对外显示JS 临时切换用 --}}
<option value="欢迎" style="display:none"></option>
</select>
</label>
<label>字色:
<input type="color" id="font_color" name="font_color" value="{{ $user->s_color ?? '#000000' }}"
style="width: 22px; height: 18px; padding: 0; border: 1px solid navy; cursor: pointer;">
</label>
<label>字号:
<select id="font_size_select" style="color: #224466;" onchange="applyFontSize(this.value)">
<option value="12">12</option>
<option value="13">13</option>
<option value="14" selected>14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="18">18</option>
<option value="20">20</option>
<option value="22">22</option>
</select>
</label>
<label title="仅对方和自己可见">
<input type="checkbox" id="is_secret" name="is_secret" value="1">
悄悄话
</label>
<label title="勾选后关闭所有特效声音">
<input type="checkbox" id="sound_muted" onchange="toggleSoundMute(this.checked)">
🔇 禁音
</label>
<label title="自动滚屏到最新消息">
<input type="checkbox" id="auto_scroll" checked>
滚屏
</label>
{{-- 欢迎语快捷按钮 + 下拉浮层 --}}
<div style="position:relative;display:inline-block;" id="welcome-btn-wrap">
<button type="button" onclick="toggleWelcomeMenu(event)"
style="font-size:11px;padding:1px 6px;background:#e07820;color:#fff;border:none;border-radius:2px;cursor:pointer;">
💬 欢迎
</button>
<div id="welcome-menu" class="welcome-menu" style="display:none;">
@php
$welcomeMessages = [
'欢迎【{name}】来到我们的聊天室,请遵守规则,文明聊天!',
'【{name}】,你好!欢迎来访,有什么问题随时告诉我们!',
'热烈欢迎【{name}】加入,愿您在这里度过愉快的时光!',
'欢迎新朋友【{name}】!请先阅读公告,了解聊天室规则哦~',
'【{name}】来了!欢迎欢迎,希望你在这里玩得开心!',
'亲爱的【{name}】,欢迎光临本聊天室,请保持文明礼貌!',
'欢迎【{name}】入驻!有问题请联系管理员,我们随时为您服务!',
'【{name}】,初来乍到,欢迎多多关照,我们是一家人!',
'大家欢迎新成员【{name}】!请遵守群规,共建和谐聊天环境!',
'欢迎【{name}】莅临指导!希望你常来,让我们一起聊天!',
];
@endphp
@foreach ($welcomeMessages as $msg)
<div class="welcome-menu-item" onclick="sendWelcomeTpl({{ json_encode($msg) }})">
{{ $msg }}</div>
@endforeach
</div>
</div>
@if (
$user->user_level >= (int) \App\Models\Sysparam::getValue('level_announcement', '10') ||
$room->master == $user->username)
<button type="button" onclick="promptAnnouncement()"
style="font-size: 11px; padding: 1px 6px; background: #4a9; color: #fff; border: none; border-radius: 2px; cursor: pointer;">设公告</button>
@endif
<button type="button" id="fishing-btn" onclick="startFishing()"
style="font-size: 11px; padding: 1px 6px; background: #2563eb; color: #fff; border: none; border-radius: 2px; cursor: pointer;">🎣
钓鱼</button>
@if ($user->user_level >= (int) \App\Models\Sysparam::getValue('superlevel', '100'))
<button type="button" onclick="promptAnnounceMessage()"
style="font-size: 11px; padding: 1px 6px; background: #7c3aed; color: #fff; border: none; border-radius: 2px; cursor: pointer;">📢
公屏</button>
<button type="button" onclick="adminClearScreen()"
style="font-size: 11px; padding: 1px 6px; background: #dc2626; color: #fff; border: none; border-radius: 2px; cursor: pointer;">🧹
清屏</button>
<button type="button" id="red-packet-btn" onclick="sendRedPacket()"
style="font-size: 11px; padding: 1px 6px; background: linear-gradient(135deg, #dc2626, #d97706); color: #fff; border: none; border-radius: 2px; cursor: pointer; font-weight: bold;">🧧
礼包</button>
<button type="button" onclick="openAdminBaccaratLossCoverModal()"
style="font-size: 11px; padding: 1px 6px; background: linear-gradient(135deg, #15803d, #22c55e); color: #fff; border: none; border-radius: 2px; cursor: pointer; font-weight: bold;">🎁
买单活动</button>
{{-- 全屏特效按钮组(仅管理员可见) --}}
<button type="button" onclick="triggerEffect('fireworks')" title="全屏烟花"
style="font-size: 11px; padding: 1px 6px; background: #ea580c; color: #fff; border: none; border-radius: 2px; cursor: pointer;">🎆
烟花</button>
<button type="button" onclick="triggerEffect('rain')" title="全屏下雨"
style="font-size: 11px; padding: 1px 6px; background: #2563eb; color: #fff; border: none; border-radius: 2px; cursor: pointer;">🌧️
下雨</button>
<button type="button" onclick="triggerEffect('lightning')" title="全屏雷电"
style="font-size: 11px; padding: 1px 6px; background: #7c3aed; color: #fff; border: none; border-radius: 2px; cursor: pointer;">
雷电</button>
<button type="button" onclick="triggerEffect('snow')" title="全屏下雪"
style="font-size: 11px; padding: 1px 6px; background: #0891b2; color: #fff; border: none; border-radius: 2px; cursor: pointer;">❄️
下雪</button>
@endif
<button type="button" onclick="localClearScreen()"
style="font-size: 11px; padding: 1px 6px; background: #64748b; color: #fff; border: none; border-radius: 2px; cursor: pointer;">🔄
清屏</button>
</div>
{{-- 第二行:输入框 + 发送 --}}
<div class="input-row">
<input type="text" id="content" name="content" class="say-input"
placeholder="在这里输入聊天内容,按 Enter 发送..." autocomplete="off">
<button type="submit" id="send-btn" class="send-btn">发送</button>
</div>
</form>
</div>
@if ($user->user_level >= (int) \App\Models\Sysparam::getValue('superlevel', '100'))
<div id="baccarat-loss-cover-admin-modal"
style="display:none; position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:10010; justify-content:center; align-items:center;">
<div
style="width:560px; max-width:96vw; max-height:88vh; overflow:hidden; border-radius:8px; background:#fff; box-shadow:0 8px 32px rgba(0,0,0,.3); display:flex; flex-direction:column;">
<div
style="background:linear-gradient(135deg,#15803d,#22c55e); color:#fff; padding:12px 16px; display:flex; justify-content:space-between; align-items:center;">
<div>
<div style="font-size:14px; font-weight:bold;">🎁 买单活动设置</div>
<div style="font-size:11px; color:rgba(255,255,255,.85); margin-top:2px;">创建百家乐“你玩游戏我买单”活动,并查看当前状态</div>
</div>
<span onclick="closeAdminBaccaratLossCoverModal()"
style="cursor:pointer; font-size:18px; opacity:.85;">&times;</span>
</div>
<div style="flex:1; overflow-y:auto; padding:16px; background:#f6fff8;">
<div id="blc-admin-current"
style="background:#fff; border:1px solid #dcfce7; border-radius:10px; padding:14px; color:#166534; margin-bottom:14px;">
正在加载当前活动…
</div>
<form id="baccarat-loss-cover-admin-form" onsubmit="submitBaccaratLossCoverEvent(event)"
style="background:#fff; border:1px solid #dcfce7; border-radius:10px; padding:14px;">
<div style="font-size:13px; font-weight:bold; color:#166534; margin-bottom:12px;">新建活动</div>
<div style="display:flex; flex-direction:column; gap:10px;">
<div>
<label style="display:block; font-size:12px; color:#4b5563; margin-bottom:4px;">活动标题</label>
<input type="text" id="blc-admin-title" maxlength="100" value="你玩游戏我买单"
style="width:100%; box-sizing:border-box; padding:8px 10px; border:1px solid #bbf7d0; border-radius:8px; font-size:12px;">
</div>
<div>
<label style="display:block; font-size:12px; color:#4b5563; margin-bottom:4px;">活动说明</label>
<textarea id="blc-admin-description" rows="3"
style="width:100%; box-sizing:border-box; padding:8px 10px; border:1px solid #bbf7d0; border-radius:8px; font-size:12px; resize:vertical;">活动期间参与百家乐,赢得归个人,输掉的金币可在活动结束后领取补偿。</textarea>
</div>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:10px;">
<div>
<label style="display:block; font-size:12px; color:#4b5563; margin-bottom:4px;">开始时间</label>
<input type="datetime-local" id="blc-admin-starts-at"
style="width:100%; box-sizing:border-box; padding:8px 10px; border:1px solid #bbf7d0; border-radius:8px; font-size:12px;">
</div>
<div>
<label style="display:block; font-size:12px; color:#4b5563; margin-bottom:4px;">结束时间</label>
<input type="datetime-local" id="blc-admin-ends-at"
style="width:100%; box-sizing:border-box; padding:8px 10px; border:1px solid #bbf7d0; border-radius:8px; font-size:12px;">
</div>
</div>
<div>
<label style="display:block; font-size:12px; color:#4b5563; margin-bottom:4px;">领取截止时间</label>
<input type="datetime-local" id="blc-admin-claim-deadline-at"
style="width:100%; box-sizing:border-box; padding:8px 10px; border:1px solid #bbf7d0; border-radius:8px; font-size:12px;">
</div>
</div>
<div style="display:flex; gap:8px; justify-content:flex-end; margin-top:14px;">
<button type="button" onclick="closeAdminBaccaratLossCoverModal()"
style="padding:8px 16px; border:none; border-radius:8px; background:#dcfce7; color:#166534; font-size:12px; font-weight:bold; cursor:pointer;">
关闭
</button>
<button type="submit"
style="padding:8px 16px; border:none; border-radius:8px; background:#16a34a; color:#fff; font-size:12px; font-weight:bold; cursor:pointer;">
创建活动
</button>
</div>
</form>
</div>
</div>
</div>
<script>
(function() {
const SUMMARY_URL = '{{ route('baccarat-loss-cover.summary') }}';
const STORE_URL = '{{ route('command.baccarat_loss_cover.store') }}';
function formatDateInput(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day}T${hour}:${minute}`;
}
async function loadAdminCurrentLossCoverEvent() {
const box = document.getElementById('blc-admin-current');
box.innerHTML = '正在加载当前活动…';
try {
const response = await fetch(SUMMARY_URL, {
headers: {
'Accept': 'application/json'
}
});
const data = await response.json();
const event = data.event;
if (!event) {
box.innerHTML = '<div style="font-size:12px; color:#4b5563;">当前没有进行中、待开始或待领取的买单活动。</div>';
return;
}
const closeButton = ['scheduled', 'active', 'settlement_pending'].includes(event.status) ?
`<button type="button" onclick="closeCurrentBaccaratLossCoverEvent(${event.id})" style="margin-top:10px; padding:7px 14px; border:none; border-radius:999px; background:#dc2626; color:#fff; font-size:12px; font-weight:bold; cursor:pointer;">立即结束</button>` :
'';
box.innerHTML = `
<div style="display:flex; justify-content:space-between; gap:10px; align-items:flex-start;">
<div style="flex:1;">
<div style="font-size:15px; font-weight:bold; color:#166534;">${event.title}</div>
<div style="font-size:12px; color:#4b5563; margin-top:4px;">开启人:${event.creator_username}</div>
</div>
<span style="padding:4px 10px; border-radius:999px; background:#dcfce7; color:#166534; font-size:12px; font-weight:bold;">${event.status_label}</span>
</div>
<div style="margin-top:10px; font-size:12px; color:#4b5563; line-height:1.7;">
活动时间:${new Date(event.starts_at).toLocaleString('zh-CN')} - ${new Date(event.ends_at).toLocaleString('zh-CN')}<br>
最终已发补偿:${Number(event.total_claimed_amount || 0).toLocaleString()} 金币
</div>
${closeButton}
`;
} catch (error) {
box.innerHTML = '<div style="font-size:12px; color:#dc2626;">当前活动加载失败,请稍后再试。</div>';
}
}
window.openAdminBaccaratLossCoverModal = async function() {
const now = new Date();
const end = new Date(now.getTime() + 30 * 60 * 1000);
const claimDeadline = new Date(end.getTime() + 24 * 60 * 60 * 1000);
document.getElementById('blc-admin-starts-at').value = formatDateInput(now);
document.getElementById('blc-admin-ends-at').value = formatDateInput(end);
document.getElementById('blc-admin-claim-deadline-at').value = formatDateInput(claimDeadline);
document.getElementById('baccarat-loss-cover-admin-modal').style.display = 'flex';
await loadAdminCurrentLossCoverEvent();
};
window.closeAdminBaccaratLossCoverModal = function() {
document.getElementById('baccarat-loss-cover-admin-modal').style.display = 'none';
};
window.submitBaccaratLossCoverEvent = async function(event) {
event.preventDefault();
const payload = {
title: document.getElementById('blc-admin-title').value,
description: document.getElementById('blc-admin-description').value,
starts_at: document.getElementById('blc-admin-starts-at').value,
ends_at: document.getElementById('blc-admin-ends-at').value,
claim_deadline_at: document.getElementById('blc-admin-claim-deadline-at').value,
};
try {
const response = await fetch(STORE_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || '',
},
body: JSON.stringify(payload)
});
const data = await response.json();
if (data.ok) {
await window.chatDialog?.alert(data.message || '活动创建成功', '系统通知', '#16a34a');
await loadAdminCurrentLossCoverEvent();
return;
}
await window.chatDialog?.alert(data.message || '活动创建失败', '提示', '#f59e0b');
} catch (error) {
await window.chatDialog?.alert('活动创建失败,请稍后重试。', '提示', '#dc2626');
}
};
window.closeCurrentBaccaratLossCoverEvent = async function(eventId) {
try {
const response = await fetch(`/command/baccarat-loss-cover/${eventId}/close`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || '',
}
});
const data = await response.json();
await window.chatDialog?.alert(data.message || '活动状态已更新', '系统通知', '#16a34a');
await loadAdminCurrentLossCoverEvent();
} catch (error) {
await window.chatDialog?.alert('活动关闭失败,请稍后重试。', '提示', '#dc2626');
}
};
document.getElementById('baccarat-loss-cover-admin-modal').addEventListener('click', function(event) {
if (event.target === this) {
closeAdminBaccaratLossCoverModal();
}
});
})();
</script>
@endif