1033 lines
33 KiB
PHP
1033 lines
33 KiB
PHP
{{--
|
|
文件功能:和平聊吧登录首页(全屏军旅版)
|
|
说明:展示军旅海报主视觉、战友登录表单与房间选择,并保留原有登录交互逻辑
|
|
--}}
|
|
@php
|
|
$systemName = \App\Models\SysParam::where('alias', 'sys_name')->value('body') ?? '和平聊吧';
|
|
$systemNotice = \App\Models\SysParam::where('alias', 'sys_notice')->value('body') ?? '欢迎归队,第一次登录即为注册,请妥善保管密码。';
|
|
$smtpEnabled = \App\Models\SysParam::where('alias', 'smtp_enabled')->value('body') === '1';
|
|
$roomCount = count($rooms);
|
|
$defaultRoom = $rooms[0] ?? null;
|
|
$heroImage = asset('images/veteran-hero.jpg');
|
|
@endphp
|
|
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{{ $systemName }}</title>
|
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700;900&family=Noto+Serif+SC:wght@700;900&family=Oswald:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--bg: #0d0f0d;
|
|
--panel: #ded3bd;
|
|
--panel-soft: #ece3d1;
|
|
--text: #1b1a15;
|
|
--text-soft: #5f5b4f;
|
|
--border: rgba(71, 58, 36, 0.22);
|
|
--red: #7d231c;
|
|
--red-deep: #57140f;
|
|
--gold: #c6a35b;
|
|
--khaki: #5c654f;
|
|
--line: rgba(255, 255, 255, 0.08);
|
|
--success: #34553e;
|
|
--danger: #8f2e27;
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
height: 100%;
|
|
}
|
|
|
|
body {
|
|
font-family: "Noto Sans SC", "Microsoft YaHei", sans-serif;
|
|
background:
|
|
radial-gradient(circle at 10% 16%, rgba(198, 163, 91, 0.13), transparent 24%),
|
|
radial-gradient(circle at 90% 86%, rgba(125, 35, 28, 0.14), transparent 22%),
|
|
linear-gradient(145deg, #090b09, #161915 46%, #0c0d0c 100%);
|
|
color: var(--text);
|
|
padding: 16px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
body::before {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
background-image:
|
|
linear-gradient(var(--line) 1px, transparent 1px),
|
|
linear-gradient(90deg, var(--line) 1px, transparent 1px);
|
|
background-size: 26px 26px;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.shell {
|
|
width: min(1440px, 100%);
|
|
height: min(920px, calc(100svh - 32px));
|
|
margin: 0 auto;
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1.28fr) minmax(420px, 0.72fr);
|
|
border: 1px solid rgba(198, 163, 91, 0.28);
|
|
background: rgba(7, 8, 7, 0.92);
|
|
box-shadow: 0 26px 70px rgba(0, 0, 0, 0.4);
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.shell::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 8px;
|
|
border: 1px solid rgba(198, 163, 91, 0.14);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.poster {
|
|
position: relative;
|
|
padding: 26px 30px 24px;
|
|
display: grid;
|
|
grid-template-rows: auto 1fr auto;
|
|
overflow: hidden;
|
|
color: #f7f1e1;
|
|
background:
|
|
linear-gradient(90deg, rgba(4, 5, 4, 0.92) 0%, rgba(4, 5, 4, 0.78) 26%, rgba(6, 7, 6, 0.42) 58%, rgba(73, 18, 15, 0.3) 100%),
|
|
linear-gradient(180deg, rgba(9, 10, 8, 0.1), rgba(9, 10, 8, 0.76)),
|
|
linear-gradient(135deg, rgba(198, 163, 91, 0.12), transparent 30%),
|
|
linear-gradient(220deg, rgba(125, 35, 28, 0.18), transparent 30%),
|
|
url('{{ $heroImage }}') center center / cover no-repeat,
|
|
#060707;
|
|
}
|
|
|
|
.poster::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
background:
|
|
radial-gradient(circle at center, rgba(198, 163, 91, 0.08), transparent 42%),
|
|
repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.018) 0, rgba(255, 255, 255, 0.018) 1px, transparent 1px, transparent 96px);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.poster::after {
|
|
content: "93";
|
|
position: absolute;
|
|
right: 18px;
|
|
bottom: -10px;
|
|
font-family: "Oswald", sans-serif;
|
|
font-size: clamp(150px, 18vw, 250px);
|
|
line-height: 0.85;
|
|
color: rgba(198, 163, 91, 0.08);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.poster > * {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.poster-top {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 16px;
|
|
}
|
|
|
|
.poster-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 10px 14px;
|
|
border: 1px solid rgba(255, 241, 210, 0.24);
|
|
background: rgba(0, 0, 0, 0.34);
|
|
font-size: 12px;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.poster-badge svg {
|
|
width: 18px;
|
|
height: 18px;
|
|
color: var(--gold);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.poster-code {
|
|
text-align: right;
|
|
font-family: "Oswald", sans-serif;
|
|
font-size: 12px;
|
|
line-height: 1.55;
|
|
letter-spacing: 0.16em;
|
|
color: rgba(247, 241, 225, 0.72);
|
|
}
|
|
|
|
.poster-main {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
max-width: 650px;
|
|
}
|
|
|
|
.poster-stamp {
|
|
position: absolute;
|
|
top: 18px;
|
|
right: -26px;
|
|
border: 1px solid rgba(198, 163, 91, 0.42);
|
|
color: rgba(198, 163, 91, 0.96);
|
|
padding: 8px 14px;
|
|
transform: rotate(12deg);
|
|
font-family: "Oswald", sans-serif;
|
|
font-size: 13px;
|
|
letter-spacing: 0.14em;
|
|
background: rgba(0, 0, 0, 0.28);
|
|
}
|
|
|
|
.poster-copy {
|
|
max-width: 560px;
|
|
}
|
|
|
|
.poster-kicker {
|
|
display: inline-block;
|
|
padding: 8px 14px;
|
|
background: linear-gradient(90deg, var(--red), rgba(125, 35, 28, 0.6));
|
|
border-left: 4px solid var(--gold);
|
|
font-size: 12px;
|
|
letter-spacing: 0.18em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.poster-title {
|
|
margin-top: 18px;
|
|
font-family: "Noto Serif SC", serif;
|
|
font-size: clamp(56px, 6vw, 88px);
|
|
line-height: 1.02;
|
|
letter-spacing: 0.04em;
|
|
text-shadow: 0 10px 26px rgba(0, 0, 0, 0.34);
|
|
}
|
|
|
|
.poster-lead {
|
|
margin-top: 16px;
|
|
font-size: clamp(18px, 2vw, 28px);
|
|
line-height: 1.5;
|
|
color: rgba(247, 241, 225, 0.95);
|
|
}
|
|
|
|
.poster-story {
|
|
margin-top: 18px;
|
|
max-width: 520px;
|
|
padding-left: 16px;
|
|
border-left: 3px solid rgba(198, 163, 91, 0.7);
|
|
font-size: 15px;
|
|
line-height: 1.9;
|
|
color: rgba(247, 241, 225, 0.8);
|
|
}
|
|
|
|
.poster-points {
|
|
margin-top: 22px;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
}
|
|
|
|
.poster-point {
|
|
padding: 10px 14px;
|
|
border: 1px solid rgba(255, 241, 210, 0.16);
|
|
background: rgba(12, 14, 12, 0.48);
|
|
font-size: 13px;
|
|
line-height: 1.4;
|
|
color: rgba(247, 241, 225, 0.88);
|
|
}
|
|
|
|
.poster-bottom {
|
|
display: grid;
|
|
gap: 12px;
|
|
align-self: end;
|
|
}
|
|
|
|
.poster-notice {
|
|
width: min(100%, 700px);
|
|
padding: 12px 14px;
|
|
border-left: 4px solid var(--gold);
|
|
background: linear-gradient(90deg, rgba(17, 14, 12, 0.88), rgba(17, 14, 12, 0.36));
|
|
font-size: 13px;
|
|
line-height: 1.8;
|
|
color: rgba(247, 241, 225, 0.88);
|
|
}
|
|
|
|
.poster-meta {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
width: min(100%, 700px);
|
|
font-size: 11px;
|
|
line-height: 1.6;
|
|
color: rgba(247, 241, 225, 0.66);
|
|
}
|
|
|
|
.poster-meta a {
|
|
color: rgba(245, 217, 159, 0.96);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.poster-meta a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.panel {
|
|
position: relative;
|
|
display: grid;
|
|
grid-template-rows: auto auto 1fr auto;
|
|
gap: 14px;
|
|
padding: 24px 24px 18px;
|
|
background:
|
|
linear-gradient(180deg, rgba(18, 18, 17, 0.96), rgba(33, 25, 20, 0.96)),
|
|
radial-gradient(circle at 8% 12%, rgba(198, 163, 91, 0.08), transparent 28%),
|
|
repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.025) 0, rgba(255, 255, 255, 0.025) 1px, transparent 1px, transparent 32px);
|
|
color: #f2eadc;
|
|
overflow: hidden;
|
|
border-left: 1px solid rgba(198, 163, 91, 0.16);
|
|
}
|
|
|
|
.panel::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 6px;
|
|
background: linear-gradient(90deg, var(--red-deep), var(--gold), var(--khaki));
|
|
}
|
|
|
|
.panel-header {
|
|
border-bottom: 1px solid rgba(198, 163, 91, 0.18);
|
|
padding-bottom: 14px;
|
|
}
|
|
|
|
.panel-header small {
|
|
display: block;
|
|
font-family: "Oswald", sans-serif;
|
|
font-size: 11px;
|
|
letter-spacing: 0.2em;
|
|
color: rgba(198, 163, 91, 0.74);
|
|
}
|
|
|
|
.panel-header h2 {
|
|
margin-top: 6px;
|
|
font-family: "Noto Serif SC", serif;
|
|
font-size: clamp(34px, 4vw, 48px);
|
|
line-height: 1.08;
|
|
color: #f6efe2;
|
|
}
|
|
|
|
.panel-header p {
|
|
margin-top: 10px;
|
|
font-size: 13px;
|
|
line-height: 1.7;
|
|
color: rgba(242, 234, 220, 0.68);
|
|
}
|
|
|
|
#alert-box {
|
|
display: none;
|
|
padding: 10px 12px;
|
|
border-left: 4px solid transparent;
|
|
font-size: 13px;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.alert-error {
|
|
background: rgba(143, 46, 39, 0.08);
|
|
border-color: var(--danger);
|
|
color: var(--danger);
|
|
}
|
|
|
|
.alert-success {
|
|
background: rgba(52, 85, 62, 0.08);
|
|
border-color: var(--success);
|
|
color: var(--success);
|
|
}
|
|
|
|
.login-form {
|
|
display: grid;
|
|
grid-template-rows: auto auto auto auto auto auto;
|
|
gap: 12px;
|
|
min-height: 0;
|
|
align-content: start;
|
|
}
|
|
|
|
.field-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 10px;
|
|
}
|
|
|
|
.field-block label,
|
|
.field-title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 6px;
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
color: rgba(246, 239, 226, 0.94);
|
|
}
|
|
|
|
.field-index {
|
|
min-width: 24px;
|
|
font-family: "Oswald", sans-serif;
|
|
font-size: 12px;
|
|
letter-spacing: 0.12em;
|
|
color: rgba(198, 163, 91, 0.74);
|
|
}
|
|
|
|
.field-input,
|
|
.field-select {
|
|
width: 100%;
|
|
height: 48px;
|
|
padding: 0 14px;
|
|
border: 1px solid rgba(198, 163, 91, 0.24);
|
|
background: rgba(255, 248, 236, 0.06);
|
|
color: #f5eee0;
|
|
font-size: 14px;
|
|
transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
|
|
.field-select {
|
|
appearance: none;
|
|
background-image:
|
|
linear-gradient(45deg, transparent 50%, #b6a27c 50%),
|
|
linear-gradient(135deg, #b6a27c 50%, transparent 50%);
|
|
background-position:
|
|
calc(100% - 20px) 21px,
|
|
calc(100% - 14px) 21px;
|
|
background-size: 6px 6px, 6px 6px;
|
|
background-repeat: no-repeat;
|
|
padding-right: 38px;
|
|
}
|
|
|
|
.field-input::placeholder {
|
|
color: rgba(242, 234, 220, 0.42);
|
|
}
|
|
|
|
.field-input:focus,
|
|
.field-select:focus {
|
|
outline: none;
|
|
border-color: rgba(198, 163, 91, 0.56);
|
|
background: rgba(255, 248, 236, 0.1);
|
|
box-shadow: 0 0 0 3px rgba(198, 163, 91, 0.08);
|
|
}
|
|
|
|
.captcha-row {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) 150px;
|
|
gap: 10px;
|
|
}
|
|
|
|
.captcha-image {
|
|
width: 100%;
|
|
height: 48px;
|
|
border: 1px solid rgba(198, 163, 91, 0.24);
|
|
background: rgba(255, 248, 236, 0.96);
|
|
object-fit: cover;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.gender-row {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 10px;
|
|
}
|
|
|
|
.gender-option {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
height: 48px;
|
|
padding: 0 14px;
|
|
border: 1px solid rgba(198, 163, 91, 0.24);
|
|
background: rgba(255, 248, 236, 0.06);
|
|
cursor: pointer;
|
|
transition: border-color 0.2s ease, background-color 0.2s ease;
|
|
}
|
|
|
|
.gender-option:hover {
|
|
border-color: rgba(198, 163, 91, 0.52);
|
|
background: rgba(255, 248, 236, 0.1);
|
|
}
|
|
|
|
.gender-option.selected {
|
|
border-color: rgba(198, 163, 91, 0.62);
|
|
background: linear-gradient(90deg, rgba(125, 35, 28, 0.18), rgba(255, 248, 236, 0.08));
|
|
}
|
|
|
|
.gender-option input {
|
|
accent-color: var(--red);
|
|
}
|
|
|
|
.room-hint {
|
|
margin-top: 6px;
|
|
font-size: 12px;
|
|
line-height: 1.6;
|
|
color: rgba(242, 234, 220, 0.54);
|
|
}
|
|
|
|
.action-row {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) 136px;
|
|
gap: 10px;
|
|
}
|
|
|
|
.btn {
|
|
height: 52px;
|
|
border: 1px solid transparent;
|
|
font-size: 16px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.04em;
|
|
cursor: pointer;
|
|
transition: filter 0.2s ease, transform 0.2s ease, background-color 0.2s ease;
|
|
}
|
|
|
|
.btn:focus-visible {
|
|
outline: 2px solid rgba(125, 35, 28, 0.58);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: linear-gradient(90deg, var(--red-deep), var(--red), #8d342d);
|
|
color: #f6eddc;
|
|
border-top: 2px solid rgba(234, 212, 170, 0.46);
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
transform: translateY(-1px);
|
|
filter: brightness(1.04);
|
|
}
|
|
|
|
.btn-secondary {
|
|
background: rgba(255, 248, 236, 0.05);
|
|
border-color: rgba(198, 163, 91, 0.24);
|
|
color: rgba(246, 239, 226, 0.88);
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
background: rgba(255, 248, 236, 0.09);
|
|
}
|
|
|
|
.btn:disabled {
|
|
opacity: 0.65;
|
|
cursor: not-allowed;
|
|
transform: none;
|
|
filter: none;
|
|
}
|
|
|
|
.panel-footer {
|
|
display: grid;
|
|
gap: 6px;
|
|
align-self: end;
|
|
font-size: 12px;
|
|
line-height: 1.6;
|
|
color: rgba(242, 234, 220, 0.6);
|
|
}
|
|
|
|
.panel-footer a {
|
|
color: rgba(222, 109, 96, 0.98);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.panel-footer a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.site-credit {
|
|
font-family: "Oswald", sans-serif;
|
|
font-size: 13px;
|
|
letter-spacing: 0.08em;
|
|
color: rgba(198, 163, 91, 0.6);
|
|
}
|
|
|
|
@media (max-width: 1180px) {
|
|
.shell {
|
|
height: auto;
|
|
min-height: calc(100svh - 32px);
|
|
grid-template-columns: 1fr;
|
|
grid-template-rows: minmax(280px, 34svh) auto;
|
|
}
|
|
|
|
.poster {
|
|
min-height: 0;
|
|
}
|
|
|
|
.panel {
|
|
grid-template-rows: auto auto auto auto;
|
|
min-height: 0;
|
|
overflow: visible;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 760px) {
|
|
body {
|
|
padding: 10px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.shell {
|
|
height: auto;
|
|
min-height: calc(100svh - 20px);
|
|
grid-template-rows: minmax(250px, 31svh) auto;
|
|
}
|
|
|
|
.poster {
|
|
padding: 18px 18px 16px;
|
|
}
|
|
|
|
.poster::after {
|
|
font-size: 118px;
|
|
right: 10px;
|
|
bottom: -6px;
|
|
}
|
|
|
|
.poster-top {
|
|
gap: 10px;
|
|
}
|
|
|
|
.poster-badge {
|
|
padding: 8px 10px;
|
|
font-size: 11px;
|
|
letter-spacing: 0.08em;
|
|
}
|
|
|
|
.poster-code {
|
|
font-size: 10px;
|
|
}
|
|
|
|
.poster-stamp {
|
|
top: auto;
|
|
right: 0;
|
|
bottom: 6px;
|
|
transform: rotate(0deg);
|
|
font-size: 11px;
|
|
padding: 6px 10px;
|
|
}
|
|
|
|
.poster-title {
|
|
margin-top: 12px;
|
|
font-size: clamp(40px, 14vw, 58px);
|
|
}
|
|
|
|
.poster-lead {
|
|
margin-top: 10px;
|
|
font-size: 16px;
|
|
line-height: 1.45;
|
|
}
|
|
|
|
.poster-story {
|
|
margin-top: 10px;
|
|
font-size: 13px;
|
|
line-height: 1.7;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.poster-points {
|
|
margin-top: 12px;
|
|
gap: 8px;
|
|
}
|
|
|
|
.poster-point {
|
|
padding: 8px 10px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.poster-notice,
|
|
.poster-meta {
|
|
width: 100%;
|
|
}
|
|
|
|
.poster-notice {
|
|
padding: 10px 12px;
|
|
font-size: 12px;
|
|
line-height: 1.7;
|
|
}
|
|
|
|
.poster-meta {
|
|
font-size: 10px;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 4px;
|
|
}
|
|
|
|
.panel {
|
|
padding: 16px 16px 14px;
|
|
gap: 10px;
|
|
overflow: visible;
|
|
grid-template-rows: auto auto auto auto;
|
|
}
|
|
|
|
.panel-header {
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.panel-header p {
|
|
margin-top: 8px;
|
|
font-size: 12px;
|
|
line-height: 1.55;
|
|
}
|
|
|
|
.field-grid,
|
|
.gender-row {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.login-form {
|
|
gap: 10px;
|
|
}
|
|
|
|
.field-block label,
|
|
.field-title {
|
|
margin-bottom: 5px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.field-input,
|
|
.field-select,
|
|
.captcha-image,
|
|
.gender-option,
|
|
.btn {
|
|
height: 44px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.captcha-row {
|
|
grid-template-columns: minmax(0, 1fr) 124px;
|
|
}
|
|
|
|
.action-row {
|
|
grid-template-columns: minmax(0, 1fr) 110px;
|
|
}
|
|
|
|
.panel-footer {
|
|
gap: 4px;
|
|
font-size: 11px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.site-credit {
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
|
|
@media (max-height: 820px) and (min-width: 761px) {
|
|
.poster {
|
|
padding: 22px 24px 18px;
|
|
}
|
|
|
|
.poster-title {
|
|
font-size: clamp(46px, 5vw, 72px);
|
|
}
|
|
|
|
.poster-lead {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.poster-story {
|
|
margin-top: 14px;
|
|
font-size: 14px;
|
|
line-height: 1.75;
|
|
}
|
|
|
|
.poster-points {
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.panel {
|
|
padding: 18px 18px 14px;
|
|
gap: 10px;
|
|
}
|
|
|
|
.panel-header h2 {
|
|
font-size: 36px;
|
|
}
|
|
|
|
.field-input,
|
|
.field-select,
|
|
.captcha-image,
|
|
.gender-option,
|
|
.btn {
|
|
height: 44px;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
animation: none !important;
|
|
transition: none !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<main class="shell">
|
|
<section class="poster">
|
|
<div class="poster-top">
|
|
<div class="poster-badge">
|
|
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
<path d="M12 3L14.6 8.27L20.42 9.11L16.21 13.22L17.21 19L12 16.26L6.79 19L7.79 13.22L3.58 9.11L9.4 8.27L12 3Z" fill="currentColor" />
|
|
</svg>
|
|
Veteran Reunion Channel
|
|
</div>
|
|
<div class="poster-code">
|
|
<div>FILE NO. HC-093</div>
|
|
<div>RETURN TO CHANNEL</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="poster-main">
|
|
<div class="poster-copy">
|
|
<div class="poster-kicker">退伍不褪色 · 离队不离心</div>
|
|
<h1 class="poster-title">{{ $systemName }}</h1>
|
|
<p class="poster-lead">这是一个给复原老兵的聊天室,不追求花哨,只留下熟悉的劲头和说话方式。</p>
|
|
<p class="poster-story">
|
|
从军营里建立,到回地方后重新用 PHP 写回来。战友进来,不是游客,是归队。
|
|
</p>
|
|
<div class="poster-points">
|
|
<span class="poster-point">军旅记忆</span>
|
|
<span class="poster-point">战友情义</span>
|
|
<span class="poster-point">老兵归队</span>
|
|
</div>
|
|
</div>
|
|
<div class="poster-stamp">AUTHORIZED VETERAN</div>
|
|
</div>
|
|
|
|
<div class="poster-bottom">
|
|
<div class="poster-notice">{{ $systemNotice }}</div>
|
|
<div class="poster-meta">
|
|
<span>左侧主视觉已固定为你提供的图片,并做了轻度清晰度增强处理。</span>
|
|
<span>首页当前只使用这一张图。</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="panel">
|
|
<div class="panel-header">
|
|
<small>VETERAN ACCESS FORM</small>
|
|
<h2>战友登录</h2>
|
|
<p>主视觉已固定,验证通过后直接进入房间。</p>
|
|
</div>
|
|
|
|
<div id="alert-box" aria-live="polite"></div>
|
|
|
|
<form id="login-form" class="login-form">
|
|
<div class="field-grid">
|
|
<div class="field-block">
|
|
<label for="username"><span class="field-index">01</span>昵称</label>
|
|
<input class="field-input" type="text" id="username" name="username" maxlength="10" placeholder="中英文、数字、下划线" required>
|
|
</div>
|
|
<div class="field-block">
|
|
<label for="password"><span class="field-index">02</span>密码</label>
|
|
<input class="field-input" type="password" id="password" name="password" maxlength="20" placeholder="请输入密码" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field-block">
|
|
<label for="captcha"><span class="field-index">03</span>验证码</label>
|
|
<div class="captcha-row">
|
|
<input class="field-input" type="text" id="captcha" name="captcha" maxlength="10" placeholder="输入验证码" required>
|
|
<img src="/captcha/default?{{ mt_rand() }}" alt="验证码" id="captcha-img" class="captcha-image" onclick="refreshCaptcha()" title="点击刷新验证码">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field-block">
|
|
<div class="field-title"><span class="field-index">04</span>性别</div>
|
|
<div class="gender-row">
|
|
<label class="gender-option selected">
|
|
<input type="radio" name="bSex" value="1" checked>
|
|
男
|
|
</label>
|
|
<label class="gender-option">
|
|
<input type="radio" name="bSex" value="2">
|
|
女
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field-block">
|
|
<label for="room_id"><span class="field-index">05</span>选择房间</label>
|
|
<select class="field-select" id="room_id" name="room_id" {{ $roomCount === 0 ? 'disabled' : '' }}>
|
|
@forelse ($rooms as $room)
|
|
<option value="{{ $room->id }}" data-room-name="{{ $room->name }}" data-room-owner="{{ $room->master ?: '未设置' }}" {{ $loop->first ? 'selected' : '' }}>
|
|
{{ $room->name }}
|
|
</option>
|
|
@empty
|
|
<option value="">暂无可用房间</option>
|
|
@endforelse
|
|
</select>
|
|
<div id="room-hint" class="room-hint">
|
|
@if ($defaultRoom)
|
|
当前房间:{{ $defaultRoom->name }} / 房主:{{ $defaultRoom->master ?: '未设置' }}
|
|
@else
|
|
当前暂无可用房间,请联系管理员。
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<div class="action-row">
|
|
<button type="submit" id="submit-btn" class="btn btn-primary" {{ $roomCount === 0 ? 'disabled' : '' }}>进入和平聊吧</button>
|
|
<button type="reset" class="btn btn-secondary">重填</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="panel-footer">
|
|
<div>第一次登录即为注册,请妥善保管密码。当前共 {{ $roomCount }} 个房间。</div>
|
|
@if ($smtpEnabled)
|
|
<div><a href="javascript:alert('邮箱找回密码业务即将上线...');">忘了密码?点击通过邮箱找回</a></div>
|
|
@endif
|
|
<div>
|
|
推荐浏览器:
|
|
<a href="https://www.microsoft.com/zh-cn/edge/download" target="_blank" rel="noopener noreferrer">Edge</a>
|
|
/
|
|
<a href="https://www.google.com/chrome/" target="_blank" rel="noopener noreferrer">Chrome</a>
|
|
</div>
|
|
<div class="site-credit">POWERED BY 流星 · {{ date('Y') }}</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<script>
|
|
function refreshCaptcha() {
|
|
document.getElementById('captcha-img').src = '/captcha/default?' + Math.random();
|
|
}
|
|
|
|
function syncSelectedState() {
|
|
document.querySelectorAll('.gender-option').forEach(function(option) {
|
|
const input = option.querySelector('input[type="radio"]');
|
|
option.classList.toggle('selected', Boolean(input && input.checked));
|
|
});
|
|
}
|
|
|
|
function updateRoomHint() {
|
|
const roomSelect = document.getElementById('room_id');
|
|
const hint = document.getElementById('room-hint');
|
|
|
|
if (!roomSelect || !hint || roomSelect.selectedIndex < 0) {
|
|
return;
|
|
}
|
|
|
|
const selectedOption = roomSelect.options[roomSelect.selectedIndex];
|
|
const roomName = selectedOption.getAttribute('data-room-name') || selectedOption.text;
|
|
const roomOwner = selectedOption.getAttribute('data-room-owner') || '未设置';
|
|
|
|
hint.textContent = '当前房间:' + roomName + ' / 房主:' + roomOwner;
|
|
}
|
|
|
|
document.querySelectorAll('.gender-option input[type="radio"]').forEach(function(input) {
|
|
input.addEventListener('change', syncSelectedState);
|
|
});
|
|
|
|
const roomSelect = document.getElementById('room_id');
|
|
if (roomSelect) {
|
|
roomSelect.addEventListener('change', updateRoomHint);
|
|
}
|
|
|
|
syncSelectedState();
|
|
updateRoomHint();
|
|
|
|
document.getElementById('login-form').addEventListener('submit', function(event) {
|
|
event.preventDefault();
|
|
|
|
const button = document.getElementById('submit-btn');
|
|
const formData = new FormData(this);
|
|
const data = Object.fromEntries(formData.entries());
|
|
const roomId = data.room_id || '1';
|
|
|
|
button.disabled = true;
|
|
button.innerText = '正在进入...';
|
|
showAlert('', 'error', false);
|
|
|
|
fetch('{{ route('login.post') }}', {
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
|
'Accept': 'application/json',
|
|
},
|
|
body: JSON.stringify(data),
|
|
})
|
|
.then(function(response) {
|
|
return response.json().then(function(body) {
|
|
return {
|
|
status: response.status,
|
|
body: body,
|
|
};
|
|
});
|
|
})
|
|
.then(function(result) {
|
|
if (result.status === 419 || (result.body && result.body.message === 'CSRF token mismatch.')) {
|
|
showAlert('安全令牌已过期,正在刷新页面...', 'error', true);
|
|
setTimeout(function() {
|
|
window.location.reload();
|
|
}, 1500);
|
|
return;
|
|
}
|
|
|
|
if (result.status === 200 && result.body.status === 'success') {
|
|
showAlert(result.body.message, 'success', true);
|
|
const chatUrl = '/room/' + roomId;
|
|
const chatWindow = window.open(
|
|
chatUrl,
|
|
'chatroom',
|
|
'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes'
|
|
);
|
|
|
|
if (chatWindow) {
|
|
chatWindow.moveTo(0, 0);
|
|
chatWindow.resizeTo(screen.availWidth, screen.availHeight);
|
|
chatWindow.focus();
|
|
}
|
|
|
|
setTimeout(function() {
|
|
window.location.href = '/rooms';
|
|
}, 1500);
|
|
} else {
|
|
const errorMessage =
|
|
result.body.message ||
|
|
(result.body.errors ? Object.values(result.body.errors)[0][0] : '登录失败,请稍后再试。');
|
|
showAlert(errorMessage, 'error', true);
|
|
refreshCaptcha();
|
|
document.getElementById('captcha').value = '';
|
|
button.disabled = false;
|
|
button.innerText = '进入和平聊吧';
|
|
}
|
|
})
|
|
.catch(function() {
|
|
showAlert('网络或服务器异常,请稍后再试。', 'error', true);
|
|
refreshCaptcha();
|
|
button.disabled = false;
|
|
button.innerText = '进入和平聊吧';
|
|
});
|
|
});
|
|
|
|
function showAlert(message, type, visible) {
|
|
const alertBox = document.getElementById('alert-box');
|
|
alertBox.textContent = message;
|
|
alertBox.className = type === 'success' ? 'alert-success' : 'alert-error';
|
|
alertBox.id = 'alert-box';
|
|
alertBox.style.display = visible ? 'block' : 'none';
|
|
}
|
|
</script>
|
|
</body>
|
|
|
|
</html>
|