2025-08-21 09:36:11 +08:00

3258 lines
142 KiB
HTML
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.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>闲鱼自动回复管理系统</title>
<link rel="stylesheet" href="/static/lib/bootstrap/bootstrap.min.css">
<link rel="stylesheet" href="/static/lib/bootstrap-icons/bootstrap-icons.css">
<link rel="stylesheet" href="/static/css/app.css">
</head>
<body>
<!-- 移动端菜单切换按钮 -->
<button class="mobile-toggle" onclick="toggleSidebar()">
<i class="bi bi-list"></i>
</button>
<!-- 侧边栏 -->
<div class="sidebar" id="sidebar">
<div class="sidebar-header">
<a href="#" class="sidebar-brand">
<i class="bi bi-chat-dots-fill me-2"></i>
闲鱼管理系统
</a>
</div>
<nav class="sidebar-nav">
<div class="nav-item">
<a href="#" class="nav-link active" onclick="showSection('dashboard')">
<i class="bi bi-speedometer2"></i>
仪表盘
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('accounts')">
<i class="bi bi-person-circle"></i>
账号管理
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('items')">
<i class="bi bi-box-seam"></i>
商品管理
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('orders')">
<i class="bi bi-receipt-cutoff"></i>
订单管理
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('auto-reply')">
<i class="bi bi-chat-left-text"></i>
自动回复
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('items-reply')">
<i class="bi bi-chat-left-text"></i>
指定商品回复
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('cards')">
<i class="bi bi-credit-card"></i>
卡券管理
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('auto-delivery')">
<i class="bi bi-truck"></i>
自动发货
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('notification-channels')">
<i class="bi bi-bell"></i>
通知渠道
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('message-notifications')">
<i class="bi bi-chat-dots"></i>
消息通知
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('item-search')">
<i class="bi bi-search"></i>
商品搜索
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('system-settings')">
<i class="bi bi-gear"></i>
系统设置
</a>
</div>
<!-- 管理员专用菜单 -->
<div id="adminMenuSection" style="display: none;">
<div class="nav-divider mt-3 mb-2">
<small class="text-white-50">管理员功能</small>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('user-management')">
<i class="bi bi-people"></i>
用户管理
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('logs')">
<i class="bi bi-file-text-fill"></i>
系统日志
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('data-management')">
<i class="bi bi-database"></i>
数据管理
</a>
</div>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="showSection('about')">
<i class="bi bi-info-circle"></i>
关于
</a>
</div>
<!-- 底部分隔符 -->
<div class="nav-divider mt-3 mb-2">
<small class="text-white-50">系统操作</small>
</div>
<div class="nav-item">
<a href="#" class="nav-link" onclick="logout()">
<i class="bi bi-box-arrow-right"></i>
登出
</a>
</div>
</nav>
</div>
<!-- 主内容区域 -->
<div class="main-content">
<!-- 仪表盘内容 -->
<div id="dashboard-section" class="content-section active">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-speedometer2 me-2"></i>
仪表盘
</h2>
<p class="text-muted mb-0">系统概览和统计信息</p>
</div>
<div class="content-body">
<div class="dashboard-stats">
<div class="stat-card">
<div class="stat-icon primary">
<i class="bi bi-person-circle"></i>
</div>
<div class="stat-number" id="totalAccounts">0</div>
<div class="stat-label">总账号数</div>
</div>
<div class="stat-card">
<div class="stat-icon success">
<i class="bi bi-chat-left-text"></i>
</div>
<div class="stat-number" id="totalKeywords">0</div>
<div class="stat-label">总关键词数</div>
</div>
<div class="stat-card">
<div class="stat-icon warning">
<i class="bi bi-activity"></i>
</div>
<div class="stat-number" id="activeAccounts">0</div>
<div class="stat-label">启用账号数</div>
</div>
<div class="stat-card">
<div class="stat-icon info">
<i class="bi bi-receipt-cutoff"></i>
</div>
<div class="stat-number" id="totalOrders">0</div>
<div class="stat-label">总订单数</div>
</div>
</div>
<!-- 账号详情列表 -->
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="bi bi-list-ul me-2"></i>
账号详情
</h5>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th>账号ID</th>
<th>关键词数量</th>
<th>状态</th>
<th>最后更新</th>
</tr>
</thead>
<tbody id="dashboardAccountsList">
<!-- 动态生成 -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 账号管理内容 -->
<div id="accounts-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-person-circle me-2"></i>
账号管理
</h2>
<p class="text-muted mb-0">管理闲鱼账号Cookie信息</p>
</div>
<div class="content-body">
<!-- 添加Cookie卡片 -->
<div class="card mb-4">
<div class="card-header">
<span><i class="bi bi-plus-circle me-2"></i>添加新账号</span>
</div>
<div class="card-body">
<!-- 添加方式选择 -->
<div class="row mb-4">
<div class="col-12">
<div class="d-grid gap-2 d-md-flex justify-content-md-center">
<button type="button" class="btn btn-success btn-lg me-md-2 flex-fill qr-login-btn" onclick="showQRCodeLogin()" style="max-width: 300px;">
<i class="bi bi-qr-code me-2"></i>
<span class="fw-bold">扫码登录</span>
<br>
<small class="opacity-75">推荐方式,安全便捷</small>
</button>
<button type="button" class="btn btn-outline-secondary btn-lg flex-fill manual-input-btn" onclick="toggleManualInput()" style="max-width: 300px;">
<i class="bi bi-keyboard me-2"></i>
<span class="fw-bold">手动输入</span>
<br>
<small class="opacity-75">输入Cookie信息</small>
</button>
</div>
</div>
</div>
<!-- 手动输入表单(默认隐藏) -->
<div id="manualInputForm" style="display: none;">
<div class="alert alert-info">
<i class="bi bi-info-circle me-2"></i>
<strong>提示:</strong>推荐使用扫码登录更加安全便捷。如需手动输入请确保Cookie信息的准确性。
</div>
<form id="addForm" class="row g-3">
<div class="col-md-3">
<label for="cookieId" class="form-label">账号ID</label>
<input type="text" class="form-control" id="cookieId" placeholder="唯一标识" required>
</div>
<div class="col-md-9">
<label for="cookieValue" class="form-label">Cookie值</label>
<input type="text" class="form-control" id="cookieValue" placeholder="完整Cookie字符串" required>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">
<i class="bi bi-plus-lg me-1"></i>添加账号
</button>
<button type="button" class="btn btn-secondary ms-2" onclick="toggleManualInput()">
<i class="bi bi-x-circle me-1"></i>取消
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Cookie列表卡片 -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span><i class="bi bi-list-ul me-2"></i>账号列表</span>
<div class="btn-group">
<button class="btn btn-sm btn-outline-success" onclick="openDefaultReplyManager()">
<i class="bi bi-chat-text me-1"></i>默认回复管理
</button>
<button class="btn btn-sm btn-outline-primary" onclick="loadCookies()">
<i class="bi bi-arrow-clockwise me-1"></i>刷新
</button>
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover" id="cookieTable">
<thead>
<tr>
<th style="width: 9%">账号ID</th>
<th style="width: 14%">Cookie值</th>
<th style="width: 7%">关键词</th>
<th style="width: 7%">状态</th>
<th style="width: 8%">默认回复</th>
<th style="width: 8%">AI回复</th>
<th style="width: 9%">自动确认发货</th>
<th style="width: 10%">备注</th>
<th style="width: 10%">
暂停时间
<i class="bi bi-question-circle ms-1"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="检测到手动发出消息后,自动回复暂停的时间长度(分钟)。如果在暂停期间再次手动发出消息,会重新开始计时。"></i>
</th>
<th style="width: 18%">操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 商品管理内容 -->
<div id="items-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-box-seam me-2"></i>
商品管理
</h2>
<p class="text-muted mb-0">管理各账号的商品信息</p>
</div>
<div class="content-body">
<!-- 筛选和搜索 -->
<div class="card mb-4">
<div class="card-body">
<div class="row align-items-end mb-3">
<div class="col-md-6">
<label for="itemCookieFilter" class="form-label">筛选账号</label>
<select class="form-select" id="itemCookieFilter" onchange="loadItemsByCookie()">
<option value="">所有账号</option>
</select>
</div>
<div class="col-md-6">
<div class="d-flex justify-content-end align-items-end gap-2">
<!-- 页码输入 -->
<div class="d-flex align-items-center gap-2">
<label for="pageNumber" class="form-label mb-0 text-nowrap">页码:</label>
<input type="number" class="form-control" id="pageNumber" placeholder="页码" min="1" value="1" style="width: 80px;">
</div>
<div class="d-flex gap-2">
<button class="btn btn-success" onclick="getAllItemsFromAccount()">
<i class="bi bi-download me-1"></i>获取指定页
</button>
<button class="btn btn-warning" onclick="getAllItemsFromAccountAll()">
<i class="bi bi-collection me-1"></i>获取所有页
</button>
<button class="btn btn-primary" onclick="refreshItems()">
<i class="bi bi-arrow-clockwise me-1"></i>刷新
</button>
</div>
</div>
</div>
</div>
<!-- 搜索结果统计 -->
<div id="itemSearchStats" class="text-muted small" style="display: none;">
<i class="bi bi-search me-1"></i>
<span id="itemSearchStatsText"></span>
</div>
</div>
</div>
<!-- 商品列表 -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="d-flex align-items-center gap-3">
<input type="text" class="form-control" id="itemSearchInput"
placeholder="搜索商品标题或详情..." style="width: 300px;">
<h5 class="mb-0">商品列表(自动发货根据商品标题和商品详情匹配关键字)</h5>
</div>
<button class="btn btn-sm btn-outline-danger" onclick="batchDeleteItems()" id="batchDeleteBtn" disabled>
<i class="bi bi-trash"></i> 批量删除
</button>
</div>
<div class="card-body">
<!-- 搜索统计信息 -->
<div id="itemSearchStats" class="text-muted small mb-2" style="display: none;">
<i class="bi bi-search me-1"></i>
<span id="itemSearchStatsText"></span>
</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th style="width: 5%">
<input type="checkbox" id="selectAllItems" onchange="toggleSelectAll(this)">
</th>
<th style="width: 10%">账号ID</th>
<th style="width: 10%">商品ID</th>
<th style="width: 16%">商品标题</th>
<th style="width: 18%">商品详情</th>
<th style="width: 18%">商品价格</th>
<th style="width: 8%">多规格</th>
<th style="width: 8%">多数量发货</th>
<th style="width: 10%">更新时间</th>
<th style="width: 15%">操作</th>
</tr>
</thead>
<tbody id="itemsTableBody">
<tr>
<td colspan="10" class="text-center text-muted">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 分页控件 -->
<div class="card-footer" id="itemsPagination">
<div class="d-flex justify-content-between align-items-center">
<div class="text-muted small">
<span id="itemsPageInfo">显示第 1-10 条,共 0 条记录</span>
</div>
<div class="d-flex align-items-center gap-2">
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-secondary btn-sm" id="itemsFirstPage" onclick="goToItemsPage(1)" disabled>
<i class="bi bi-chevron-double-left"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="itemsPrevPage" onclick="goToItemsPage(currentItemsPage - 1)" disabled>
<i class="bi bi-chevron-left"></i>
</button>
</div>
<div class="d-flex align-items-center gap-2 mx-2">
<span class="text-muted small"></span>
<input type="number" class="form-control form-control-sm" id="itemsPageInput"
style="width: 60px;" min="1" value="1">
<span class="text-muted small">页,共 <span id="itemsTotalPages">0</span></span>
</div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-secondary btn-sm" id="itemsNextPage" onclick="goToItemsPage(currentItemsPage + 1)" disabled>
<i class="bi bi-chevron-right"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="itemsLastPage" onclick="goToItemsPage(totalItemsPages)" disabled>
<i class="bi bi-chevron-double-right"></i>
</button>
</div>
<select class="form-select form-select-sm ms-2" id="itemsPageSize" style="width: auto;">
<option value="10">10条/页</option>
<option value="20" selected>20条/页</option>
<option value="50">50条/页</option>
<option value="100">100条/页</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 指定商品自动管理内容 -->
<div id="items-reply-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-box-seam me-2"></i>
商品回复管理
</h2>
<p class="text-muted mb-0">管理各账号的商品信息</p>
</div>
<div class="content-body">
<!-- Cookie筛选 -->
<div class="card mb-4">
<div class="card-body">
<div class="row align-items-end">
<div class="col-md-6">
<label for="itemCookieFilter" class="form-label">筛选账号</label>
<select class="form-select" id="itemReplayCookieFilter" onchange="loadItemsReplayByCookie()">
<option value="">所有账号</option>
</select>
</div>
<div class="col-md-6">
<div class="d-flex justify-content-end align-items-end gap-2">
<!-- 页码输入 -->
<div class="d-flex align-items-center gap-2">
<label for="pageNumber" class="form-label mb-0 text-nowrap">页码:</label>
<input type="number" class="form-control" id="pageNumber" placeholder="页码" min="1" value="1" style="width: 80px;">
</div>
<div class="d-flex gap-2">
<button class="btn btn-success" onclick="showItemReplayEdit()">
添加商品回复
</button>
<button class="btn btn-primary" onclick="refreshItemReplayS()">
<i class="bi bi-arrow-clockwise me-1"></i>刷新
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 商品列表 -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">商品列表(用于设置商品的默认回复信息)</h5>
<button class="btn btn-sm btn-outline-danger" onclick="batchDeleteItemReplies()">
<i class="bi bi-trash"></i> 批量删除
</button>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th style="width: 5%">
<input type="checkbox" id="selectAllItemReplay" onchange="toggleSelectAll(this)">
</th>
<th style="width: 12%">账号ID</th>
<th style="width: 12%">商品ID</th>
<th style="width: 18%">商品标题</th>
<th style="width: 20%">商品内容</th>
<th style="width: 18%">回复内容</th>
<th style="width: 10%">更新时间</th>
<th style="width: 15%">操作</th>
</tr>
</thead>
<tbody id="itemReplaysTableBody">
<tr>
<td colspan="5" class="text-center text-muted">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 商品回复弹框 -->
<!-- 添加/编辑商品回复模态框 -->
<div class="modal fade" id="editItemReplyModal" tabindex="-1">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-chat-text me-2"></i><span id="itemReplayTitle">编辑商品回复</span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="editItemReplyForm">
<input type="hidden" id="editReplyCookieId">
<input type="hidden" id="editReplyItemId">
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label">账号ID<span class="text-danger">*</span></label>
<select id="editReplyCookieIdSelect" class="form-select" onchange="onCookieChangeForReply()">
<option value="">请选择账号</option>
<!-- JS 动态填充账号选项 -->
</select>
</div>
<div class="col-md-6">
<label class="form-label">商品ID<span class="text-danger">*</span></label>
<select id="editReplyItemIdSelect" class="form-select">
<option value="">选择商品</option>
<!-- JS 动态填充商品选项 -->
</select>
</div>
</div>
<div class="mb-3">
<label for="editReplyContent" class="form-label">商品回复内容 <span class="text-danger">*</span></label>
<textarea class="form-control" id="editItemReplyContent" rows="10"
placeholder="请输入商品回复内容..."></textarea>
<div class="form-text">
<i class="bi bi-info-circle me-1"></i>
请输入商品的自动回复内容,用户购买后将收到该回复。
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="saveItemReply()">
<i class="bi bi-check-circle me-1"></i>保存
</button>
</div>
</div>
</div>
</div>
<!-- 订单管理内容 -->
<div id="orders-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-receipt-cutoff me-2"></i>
订单管理
</h2>
<p class="text-muted mb-0">查看和管理所有订单信息</p>
</div>
<div class="content-body">
<!-- Cookie筛选器 -->
<div class="row mb-3">
<div class="col-md-4">
<label class="form-label">筛选账号</label>
<select class="form-select" id="orderCookieFilter" onchange="loadOrdersByCookie()">
<option value="">所有账号</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">订单状态</label>
<select class="form-select" id="orderStatusFilter" onchange="filterOrders()">
<option value="">所有状态</option>
<option value="processing">处理中</option>
<option value="processed">已处理</option>
<option value="completed">已完成</option>
<option value="unknown">未知</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">&nbsp;</label>
<div class="d-flex gap-2">
<button class="btn btn-outline-primary" onclick="refreshOrders()">
<i class="bi bi-arrow-clockwise"></i> 刷新
</button>
<button class="btn btn-outline-secondary" onclick="clearOrderFilters()">
<i class="bi bi-x-circle"></i> 清空筛选
</button>
</div>
</div>
</div>
<!-- 订单列表 -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<div class="d-flex align-items-center gap-3">
<input type="text" class="form-control" id="orderSearchInput"
placeholder="搜索订单ID或商品ID..." style="width: 300px;">
<h5 class="mb-0">订单列表</h5>
</div>
<button class="btn btn-sm btn-outline-danger" onclick="batchDeleteOrders()" id="batchDeleteOrdersBtn" disabled>
<i class="bi bi-trash"></i> 批量删除
</button>
</div>
<div class="card-body">
<!-- 搜索统计信息 -->
<div id="orderSearchStats" class="text-muted small mb-2" style="display: none;">
<i class="bi bi-search me-1"></i>
<span id="orderSearchStatsText"></span>
</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th style="width: 5%">
<input type="checkbox" id="selectAllOrders" onchange="toggleSelectAllOrders(this)">
</th>
<th style="width: 15%">订单ID</th>
<th style="width: 12%">商品ID</th>
<th style="width: 10%">买家ID</th>
<th style="width: 12%">规格信息</th>
<th style="width: 8%">数量</th>
<th style="width: 10%">金额</th>
<th style="width: 8%">状态</th>
<th style="width: 10%">账号ID</th>
<th style="width: 10%">操作</th>
</tr>
</thead>
<tbody id="ordersTableBody">
<tr>
<td colspan="10" class="text-center text-muted">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 分页控件 -->
<div class="card-footer" id="ordersPagination">
<div class="d-flex justify-content-between align-items-center">
<div class="text-muted small">
<span id="ordersPageInfo">显示第 1-10 条,共 0 条记录</span>
</div>
<div class="d-flex align-items-center gap-2">
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-secondary btn-sm" id="ordersFirstPage" onclick="goToOrdersPage(1)" disabled>
<i class="bi bi-chevron-double-left"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="ordersPrevPage" onclick="goToOrdersPage(currentOrdersPage - 1)" disabled>
<i class="bi bi-chevron-left"></i>
</button>
</div>
<div class="d-flex align-items-center gap-2 mx-2">
<span class="text-muted small"></span>
<input type="number" class="form-control form-control-sm" id="ordersPageInput"
style="width: 60px;" min="1" value="1">
<span class="text-muted small">页,共 <span id="ordersTotalPages">0</span></span>
</div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-secondary btn-sm" id="ordersNextPage" onclick="goToOrdersPage(currentOrdersPage + 1)" disabled>
<i class="bi bi-chevron-right"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="ordersLastPage" onclick="goToOrdersPage(totalOrdersPages)" disabled>
<i class="bi bi-chevron-double-right"></i>
</button>
</div>
<select class="form-select form-select-sm ms-2" id="ordersPageSize" style="width: auto;">
<option value="10">10条/页</option>
<option value="20" selected>20条/页</option>
<option value="50">50条/页</option>
<option value="100">100条/页</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 自动回复内容 -->
<div id="auto-reply-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-chat-left-text me-2"></i>
自动回复
</h2>
<p class="text-muted mb-0">设置账号的关键词自动回复</p>
</div>
<div class="content-body">
<!-- 现代化账号选择器 -->
<div class="account-selector">
<div class="selector-header">
<div class="selector-icon">
<i class="bi bi-person-circle"></i>
</div>
<div>
<h3 class="selector-title">选择账号</h3>
<p class="selector-subtitle">选择要配置自动回复的闲鱼账号</p>
</div>
</div>
<div class="row g-3 align-items-end">
<div class="col-md-8">
<div class="account-select-wrapper">
<select class="account-select" id="accountSelect" onchange="loadAccountKeywords()">
<option value="">🔍 请选择一个账号开始配置...</option>
</select>
</div>
</div>
<div class="col-md-4">
<button class="btn btn-primary w-100 d-flex align-items-center justify-content-center" onclick="refreshAccountList()" style="padding: 1rem 1.25rem; height: auto;">
<i class="bi bi-arrow-clockwise me-2"></i>
<span>刷新列表</span>
</button>
</div>
</div>
</div>
<!-- 现代化关键词管理容器 -->
<div class="keyword-container" id="keywordManagement" style="display: none;">
<div class="keyword-header">
<h3>
<i class="bi bi-chat-dots me-2"></i>
关键词管理
</h3>
<div class="d-flex align-items-center gap-2">
<div class="account-badge" id="currentAccountBadge">
<!-- 动态显示当前账号 -->
</div>
<div class="btn-group" role="group">
<button class="btn btn-outline-success btn-sm" onclick="exportKeywords()" title="导出关键词">
<i class="bi bi-download"></i> 导出
</button>
<button class="btn btn-outline-primary btn-sm" onclick="showImportModal()" title="导入关键词">
<i class="bi bi-upload"></i> 导入
</button>
</div>
</div>
</div>
<!-- 添加关键词区域 -->
<div class="keyword-input-area">
<div class="keyword-input-group">
<div class="input-field">
<label>关键词</label>
<input type="text" id="newKeyword" placeholder="例如:你好">
</div>
<div class="input-field">
<label>自动回复内容(可选)</label>
<input type="text" id="newReply" placeholder="例如:您好,欢迎咨询!留空表示不回复">
</div>
<div class="input-field">
<label>商品ID可选</label>
<select id="newItemIdSelect" class="form-select">
<option value="">选择商品或留空表示通用关键词</option>
</select>
</div>
<button class="add-btn" onclick="addKeyword()">
<i class="bi bi-plus-lg"></i>
添加文本关键词
</button>
<button class="add-btn btn-image" onclick="showAddImageKeywordModal()">
<i class="bi bi-image"></i>
添加图片关键词
</button>
</div>
<div class="mt-3">
<small class="text-muted">
<i class="bi bi-lightbulb me-1"></i>
<strong>支持变量:</strong>
<code>{send_user_name}</code> 用户昵称,
<code>{send_user_id}</code> 用户ID
<code>{send_message}</code> 用户消息<br>
<i class="bi bi-info-circle me-1"></i>
<strong>提示:</strong>回复内容留空时,匹配到关键词但不会自动回复,可用于屏蔽特定消息
</small>
</div>
</div>
<!-- 关键词列表 -->
<div class="keywords-list" id="keywordsList">
<!-- 动态生成的关键词列表 -->
</div>
</div>
</div>
</div>
<!-- 卡券管理内容 -->
<div id="cards-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-credit-card me-2"></i>
卡券管理
</h2>
<p class="text-muted mb-0">管理虚拟商品的卡券数据支持API、固定文字和批量数据</p>
</div>
<div class="content-body">
<!-- 卡券列表 -->
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">卡券列表</h5>
<button class="btn btn-primary btn-sm" onclick="showAddCardModal()">
<i class="bi bi-plus-lg me-1"></i>添加卡券
</button>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>卡券名称</th>
<th>类型</th>
<th>规格信息</th>
<th>数据量</th>
<th>延时时间</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="cardsTableBody">
<tr>
<td colspan="7" class="text-center py-4 text-muted">
<i class="bi bi-credit-card fs-1 d-block mb-3"></i>
<h5>暂无卡券数据</h5>
<p class="mb-0">点击"添加卡券"开始创建您的第一个卡券</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">统计信息</h5>
</div>
<div class="card-body">
<div class="stat-item mb-3">
<div class="d-flex justify-content-between">
<span>总卡券数</span>
<span class="badge bg-primary" id="totalCards">0</span>
</div>
</div>
<div class="stat-item mb-3">
<div class="d-flex justify-content-between">
<span>API类型</span>
<span class="badge bg-info" id="apiCards">0</span>
</div>
</div>
<div class="stat-item mb-3">
<div class="d-flex justify-content-between">
<span>固定文字</span>
<span class="badge bg-success" id="textCards">0</span>
</div>
</div>
<div class="stat-item">
<div class="d-flex justify-content-between">
<span>批量数据</span>
<span class="badge bg-warning" id="dataCards">0</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 自动发货内容 -->
<div id="auto-delivery-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-truck me-2"></i>
自动发货
</h2>
<p class="text-muted mb-0">根据商品关键字自动匹配卡券进行发货</p>
</div>
<div class="content-body">
<!-- 发货规则列表 -->
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">发货规则</h5>
<button class="btn btn-primary btn-sm" onclick="showAddDeliveryRuleModal()">
<i class="bi bi-plus-lg me-1"></i>添加规则
</button>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>商品关键字</th>
<th>匹配卡券</th>
<th>卡券类型</th>
<th>发货数量</th>
<th>状态</th>
<th>已发货次数</th>
<th>操作</th>
</tr>
</thead>
<tbody id="deliveryRulesTableBody">
<tr>
<td colspan="7" class="text-center py-4 text-muted">
<i class="bi bi-truck fs-1 d-block mb-3"></i>
<h5>暂无发货规则</h5>
<p class="mb-0">点击"添加规则"开始配置自动发货规则</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">发货统计</h5>
</div>
<div class="card-body">
<div class="stat-item mb-3">
<div class="d-flex justify-content-between">
<span>总规则数</span>
<span class="badge bg-primary" id="totalRules">0</span>
</div>
</div>
<div class="stat-item mb-3">
<div class="d-flex justify-content-between">
<span>启用规则</span>
<span class="badge bg-success" id="activeRules">0</span>
</div>
</div>
<div class="stat-item mb-3">
<div class="d-flex justify-content-between">
<span>今日发货</span>
<span class="badge bg-info" id="todayDeliveries">0</span>
</div>
</div>
<div class="stat-item">
<div class="d-flex justify-content-between">
<span>总发货量</span>
<span class="badge bg-warning" id="totalDeliveries">0</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 通知渠道管理内容 -->
<div id="notification-channels-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-bell me-2"></i>
通知渠道管理
</h2>
<p class="text-muted mb-0">管理消息通知渠道支持QQ通知等多种方式</p>
</div>
<div class="content-body">
<!-- 通知渠道类型选择 -->
<div class="card mb-4">
<div class="card-header">
<span><i class="bi bi-plus-circle me-2"></i>添加通知渠道</span>
</div>
<div class="card-body">
<div class="alert alert-info mb-4">
<i class="bi bi-info-circle me-2"></i>
<strong>选择通知方式:</strong>点击下方按钮选择您要配置的通知渠道类型
</div>
<!-- 通知渠道类型按钮 -->
<div class="row g-2">
<div class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100 channel-type-card" onclick="showAddChannelModal('qq')">
<div class="card-body text-center">
<div class="channel-icon">
<i class="bi bi-chat-dots-fill text-primary"></i>
</div>
<h6 class="card-title">QQ通知</h6>
<p class="card-text text-muted">QQ机器人消息</p>
<div class="mt-auto">
<button class="btn btn-outline-primary btn-sm">
<i class="bi bi-plus-circle me-1"></i>配置
</button>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100 channel-type-card" onclick="showAddChannelModal('dingtalk')">
<div class="card-body text-center">
<div class="channel-icon">
<i class="bi bi-bell-fill text-info"></i>
</div>
<h6 class="card-title">钉钉通知</h6>
<p class="card-text text-muted">钉钉机器人消息</p>
<div class="mt-auto">
<button class="btn btn-outline-info btn-sm">
<i class="bi bi-plus-circle me-1"></i>配置
</button>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100 channel-type-card" onclick="showAddChannelModal('feishu')">
<div class="card-body text-center">
<div class="channel-icon">
<i class="bi bi-chat-square-text-fill text-warning"></i>
</div>
<h6 class="card-title">飞书通知</h6>
<p class="card-text text-muted">飞书机器人消息</p>
<div class="mt-auto">
<button class="btn btn-outline-warning btn-sm">
<i class="bi bi-plus-circle me-1"></i>配置
</button>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100 channel-type-card" onclick="showAddChannelModal('bark')">
<div class="card-body text-center">
<div class="channel-icon">
<i class="bi bi-phone-fill text-dark"></i>
</div>
<h6 class="card-title">Bark通知</h6>
<p class="card-text text-muted">iOS推送通知</p>
<div class="mt-auto">
<button class="btn btn-outline-dark btn-sm">
<i class="bi bi-plus-circle me-1"></i>配置
</button>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100 channel-type-card" onclick="showAddChannelModal('email')">
<div class="card-body text-center">
<div class="channel-icon">
<i class="bi bi-envelope-fill text-success"></i>
</div>
<h6 class="card-title">邮件通知</h6>
<p class="card-text text-muted">SMTP邮件发送</p>
<div class="mt-auto">
<button class="btn btn-outline-success btn-sm">
<i class="bi bi-plus-circle me-1"></i>配置
</button>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100 channel-type-card" onclick="showAddChannelModal('webhook')">
<div class="card-body text-center">
<div class="channel-icon">
<i class="bi bi-link-45deg text-warning"></i>
</div>
<h6 class="card-title">Webhook</h6>
<p class="card-text text-muted">自定义HTTP请求</p>
<div class="mt-auto">
<button class="btn btn-outline-warning btn-sm">
<i class="bi bi-plus-circle me-1"></i>配置
</button>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100 channel-type-card" onclick="showAddChannelModal('wechat')">
<div class="card-body text-center">
<div class="channel-icon">
<i class="bi bi-wechat text-success"></i>
</div>
<h6 class="card-title">微信通知</h6>
<p class="card-text text-muted">企业微信机器人</p>
<div class="mt-auto">
<button class="btn btn-outline-success btn-sm">
<i class="bi bi-plus-circle me-1"></i>配置
</button>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100 channel-type-card" onclick="showAddChannelModal('telegram')">
<div class="card-body text-center">
<div class="channel-icon">
<i class="bi bi-telegram text-primary"></i>
</div>
<h6 class="card-title">Telegram</h6>
<p class="card-text text-muted">Telegram机器人</p>
<div class="mt-auto">
<button class="btn btn-outline-primary btn-sm">
<i class="bi bi-plus-circle me-1"></i>配置
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 通知渠道列表 -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span><i class="bi bi-list-ul me-2"></i>通知渠道列表</span>
<button class="btn btn-sm btn-outline-primary" onclick="loadNotificationChannels()">
<i class="bi bi-arrow-clockwise me-1"></i>刷新
</button>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover" id="channelsTable">
<thead>
<tr>
<th style="width: 10%">ID</th>
<th style="width: 25%">名称</th>
<th style="width: 15%">类型</th>
<th style="width: 20%">配置</th>
<th style="width: 10%">状态</th>
<th style="width: 20%">操作</th>
</tr>
</thead>
<tbody id="channelsTableBody">
<!-- 动态生成 -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 消息通知配置内容 -->
<div id="message-notifications-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-chat-dots me-2"></i>
消息通知配置
</h2>
<p class="text-muted mb-0">为每个账号配置消息通知渠道</p>
</div>
<div class="content-body">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span><i class="bi bi-gear me-2"></i>账号通知配置</span>
<button class="btn btn-sm btn-outline-primary" onclick="loadMessageNotifications()">
<i class="bi bi-arrow-clockwise me-1"></i>刷新
</button>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover" id="notificationsTable">
<thead>
<tr>
<th style="width: 20%">账号ID</th>
<th style="width: 30%">通知渠道</th>
<th style="width: 15%">状态</th>
<th style="width: 35%">操作</th>
</tr>
</thead>
<tbody id="notificationsTableBody">
<!-- 动态生成 -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 日志管理内容 -->
<div id="logs-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-file-text me-2"></i>
日志管理
</h2>
<p class="text-muted mb-0">实时显示系统日志,支持自动刷新和统计分析</p>
</div>
<div class="content-body">
<!-- 日志控制面板 -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="bi bi-sliders"></i> 日志控制
</h5>
</div>
<div class="card-body">
<div class="row align-items-center">
<div class="col-md-3">
<label class="form-label">显示行数</label>
<select class="form-select" id="logLines" onchange="loadSystemLogs()">
<option value="50">50行</option>
<option value="100" selected>100行</option>
<option value="200">200行</option>
<option value="500">500行</option>
<option value="1000">1000行</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">日志级别过滤</label>
<div class="d-flex gap-2 flex-wrap">
<span class="badge bg-secondary filter-badge active" data-level="" onclick="filterLogsByLevel('')">
全部
</span>
<span class="badge bg-info filter-badge" data-level="info" onclick="filterLogsByLevel('info')">
INFO
</span>
<span class="badge bg-warning filter-badge" data-level="warning" onclick="filterLogsByLevel('warning')">
WARNING
</span>
<span class="badge bg-danger filter-badge" data-level="error" onclick="filterLogsByLevel('error')">
ERROR
</span>
<span class="badge bg-secondary filter-badge" data-level="debug" onclick="filterLogsByLevel('debug')">
DEBUG
</span>
</div>
</div>
<div class="col-md-3">
<label class="form-label">自动刷新</label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="autoRefreshLogs" onchange="toggleLogAutoRefresh()">
<label class="form-check-label" for="autoRefreshLogs">
<span id="autoRefreshLogLabel">关闭</span>
<i id="autoRefreshLogIcon" class="bi bi-circle" style="display: none;"></i>
</label>
</div>
</div>
<div class="col-md-2">
<label class="form-label">&nbsp;</label>
<div class="d-grid">
<button class="btn btn-primary" onclick="loadSystemLogs()">
<i class="bi bi-arrow-clockwise"></i> 刷新
</button>
</div>
</div>
</div>
</div>
</div>
<!-- 日志信息 -->
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="bi bi-info-circle"></i> 日志信息
</h5>
<small class="text-muted" id="logLastUpdate">最后更新: -</small>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<strong>日志文件:</strong>
<span id="logFileName" class="text-muted">-</span>
</div>
<div class="col-md-4">
<strong>显示行数:</strong>
<span id="logDisplayLines" class="text-muted">-</span>
</div>
<div class="col-md-4">
<strong>当前过滤:</strong>
<span id="logCurrentFilter" class="text-muted">全部</span>
</div>
</div>
</div>
</div>
<!-- 日志内容 -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="bi bi-terminal"></i> 日志内容
</h5>
<div class="d-flex gap-2">
<button class="btn btn-sm btn-outline-secondary" onclick="scrollLogToTop()">
<i class="bi bi-arrow-up"></i> 顶部
</button>
<button class="btn btn-sm btn-outline-secondary" onclick="scrollLogToBottom()">
<i class="bi bi-arrow-down"></i> 底部
</button>
</div>
</div>
<div class="card-body p-0">
<div id="loadingSystemLogs" class="text-center py-4">
<div class="spinner-border" role="status">
<span class="visually-hidden">加载中...</span>
</div>
<p class="mt-2">正在加载日志...</p>
</div>
<div id="systemLogContainer" class="log-container" style="display: none;"></div>
<div id="noSystemLogs" class="text-center py-4" style="display: none;">
<i class="bi bi-file-text" style="font-size: 3rem; color: #ccc;"></i>
<p class="mt-2 text-muted">暂无日志数据</p>
</div>
</div>
</div>
</div>
</div>
<!-- 商品搜索内容 -->
<div id="item-search-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-search me-2"></i>
商品搜索
</h2>
<p class="text-muted mb-0">搜索闲鱼商品,获取真实商品数据</p>
</div>
<div class="content-body">
<!-- 搜索表单 -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="bi bi-search me-2"></i>
闲鱼商品搜索
</h5>
</div>
<div class="card-body">
<div class="alert alert-info mb-4">
<i class="bi bi-info-circle me-2"></i>
<strong>功能说明:</strong>
<ul class="mb-0 mt-2">
<li><strong>查询总页数:</strong>输入要获取的页数1-20页系统会一次性获取所有页面的数据</li>
<li><strong>每页显示:</strong>前端分页显示的每页商品数量</li>
<li><strong>数据来源:</strong>使用真实的闲鱼数据,通过浏览器自动化技术获取</li>
</ul>
</div>
<form id="itemSearchForm">
<div class="row">
<div class="col-md-5">
<label for="searchKeyword" class="form-label">搜索关键词</label>
<input type="text" class="form-control" id="searchKeyword" placeholder="请输入商品关键词" required>
</div>
<div class="col-md-3">
<label for="searchTotalPages" class="form-label">查询总页数</label>
<input type="number" class="form-control" id="searchTotalPages" value="1" min="1" max="20" placeholder="输入页数">
</div>
<div class="col-md-2">
<label for="searchPageSize" class="form-label">每页显示</label>
<select class="form-select" id="searchPageSize">
<option value="10">10条</option>
<option value="20" selected>20条</option>
<option value="30">30条</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label">&nbsp;</label>
<div class="d-grid">
<button type="submit" class="btn btn-primary">
<i class="bi bi-search me-2"></i>
搜索
</button>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- 搜索状态 -->
<div id="searchStatus" class="card mb-4" style="display: none;">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="spinner-border spinner-border-sm me-3" role="status">
<span class="visually-hidden">搜索中...</span>
</div>
<div>
<strong>正在搜索商品...</strong>
<div class="text-muted small" id="searchProgress">准备开始搜索</div>
</div>
</div>
</div>
</div>
<!-- 搜索结果统计 -->
<div id="searchResultStats" class="card mb-4" style="display: none;">
<div class="card-body">
<div class="row text-center">
<div class="col-md-3">
<div class="stat-number text-primary" id="totalItemsFound">0</div>
<div class="stat-label">找到商品</div>
</div>
<div class="col-md-3">
<div class="stat-number text-success" id="totalPagesSearched">0</div>
<div class="stat-label">搜索页数</div>
</div>
<div class="col-md-3">
<div class="stat-number text-info" id="currentDisplayPage">0</div>
<div class="stat-label">当前页</div>
</div>
<div class="col-md-3">
<div class="stat-number text-warning" id="totalDisplayPages">0</div>
<div class="stat-label">总页数</div>
</div>
</div>
</div>
</div>
<!-- 搜索结果 -->
<div id="searchResults" class="card" style="display: none;">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="bi bi-grid me-2"></i>
搜索结果
</h5>
<div class="d-flex gap-2">
<button class="btn btn-sm btn-outline-secondary" onclick="exportSearchResults()">
<i class="bi bi-download"></i> 导出结果
</button>
</div>
</div>
<div class="card-body">
<div id="searchResultsContainer" class="row">
<!-- 搜索结果将在这里显示 -->
</div>
<!-- 分页控件 -->
<div id="searchPagination" class="d-flex justify-content-center mt-4">
<!-- 分页按钮将在这里显示 -->
</div>
</div>
</div>
<!-- 无结果提示 -->
<div id="noSearchResults" class="card" style="display: none;">
<div class="card-body text-center py-5">
<i class="bi bi-search" style="font-size: 3rem; color: #ccc;"></i>
<h5 class="mt-3 text-muted">未找到相关商品</h5>
<p class="text-muted">请尝试使用其他关键词或调整搜索条件</p>
</div>
</div>
</div>
</div>
<!-- 系统设置内容 -->
<div id="system-settings-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-gear me-2"></i>
系统设置
</h2>
<p class="text-muted mb-0">管理系统配置和用户设置</p>
</div>
<div class="content-body">
<div class="row">
<!-- 密码设置 -->
<div class="col-md-6">
<div class="card">
<div class="card-header">
<i class="bi bi-shield-lock me-2"></i>密码设置
</div>
<div class="card-body">
<form id="passwordForm">
<div class="mb-3">
<label for="currentPassword" class="form-label">当前密码</label>
<input type="password" class="form-control" id="currentPassword" required>
</div>
<div class="mb-3">
<label for="newPassword" class="form-label">新密码</label>
<input type="password" class="form-control" id="newPassword" required>
</div>
<div class="mb-3">
<label for="confirmPassword" class="form-label">确认新密码</label>
<input type="password" class="form-control" id="confirmPassword" required>
</div>
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle me-1"></i>更新密码
</button>
</form>
</div>
</div>
</div>
<!-- 主题设置 -->
<div class="col-md-6">
<div class="card">
<div class="card-header">
<i class="bi bi-palette me-2"></i>主题设置
</div>
<div class="card-body">
<form id="themeForm">
<div class="mb-3">
<label for="themeColor" class="form-label">主题颜色</label>
<select class="form-select" id="themeColor">
<option value="blue">蓝色</option>
<option value="green">绿色</option>
<option value="purple">紫色</option>
<option value="red">红色</option>
<option value="orange">橙色</option>
</select>
</div>
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle me-1"></i>应用主题
</button>
</form>
</div>
</div>
</div>
</div>
<!-- 注册设置 (仅管理员可见) -->
<div id="registration-settings" class="row mt-4" style="display: none;">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<i class="bi bi-person-plus me-2"></i>注册设置
<span class="badge bg-warning ms-2">管理员专用</span>
</div>
<div class="card-body">
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="registrationEnabled">
<label class="form-check-label" for="registrationEnabled">
<strong>开启用户注册</strong>
</label>
</div>
<div class="form-text">
<i class="bi bi-info-circle me-1"></i>
关闭后,新用户将无法注册账号,登录页面也不会显示注册链接
</div>
</div>
<button type="button" class="btn btn-primary" onclick="updateRegistrationSettings()">
<i class="bi bi-check-circle me-1"></i>保存设置
</button>
<div id="registrationStatus" class="mt-3" style="display: none;">
<div class="alert alert-info mb-0">
<i class="bi bi-info-circle me-2"></i>
<span id="registrationStatusText"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 外发配置 (仅管理员可见) -->
<div id="outgoing-configs" class="row mt-4" style="display: none;">
<!-- 外发配置内容将由JavaScript动态生成 -->
</div>
<!-- 备份管理 (仅管理员可见) -->
<div id="backup-management" class="row mt-4" style="display: none;">
<div class="col-12">
<div class="card">
<div class="card-header">
<i class="bi bi-archive me-2"></i>备份管理
<span class="badge bg-warning ms-2">管理员专用</span>
</div>
<div class="card-body">
<div class="row">
<!-- 数据库备份 -->
<div class="col-md-6">
<h6 class="mb-3">
<i class="bi bi-database-down me-2"></i>数据库备份
</h6>
<p class="text-muted mb-3">直接下载完整的数据库文件,包含所有用户数据和设置</p>
<button type="button" class="btn btn-success" onclick="downloadDatabaseBackup()">
<i class="bi bi-download me-1"></i>下载数据库
</button>
<div class="mt-2">
<small class="text-muted">
<i class="bi bi-info-circle me-1"></i>
推荐方式:完整备份,恢复简单
</small>
</div>
</div>
<!-- 数据库恢复 -->
<div class="col-md-6">
<h6 class="mb-3">
<i class="bi bi-database-up me-2"></i>数据库恢复
</h6>
<p class="text-muted mb-3">上传数据库文件直接替换当前数据库,系统将自动重新加载</p>
<div class="mb-3">
<input type="file" class="form-control" id="databaseFile" accept=".db">
</div>
<button type="button" class="btn btn-danger" onclick="uploadDatabaseBackup()">
<i class="bi bi-upload me-1"></i>恢复数据库
</button>
<div class="mt-2">
<small class="text-danger">
<i class="bi bi-exclamation-triangle me-1"></i>
警告:将覆盖所有当前数据!
</small>
</div>
</div>
</div>
<!-- 系统缓存管理 -->
<div class="row mt-4">
<div class="col-12">
<h6 class="mb-3">
<i class="bi bi-arrow-clockwise me-2"></i>系统缓存管理
</h6>
<p class="text-muted mb-3">如果导入备份后关键字等数据没有立即更新,可以手动刷新系统缓存</p>
<button type="button" class="btn btn-info" onclick="reloadSystemCache()">
<i class="bi bi-arrow-clockwise me-1"></i>刷新系统缓存
</button>
</div>
</div>
<div class="alert alert-warning mt-4" role="alert">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>注意:</strong>导入备份将会覆盖当前系统的所有数据,请谨慎操作!建议在导入前先导出当前数据作为备份。
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 用户管理内容 -->
<div id="user-management-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-people me-2"></i>
用户管理
</h2>
<p class="text-muted mb-0">管理系统中的所有用户账号</p>
</div>
<div class="content-body">
<!-- 统计信息 -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body text-center">
<h3 id="totalUsers">-</h3>
<p class="mb-0">总用户数</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-info text-white">
<div class="card-body text-center">
<h3 id="totalUserCookies">-</h3>
<p class="mb-0">总Cookie数</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body text-center">
<h3 id="totalUserCards">-</h3>
<p class="mb-0">总卡券数</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white">
<div class="card-body text-center">
<h3 id="systemUptime">运行中</h3>
<p class="mb-0">系统状态</p>
</div>
</div>
</div>
</div>
<!-- 用户列表 -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="bi bi-people-fill"></i> 用户列表
</h5>
<button class="btn btn-primary" onclick="refreshUsers()">
<i class="bi bi-arrow-clockwise"></i> 刷新
</button>
</div>
<div class="card-body">
<div id="loadingUsers" class="text-center py-4">
<div class="spinner-border" role="status">
<span class="visually-hidden">加载中...</span>
</div>
<p class="mt-2">正在加载用户信息...</p>
</div>
<div id="usersList" class="row" style="display: none;"></div>
<div id="noUsers" class="text-center py-4" style="display: none;">
<i class="bi bi-people" style="font-size: 3rem; color: #ccc;"></i>
<p class="mt-2 text-muted">暂无用户</p>
</div>
</div>
</div>
</div>
</div>
<!-- 数据管理内容 -->
<div id="data-management-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-database me-2"></i>
数据管理
</h2>
<p class="text-muted mb-0">查看和管理数据库中的所有表数据</p>
</div>
<div class="content-body">
<!-- 表选择器 -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="bi bi-table"></i> 数据表选择
</h5>
</div>
<div class="card-body">
<div class="row align-items-center">
<div class="col-md-6">
<label class="form-label">选择数据表</label>
<select class="form-select" id="tableSelect" onchange="loadTableData()">
<option value="">请选择数据表...</option>
<option value="users">users - 用户表</option>
<option value="cookies">cookies - Cookie账号表</option>
<option value="cookie_status">cookie_status - Cookie状态表</option>
<option value="keywords">keywords - 关键字表</option>
<option value="default_replies">default_replies - 默认回复表</option>
<option value="item_replay">item_replay - 指定商品回复表</option>
<option value="default_reply_records">default_reply_records - 默认回复记录表</option>
<option value="ai_reply_settings">ai_reply_settings - AI回复设置表</option>
<option value="ai_conversations">ai_conversations - AI对话历史表</option>
<option value="ai_item_cache">ai_item_cache - AI商品信息缓存表</option>
<option value="item_info">item_info - 商品信息表</option>
<option value="message_notifications">message_notifications - 消息通知表</option>
<option value="cards">cards - 卡券表</option>
<option value="delivery_rules">delivery_rules - 发货规则表</option>
<option value="notification_channels">notification_channels - 通知渠道表</option>
<option value="user_settings">user_settings - 用户设置表</option>
<option value="system_settings">system_settings - 系统设置表</option>
<option value="email_verifications">email_verifications - 邮箱验证表</option>
<option value="captcha_codes">captcha_codes - 验证码表</option>
<option value="orders">orders - 订单表</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">数据统计</label>
<div class="card">
<div class="card-body text-center py-2">
<h5 id="recordCount" class="mb-0">-</h5>
<small>条记录</small>
</div>
</div>
</div>
<div class="col-md-3">
<label class="form-label">&nbsp;</label>
<div class="d-grid">
<button class="btn btn-primary" onclick="refreshTableData()">
<i class="bi bi-arrow-clockwise"></i> 刷新数据
</button>
</div>
</div>
</div>
</div>
</div>
<!-- 数据表格 -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0" id="tableTitle">
<i class="bi bi-table"></i> 数据表
</h5>
<div class="btn-group">
<button class="btn btn-outline-danger btn-sm" onclick="clearTableData()" id="clearBtn" disabled>
<i class="bi bi-trash"></i> 清空
</button>
</div>
</div>
<div class="card-body">
<div id="loadingTable" class="text-center py-4" style="display: none;">
<div class="spinner-border" role="status">
<span class="visually-hidden">加载中...</span>
</div>
<p class="mt-2">正在加载数据...</p>
</div>
<div id="noTableSelected" class="text-center py-4">
<i class="bi bi-table" style="font-size: 3rem; color: #ccc;"></i>
<p class="mt-2 text-muted">请选择要查看的数据表</p>
</div>
<div id="noTableData" class="text-center py-4" style="display: none;">
<i class="bi bi-inbox" style="font-size: 3rem; color: #ccc;"></i>
<p class="mt-2 text-muted">该表暂无数据</p>
</div>
<div id="tableContainer" style="display: none;">
<div class="table-responsive" style="max-height: 600px; overflow-y: auto;">
<table class="table table-striped table-hover" id="dataTable">
<thead class="table-dark sticky-top">
<tr id="tableHeaders"></tr>
</thead>
<tbody id="tableBody"></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 关于页面内容 -->
<div id="about-section" class="content-section">
<div class="content-header">
<h2 class="mb-0">
<i class="bi bi-info-circle me-2"></i>
关于
</h2>
<p class="text-muted mb-0">联系我们和技术支持</p>
</div>
<div class="content-body">
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<i class="bi bi-wechat me-2"></i>微信群
</div>
<div class="card-body text-center">
<img src="/static/wechat-group.png" alt="微信群二维码" class="img-fluid" style="max-width: 200px;">
<p class="mt-3 text-muted">扫码加入微信技术交流群</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<i class="bi bi-chat-square me-2"></i>QQ群
</div>
<div class="card-body text-center">
<img src="/static/qq-group.png" alt="QQ群二维码" class="img-fluid" style="max-width: 200px;">
<p class="mt-3 text-muted">扫码加入QQ技术交流群</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div> <!-- 结束 main-content -->
<!-- 扫码登录模态框 -->
<div class="modal fade" id="qrCodeLoginModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header bg-success text-white">
<h5 class="modal-title">
<i class="bi bi-qr-code me-2"></i>扫码登录闲鱼账号
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body text-center py-4">
<!-- 步骤指引 -->
<div class="row mb-4">
<div class="col-12">
<div class="d-flex justify-content-center align-items-center">
<div class="step-item me-3">
<div class="step-number bg-success text-white rounded-circle d-inline-flex align-items-center justify-content-center" style="width: 30px; height: 30px;">1</div>
<small class="d-block mt-1">打开闲鱼APP</small>
</div>
<i class="bi bi-arrow-right text-muted me-3"></i>
<div class="step-item me-3">
<div class="step-number bg-success text-white rounded-circle d-inline-flex align-items-center justify-content-center" style="width: 30px; height: 30px;">2</div>
<small class="d-block mt-1">扫描二维码</small>
</div>
<i class="bi bi-arrow-right text-muted me-3"></i>
<div class="step-item">
<div class="step-number bg-success text-white rounded-circle d-inline-flex align-items-center justify-content-center" style="width: 30px; height: 30px;">3</div>
<small class="d-block mt-1">自动添加账号</small>
</div>
</div>
</div>
</div>
<!-- 二维码区域 -->
<div id="qrCodeContainer">
<div class="spinner-border text-success mb-3" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">生成二维码中...</span>
</div>
<p class="text-muted fs-5 mb-2">正在生成二维码...</p>
<div class="alert alert-warning border-0 bg-light-warning d-inline-block qr-loading-tip">
<i class="bi bi-clock me-2 text-warning"></i>
<small class="text-warning fw-bold">二维码生成较慢,请耐心等待</small>
</div>
</div>
<div id="qrCodeImage" style="display: none;">
<div class="qr-code-wrapper p-3 bg-light rounded-3 d-inline-block mb-3">
<img id="qrCodeImg" src="" alt="登录二维码" class="img-fluid" style="max-width: 280px;">
</div>
<h6 class="text-success mb-2">
<i class="bi bi-phone me-2"></i>请使用闲鱼APP扫描二维码
</h6>
<div class="alert alert-info border-0 bg-light">
<i class="bi bi-info-circle me-2 text-info"></i>
<small>扫码后请等待页面提示,系统会自动获取并保存您的账号信息</small>
</div>
</div>
<!-- 状态显示 -->
<div id="qrCodeStatus" class="mt-3">
<div class="d-flex align-items-center justify-content-center">
<div class="spinner-border spinner-border-sm text-success me-2" role="status" style="display: none;" id="statusSpinner">
<span class="visually-hidden">检查中...</span>
</div>
<span id="statusText" class="text-muted">等待扫码...</span>
</div>
</div>
</div>
<div class="modal-footer bg-light">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
<i class="bi bi-x-circle me-1"></i>关闭
</button>
<button type="button" class="btn btn-success" onclick="refreshQRCode()" id="refreshQRBtn">
<i class="bi bi-arrow-clockwise me-1"></i>重新生成二维码
</button>
</div>
</div>
</div>
</div>
<!-- 添加通知渠道模态框 -->
<div class="modal fade" id="addChannelModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-plus-circle me-2"></i>
<span id="addChannelModalTitle">添加通知渠道</span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<!-- 渠道类型说明 -->
<div id="channelTypeInfo" class="alert alert-info">
<i class="bi bi-info-circle me-2"></i>
<span id="channelTypeDescription">请配置通知渠道信息</span>
</div>
<form id="addChannelForm">
<input type="hidden" id="channelType">
<!-- 基本信息 -->
<div class="row mb-3">
<div class="col-md-6">
<label for="channelName" class="form-label">渠道名称 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="channelName" placeholder="例如我的QQ通知" required>
</div>
<div class="col-md-6">
<label for="channelEnabled" class="form-label">状态</label>
<div class="form-check form-switch mt-2">
<input class="form-check-input" type="checkbox" id="channelEnabled" checked>
<label class="form-check-label" for="channelEnabled">
启用此通知渠道
</label>
</div>
</div>
</div>
<!-- 动态配置字段 -->
<div id="channelConfigFields">
<!-- 根据渠道类型动态生成 -->
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="bi bi-x-circle me-1"></i>取消
</button>
<button type="button" class="btn btn-primary" onclick="saveNotificationChannel()">
<i class="bi bi-check-circle me-1"></i>保存配置
</button>
</div>
</div>
</div>
</div>
<!-- 编辑通知渠道模态框 -->
<div class="modal fade" id="editChannelModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-pencil me-2"></i>
编辑通知渠道
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="editChannelForm">
<input type="hidden" id="editChannelId">
<input type="hidden" id="editChannelType">
<!-- 基本信息 -->
<div class="row mb-3">
<div class="col-md-6">
<label for="editChannelName" class="form-label">渠道名称 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="editChannelName" placeholder="例如我的QQ通知" required>
</div>
<div class="col-md-6">
<label for="editChannelEnabled" class="form-label">状态</label>
<div class="form-check form-switch mt-2">
<input class="form-check-input" type="checkbox" id="editChannelEnabled" checked>
<label class="form-check-label" for="editChannelEnabled">
启用此通知渠道
</label>
</div>
</div>
</div>
<!-- 动态配置字段 -->
<div id="editChannelConfigFields">
<!-- 根据渠道类型动态生成 -->
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="updateNotificationChannel()">保存修改</button>
</div>
</div>
</div>
</div>
<!-- 配置账号通知模态框 -->
<div class="modal fade" id="configNotificationModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-gear me-2"></i>
配置账号通知
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="configNotificationForm">
<input type="hidden" id="configAccountId">
<div class="mb-3">
<label class="form-label">账号ID</label>
<input type="text" class="form-control" id="displayAccountId" readonly>
</div>
<div class="mb-3">
<label for="notificationChannel" class="form-label">选择通知渠道 <span class="text-danger">*</span></label>
<select class="form-select" id="notificationChannel" required>
<option value="">请选择通知渠道</option>
</select>
<small class="form-text text-muted">选择要接收此账号消息通知的渠道</small>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="notificationEnabled" checked>
<label class="form-check-label" for="notificationEnabled">
启用消息通知
</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="saveAccountNotification()">保存配置</button>
</div>
</div>
</div>
</div>
<!-- 添加卡券模态框 -->
<div class="modal fade" id="addCardModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-credit-card me-2"></i>
添加卡券
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="addCardForm" onsubmit="event.preventDefault(); saveCard(); return false;">
<div class="mb-3">
<label class="form-label">卡券名称 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="cardName" placeholder="例如:游戏点卡、会员卡等" required>
</div>
<div class="mb-3">
<label class="form-label">卡券类型 <span class="text-danger">*</span></label>
<select class="form-select" id="cardType" onchange="toggleCardTypeFields()" required>
<option value="">请选择类型</option>
<option value="api">API接口</option>
<option value="text">固定文字</option>
<option value="data">批量数据</option>
<option value="image">图片</option>
</select>
</div>
<!-- API配置 -->
<div id="apiFields" class="card mb-3" style="display: none;">
<div class="card-header">
<h6 class="mb-0">API配置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">API地址</label>
<input type="url" class="form-control" id="apiUrl" placeholder="https://api.example.com/get-card">
</div>
<div class="row">
<div class="col-md-6">
<label class="form-label">请求方法</label>
<select class="form-select" id="apiMethod">
<option value="GET">GET</option>
<option value="POST">POST</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">超时时间(秒)</label>
<input type="number" class="form-control" id="apiTimeout" value="10" min="1" max="60">
</div>
</div>
<div class="mb-3">
<label class="form-label">请求头 (JSON格式)</label>
<textarea class="form-control" id="apiHeaders" rows="3" placeholder='{"Authorization": "Bearer token", "Content-Type": "application/json"}'></textarea>
</div>
<div class="mb-3">
<label class="form-label">请求参数 (JSON格式)</label>
<textarea class="form-control" id="apiParams" rows="3" placeholder='{"type": "card", "count": 1}'></textarea>
<!-- POST类型参数提示 -->
<div id="postParamsHelp" class="mt-2" style="display: none;">
<small class="form-text text-muted">
<i class="bi bi-info-circle me-1"></i>
<strong>POST请求可用参数可选</strong>
</small>
<div class="mt-2">
<div class="row">
<div class="col-md-6">
<div class="param-item mb-2">
<code class="param-name">order_id</code>
<span class="text-muted ms-2">订单编号</span>
</div>
<div class="param-item mb-2">
<code class="param-name">item_id</code>
<span class="text-muted ms-2">商品编号</span>
</div>
<div class="param-item mb-2">
<code class="param-name">item_detail</code>
<span class="text-muted ms-2">商品详情</span>
</div>
<div class="param-item mb-2">
<code class="param-name">order_amount</code>
<span class="text-muted ms-2">订单金额</span>
</div>
</div>
<div class="col-md-6">
<div class="param-item mb-2">
<code class="param-name">order_quantity</code>
<span class="text-muted ms-2">订单数量</span>
</div>
<div class="param-item mb-2">
<code class="param-name">spec_name</code>
<span class="text-muted ms-2">规格名称</span>
</div>
<div class="param-item mb-2">
<code class="param-name">spec_value</code>
<span class="text-muted ms-2">规格值</span>
</div>
<div class="param-item mb-2">
<code class="param-name">cookie_id</code>
<span class="text-muted ms-2">cookies账号id</span>
</div>
<div class="param-item mb-2">
<code class="param-name">buyer_id</code>
<span class="text-muted ms-2">买家id</span>
</div>
</div>
</div>
<div class="alert alert-info mt-2 mb-0">
<small>
<i class="bi bi-lightbulb me-1"></i>
<strong>使用说明:</strong>这些参数都是可选的您可以根据API需要选择使用。例如
<br>
<code>{"order_id": "{order_id}", "item_id": "{item_id}", "quantity": "{order_quantity}"}</code>
</small>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 固定文字配置 -->
<div id="textFields" class="card mb-3" style="display: none;">
<div class="card-header">
<h6 class="mb-0">固定文字配置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">固定文字内容</label>
<textarea class="form-control" id="textContent" rows="5" placeholder="请输入要发送的固定文字内容..."></textarea>
</div>
</div>
</div>
<!-- 批量数据配置 -->
<div id="dataFields" class="card mb-3" style="display: none;">
<div class="card-header">
<h6 class="mb-0">批量数据配置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">数据内容 (一行一个)</label>
<textarea class="form-control" id="dataContent" rows="10" placeholder="请输入数据,每行一个:&#10;卡号1:密码1&#10;卡号2:密码2&#10;或者&#10;兑换码1&#10;兑换码2"></textarea>
<small class="form-text text-muted">支持格式:卡号:密码 或 单独的兑换码</small>
</div>
</div>
</div>
<!-- 图片配置 -->
<div id="imageFields" class="card mb-3" style="display: none;">
<div class="card-header">
<h6 class="mb-0">图片配置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">选择图片 <span class="text-danger">*</span></label>
<input type="file" class="form-control" id="cardImageFile" accept="image/*">
<small class="form-text text-muted">
<i class="bi bi-info-circle me-1"></i>
支持JPG、PNG、GIF格式最大5MB建议尺寸不超过4096x4096像素
</small>
</div>
<div id="cardImagePreview" class="mb-3" style="display: none;">
<label class="form-label">图片预览</label>
<div class="preview-container">
<img id="cardPreviewImg" src="" alt="预览图片"
style="max-width: 100%; max-height: 300px; border-radius: 8px; border: 1px solid #ddd;">
</div>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">延时发货时间</label>
<div class="input-group">
<input type="number" class="form-control" id="cardDelaySeconds" value="0" min="0" max="3600" placeholder="0">
<span class="input-group-text"></span>
</div>
<small class="form-text text-muted">
<i class="bi bi-clock me-1"></i>
设置自动发货的延时时间0表示立即发货最大3600秒(1小时)
</small>
</div>
<div class="mb-3">
<label class="form-label">备注信息</label>
<textarea class="form-control" id="cardDescription" rows="3" placeholder="可选的备注信息,支持变量替换:&#10;{DELIVERY_CONTENT} - 发货内容&#10;例如:您的卡券信息:{DELIVERY_CONTENT},请妥善保管。"></textarea>
<small class="form-text text-muted">
<i class="bi bi-info-circle me-1"></i>
备注内容会与发货内容一起发送。使用 <code>{DELIVERY_CONTENT}</code> 变量可以在备注中插入实际的发货内容。
</small>
</div>
<!-- 多规格设置 -->
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="isMultiSpec" onchange="toggleMultiSpecFields()">
<label class="form-check-label" for="isMultiSpec">
<strong>多规格卡券</strong>
</label>
</div>
<div class="form-text">开启后可以为同一商品的不同规格创建不同的卡券</div>
</div>
<!-- 多规格字段 -->
<div id="multiSpecFields" style="display: none;">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">规格名称 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="specName" placeholder="例如:套餐类型、颜色、尺寸">
<div class="form-text">规格的名称,如套餐类型、颜色等</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">规格值 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="specValue" placeholder="例如30天、红色、XL">
<div class="form-text">具体的规格值如30天、红色等</div>
</div>
</div>
</div>
<div class="alert alert-info">
<i class="bi bi-info-circle"></i>
<strong>多规格说明:</strong>
<ul class="mb-0 mt-2">
<li>同一卡券名称可以创建多个不同规格的卡券</li>
<li>卡券名称+规格名称+规格值必须唯一</li>
<li>自动发货时会优先匹配精确规格,找不到时使用普通卡券兜底</li>
</ul>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="saveCard()">保存卡券</button>
</div>
</div>
</div>
</div>
<!-- 编辑卡券模态框 -->
<div class="modal fade" id="editCardModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-pencil me-2"></i>
编辑卡券
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="editCardForm">
<input type="hidden" id="editCardId">
<div class="mb-3">
<label class="form-label">卡券名称 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="editCardName" required>
</div>
<div class="mb-3">
<label class="form-label">卡券类型 <span class="text-danger">*</span></label>
<select class="form-select" id="editCardType" onchange="toggleEditCardTypeFields()" required>
<option value="api">API接口</option>
<option value="text">固定文字</option>
<option value="data">批量数据</option>
<option value="image">图片</option>
</select>
</div>
<!-- API配置 -->
<div id="editApiFields" class="card mb-3" style="display: none;">
<div class="card-header">
<h6 class="mb-0">API配置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">API地址</label>
<input type="url" class="form-control" id="editApiUrl">
</div>
<div class="row">
<div class="col-md-6">
<label class="form-label">请求方法</label>
<select class="form-select" id="editApiMethod">
<option value="GET">GET</option>
<option value="POST">POST</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">超时时间(秒)</label>
<input type="number" class="form-control" id="editApiTimeout" value="10" min="1" max="60">
</div>
</div>
<div class="mb-3">
<label class="form-label">请求头 (JSON格式)</label>
<textarea class="form-control" id="editApiHeaders" rows="3"></textarea>
</div>
<div class="mb-3">
<label class="form-label">请求参数 (JSON格式)</label>
<textarea class="form-control" id="editApiParams" rows="3"></textarea>
<!-- POST类型参数提示 -->
<div id="editPostParamsHelp" class="mt-2" style="display: none;">
<small class="form-text text-muted">
<i class="bi bi-info-circle me-1"></i>
<strong>POST请求可用参数可选</strong>
</small>
<div class="mt-2">
<div class="row">
<div class="col-md-6">
<div class="param-item mb-2">
<code class="param-name">order_id</code>
<span class="text-muted ms-2">订单编号</span>
</div>
<div class="param-item mb-2">
<code class="param-name">item_id</code>
<span class="text-muted ms-2">商品编号</span>
</div>
<div class="param-item mb-2">
<code class="param-name">item_detail</code>
<span class="text-muted ms-2">商品详情</span>
</div>
<div class="param-item mb-2">
<code class="param-name">order_amount</code>
<span class="text-muted ms-2">订单金额</span>
</div>
</div>
<div class="col-md-6">
<div class="param-item mb-2">
<code class="param-name">order_quantity</code>
<span class="text-muted ms-2">订单数量</span>
</div>
<div class="param-item mb-2">
<code class="param-name">spec_name</code>
<span class="text-muted ms-2">规格名称</span>
</div>
<div class="param-item mb-2">
<code class="param-name">spec_value</code>
<span class="text-muted ms-2">规格值</span>
</div>
<div class="param-item mb-2">
<code class="param-name">cookie_id</code>
<span class="text-muted ms-2">cookies账号id</span>
</div>
<div class="param-item mb-2">
<code class="param-name">buyer_id</code>
<span class="text-muted ms-2">买家id</span>
</div>
</div>
</div>
<div class="alert alert-info mt-2 mb-0">
<small>
<i class="bi bi-lightbulb me-1"></i>
<strong>使用说明:</strong>这些参数都是可选的您可以根据API需要选择使用。例如
<br>
<code>{"order_id": "{order_id}", "item_id": "{item_id}", "quantity": "{order_quantity}"}</code>
</small>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 固定文字配置 -->
<div id="editTextFields" class="card mb-3" style="display: none;">
<div class="card-header">
<h6 class="mb-0">固定文字配置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">固定文字内容</label>
<textarea class="form-control" id="editTextContent" rows="5"></textarea>
</div>
</div>
</div>
<!-- 批量数据配置 -->
<div id="editDataFields" class="card mb-3" style="display: none;">
<div class="card-header">
<h6 class="mb-0">批量数据配置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">数据内容 (一行一个)</label>
<textarea class="form-control" id="editDataContent" rows="10"></textarea>
<small class="form-text text-muted">支持格式:卡号:密码 或 单独的兑换码</small>
</div>
</div>
</div>
<!-- 图片配置 -->
<div id="editImageFields" class="card mb-3" style="display: none;">
<div class="card-header">
<h6 class="mb-0">图片配置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">当前图片</label>
<div id="editCurrentImagePreview" style="display: none;">
<img id="editCurrentImg" src="" alt="当前图片"
style="max-width: 100%; max-height: 200px; border-radius: 8px; border: 1px solid #ddd;">
<div class="mt-2">
<small class="text-muted">当前使用的图片</small>
</div>
</div>
<div id="editNoImageText" class="text-muted">
<i class="bi bi-image me-1"></i>暂无图片
</div>
</div>
<div class="mb-3">
<label class="form-label">更换图片</label>
<input type="file" class="form-control" id="editCardImageFile" accept="image/*">
<small class="form-text text-muted">
<i class="bi bi-info-circle me-1"></i>
支持JPG、PNG、GIF格式最大5MB建议尺寸不超过4096x4096像素
</small>
</div>
<div id="editCardImagePreview" class="mb-3" style="display: none;">
<label class="form-label">新图片预览</label>
<div class="preview-container">
<img id="editCardPreviewImg" src="" alt="预览图片"
style="max-width: 100%; max-height: 300px; border-radius: 8px; border: 1px solid #ddd;">
</div>
</div>
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="editCardEnabled">
<label class="form-check-label" for="editCardEnabled">
启用此卡券
</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">延时发货时间</label>
<div class="input-group">
<input type="number" class="form-control" id="editCardDelaySeconds" value="0" min="0" max="3600" placeholder="0">
<span class="input-group-text"></span>
</div>
<small class="form-text text-muted">
<i class="bi bi-clock me-1"></i>
设置自动发货的延时时间0表示立即发货最大3600秒(1小时)
</small>
</div>
<div class="mb-3">
<label class="form-label">备注信息</label>
<textarea class="form-control" id="editCardDescription" rows="3" placeholder="可选的备注信息,支持变量替换:&#10;{DELIVERY_CONTENT} - 发货内容&#10;例如:您的卡券信息:{DELIVERY_CONTENT},请妥善保管。"></textarea>
<small class="form-text text-muted">
<i class="bi bi-info-circle me-1"></i>
备注内容会与发货内容一起发送。使用 <code>{DELIVERY_CONTENT}</code> 变量可以在备注中插入实际的发货内容。
</small>
</div>
<!-- 多规格设置 -->
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="editIsMultiSpec" onchange="toggleEditMultiSpecFields()">
<label class="form-check-label" for="editIsMultiSpec">
<strong>多规格卡券</strong>
</label>
</div>
<div class="form-text">开启后可以为同一商品的不同规格创建不同的卡券</div>
</div>
<!-- 多规格字段 -->
<div id="editMultiSpecFields" style="display: none;">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">规格名称 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="editSpecName" placeholder="例如:套餐类型、颜色、尺寸">
<div class="form-text">规格的名称,如套餐类型、颜色等</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">规格值 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="editSpecValue" placeholder="例如30天、红色、XL">
<div class="form-text">具体的规格值如30天、红色等</div>
</div>
</div>
</div>
<div class="alert alert-info">
<i class="bi bi-info-circle"></i>
<strong>多规格说明:</strong>
<ul class="mb-0 mt-2">
<li>同一卡券名称可以创建多个不同规格的卡券</li>
<li>卡券名称+规格名称+规格值必须唯一</li>
<li>自动发货时会优先匹配精确规格,找不到时使用普通卡券兜底</li>
</ul>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="updateCard()">保存修改</button>
</div>
</div>
</div>
</div>
<!-- 添加发货规则模态框 -->
<div class="modal fade" id="addDeliveryRuleModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-truck me-2"></i>
添加发货规则
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="addDeliveryRuleForm">
<div class="mb-3">
<label class="form-label">商品关键字 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="productKeyword" placeholder="例如:游戏点卡、会员卡等" required>
<small class="form-text text-muted">当商品标题包含此关键字时触发自动发货</small>
</div>
<div class="mb-3">
<label class="form-label">匹配卡券 <span class="text-danger">*</span></label>
<select class="form-select" id="selectedCard" required>
<option value="">请选择卡券</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">发货数量</label>
<input type="number" class="form-control" id="deliveryCount" value="1" min="1" max="10">
<small class="form-text text-muted">每次发货的数量</small>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="ruleEnabled" checked>
<label class="form-check-label" for="ruleEnabled">
启用此规则
</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">备注</label>
<textarea class="form-control" id="ruleDescription" rows="2" placeholder="可选的备注信息..."></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="saveDeliveryRule()">保存规则</button>
</div>
</div>
</div>
</div>
<!-- 编辑发货规则模态框 -->
<div class="modal fade" id="editDeliveryRuleModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-pencil me-2"></i>
编辑发货规则
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="editDeliveryRuleForm">
<input type="hidden" id="editRuleId">
<div class="mb-3">
<label class="form-label">商品关键字 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="editProductKeyword" required>
<small class="form-text text-muted">当商品标题包含此关键字时触发自动发货</small>
</div>
<div class="mb-3">
<label class="form-label">匹配卡券 <span class="text-danger">*</span></label>
<select class="form-select" id="editSelectedCard" required>
<option value="">请选择卡券</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">发货数量</label>
<input type="number" class="form-control" id="editDeliveryCount" value="1" min="1" max="10">
<small class="form-text text-muted">每次发货的数量</small>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="editRuleEnabled">
<label class="form-check-label" for="editRuleEnabled">
启用此规则
</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">备注</label>
<textarea class="form-control" id="editRuleDescription" rows="2"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="updateDeliveryRule()">保存修改</button>
</div>
</div>
</div>
</div>
<!-- 加载动画 -->
<div class="loading d-none" id="loading">
<div class="spinner-border text-primary loading-spinner" role="status">
<span class="visually-hidden">加载中...</span>
</div>
</div>
<!-- 提示消息容器 -->
<div class="toast-container"></div>
<!-- JS依赖 -->
<script src="/static/lib/bootstrap/bootstrap.bundle.min.js"></script>
<script src="/static/js/app.js?v=2.2.0"></script>
<!-- 默认回复管理模态框 -->
<div class="modal fade" id="defaultReplyModal" tabindex="-1" aria-labelledby="defaultReplyModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="defaultReplyModalLabel">
<i class="bi bi-chat-text me-2"></i>默认回复管理
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="alert alert-info">
<i class="bi bi-info-circle me-2"></i>
<strong>功能说明:</strong>当没有匹配到关键词时,系统会使用默认回复。支持以下变量:
<code>{send_user_name}</code> 用户昵称、
<code>{send_user_id}</code> 用户ID、
<code>{send_message}</code> 用户消息
<br><br>
<strong>只回复一次:</strong>开启后,每个对话只会触发一次默认回复,避免重复回复同一用户。
</div>
<div class="table-responsive">
<table class="table table-hover" id="defaultReplyTable">
<thead>
<tr>
<th style="width: 15%">账号ID</th>
<th style="width: 12%">状态</th>
<th style="width: 12%">只回复一次</th>
<th style="width: 41%">默认回复内容</th>
<th style="width: 20%">操作</th>
</tr>
</thead>
<tbody id="defaultReplyTableBody">
<!-- 动态生成 -->
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<div class="text-muted me-auto">
<small><i class="bi bi-info-circle me-1"></i>请点击每个账号的"编辑"按钮进行单独设置</small>
</div>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">
<i class="bi bi-check-circle me-1"></i>完成
</button>
</div>
</div>
</div>
</div>
<!-- 编辑默认回复模态框 -->
<div class="modal fade" id="editDefaultReplyModal" tabindex="-1" aria-labelledby="editDefaultReplyModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editDefaultReplyModalLabel">
<i class="bi bi-pencil-square me-2"></i>编辑默认回复
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="editDefaultReplyForm">
<input type="hidden" id="editAccountId" />
<div class="mb-3">
<label class="form-label">账号ID</label>
<input type="text" class="form-control" id="editAccountIdDisplay" readonly />
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="editDefaultReplyEnabled" onchange="toggleReplyContentVisibility()" />
<label class="form-check-label" for="editDefaultReplyEnabled">
启用默认回复
</label>
</div>
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="editReplyOnce" />
<label class="form-check-label" for="editReplyOnce">
只回复一次
</label>
<div class="form-text">
<i class="bi bi-info-circle me-1"></i>
开启后,每个对话只会触发一次默认回复,避免重复回复
</div>
</div>
</div>
<div class="mb-3" id="editReplyContentGroup">
<label for="editReplyContent" class="form-label">默认回复内容</label>
<textarea class="form-control" id="editReplyContent" rows="4"
placeholder="请输入默认回复内容,支持变量:{send_user_name} {send_user_id} {send_message}"></textarea>
<div class="form-text">
<strong>可用变量:</strong>
<span class="badge bg-secondary me-1">{send_user_name}</span>
<span class="badge bg-secondary me-1">{send_user_id}</span>
<span class="badge bg-secondary me-1">{send_message}</span>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="saveDefaultReply()">
<i class="bi bi-check-circle me-1"></i>保存
</button>
</div>
</div>
</div>
</div>
<!-- 编辑商品详情模态框 -->
<div class="modal fade" id="editItemModal" tabindex="-1">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-pencil me-2"></i>编辑商品详情
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="editItemForm">
<input type="hidden" id="editItemCookieId">
<input type="hidden" id="editItemId">
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label">账号ID</label>
<input type="text" class="form-control" id="editItemCookieIdDisplay" readonly>
</div>
<div class="col-md-6">
<label class="form-label">商品ID</label>
<input type="text" class="form-control" id="editItemIdDisplay" readonly>
</div>
</div>
<div class="mb-3">
<label for="editItemDetail" class="form-label">商品详情 <span class="text-danger">*</span></label>
<textarea class="form-control" id="editItemDetail" rows="20"
placeholder="请输入商品详情内容..."></textarea>
<div class="form-text">
<i class="bi bi-info-circle me-1"></i>
请输入商品详情内容,这些内容将用于自动发货时的关键词匹配。
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="saveItemDetail()">
<i class="bi bi-check-circle me-1"></i>保存
</button>
</div>
</div>
</div>
</div>
<!-- AI回复配置模态框 -->
<div class="modal fade" id="aiReplyConfigModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-robot me-2"></i>AI回复配置
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="aiReplyConfigForm">
<input type="hidden" id="aiConfigAccountId">
<!-- 基本设置 -->
<div class="card mb-3">
<div class="card-header">
<h6 class="mb-0"><i class="bi bi-gear me-2"></i>基本设置</h6>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label">账号ID</label>
<input type="text" class="form-control" id="aiConfigAccountIdDisplay" readonly>
</div>
<div class="col-md-6">
<div class="form-check form-switch mt-4">
<input class="form-check-input" type="checkbox" id="aiReplyEnabled"
onchange="toggleAIReplySettings()">
<label class="form-check-label" for="aiReplyEnabled">
<strong>启用AI回复</strong>
</label>
<small class="form-text text-muted d-block">启用后将自动禁用关键词匹配和默认回复</small>
</div>
</div>
</div>
<div id="aiReplySettings" style="display: none;">
<div class="row mb-3">
<div class="col-md-6">
<label for="aiModelName" class="form-label"></label>AI模型</label>
<select class="form-select" id="aiModelName" onchange="toggleCustomModelInput()">
<option value="qwen-plus">通义千问Plus</option>
<option value="qwen-turbo">通义千问Turbo</option>
<option value="qwen-max">通义千问Max</option>
<option value="gpt-3.5-turbo">GPT-3.5 Turbo</option>
<option value="gpt-4">GPT-4</option>
<option value="custom">自定义模型</option>
</select>
<input type="text" class="form-control mt-2" id="customModelName" placeholder="请输入自定义模型名称"
style="display: none;">
</div>
<div class="col-md-6">
<label for="aiBaseUrl" class="form-label">API地址</label>
<input type="url" class="form-control" id="aiBaseUrl"
value="https://dashscope.aliyuncs.com/compatible-mode/v1" placeholder="API Base URL">
</div>
</div>
<div class="mb-3">
<label for="aiApiKey" class="form-label">API密钥 <span class="text-danger">*</span></label>
<input type="password" class="form-control" id="aiApiKey" placeholder="请输入API密钥" required>
<small class="form-text text-muted">
通义千问请使用DashScope API KeyGPT请使用OpenAI API Key
</small>
</div>
</div>
</div>
</div>
<!-- 议价设置 -->
<div class="card mb-3" id="bargainSettings" style="display: none;">
<div class="card-header">
<h6 class="mb-0"><i class="bi bi-currency-dollar me-2"></i>议价设置</h6>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-md-4">
<label for="maxDiscountPercent" class="form-label">最大优惠百分比</label>
<div class="input-group">
<input type="number" class="form-control" id="maxDiscountPercent"
min="0" max="50" value="10">
<span class="input-group-text">%</span>
</div>
</div>
<div class="col-md-4">
<label for="maxDiscountAmount" class="form-label">最大优惠金额</label>
<div class="input-group">
<input type="number" class="form-control" id="maxDiscountAmount"
min="0" value="100">
<span class="input-group-text"></span>
</div>
</div>
<div class="col-md-4">
<label for="maxBargainRounds" class="form-label">最大议价轮数</label>
<input type="number" class="form-control" id="maxBargainRounds"
min="1" max="10" value="3">
</div>
</div>
</div>
</div>
<!-- 提示词设置 -->
<div class="card mb-3" id="promptSettings" style="display: none;">
<div class="card-header">
<h6 class="mb-0"><i class="bi bi-chat-quote me-2"></i>提示词设置</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">自定义提示词 (JSON格式)</label>
<textarea class="form-control" id="customPrompts" rows="8"
placeholder='{"classify": "分类提示词", "price": "议价提示词", "tech": "技术提示词", "default": "默认提示词"}'></textarea>
<small class="form-text text-muted">
留空使用系统默认提示词。格式:{"classify": "...", "price": "...", "tech": "...", "default": "..."}
</small>
</div>
</div>
</div>
<!-- 测试区域 -->
<div class="card" id="testArea" style="display: none;">
<div class="card-header">
<h6 class="mb-0"><i class="bi bi-play-circle me-2"></i>功能测试</h6>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-md-6">
<label for="testMessage" class="form-label">测试消息</label>
<input type="text" class="form-control" id="testMessage"
value="你好,这个商品能便宜点吗?" placeholder="输入测试消息">
</div>
<div class="col-md-6">
<label for="testItemPrice" class="form-label">商品价格</label>
<input type="number" class="form-control" id="testItemPrice"
value="100" placeholder="商品价格">
</div>
</div>
<button type="button" class="btn btn-outline-primary" onclick="testAIReply()">
<i class="bi bi-play me-1"></i>测试AI回复
</button>
<div id="testResult" class="mt-3" style="display: none;">
<div class="alert alert-info">
<strong>AI回复</strong>
<div id="testReplyContent"></div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="saveAIReplyConfig()">
<i class="bi bi-check-lg me-1"></i>保存配置
</button>
</div>
</div>
</div>
</div>
<!-- 导入关键词模态框 -->
<div class="modal fade" id="importKeywordsModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-upload me-2"></i>导入关键词
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">选择Excel文件</label>
<input type="file" class="form-control" id="importFileInput" accept=".xlsx,.xls">
<div class="form-text">
<i class="bi bi-info-circle me-1"></i>
请上传包含"关键词"、"商品ID"、"关键词内容"三列的Excel文件仅导入文本类型关键词图片关键词将保留
</div>
</div>
<div class="alert alert-warning">
<h6><i class="bi bi-exclamation-triangle me-1"></i>导入说明:</h6>
<ul class="mb-0">
<li>Excel文件必须包含三列关键词、商品ID、关键词内容</li>
<li>商品ID可以为空表示通用关键词</li>
<li>导入的关键词默认为文本类型</li>
<li>如果关键词+商品ID组合已存在将更新关键词内容</li>
<li><strong>导入只会替换文本类型关键词,图片关键词将被保留</strong></li>
<li>导入完成后,您的图片关键词仍然存在且正常工作</li>
</ul>
</div>
<div id="importProgress" style="display: none;">
<div class="progress mb-2">
<div class="progress-bar" role="progressbar" style="width: 0%"></div>
</div>
<small class="text-muted">正在导入...</small>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="importKeywords()">
<i class="bi bi-upload me-1"></i>开始导入
</button>
</div>
</div>
</div>
</div>
<!-- 添加图片关键词模态框 -->
<div class="modal fade" id="addImageKeywordModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-image me-2"></i>添加图片关键词
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="addImageKeywordForm">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">关键词 <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="imageKeyword" placeholder="例如:图片、照片" required>
<div class="form-text">用户发送此关键词时将回复图片</div>
</div>
<div class="mb-3">
<label class="form-label">关联商品(可选)</label>
<select class="form-select" id="imageItemIdSelect">
<option value="">选择商品或留空表示通用关键词</option>
</select>
<div class="form-text">选择特定商品时,仅在该商品对话中生效</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">上传图片 <span class="text-danger">*</span></label>
<input type="file" class="form-control" id="imageFile" accept="image/*" required>
<div class="form-text">支持 JPG、PNG、GIF 格式,建议大小不超过 5MB</div>
</div>
<div class="mb-3">
<div class="image-preview" id="imagePreview" style="display: none;">
<label class="form-label">图片预览</label>
<div class="preview-container">
<img id="previewImg" src="" alt="预览图片" style="max-width: 100%; max-height: 200px; border-radius: 8px; border: 1px solid #ddd;">
</div>
</div>
</div>
</div>
</div>
<div class="alert alert-info">
<i class="bi bi-info-circle me-2"></i>
<strong>说明:</strong>
<ul class="mb-0 mt-2">
<li>图片关键词优先级高于文本关键词</li>
<li>用户发送匹配的关键词时,系统将回复上传的图片</li>
<li>图片将被转换为适合聊天的格式</li>
</ul>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="addImageKeyword()">
<i class="bi bi-plus-lg me-1"></i>添加图片关键词
</button>
</div>
</div>
</div>
</div>
<!-- 删除用户确认模态框 -->
<div class="modal fade" id="deleteUserModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-exclamation-triangle text-warning me-2"></i>
确认删除用户
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>您确定要删除这个用户吗?</p>
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>警告:</strong>此操作将同时删除该用户的所有数据包括Cookie、关键词、卡券等且不可撤销
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-danger" onclick="confirmDeleteUser()">
<i class="bi bi-trash"></i> 确认删除
</button>
</div>
</div>
</div>
</div>
<!-- 删除数据记录确认模态框 -->
<div class="modal fade" id="deleteRecordModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="bi bi-exclamation-triangle text-warning me-2"></i>
确认删除记录
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>您确定要删除这条记录吗?</p>
<div class="alert alert-info">
<i class="bi bi-info-circle me-2"></i>
<strong>记录信息:</strong>
<div id="deleteRecordInfo" class="mt-2">
<!-- 记录信息将在这里显示 -->
</div>
</div>
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>警告:</strong>此操作不可撤销!
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-danger" onclick="confirmDeleteRecord()">
<i class="bi bi-trash"></i> 确认删除
</button>
</div>
</div>
</div>
</div>
</body>
</html>