Autosave: 20260318-152931
This commit is contained in:
parent
678400ba66
commit
ba0aeb359f
77
admin.php
77
admin.php
@ -10,67 +10,66 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>SMS Chat — 管理后台</title>
|
<title>SMS后台管理</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link href="assets/css/custom.css?v=<?= time() ?>" rel="stylesheet">
|
<link href="assets/css/custom.css?v=<?= time() ?>" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body data-page="admin">
|
<body data-page="admin">
|
||||||
|
<div class="app-admin">
|
||||||
<header class="topbar">
|
<header class="topbar">
|
||||||
<div class="brand">
|
<div class="brand">
|
||||||
<div class="brand-badge">S</div>
|
<div class="brand-logo" style="width: 40px; height: 40px; background: #25D366; color: white; display: flex; align-items: center; justify-content: center; border-radius: 8px; font-weight: bold; font-size: 1.2rem;">S</div>
|
||||||
<div>
|
<div>
|
||||||
SMS Chat
|
<div class="fs-5 fw-bold text-white">SMS后台管理</div>
|
||||||
<div class="small text-muted">管理后台</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="meta">
|
<div class="meta d-flex align-items-center gap-3">
|
||||||
<span class="status-pill">● 系统正常</span>
|
<span class="status-pill text-white"><small>● 系统正常运行</small></span>
|
||||||
<span>管理员:Admin</span>
|
<span class="text-white">管理员:Admin</span>
|
||||||
<a class="btn btn-sm btn-outline-secondary" href="logout.php">退出登录</a>
|
<a class="btn btn-sm btn-outline-light" href="logout.php">退出登录</a>
|
||||||
<a class="btn btn-sm btn-outline-secondary ms-2" href="index.php">返回工作台</a>
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="admin-shell">
|
<main class="admin-shell">
|
||||||
<aside class="admin-sidebar">
|
<aside class="admin-sidebar">
|
||||||
<nav class="nav flex-column">
|
<nav class="nav flex-column gap-1">
|
||||||
<a class="nav-link active" href="#" data-section-link="dashboard">仪表盘</a>
|
<a class="nav-link active" href="#" data-section-link="dashboard">📊 仪表盘</a>
|
||||||
<a class="nav-link" href="#" data-section-link="contacts">客户管理</a>
|
<a class="nav-link" href="#" data-section-link="contacts">👥 客户管理</a>
|
||||||
<a class="nav-link" href="#" data-section-link="messages">消息记录</a>
|
<a class="nav-link" href="#" data-section-link="messages">💬 消息记录</a>
|
||||||
<a class="nav-link" href="#" data-section-link="send">发送短信</a>
|
<a class="nav-link" href="#" data-section-link="send">📤 发送短信</a>
|
||||||
<a class="nav-link" href="#" data-section-link="auto">自动回复</a>
|
<a class="nav-link" href="#" data-section-link="auto">🤖 自动回复</a>
|
||||||
<a class="nav-link" href="#" data-section-link="settings">Twilio 配置</a>
|
<a class="nav-link" href="#" data-section-link="settings">⚙️ Twilio 配置</a>
|
||||||
<a class="nav-link" href="#" data-section-link="system">系统设置</a>
|
<a class="nav-link" href="#" data-section-link="system">🖥 系统设置</a>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<section class="admin-content">
|
<section class="admin-content">
|
||||||
<div class="section-card mb-4" data-section="dashboard">
|
<div class="section-card mb-4" data-section="dashboard">
|
||||||
<h5 class="mb-3">今日概览</h5>
|
<h5 class="mb-3">📊 今日概览</h5>
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="muted">今日发送</div>
|
<div class="text-muted small">今日发送数量</div>
|
||||||
<div class="fs-3 fw-semibold" data-stat="sent">0</div>
|
<div class="fs-3 fw-bold mt-1" data-stat="sent">0</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="muted">今日接收</div>
|
<div class="text-muted small">今日接收数量</div>
|
||||||
<div class="fs-3 fw-semibold" data-stat="received">0</div>
|
<div class="fs-3 fw-bold mt-1" data-stat="received">0</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="muted">活跃客户</div>
|
<div class="text-muted small">活跃客户数</div>
|
||||||
<div class="fs-3 fw-semibold" data-stat="active">0</div>
|
<div class="fs-3 fw-bold mt-1" data-stat="active">0</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-card mb-4 d-none" data-section="contacts">
|
<div class="section-card mb-4 d-none" data-section="contacts">
|
||||||
<h5 class="mb-3">客户管理</h5>
|
<h5 class="mb-3">👥 客户管理</h5>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table align-middle">
|
<table class="table align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
@ -87,7 +86,7 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-card mb-4 d-none" data-section="messages">
|
<div class="section-card mb-4 d-none" data-section="messages">
|
||||||
<h5 class="mb-3">消息记录</h5>
|
<h5 class="mb-3">💬 消息记录</h5>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table align-middle">
|
<table class="table align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
@ -104,7 +103,7 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-card mb-4 d-none" data-section="send">
|
<div class="section-card mb-4 d-none" data-section="send">
|
||||||
<h5 class="mb-3">发送短信</h5>
|
<h5 class="mb-3">📤 发送短信</h5>
|
||||||
<form class="row g-3" data-send-form>
|
<form class="row g-3" data-send-form>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">手机号</label>
|
<label class="form-label">手机号</label>
|
||||||
@ -112,16 +111,16 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<label class="form-label">短信内容</label>
|
<label class="form-label">短信内容</label>
|
||||||
<input class="form-control" name="body" placeholder="输入要发送的短信内容" required>
|
<input class="form-control" name="body" placeholder="输入要发送的内容" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<button class="btn btn-primary px-4" type="submit">发送</button>
|
<button class="btn btn-success px-4" type="submit">发送短信</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-card mb-4 d-none" data-section="auto">
|
<div class="section-card mb-4 d-none" data-section="auto">
|
||||||
<h5 class="mb-3">自动回复</h5>
|
<h5 class="mb-3">🤖 自动回复规则</h5>
|
||||||
<form class="row g-3 mb-4" data-reply-form>
|
<form class="row g-3 mb-4" data-reply-form>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">关键词</label>
|
<label class="form-label">关键词</label>
|
||||||
@ -132,14 +131,14 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
|||||||
<input class="form-control" name="reply" required>
|
<input class="form-control" name="reply" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<button class="btn btn-primary px-4" type="submit">添加规则</button>
|
<button class="btn btn-success px-4" type="submit">添加规则</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<ul class="list-group" data-reply-list></ul>
|
<ul class="list-group" data-reply-list></ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-card mb-4 d-none" data-section="settings">
|
<div class="section-card mb-4 d-none" data-section="settings">
|
||||||
<h5 class="mb-3">Twilio 配置</h5>
|
<h5 class="mb-3">⚙️ Twilio 配置</h5>
|
||||||
<form class="row g-3" data-settings-form>
|
<form class="row g-3" data-settings-form>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">Account SID</label>
|
<label class="form-label">Account SID</label>
|
||||||
@ -158,36 +157,30 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
|||||||
<input class="form-control" name="webhook" placeholder="https://your-domain.com/twilio/webhook">
|
<input class="form-control" name="webhook" placeholder="https://your-domain.com/twilio/webhook">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<button class="btn btn-primary px-4" type="submit">保存配置</button>
|
<button class="btn btn-success px-4" type="submit">保存配置</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-card d-none" data-section="system">
|
<div class="section-card d-none" data-section="system">
|
||||||
<h5 class="mb-3">系统设置</h5>
|
<h5 class="mb-3">🖥 系统设置</h5>
|
||||||
<form class="row g-3" data-system-form>
|
<form class="row g-3" data-system-form>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">刷新频率(秒)</label>
|
<label class="form-label">刷新频率(秒)</label>
|
||||||
<input class="form-control" name="refresh_interval" value="3">
|
<input class="form-control" name="refresh_interval" value="3">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
|
||||||
<label class="form-label">主题</label>
|
|
||||||
<select class="form-select" name="theme">
|
|
||||||
<option value="light">浅色</option>
|
|
||||||
<option value="dark">深色</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">管理员名称</label>
|
<label class="form-label">管理员名称</label>
|
||||||
<input class="form-control" name="admin_name" value="Admin">
|
<input class="form-control" name="admin_name" value="Admin">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<button class="btn btn-primary px-4" type="submit">保存设置</button>
|
<button class="btn btn-success px-4" type="submit">保存设置</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="toast-container"></div>
|
<div class="toast-container"></div>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" defer></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" defer></script>
|
||||||
|
|||||||
@ -1,16 +1,62 @@
|
|||||||
.topbar {
|
/* Wrapper for Frontend */
|
||||||
|
.app-frontend {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.app-frontend .frontend-topbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 1rem 2rem;
|
padding: 0.8rem 2rem;
|
||||||
background: #1f2937;
|
background: #fff;
|
||||||
color: #fff;
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
color: #333;
|
||||||
|
height: 60px;
|
||||||
}
|
}
|
||||||
.brand { display: flex; align-items: center; gap: 10px; }
|
.app-frontend .brand { display: flex; align-items: center; gap: 15px; font-weight: bold; }
|
||||||
.brand-badge { background: #25D366; color: white; padding: 5px 12px; border-radius: 5px; font-weight: bold; }
|
.app-frontend .frontend-app-shell {
|
||||||
.admin-shell { display: flex; min-height: 90vh; background: #f3f4f6; }
|
display: flex;
|
||||||
.admin-sidebar { width: 240px; background: white; padding: 20px; border-right: 1px solid #e5e7eb; }
|
flex: 1;
|
||||||
.admin-content { flex: 1; padding: 20px; }
|
overflow: hidden;
|
||||||
.section-card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
}
|
||||||
.stat-card { padding: 15px; border-radius: 8px; background: #f9fafb; border: 1px solid #e5e7eb; }
|
.app-frontend .contacts-panel { width: 300px; border-right: 1px solid #e5e7eb; padding: 1rem; background: #fff;}
|
||||||
.toast-container { position: fixed; bottom: 20px; right: 20px; }
|
.app-frontend .chat-panel { flex: 1; background: #f8f9fa; display: flex; flex-direction: column;}
|
||||||
|
.app-frontend .frontend-chat-header { padding: 1rem; border-bottom: 1px solid #e5e7eb; background: #fff; }
|
||||||
|
.app-frontend .frontend-chat-body { flex: 1; padding: 1rem; overflow-y: auto; }
|
||||||
|
.app-frontend .frontend-chat-input-wrapper { padding: 1rem; border-top: 1px solid #e5e7eb; background: #fff; }
|
||||||
|
|
||||||
|
/* Wrapper for Admin */
|
||||||
|
.app-admin {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.app-admin .topbar {
|
||||||
|
height: 60px;
|
||||||
|
background: #25D366;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
.app-admin .brand { display: flex; align-items: center; gap: 15px; }
|
||||||
|
.app-admin .admin-shell { display: flex; flex: 1; background: #f3f4f6; }
|
||||||
|
.app-admin .admin-sidebar { width: 260px; background: white; padding: 20px; border-right: 1px solid #e5e7eb; }
|
||||||
|
.app-admin .admin-sidebar .nav-link {
|
||||||
|
color: #374151;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.app-admin .admin-sidebar .nav-link:hover, .app-admin .admin-sidebar .nav-link.active {
|
||||||
|
background: #ecfdf5;
|
||||||
|
color: #059669;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.app-admin .admin-content { flex: 1; padding: 20px; overflow-y: auto; }
|
||||||
|
.app-admin .section-card { background: white; padding: 24px; border-radius: 12px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1); }
|
||||||
|
.app-admin .stat-card { padding: 20px; border-radius: 12px; background: #f9fafb; border: 1px solid #e5e7eb; }
|
||||||
|
.app-admin .btn-success { background-color: #25D366; border-color: #25D366; color: white; }
|
||||||
|
.app-admin .btn-success:hover { background-color: #128C7E; border-color: #128C7E; }
|
||||||
|
.app-admin .toast-container { position: fixed; bottom: 20px; right: 20px; }
|
||||||
@ -28,6 +28,90 @@ const showToast = (message, type = 'success') => {
|
|||||||
setTimeout(() => toast.remove(), 3200);
|
setTimeout(() => toast.remove(), 3200);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const initFrontend = () => {
|
||||||
|
const countrySearch = document.getElementById('countrySearch');
|
||||||
|
const countryList = document.getElementById('countryList');
|
||||||
|
const selectedCode = document.getElementById('selectedCode');
|
||||||
|
const phoneNumber = document.getElementById('phoneNumber');
|
||||||
|
const startChat = document.getElementById('startChat');
|
||||||
|
const shortcutListUI = document.getElementById('shortcutList');
|
||||||
|
const newShortcut = document.getElementById('newShortcut');
|
||||||
|
const addShortcut = document.getElementById('addShortcut');
|
||||||
|
const chatInput = document.querySelector('[data-chat-input]');
|
||||||
|
const shortcutsDisplay = document.querySelector('[data-shortcuts]');
|
||||||
|
const emojiTrigger = document.querySelector('[data-emoji-trigger]');
|
||||||
|
const emojiPicker = document.querySelector('[data-emoji-picker]');
|
||||||
|
|
||||||
|
// Country Search & Selection
|
||||||
|
const renderCountries = (filter = '') => {
|
||||||
|
countryList.innerHTML = countries
|
||||||
|
.filter(c => c.name.includes(filter) || c.code.includes(filter))
|
||||||
|
.map(c => `
|
||||||
|
<div class="p-2 border-bottom" role="button" onclick="selectCountry('${c.name}', '${c.code}')">
|
||||||
|
${c.name} <span class="text-muted">${c.code}</span>
|
||||||
|
</div>
|
||||||
|
`).join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
countrySearch.addEventListener('input', (e) => renderCountries(e.target.value));
|
||||||
|
|
||||||
|
window.selectCountry = (name, code) => {
|
||||||
|
selectedCode.textContent = code;
|
||||||
|
document.getElementById('searchTrigger').textContent = name + ' (' + code + ')';
|
||||||
|
bootstrap.Modal.getInstance(document.getElementById('countryModal')).hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
renderCountries();
|
||||||
|
|
||||||
|
// Shortcuts Management
|
||||||
|
let shortcuts = JSON.parse(localStorage.getItem('shortcuts') || '[]');
|
||||||
|
|
||||||
|
const renderShortcuts = () => {
|
||||||
|
shortcutListUI.innerHTML = shortcuts.map((s, i) => `
|
||||||
|
<li class="list-group-item d-flex justify-content-between">${s}
|
||||||
|
<button class="btn btn-sm btn-danger" onclick="deleteShortcut(${i})">删除</button>
|
||||||
|
</li>
|
||||||
|
`).join('');
|
||||||
|
|
||||||
|
shortcutsDisplay.innerHTML = shortcuts.map(s => `
|
||||||
|
<button class="btn btn-sm btn-outline-info me-1" onclick="insertShortcut('${s}')">${s}</button>
|
||||||
|
`).join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
window.insertShortcut = (text) => chatInput.value += text;
|
||||||
|
window.deleteShortcut = (index) => {
|
||||||
|
shortcuts.splice(index, 1);
|
||||||
|
localStorage.setItem('shortcuts', JSON.stringify(shortcuts));
|
||||||
|
renderShortcuts();
|
||||||
|
};
|
||||||
|
|
||||||
|
addShortcut.addEventListener('click', () => {
|
||||||
|
if (!newShortcut.value) return;
|
||||||
|
shortcuts.push(newShortcut.value);
|
||||||
|
localStorage.setItem('shortcuts', JSON.stringify(shortcuts));
|
||||||
|
newShortcut.value = '';
|
||||||
|
renderShortcuts();
|
||||||
|
});
|
||||||
|
|
||||||
|
renderShortcuts();
|
||||||
|
|
||||||
|
// Emoji Picker
|
||||||
|
emojiTrigger.addEventListener('click', () => emojiPicker.toggleAttribute('hidden'));
|
||||||
|
emojiPicker.addEventListener('emoji-click', (e) => {
|
||||||
|
chatInput.value += e.detail.unicode;
|
||||||
|
emojiPicker.setAttribute('hidden', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start Chat
|
||||||
|
startChat.addEventListener('click', () => {
|
||||||
|
if (!phoneNumber.value) return;
|
||||||
|
const phone = selectedCode.textContent + phoneNumber.value;
|
||||||
|
document.querySelector('[data-chat-title]').textContent = phone;
|
||||||
|
bootstrap.Modal.getInstance(document.getElementById('countryModal')).hide();
|
||||||
|
showToast('已开始与 ' + phone + ' 的聊天');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const initAdmin = () => {
|
const initAdmin = () => {
|
||||||
const navLinks = document.querySelectorAll('[data-section-link]');
|
const navLinks = document.querySelectorAll('[data-section-link]');
|
||||||
const sections = document.querySelectorAll('[data-section]');
|
const sections = document.querySelectorAll('[data-section]');
|
||||||
@ -160,5 +244,6 @@ const initAdmin = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
if (document.body.dataset.page === 'agent') initFrontend();
|
||||||
if (document.body.dataset.page === 'admin') initAdmin();
|
if (document.body.dataset.page === 'admin') initAdmin();
|
||||||
});
|
});
|
||||||
BIN
assets/pasted-20260318-133548-068e767a.png
Normal file
BIN
assets/pasted-20260318-133548-068e767a.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
BIN
assets/pasted-20260318-133754-9e79eb96.png
Normal file
BIN
assets/pasted-20260318-133754-9e79eb96.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
BIN
assets/pasted-20260318-134030-9f06e8f9.png
Normal file
BIN
assets/pasted-20260318-134030-9f06e8f9.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
BIN
assets/pasted-20260318-134348-b5f1b3ad.png
Normal file
BIN
assets/pasted-20260318-134348-b5f1b3ad.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
BIN
assets/pasted-20260318-151658-a33090bb.png
Normal file
BIN
assets/pasted-20260318-151658-a33090bb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
BIN
assets/pasted-20260318-152545-838ae9af.png
Normal file
BIN
assets/pasted-20260318-152545-838ae9af.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
23
index.php
23
index.php
@ -14,19 +14,13 @@ declare(strict_types=1);
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/emoji-picker-element@1.18.10/dist/index.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/emoji-picker-element@1.18.10/dist/index.css" rel="stylesheet">
|
||||||
<link href="assets/css/custom.css?v=<?= time() ?>" rel="stylesheet">
|
<link href="assets/css/custom.css?v=<?= time() ?>" rel="stylesheet">
|
||||||
<style>
|
|
||||||
.country-item { cursor: pointer; padding: 10px; border-bottom: 1px solid #eee; }
|
|
||||||
.country-item:hover { background-color: #f8f9fa; }
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body data-page="agent">
|
<body data-page="agent">
|
||||||
<header class="topbar">
|
<div class="app-frontend">
|
||||||
|
<header class="frontend-topbar">
|
||||||
<div class="brand">
|
<div class="brand">
|
||||||
<img src="assets/pasted-20260318-121747-861d2826.jpg" alt="logo" style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover;" />
|
<img src="assets/pasted-20260318-121747-861d2826.jpg" alt="logo" style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover;" />
|
||||||
<div>
|
|
||||||
SMS短信平台
|
SMS短信平台
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="meta">
|
<div class="meta">
|
||||||
<span class="status-pill">● 在线</span>
|
<span class="status-pill">● 在线</span>
|
||||||
@ -35,23 +29,23 @@ declare(strict_types=1);
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="app-shell">
|
<main class="frontend-app-shell">
|
||||||
<section class="panel contacts-panel">
|
<section class="contacts-panel">
|
||||||
<div class="search d-flex gap-2">
|
<div class="search d-flex gap-2">
|
||||||
<div class="form-control" role="button" id="searchTrigger" data-bs-toggle="modal" data-bs-target="#countryModal" style="cursor: pointer; background: #fff; border: 1px solid #ced4da;">🔍 点击选择国家开始聊天...</div>
|
<div class="form-control" role="button" id="searchTrigger" data-bs-toggle="modal" data-bs-target="#countryModal" style="cursor: pointer; background: #fff; border: 1px solid #ced4da;">🔍 点击选择国家开始聊天...</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="contacts-list" data-contacts></div>
|
<div class="contacts-list" data-contacts></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="panel chat-panel">
|
<section class="chat-panel">
|
||||||
<div class="chat-header">
|
<div class="frontend-chat-header">
|
||||||
<div>
|
<div>
|
||||||
<div class="fw-semibold" data-chat-title>请选择联系人</div>
|
<div class="fw-semibold" data-chat-title>请选择联系人</div>
|
||||||
<div class="small muted" data-chat-meta>状态</div>
|
<div class="small muted" data-chat-meta>状态</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chat-body" data-chat-body></div>
|
<div class="frontend-chat-body" data-chat-body></div>
|
||||||
<div class="chat-input-wrapper">
|
<div class="frontend-chat-input-wrapper">
|
||||||
<div class="shortcut-list mb-2" data-shortcuts></div>
|
<div class="shortcut-list mb-2" data-shortcuts></div>
|
||||||
<div class="chat-input">
|
<div class="chat-input">
|
||||||
<form class="d-flex gap-2 align-items-center" data-chat-form>
|
<form class="d-flex gap-2 align-items-center" data-chat-form>
|
||||||
@ -66,6 +60,7 @@ declare(strict_types=1);
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Country Selection Modal -->
|
<!-- Country Selection Modal -->
|
||||||
<div class="modal fade" id="countryModal" tabindex="-1">
|
<div class="modal fade" id="countryModal" tabindex="-1">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user