Autosave: 20260318-152931
This commit is contained in:
parent
678400ba66
commit
ba0aeb359f
309
admin.php
309
admin.php
@ -10,184 +10,177 @@ if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<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="assets/css/custom.css?v=<?= time() ?>" rel="stylesheet">
|
||||
</head>
|
||||
<body data-page="admin">
|
||||
<header class="topbar">
|
||||
<div class="brand">
|
||||
<div class="brand-badge">S</div>
|
||||
<div>
|
||||
SMS Chat
|
||||
<div class="small text-muted">管理后台</div>
|
||||
<div class="app-admin">
|
||||
<header class="topbar">
|
||||
<div class="brand">
|
||||
<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 class="fs-5 fw-bold text-white">SMS后台管理</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<span class="status-pill">● 系统正常</span>
|
||||
<span>管理员:Admin</span>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="logout.php">退出登录</a>
|
||||
<a class="btn btn-sm btn-outline-secondary ms-2" href="index.php">返回工作台</a>
|
||||
</div>
|
||||
</header>
|
||||
<div class="meta d-flex align-items-center gap-3">
|
||||
<span class="status-pill text-white"><small>● 系统正常运行</small></span>
|
||||
<span class="text-white">管理员:Admin</span>
|
||||
<a class="btn btn-sm btn-outline-light" href="logout.php">退出登录</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="admin-shell">
|
||||
<aside class="admin-sidebar">
|
||||
<nav class="nav flex-column">
|
||||
<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="messages">消息记录</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="settings">Twilio 配置</a>
|
||||
<a class="nav-link" href="#" data-section-link="system">系统设置</a>
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="admin-shell">
|
||||
<aside class="admin-sidebar">
|
||||
<nav class="nav flex-column gap-1">
|
||||
<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="messages">💬 消息记录</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="settings">⚙️ Twilio 配置</a>
|
||||
<a class="nav-link" href="#" data-section-link="system">🖥 系统设置</a>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<section class="admin-content">
|
||||
<div class="section-card mb-4" data-section="dashboard">
|
||||
<h5 class="mb-3">今日概览</h5>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<div class="stat-card">
|
||||
<div class="muted">今日发送</div>
|
||||
<div class="fs-3 fw-semibold" data-stat="sent">0</div>
|
||||
<section class="admin-content">
|
||||
<div class="section-card mb-4" data-section="dashboard">
|
||||
<h5 class="mb-3">📊 今日概览</h5>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<div class="stat-card">
|
||||
<div class="text-muted small">今日发送数量</div>
|
||||
<div class="fs-3 fw-bold mt-1" data-stat="sent">0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="stat-card">
|
||||
<div class="muted">今日接收</div>
|
||||
<div class="fs-3 fw-semibold" data-stat="received">0</div>
|
||||
<div class="col-md-4">
|
||||
<div class="stat-card">
|
||||
<div class="text-muted small">今日接收数量</div>
|
||||
<div class="fs-3 fw-bold mt-1" data-stat="received">0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="stat-card">
|
||||
<div class="muted">活跃客户</div>
|
||||
<div class="fs-3 fw-semibold" data-stat="active">0</div>
|
||||
<div class="col-md-4">
|
||||
<div class="stat-card">
|
||||
<div class="text-muted small">活跃客户数</div>
|
||||
<div class="fs-3 fw-bold mt-1" data-stat="active">0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-card mb-4 d-none" data-section="contacts">
|
||||
<h5 class="mb-3">客户管理</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>手机号</th>
|
||||
<th>标签</th>
|
||||
<th>状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-admin-contacts></tbody>
|
||||
</table>
|
||||
<div class="section-card mb-4 d-none" data-section="contacts">
|
||||
<h5 class="mb-3">👥 客户管理</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>手机号</th>
|
||||
<th>标签</th>
|
||||
<th>状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-admin-contacts></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-card mb-4 d-none" data-section="messages">
|
||||
<h5 class="mb-3">消息记录</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>手机号</th>
|
||||
<th>方向</th>
|
||||
<th>内容</th>
|
||||
<th>时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-admin-messages></tbody>
|
||||
</table>
|
||||
<div class="section-card mb-4 d-none" data-section="messages">
|
||||
<h5 class="mb-3">💬 消息记录</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>手机号</th>
|
||||
<th>方向</th>
|
||||
<th>内容</th>
|
||||
<th>时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-admin-messages></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-card mb-4 d-none" data-section="send">
|
||||
<h5 class="mb-3">发送短信</h5>
|
||||
<form class="row g-3" data-send-form>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">手机号</label>
|
||||
<input class="form-control" name="phone" placeholder="+86 138 0013 8000" required>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">短信内容</label>
|
||||
<input class="form-control" name="body" placeholder="输入要发送的短信内容" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary px-4" type="submit">发送</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="section-card mb-4 d-none" data-section="send">
|
||||
<h5 class="mb-3">📤 发送短信</h5>
|
||||
<form class="row g-3" data-send-form>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">手机号</label>
|
||||
<input class="form-control" name="phone" placeholder="+86 138 0013 8000" required>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">短信内容</label>
|
||||
<input class="form-control" name="body" placeholder="输入要发送的内容" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-success px-4" type="submit">发送短信</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="section-card mb-4 d-none" data-section="auto">
|
||||
<h5 class="mb-3">自动回复</h5>
|
||||
<form class="row g-3 mb-4" data-reply-form>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">关键词</label>
|
||||
<input class="form-control" name="keyword" required>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">回复内容</label>
|
||||
<input class="form-control" name="reply" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary px-4" type="submit">添加规则</button>
|
||||
</div>
|
||||
</form>
|
||||
<ul class="list-group" data-reply-list></ul>
|
||||
</div>
|
||||
<div class="section-card mb-4 d-none" data-section="auto">
|
||||
<h5 class="mb-3">🤖 自动回复规则</h5>
|
||||
<form class="row g-3 mb-4" data-reply-form>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">关键词</label>
|
||||
<input class="form-control" name="keyword" required>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">回复内容</label>
|
||||
<input class="form-control" name="reply" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-success px-4" type="submit">添加规则</button>
|
||||
</div>
|
||||
</form>
|
||||
<ul class="list-group" data-reply-list></ul>
|
||||
</div>
|
||||
|
||||
<div class="section-card mb-4 d-none" data-section="settings">
|
||||
<h5 class="mb-3">Twilio 配置</h5>
|
||||
<form class="row g-3" data-settings-form>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Account SID</label>
|
||||
<input class="form-control" name="sid" placeholder="ACxxxxxxxx">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Auth Token</label>
|
||||
<input class="form-control" name="token" placeholder="••••••••">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">From 号码</label>
|
||||
<input class="form-control" name="from" placeholder="+14155550199">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Webhook 地址</label>
|
||||
<input class="form-control" name="webhook" placeholder="https://your-domain.com/twilio/webhook">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary px-4" type="submit">保存配置</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="section-card mb-4 d-none" data-section="settings">
|
||||
<h5 class="mb-3">⚙️ Twilio 配置</h5>
|
||||
<form class="row g-3" data-settings-form>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Account SID</label>
|
||||
<input class="form-control" name="sid" placeholder="ACxxxxxxxx">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Auth Token</label>
|
||||
<input class="form-control" name="token" placeholder="••••••••">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">From 号码</label>
|
||||
<input class="form-control" name="from" placeholder="+14155550199">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Webhook 地址</label>
|
||||
<input class="form-control" name="webhook" placeholder="https://your-domain.com/twilio/webhook">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-success px-4" type="submit">保存配置</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="section-card d-none" data-section="system">
|
||||
<h5 class="mb-3">系统设置</h5>
|
||||
<form class="row g-3" data-system-form>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">刷新频率(秒)</label>
|
||||
<input class="form-control" name="refresh_interval" value="3">
|
||||
</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">
|
||||
<label class="form-label">管理员名称</label>
|
||||
<input class="form-control" name="admin_name" value="Admin">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary px-4" type="submit">保存设置</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<div class="section-card d-none" data-section="system">
|
||||
<h5 class="mb-3">🖥 系统设置</h5>
|
||||
<form class="row g-3" data-system-form>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">刷新频率(秒)</label>
|
||||
<input class="form-control" name="refresh_interval" value="3">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">管理员名称</label>
|
||||
<input class="form-control" name="admin_name" value="Admin">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-success px-4" type="submit">保存设置</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</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>
|
||||
|
||||
@ -1,16 +1,62 @@
|
||||
.topbar {
|
||||
/* Wrapper for Frontend */
|
||||
.app-frontend {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.app-frontend .frontend-topbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem 2rem;
|
||||
background: #1f2937;
|
||||
color: #fff;
|
||||
padding: 0.8rem 2rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
color: #333;
|
||||
height: 60px;
|
||||
}
|
||||
.brand { display: flex; align-items: center; gap: 10px; }
|
||||
.brand-badge { background: #25D366; color: white; padding: 5px 12px; border-radius: 5px; font-weight: bold; }
|
||||
.admin-shell { display: flex; min-height: 90vh; background: #f3f4f6; }
|
||||
.admin-sidebar { width: 240px; background: white; padding: 20px; border-right: 1px solid #e5e7eb; }
|
||||
.admin-content { flex: 1; padding: 20px; }
|
||||
.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; }
|
||||
.toast-container { position: fixed; bottom: 20px; right: 20px; }
|
||||
.app-frontend .brand { display: flex; align-items: center; gap: 15px; font-weight: bold; }
|
||||
.app-frontend .frontend-app-shell {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.app-frontend .contacts-panel { width: 300px; border-right: 1px solid #e5e7eb; padding: 1rem; background: #fff;}
|
||||
.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);
|
||||
};
|
||||
|
||||
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 navLinks = document.querySelectorAll('[data-section-link]');
|
||||
const sections = document.querySelectorAll('[data-section]');
|
||||
@ -160,5 +244,6 @@ const initAdmin = () => {
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (document.body.dataset.page === 'agent') initFrontend();
|
||||
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 |
83
index.php
83
index.php
@ -14,58 +14,53 @@ 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/emoji-picker-element@1.18.10/dist/index.css" 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>
|
||||
<body data-page="agent">
|
||||
<header class="topbar">
|
||||
<div class="brand">
|
||||
<img src="assets/pasted-20260318-121747-861d2826.jpg" alt="logo" style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover;" />
|
||||
<div>
|
||||
<div class="app-frontend">
|
||||
<header class="frontend-topbar">
|
||||
<div class="brand">
|
||||
<img src="assets/pasted-20260318-121747-861d2826.jpg" alt="logo" style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover;" />
|
||||
SMS短信平台
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<span class="status-pill">● 在线</span>
|
||||
<span>客服:Lina</span>
|
||||
<button class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#settingsModal">⚙️ 设置</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="app-shell">
|
||||
<section class="panel contacts-panel">
|
||||
<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="meta">
|
||||
<span class="status-pill">● 在线</span>
|
||||
<span>客服:Lina</span>
|
||||
<button class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#settingsModal">⚙️ 设置</button>
|
||||
</div>
|
||||
<div class="contacts-list" data-contacts></div>
|
||||
</section>
|
||||
</header>
|
||||
|
||||
<section class="panel chat-panel">
|
||||
<div class="chat-header">
|
||||
<div>
|
||||
<div class="fw-semibold" data-chat-title>请选择联系人</div>
|
||||
<div class="small muted" data-chat-meta>状态</div>
|
||||
<main class="frontend-app-shell">
|
||||
<section class="contacts-panel">
|
||||
<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>
|
||||
</div>
|
||||
<div class="chat-body" data-chat-body></div>
|
||||
<div class="chat-input-wrapper">
|
||||
<div class="shortcut-list mb-2" data-shortcuts></div>
|
||||
<div class="chat-input">
|
||||
<form class="d-flex gap-2 align-items-center" data-chat-form>
|
||||
<div class="position-relative">
|
||||
<button class="btn btn-light border" type="button" data-emoji-trigger>😊</button>
|
||||
<emoji-picker class="position-absolute" style="bottom: 100%; left: 0; z-index: 1000;" data-emoji-picker></emoji-picker>
|
||||
</div>
|
||||
<input class="form-control" placeholder="输入短信内容..." data-chat-input />
|
||||
<button class="btn btn-primary px-4" type="submit">发送</button>
|
||||
</form>
|
||||
<div class="contacts-list" data-contacts></div>
|
||||
</section>
|
||||
|
||||
<section class="chat-panel">
|
||||
<div class="frontend-chat-header">
|
||||
<div>
|
||||
<div class="fw-semibold" data-chat-title>请选择联系人</div>
|
||||
<div class="small muted" data-chat-meta>状态</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<div class="frontend-chat-body" data-chat-body></div>
|
||||
<div class="frontend-chat-input-wrapper">
|
||||
<div class="shortcut-list mb-2" data-shortcuts></div>
|
||||
<div class="chat-input">
|
||||
<form class="d-flex gap-2 align-items-center" data-chat-form>
|
||||
<div class="position-relative">
|
||||
<button class="btn btn-light border" type="button" data-emoji-trigger>😊</button>
|
||||
<emoji-picker class="position-absolute" style="bottom: 100%; left: 0; z-index: 1000;" data-emoji-picker></emoji-picker>
|
||||
</div>
|
||||
<input class="form-control" placeholder="输入短信内容..." data-chat-input />
|
||||
<button class="btn btn-primary px-4" type="submit">发送</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Country Selection Modal -->
|
||||
<div class="modal fade" id="countryModal" tabindex="-1">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user