You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3287 lines
155 KiB

2 months ago
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>客户管理系统</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f5f7fa;
color: #333;
}
.header {
background-color: #1890ff;
color: white;
padding: 15px 30px;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.header h1 {
font-size: 24px;
font-weight: bold;
text-align: center;
}
.user-info {
position: absolute;
top: 15px;
right: 30px;
display: flex;
align-items: center;
gap: 15px;
}
.user-info span {
font-size: 14px;
}
.logout-btn {
background: transparent;
color: white;
border: 1px solid white;
padding: 5px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.logout-btn:hover {
background-color: rgba(255,255,255,0.2);
}
.container {
width: 100%;
margin: 30px 0;
padding: 0 20px;
box-sizing: border-box;
}
.data-section {
width: 100%;
}
table {
width: 100%;
2 months ago
}
.user-details {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
margin-bottom: 30px;
}
.user-details h2 {
font-size: 18px;
font-weight: bold;
margin-bottom: 15px;
color: #333;
}
.detail-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
.detail-item {
display: flex;
flex-direction: column;
}
.detail-label {
font-size: 12px;
color: #999;
margin-bottom: 5px;
}
.detail-value {
font-size: 14px;
color: #333;
font-weight: 500;
}
.data-section {
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
overflow: hidden;
}
.section-header {
background-color: #f0f2f5;
padding: 0;
border-bottom: 1px solid #e8e8e8;
}
.tab-container {
display: flex;
background-color: #fafafa;
}
.tab-button {
flex: 1;
padding: 15px 20px;
background-color: #fafafa;
border: none;
border-bottom: 2px solid transparent;
font-size: 16px;
font-weight: 500;
color: #666;
cursor: pointer;
transition: all 0.3s ease;
}
.tab-button.active {
background-color: white;
color: #1890ff;
border-bottom-color: #1890ff;
}
.tab-button:hover {
color: #1890ff;
}
.section-content {
padding: 20px;
}
.filter-bar {
margin-bottom: 20px;
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
}
.filter-bar span {
white-space: nowrap;
}
.filter-bar input[type="date"] {
white-space: nowrap;
min-width: 130px;
}
.filter-bar select {
white-space: nowrap;
min-width: 100px;
}
.filter-bar input[type="text"] {
white-space: nowrap;
min-width: 150px;
2 months ago
}
.filter-bar button {
padding: 8px 12px;
background-color: #1890ff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
white-space: nowrap;
min-width: 80px;
2 months ago
}
.filter-bar button:hover {
background-color: #40a9ff;
}
.filter-bar select {
padding: 8px 16px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
background-color: white;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 12px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
.filter-bar select:hover {
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.filter-bar select:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
/* 弹窗下拉框样式优化 */
#returnType {
padding: 10px 16px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
background-color: white;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 12px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
table-layout: auto;
}
/* 复选框列 */
th:nth-child(1), td:nth-child(1) {
width: 40px;
text-align: center;
}
/* 跟进内容列 */
th:nth-child(6), td:nth-child(6) {
min-width: 200px;
}
/* 操作列 */
th:nth-child(9), td:nth-child(9) {
min-width: 100px;
}
th {
background-color: #1890ff;
color: white;
padding: 14px 12px;
text-align: left;
font-weight: bold;
border-bottom: 2px solid #1890ff;
font-size: 14px;
}
td {
padding: 12px;
border-bottom: 1px solid #e8e8e8;
color: #333;
word-wrap: break-word;
word-break: break-all;
font-size: 14px;
}
tr:hover {
background-color: #f0f7ff;
}
tr:nth-child(even) {
background-color: #fafafa;
}
table {
border-collapse: collapse;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
2 months ago
}
.data-section {
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
overflow: hidden;
2 months ago
}
.section-content {
padding: 0;
2 months ago
}
.filter-bar {
margin: 0;
padding: 15px 20px;
background-color: #fafafa;
border-bottom: 1px solid #e8e8e8;
2 months ago
}
.pagination {
margin: 0;
padding: 15px 20px;
2 months ago
display: flex;
justify-content: center;
gap: 8px;
background-color: #fafafa;
border-top: 1px solid #e8e8e8;
2 months ago
}
.pagination button {
padding: 8px 14px;
2 months ago
border: 1px solid #d9d9d9;
background-color: white;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
}
.pagination button:hover:not(:disabled) {
border-color: #1890ff;
color: #1890ff;
2 months ago
}
.pagination button.active {
background-color: #1890ff;
color: white;
border-color: #1890ff;
}
.pagination button:disabled {
color: #ccc;
cursor: not-allowed;
border-color: #e8e8e8;
2 months ago
}
.empty-state {
text-align: center;
padding: 60px 20px;
color: #999;
font-size: 14px;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
@media (max-width: 768px) {
.user-info {
position: static;
margin-top: 15px;
justify-content: center;
}
.container {
padding: 0 15px;
}
}
/* 动画效果 */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideIn {
from {
opacity: 0;
transform: translate(-50%, -50%) scale(0.95);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}
/* 弹窗输入框和下拉框样式优化 */
#followupContent:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
#returnType:hover {
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
#returnType:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
/* 弹窗按钮样式优化 */
#followupModal button:hover,
#returnModal button:hover {
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
#followupModal button:active,
#returnModal button:active {
transform: translateY(0);
}
/* 搜索选择组件样式 */
.search-select-option:hover {
background-color: #f0f7ff;
color: #1890ff;
}
/* 搜索输入框焦点样式 */
#followupRegionSearch:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
/* 表格容器样式,添加横向滚动 */
.table-container {
width: 100%;
overflow-x: auto;
margin: 0;
padding: 0;
}
.table-container table {
width: auto;
min-width: 100%;
}
/* 确保表格列宽正确显示 */
.table-container th,
.table-container td {
white-space: nowrap;
}
/* 允许创建时间列换行 */
.table-container th:nth-child(5),
.table-container td:nth-child(5) {
white-space: normal;
min-width: 120px;
}
/* 筛选容器样式,添加横向滚动 */
.filter-container {
width: 100%;
overflow-x: auto;
margin: 0;
padding: 0;
scrollbar-width: thin;
scrollbar-color: #1890ff #f0f0f0;
}
.filter-container::-webkit-scrollbar {
height: 6px;
}
.filter-container::-webkit-scrollbar-track {
background: #f0f0f0;
border-radius: 3px;
}
.filter-container::-webkit-scrollbar-thumb {
background: #1890ff;
border-radius: 3px;
}
.filter-container::-webkit-scrollbar-thumb:hover {
background: #40a9ff;
}
.filter-container .filter-bar {
width: auto;
min-width: 100%;
flex-wrap: wrap;
padding: 10px 0;
}
/* 标签页容器样式,添加横向滚动 */
.tab-container-scroll {
width: 100%;
overflow-x: auto;
margin: 0;
padding: 0;
}
.tab-container-scroll .tab-container {
width: auto;
min-width: 100%;
}
/* 用户信息容器样式,添加横向滚动 */
.user-details-container {
width: 100%;
overflow-x: auto;
margin: 0;
padding: 0;
}
.user-details-container .user-details {
width: auto;
min-width: 100%;
}
.user-details-container .detail-grid {
width: auto;
min-width: 100%;
}
2 months ago
</style>
</head>
<body>
<div class="header">
<h1>客户管理系统</h1>
<div class="user-info">
<span id="userRole"></span>
<span id="userName"></span>
<button class="logout-btn" onclick="logout()">退出登录</button>
</div>
</div>
<div class="container">
<div class="user-details-container">
<div class="user-details">
<h2>用户信息</h2>
<div class="detail-grid">
2 months ago
<div class="detail-item">
<div class="detail-label">职位名称</div>
<div class="detail-value" id="projectName"></div>
</div>
<div class="detail-item">
<div class="detail-label">用户名</div>
<div class="detail-value" id="userNameDetail"></div>
</div>
<div class="detail-item">
<div class="detail-label">负责公司</div>
<div class="detail-value" id="managerCompany"></div>
</div>
<div class="detail-item">
<div class="detail-label">负责部门</div>
<div class="detail-value" id="managerDepartment"></div>
</div>
<div class="detail-item">
<div class="detail-label">负责小组</div>
<div class="detail-value" id="organization"></div>
</div>
<div class="detail-item">
<div class="detail-label">角色</div>
<div class="detail-value" id="role"></div>
</div>
</div>
</div>
2 months ago
</div>
<div class="data-section">
<div class="section-header">
<div class="tab-container-scroll">
<div class="tab-container">
<button class="tab-button active" onclick="switchTab('personal', this)">个人数据</button>
<button class="tab-button" onclick="switchTab('public', this)">公海池数据</button>
</div>
2 months ago
</div>
</div>
<!-- 个人数据标签页 -->
<div class="section-content">
<div id="personal" class="tab-content active">
<div class="filter-container">
<div class="filter-bar">
2 months ago
<button onclick="loadPersonalData()">刷新数据</button>
<button onclick="filterPersonalData('all')" style="background-color: #52c41a;">全部</button>
<button onclick="filterPersonalData('followed')" style="background-color: #faad14;">已跟进</button>
<button onclick="filterPersonalData('unfollowed')" style="background-color: #ff4d4f;">未跟进</button>
<button id="assignButton" onclick="openAssignModal()" style="background-color: #722ed1;">分配</button>
<input type="text" id="personalPhoneSearch" placeholder="搜索手机号" style="margin-left: 20px; padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<button onclick="searchPersonalByPhone()" style="margin-left: 8px; padding: 4px 12px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 14px;">搜索</button>
<button onclick="resetPersonalPhoneSearch()" style="margin-left: 8px; padding: 4px 12px; background-color: #666; color: white; border: none; border-radius: 4px; font-size: 14px;">重置</button>
<select id="personalManagerFilter" onchange="filterPersonalByManager()" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<option value="">全部联系人</option>
</select>
<span style="margin-left: 20px; font-size: 14px;">类型:</span>
<select id="personalTypeFilter" onchange="filterPersonalByType()" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<option value="">全部类型</option>
<option value="wholesale">批发贸易类</option>
<option value="e-commerce">电商平台类</option>
<option value="delivery_retail">配送零售类</option>
<option value="defective_egg">次品蛋专项类</option>
<option value="other">其他类型</option>
</select>
<span style="margin-left: 20px; font-size: 14px;">创建时间:</span>
<input type="date" id="personalStartDate" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<span style="margin: 0 8px; font-size: 14px;"></span>
<input type="date" id="personalEndDate" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<button onclick="filterPersonalByDate()" style="margin-left: 8px; padding: 4px 12px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 14px;">筛选</button>
<button onclick="resetPersonalDateFilter()" style="margin-left: 8px; padding: 4px 12px; background-color: #666; color: white; border: none; border-radius: 4px; font-size: 14px;">重置</button>
<div style="margin-left: auto; display: flex; align-items: center; gap: 10px;">
<span style="font-size: 14px; color: #666;">总数: <span id="personalTotalCount">0</span></span>
<select id="personalPageSize" onchange="changePersonalPageSize()" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<option value="10">10条/页</option>
<option value="50">50条/页</option>
<option value="100">100条/页</option>
</select>
</div>
</div>
2 months ago
</div>
<div id="personalFilterTags" style="margin-top: 10px; margin-bottom: 10px;"></div>
<div class="table-container">
<table id="personalTable">
<thead>
<tr>
<th><input type="checkbox" id="selectAllPersonal" onclick="selectAll('personal')"></th>
<th>昵称</th>
<th>手机号</th>
<th>类型</th>
<th>创建时间</th>
<th>跟进内容</th>
<th>响应时间</th>
<th id="managerHeader">负责人</th>
<th>操作</th>
</tr>
</thead>
<tbody id="personalBody">
</tbody>
</table>
</div>
2 months ago
<div id="personalEmpty" class="empty-state">暂无个人数据</div>
<div class="pagination" id="personalPagination">
</div>
</div>
<!-- 公海池数据标签页 -->
<div id="public" class="tab-content">
<div class="filter-container">
<div class="filter-bar">
2 months ago
<button onclick="loadPublicData()">刷新数据</button>
<button id="publicAssignButton" onclick="openAssignModal()" style="background-color: #722ed1;">分配</button>
<input type="text" id="publicPhoneSearch" placeholder="搜索手机号" style="margin-left: 20px; padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<button onclick="searchPublicByPhone()" style="margin-left: 8px; padding: 4px 12px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 14px;">搜索</button>
<button onclick="resetPublicPhoneSearch()" style="margin-left: 8px; padding: 4px 12px; background-color: #666; color: white; border: none; border-radius: 4px; font-size: 14px;">重置</button>
<span style="margin-left: 20px; font-size: 14px;">负责人:</span>
<select id="publicManagerFilter" onchange="filterPublicByManager()" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<option value="">全部联系人</option>
</select>
<span style="margin-left: 20px; font-size: 14px;">类型:</span>
<select id="publicTypeFilter" onchange="filterPublicByType()" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<option value="">全部类型</option>
<option value="wholesale">批发贸易类</option>
<option value="e-commerce">电商平台类</option>
<option value="delivery_retail">配送零售类</option>
<option value="defective_egg">次品蛋专项类</option>
<option value="other">其他类型</option>
</select>
<span style="margin-left: 20px; font-size: 14px;">创建时间:</span>
<input type="date" id="publicStartDate" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<span style="margin: 0 8px; font-size: 14px;"></span>
<input type="date" id="publicEndDate" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<button onclick="filterPublicByDate()" style="margin-left: 8px; padding: 4px 12px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 14px;">筛选</button>
<button onclick="resetPublicDateFilter()" style="margin-left: 8px; padding: 4px 12px; background-color: #666; color: white; border: none; border-radius: 4px; font-size: 14px;">重置</button>
<div style="margin-left: auto; display: flex; align-items: center; gap: 10px;">
<select id="publicPageSize" onchange="changePublicPageSize()" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
<option value="10">10条/页</option>
<option value="50">50条/页</option>
<option value="100">100条/页</option>
</select>
</div>
</div>
2 months ago
</div>
<div id="publicFilterTags" style="margin-top: 10px; margin-bottom: 10px;"></div>
<div class="table-container">
<table id="publicTable">
<thead>
<tr>
<th><input type="checkbox" id="selectAllPublic" onclick="selectAll('public')"></th>
<th>昵称</th>
<th>手机号</th>
<th>类型</th>
<th>创建时间</th>
<th>跟进内容</th>
<th>响应时间</th>
<th id="publicManagerHeader">负责人</th>
<th>操作</th>
</tr>
</thead>
<tbody id="publicBody">
</tbody>
</table>
</div>
2 months ago
<div id="publicEmpty" class="empty-state">暂无公海池数据</div>
<div class="pagination" id="publicPagination">
</div>
</div>
</div>
</div>
</div>
<script>
var userInfo = null;
var personalPage = 1;
var publicPage = 1;
var personalPageSize = 10;
var publicPageSize = 10;
var personalFilter = 'all'; // all, followed, unfollowed
2 months ago
var managersList = [];
var allPersonalData = [];
var allPublicData = [];
var isLoadingAllData = false;
var currentManagerFilter = null;
var currentFilterTable = 'personal';
var currentPhoneSearch = null;
var currentStartDate = null;
var currentEndDate = null;
var currentTypeFilter = null;
2 months ago
function init() {
var savedUserInfo = localStorage.getItem('userInfo');
if (!savedUserInfo) {
window.location.href = 'login.html';
return;
}
userInfo = JSON.parse(savedUserInfo);
displayUserInfo();
loadManagers();
2 months ago
loadPersonalData();
}
function displayUserInfo() {
var loginInfo = userInfo.loginInfo;
var personnel = userInfo.personnel;
var usersManagements = userInfo.usersManagements;
document.getElementById('userRole').innerHTML = loginInfo.projectName;
document.getElementById('userName').innerHTML = loginInfo.userName;
document.getElementById('projectName').innerHTML = loginInfo.projectName;
document.getElementById('userNameDetail').innerHTML = loginInfo.userName;
document.getElementById('managerCompany').innerHTML = personnel ? personnel.managercompany : '-';
document.getElementById('managerDepartment').innerHTML = personnel ? personnel.managerdepartment : '-';
document.getElementById('organization').innerHTML = personnel ? personnel.organization : '-';
document.getElementById('role').innerHTML = usersManagements ? usersManagements.role : '-';
// 只有管理员显示分配按钮
var isAdmin = loginInfo.projectName === '管理员';
var assignButton = document.getElementById('assignButton');
var publicAssignButton = document.getElementById('publicAssignButton');
if (assignButton) {
assignButton.style.display = isAdmin ? 'inline-block' : 'none';
}
if (publicAssignButton) {
publicAssignButton.style.display = isAdmin ? 'inline-block' : 'none';
}
2 months ago
}
function switchTab(tabName, button) {
// 切换标签按钮状态
try {
var tabButtons = document.getElementsByClassName('tab-button');
for (var i = 0; i < tabButtons.length; i++) {
tabButtons[i].classList.remove('active');
}
if (button) {
button.classList.add('active');
} else {
// 如果没有传入按钮,手动激活对应标签
var tabButtons = document.getElementsByClassName('tab-button');
for (var i = 0; i < tabButtons.length; i++) {
if (tabButtons[i].onclick.toString().indexOf("'" + tabName + "'") > -1) {
tabButtons[i].classList.add('active');
break;
}
}
}
} catch (e) {
console.error('切换标签按钮状态失败:', e);
}
// 切换内容显示
try {
var tabContents = document.getElementsByClassName('tab-content');
for (var i = 0; i < tabContents.length; i++) {
tabContents[i].classList.remove('active');
}
var tabContent = document.getElementById(tabName);
if (tabContent) {
tabContent.classList.add('active');
}
} catch (e) {
console.error('切换内容显示失败:', e);
}
// 加载对应数据
try {
if (tabName === 'personal') {
loadPersonalData();
} else if (tabName === 'public') {
loadPublicData();
}
} catch (e) {
console.error('加载数据失败:', e);
}
}
function loadPersonalData() {
// 总是加载所有数据,然后在前端进行筛选和分页
loadAllPersonalData();
}
function loadAllPersonalData() {
if (isLoadingAllData) return;
isLoadingAllData = true;
var userRole = userInfo.loginInfo.projectName;
var userName = userInfo.loginInfo.userName;
var usersManagements = userInfo.usersManagements;
// 构建查询参数,设置一个较大的pageSize来获取所有数据
var params = {
page: 1,
size: 1000, // 假设最多1000条数据
userRole: userRole,
followup: userName,
userName: userName,
managercompany: usersManagements.managercompany || '',
managerdepartment: usersManagements.managerdepartment || '',
organization: usersManagements.organization || '',
role: usersManagements.role || ''
};
// 添加负责人筛选参数
if (currentManagerFilter) {
params.managerName = currentManagerFilter;
}
var url = '/KH/api/users?' + objectToQueryString(params);
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
allPersonalData = data.users || [];
isLoadingAllData = false;
// 加载完成后显示数据
displayFilteredPersonalData();
} else if (xhr.readyState == 4) {
isLoadingAllData = false;
console.error('加载所有个人数据失败:', xhr.status, xhr.statusText);
2 months ago
}
};
xhr.send();
}
function displayFilteredPersonalData() {
var personalBody = document.getElementById('personalBody');
var personalEmpty = document.getElementById('personalEmpty');
var managerHeader = document.getElementById('managerHeader');
var personalPagination = document.getElementById('personalPagination');
var selectAllPersonal = document.getElementById('selectAllPersonal');
var personalTotalCount = document.getElementById('personalTotalCount');
personalBody.innerHTML = '';
// 检查用户角色,只对管理员显示负责人列和复选框列
var userRole = userInfo.loginInfo.projectName;
var isAdmin = userRole === '管理员';
if (isAdmin) {
managerHeader.style.display = 'table-cell';
if (selectAllPersonal) {
selectAllPersonal.style.display = 'block';
}
} else {
managerHeader.style.display = 'none';
if (selectAllPersonal) {
selectAllPersonal.style.display = 'none';
}
}
// 过滤数据
var filteredUsers = allPersonalData.filter(function(user) {
// 过滤掉同事类型
if (user.type === 'Colleague') {
return false;
}
// 根据筛选条件过滤
if (personalFilter === 'followed') {
if (!(user.followup && user.followup !== '')) {
return false;
}
} else if (personalFilter === 'unfollowed') {
if (!(!user.followup || user.followup === '')) {
return false;
}
}
// 按负责人筛选
if (currentManagerFilter) {
if (user.managerName !== currentManagerFilter) {
return false;
}
}
// 按手机号搜索
if (currentPhoneSearch) {
if (!user.phoneNumber || !user.phoneNumber.includes(currentPhoneSearch)) {
return false;
}
}
// 按创建时间范围筛选
if (currentStartDate || currentEndDate) {
var userCreatedAt = new Date(user.created_at);
if (currentStartDate) {
var startDate = new Date(currentStartDate);
if (userCreatedAt < startDate) {
return false;
}
}
if (currentEndDate) {
var endDate = new Date(currentEndDate);
// 设置结束日期为当天的23:59:59
endDate.setHours(23, 59, 59, 999);
if (userCreatedAt > endDate) {
return false;
}
}
}
// 按类型筛选
if (currentTypeFilter) {
if (user.type !== currentTypeFilter) {
return false;
}
}
// 其他情况,不过滤
return true;
});
// 更新统计信息
personalTotalCount.textContent = filteredUsers.length;
console.log('过滤后的数据量:', filteredUsers.length);
if (filteredUsers.length > 0) {
personalEmpty.style.display = 'none';
// 自主分页:根据过滤后的数据和当前页码计算显示数据
var startIndex = (personalPage - 1) * personalPageSize;
var endIndex = startIndex + personalPageSize;
var displayUsers = filteredUsers.slice(startIndex, endIndex);
// 计算总页数
var totalPages = Math.ceil(filteredUsers.length / personalPageSize);
for (var i = 0; i < displayUsers.length; i++) {
var user = displayUsers[i];
var responseTime = calculateResponseTime(user.created_at, user.followup_at);
var managerCell = '';
// 只对管理员显示负责人信息
if (userRole === '管理员') {
managerCell = '<td>' + (user.managerName || '-') + '</td>';
} else {
managerCell = '<td style="display: none;"></td>';
}
// 生成简道云按钮,根据sync_statuss字段决定状态
var jianDaoYunButton = '';
if (user.sync_statuss === 0 || user.sync_statuss === 1) {
// 已写入简道云,显示灰色不可点击按钮
jianDaoYunButton = '<button style="padding: 4px 8px; background-color: #ccc; color: #666; border: none; border-radius: 4px; font-size: 12px; cursor: not-allowed;" disabled>已写入简道云</button>';
} else {
// 未写入简道云,显示正常按钮
jianDaoYunButton = '<button onclick="openJianDaoYunModal(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', \'' + (user.followup || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #52c41a; color: white; border: none; border-radius: 4px; font-size: 12px;">简道云</button>';
}
// 只有管理员显示复选框
var checkboxCell = isAdmin ? '<td><input type="checkbox" class="userCheckbox" data-userid="' + (user.userId || '') + '"></td>' : '<td style="width: 40px;"></td>';
var row = '<tr onclick="openDetailModal(\'' + (user.userId || '') + '\')" style="cursor: pointer;">' +
checkboxCell +
'<td>' + (user.nickName || '-') + '</td>' +
'<td>' + (user.phoneNumber || '-') + '</td>' +
'<td>' + mapUserType(user.type) + '</td>' +
'<td>' + formatDateTime(user.created_at) + '</td>' +
'<td>' + (user.followup || '-') + '</td>' +
'<td>' + responseTime + '</td>' +
managerCell +
'<td><button onclick="openFollowupModal(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', \'' + (user.phoneNumber || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 12px; margin-right: 4px;">跟进</button> <button onclick="openReturnModal(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', \'' + (user.phoneNumber || '') + '\', \'' + (user.type || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #faad14; color: white; border: none; border-radius: 4px; font-size: 12px; margin-right: 4px;">归还</button> ' + jianDaoYunButton + '</td>' +
'</tr>';
personalBody.innerHTML += row;
// 有数据时显示分页控件
personalPagination.style.display = 'flex';
}
// 渲染分页控件
renderPersonalPagination(personalPage, totalPages);
} else {
personalEmpty.style.display = 'block';
// 没有数据时隐藏分页控件
personalPagination.style.display = 'none';
}
}
function filterPersonalData(filter) {
personalFilter = filter;
personalPage = 1; // 重置为第一页
// 对于已跟进和未跟进,总是加载所有数据后进行筛选
if (filter === 'followed' || filter === 'unfollowed') {
loadAllPersonalData();
} else {
// 对于全部,使用正常的分页加载
loadPersonalData();
}
}
function toggleManagerFilter(tableType) {
currentFilterTable = tableType || 'personal';
// 收集当前表格中的所有负责人名称
var managers = new Set();
var bodyElement = currentFilterTable === 'personal' ?
document.getElementById('personalBody') :
document.getElementById('publicBody');
var rows = bodyElement.getElementsByTagName('tr');
for (var i = 0; i < rows.length; i++) {
var cells = rows[i].getElementsByTagName('td');
// 找到负责人列(索引为7,因为从0开始计数)
if (cells.length > 7) {
var managerName = cells[7].textContent.trim();
if (managerName && managerName !== '-') {
managers.add(managerName);
}
}
}
// 如果没有负责人数据,显示提示
if (managers.size === 0) {
showAlert('当前表格中没有负责人数据');
return;
}
// 创建筛选菜单
createManagerFilterMenu(Array.from(managers));
}
function createManagerFilterMenu(managers) {
// 移除已存在的筛选菜单
var existingMenu = document.getElementById('managerFilterMenu');
if (existingMenu) {
existingMenu.remove();
}
// 创建筛选菜单
var menu = document.createElement('div');
menu.id = 'managerFilterMenu';
menu.style.cssText = `
position: absolute;
background-color: white;
border: 1px solid #d9d9d9;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 1001;
padding: 8px 0;
min-width: 150px;
`;
// 添加清除筛选选项
var clearOption = document.createElement('div');
clearOption.textContent = '清除筛选';
clearOption.style.cssText = `
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
`;
clearOption.onmouseover = function() {
this.style.backgroundColor = '#f5f5f5';
};
clearOption.onmouseout = function() {
this.style.backgroundColor = 'white';
};
clearOption.onclick = function() {
currentManagerFilter = null;
applyManagerFilter();
menu.remove();
};
menu.appendChild(clearOption);
// 添加分隔线
var divider = document.createElement('div');
divider.style.cssText = `
height: 1px;
background-color: #f0f0f0;
margin: 4px 0;
`;
menu.appendChild(divider);
// 添加负责人选项
managers.forEach(function(manager) {
var option = document.createElement('div');
option.textContent = manager;
option.style.cssText = `
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
`;
option.onmouseover = function() {
this.style.backgroundColor = '#f5f5f5';
};
option.onmouseout = function() {
this.style.backgroundColor = 'white';
};
option.onclick = function() {
currentManagerFilter = manager;
applyManagerFilter();
menu.remove();
};
menu.appendChild(option);
});
// 获取表头位置并显示菜单
var headerElement = currentFilterTable === 'personal' ?
document.getElementById('managerHeader') :
document.getElementById('publicManagerHeader');
var rect = headerElement.getBoundingClientRect();
menu.style.left = rect.left + 'px';
menu.style.top = (rect.top + rect.height) + 'px';
// 添加到页面
document.body.appendChild(menu);
// 点击页面其他地方关闭菜单
document.addEventListener('click', function closeMenu(event) {
if (!menu.contains(event.target) && event.target !== headerElement) {
menu.remove();
document.removeEventListener('click', closeMenu);
}
});
}
function showManagerDropdown(event, cell, managerName) {
// 防止事件冒泡
event.stopPropagation();
// 移除已存在的下拉菜单
var existingDropdown = document.getElementById('managerDropdown');
if (existingDropdown) {
existingDropdown.remove();
}
// 创建下拉菜单
var dropdown = document.createElement('div');
dropdown.id = 'managerDropdown';
dropdown.style.cssText = `
position: absolute;
background-color: white;
border: 1px solid #d9d9d9;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 1001;
padding: 8px 0;
min-width: 150px;
max-height: 200px;
overflow-y: auto;
`;
// 添加查看详情选项
var detailOption = document.createElement('div');
detailOption.textContent = '查看详情';
detailOption.style.cssText = `
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
`;
detailOption.onmouseover = function() {
this.style.backgroundColor = '#f5f5f5';
};
detailOption.onmouseout = function() {
this.style.backgroundColor = 'white';
};
detailOption.onclick = function() {
// 这里可以添加查看负责人详情的逻辑
showAlert('查看负责人:' + managerName + ' 的详情');
dropdown.remove();
};
dropdown.appendChild(detailOption);
// 添加筛选此负责人选项
var filterOption = document.createElement('div');
filterOption.textContent = '筛选此负责人';
filterOption.style.cssText = `
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
`;
filterOption.onmouseover = function() {
this.style.backgroundColor = '#f5f5f5';
};
filterOption.onmouseout = function() {
this.style.backgroundColor = 'white';
};
filterOption.onclick = function() {
currentManagerFilter = managerName;
applyManagerFilter();
dropdown.remove();
};
dropdown.appendChild(filterOption);
// 添加清除筛选选项
var clearOption = document.createElement('div');
clearOption.textContent = '清除筛选';
clearOption.style.cssText = `
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
`;
clearOption.onmouseover = function() {
this.style.backgroundColor = '#f5f5f5';
};
clearOption.onmouseout = function() {
this.style.backgroundColor = 'white';
};
clearOption.onclick = function() {
currentManagerFilter = null;
applyManagerFilter();
dropdown.remove();
};
dropdown.appendChild(clearOption);
// 固定显示在负责人表头下方
var managerHeader = document.getElementById('managerHeader') || document.getElementById('publicManagerHeader');
if (managerHeader) {
var rect = managerHeader.getBoundingClientRect();
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
dropdown.style.left = (rect.left + scrollLeft) + 'px';
dropdown.style.top = (rect.top + rect.height + scrollTop) + 'px';
} else {
// 备用方案:如果找不到表头,显示在单元格下方
var rect = cell.getBoundingClientRect();
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
dropdown.style.left = (rect.left + scrollLeft) + 'px';
dropdown.style.top = (rect.top + rect.height + scrollTop) + 'px';
}
// 添加到页面
document.body.appendChild(dropdown);
// 点击页面其他地方关闭菜单
document.addEventListener('click', function closeDropdown(event) {
if (!dropdown.contains(event.target) && event.target !== cell) {
dropdown.remove();
}
});
}
function applyManagerFilter() {
if (currentFilterTable === 'personal') {
// 个人表格筛选
personalPage = 1;
// 总是加载所有数据以便筛选
loadAllPersonalData();
// 更新个人表格筛选标签
updateFilterTags('personal');
} else {
// 公海池表格筛选
// 公海池数据需要重新加载,因为它可能有分页
loadPublicData();
// 更新公海池表格筛选标签
updateFilterTags('public');
}
// 更新表头样式
updateManagerHeaderStyle();
}
// 更新筛选标签
function updateFilterTags(tableType) {
var tagsContainer = document.getElementById(tableType + 'FilterTags');
tagsContainer.innerHTML = '';
// 显示负责人筛选标签
if (currentManagerFilter) {
var tag = document.createElement('span');
tag.style.cssText = `
display: inline-block;
padding: 4px 12px;
background-color: #e6f7ff;
color: #1890ff;
border: 1px solid #91d5ff;
border-radius: 10px;
font-size: 12px;
margin-right: 8px;
position: relative;
`;
var tagText = document.createTextNode('负责人: ' + currentManagerFilter);
tag.appendChild(tagText);
var closeButton = document.createElement('span');
closeButton.textContent = ' ×';
closeButton.style.cssText = `
margin-left: 8px;
cursor: pointer;
font-weight: bold;
`;
closeButton.onclick = function() {
currentManagerFilter = null;
applyManagerFilter();
};
tag.appendChild(closeButton);
tagsContainer.appendChild(tag);
}
// 显示手机号搜索标签
if (currentPhoneSearch) {
var tag = document.createElement('span');
tag.style.cssText = `
display: inline-block;
padding: 4px 12px;
background-color: #f6ffed;
color: #52c41a;
border: 1px solid #b7eb8f;
border-radius: 10px;
font-size: 12px;
margin-right: 8px;
position: relative;
`;
var tagText = document.createTextNode('手机号: ' + currentPhoneSearch);
tag.appendChild(tagText);
var closeButton = document.createElement('span');
closeButton.textContent = ' ×';
closeButton.style.cssText = `
margin-left: 8px;
cursor: pointer;
font-weight: bold;
`;
closeButton.onclick = function() {
currentPhoneSearch = null;
document.getElementById(tableType + 'PhoneSearch').value = '';
if (tableType === 'personal') {
personalPage = 1;
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
displayFilteredPersonalData();
} else {
loadAllPersonalData();
}
} else {
publicPage = 1;
loadPublicData();
}
updateFilterTags(tableType);
};
tag.appendChild(closeButton);
tagsContainer.appendChild(tag);
}
// 显示类型筛选标签
if (currentTypeFilter) {
var tag = document.createElement('span');
tag.style.cssText = `
display: inline-block;
padding: 4px 12px;
background-color: #e6f7ff;
color: #1890ff;
border: 1px solid #91d5ff;
border-radius: 10px;
font-size: 12px;
margin-right: 8px;
position: relative;
`;
// 映射类型值到显示文本
var typeText = '';
switch(currentTypeFilter) {
case 'wholesale': typeText = '批发贸易类'; break;
case 'e-commerce': typeText = '电商平台类'; break;
case 'delivery_retail': typeText = '配送零售类'; break;
case 'defective_egg': typeText = '次品蛋专项类'; break;
case 'other': typeText = '其他类型'; break;
default: typeText = currentTypeFilter;
}
var tagText = document.createTextNode('类型: ' + typeText);
tag.appendChild(tagText);
var closeButton = document.createElement('span');
closeButton.textContent = ' ×';
closeButton.style.cssText = `
margin-left: 8px;
cursor: pointer;
font-weight: bold;
`;
closeButton.onclick = function() {
currentTypeFilter = null;
document.getElementById(tableType + 'TypeFilter').value = '';
if (tableType === 'personal') {
personalPage = 1;
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
displayFilteredPersonalData();
} else {
loadAllPersonalData();
}
} else {
publicPage = 1;
loadPublicData();
}
updateFilterTags(tableType);
};
tag.appendChild(closeButton);
tagsContainer.appendChild(tag);
}
// 显示日期范围筛选标签
if (currentStartDate || currentEndDate) {
var tag = document.createElement('span');
tag.style.cssText = `
display: inline-block;
padding: 4px 12px;
background-color: #fff7e6;
color: #fa8c16;
border: 1px solid #ffd591;
border-radius: 10px;
font-size: 12px;
margin-right: 8px;
position: relative;
`;
var dateText = '';
if (currentStartDate && currentEndDate) {
dateText = '创建时间: ' + currentStartDate + ' 至 ' + currentEndDate;
} else if (currentStartDate) {
dateText = '创建时间: 从 ' + currentStartDate;
} else {
dateText = '创建时间: 至 ' + currentEndDate;
}
var tagText = document.createTextNode(dateText);
tag.appendChild(tagText);
var closeButton = document.createElement('span');
closeButton.textContent = ' ×';
closeButton.style.cssText = `
margin-left: 8px;
cursor: pointer;
font-weight: bold;
`;
closeButton.onclick = function() {
currentStartDate = null;
currentEndDate = null;
document.getElementById(tableType + 'StartDate').value = '';
document.getElementById(tableType + 'EndDate').value = '';
if (tableType === 'personal') {
personalPage = 1;
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
displayFilteredPersonalData();
} else {
loadAllPersonalData();
}
} else {
publicPage = 1;
loadPublicData();
}
updateFilterTags(tableType);
};
tag.appendChild(closeButton);
tagsContainer.appendChild(tag);
}
}
// 搜索个人数据手机号
function searchPersonalByPhone() {
var searchValue = document.getElementById('personalPhoneSearch').value.trim();
currentPhoneSearch = searchValue || null;
personalPage = 1; // 重置为第一页
// 总是加载所有数据以便筛选
loadAllPersonalData();
// 更新筛选标签
updateFilterTags('personal');
}
// 搜索公海池数据手机号
function searchPublicByPhone() {
var searchValue = document.getElementById('publicPhoneSearch').value.trim();
currentPhoneSearch = searchValue || null;
publicPage = 1; // 重置为第一页
loadPublicData(); // 重新加载公海池数据
// 更新筛选标签
updateFilterTags('public');
}
// 重置个人数据手机号搜索
function resetPersonalPhoneSearch() {
document.getElementById('personalPhoneSearch').value = '';
currentPhoneSearch = null;
personalPage = 1; // 重置为第一页
// 总是加载所有数据以便筛选
loadAllPersonalData();
// 更新筛选标签
updateFilterTags('personal');
}
// 重置公海池数据手机号搜索
function resetPublicPhoneSearch() {
document.getElementById('publicPhoneSearch').value = '';
currentPhoneSearch = null;
publicPage = 1; // 重置为第一页
loadPublicData(); // 重新加载公海池数据
// 更新筛选标签
updateFilterTags('public');
}
// 筛选个人数据创建时间
function filterPersonalByDate() {
var startDate = document.getElementById('personalStartDate').value;
var endDate = document.getElementById('personalEndDate').value;
currentStartDate = startDate || null;
currentEndDate = endDate || null;
personalPage = 1; // 重置为第一页
// 总是加载所有数据以便筛选
loadAllPersonalData();
// 更新筛选标签
updateFilterTags('personal');
}
// 重置个人数据创建时间筛选
function resetPersonalDateFilter() {
document.getElementById('personalStartDate').value = '';
document.getElementById('personalEndDate').value = '';
currentStartDate = null;
currentEndDate = null;
personalPage = 1; // 重置为第一页
// 总是加载所有数据以便筛选
loadAllPersonalData();
// 更新筛选标签
updateFilterTags('personal');
}
// 筛选公海池数据创建时间
function filterPublicByDate() {
var startDate = document.getElementById('publicStartDate').value;
var endDate = document.getElementById('publicEndDate').value;
currentStartDate = startDate || null;
currentEndDate = endDate || null;
publicPage = 1; // 重置为第一页
loadPublicData(); // 重新加载公海池数据
// 更新筛选标签
updateFilterTags('public');
}
// 重置公海池数据创建时间筛选
function resetPublicDateFilter() {
document.getElementById('publicStartDate').value = '';
document.getElementById('publicEndDate').value = '';
currentStartDate = null;
currentEndDate = null;
publicPage = 1; // 重置为第一页
loadPublicData(); // 重新加载公海池数据
// 更新筛选标签
updateFilterTags('public');
}
// 筛选个人数据负责人
function filterPersonalByManager() {
var managerName = document.getElementById('personalManagerFilter').value;
currentManagerFilter = managerName || null;
personalPage = 1; // 重置为第一页
// 总是加载所有数据以便筛选
loadAllPersonalData();
// 更新筛选标签
updateFilterTags('personal');
}
// 筛选公海池数据负责人
function filterPublicByManager() {
var managerName = document.getElementById('publicManagerFilter').value;
currentManagerFilter = managerName || null;
publicPage = 1; // 重置为第一页
loadPublicData(); // 重新加载公海池数据
// 更新筛选标签
updateFilterTags('public');
}
// 筛选个人数据类型
function filterPersonalByType() {
var type = document.getElementById('personalTypeFilter').value;
currentTypeFilter = type || null;
personalPage = 1; // 重置为第一页
// 总是加载所有数据以便筛选
loadAllPersonalData();
// 更新筛选标签
updateFilterTags('personal');
}
// 筛选公海池数据类型
function filterPublicByType() {
var type = document.getElementById('publicTypeFilter').value;
currentTypeFilter = type || null;
publicPage = 1; // 重置为第一页
loadPublicData(); // 重新加载公海池数据
// 更新筛选标签
updateFilterTags('public');
}
2 months ago
function loadPublicData() {
var userRole = userInfo.loginInfo.projectName;
var usersManagements = userInfo.usersManagements;
// 构建查询参数
var params = {
page: publicPage,
size: publicPageSize,
userRole: userRole,
userName: usersManagements.userName || '',
managercompany: usersManagements.managercompany || '',
managerdepartment: usersManagements.managerdepartment || '',
organization: usersManagements.organization || '',
role: usersManagements.role || ''
};
// 添加负责人筛选参数
if (currentManagerFilter) {
params.managerName = currentManagerFilter;
}
// 添加手机号搜索参数
if (currentPhoneSearch) {
params.phoneNumber = currentPhoneSearch;
}
// 添加日期范围搜索参数
if (currentStartDate) {
params.startDate = currentStartDate;
}
if (currentEndDate) {
params.endDate = currentEndDate;
}
// 添加类型筛选参数
if (currentTypeFilter) {
params.type = currentTypeFilter;
}
var url = '/KH/api/users/public?' + objectToQueryString(params);
2 months ago
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
// 保存公海池数据到全局变量
if (data.users) {
allPublicData = data.users;
}
2 months ago
displayPublicData(data);
renderPublicPagination(data.page, data.pages);
}
};
xhr.send();
}
function objectToQueryString(obj) {
return Object.keys(obj)
.map(key => key + '=' + encodeURIComponent(obj[key]))
.join('&');
}
// 跟进弹窗HTML
var followupModalHTML = `
<div id="followupModal" style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background-color: rgba(0,0,0,0.5); display: none; z-index: 9999; animation: fadeIn 0.3s ease; overflow: hidden; pointer-events: auto;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 450px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease; max-height: 90vh; overflow-y: auto;">
2 months ago
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; text-align: center;">跟进客户</h3>
<input type="hidden" id="followupUserId">
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">客户名称</label>
<input type="text" id="followupUserName" disabled style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; background-color: #f5f5f5;">
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">电话号码</label>
<input type="text" id="followupPhone" disabled style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; background-color: #f5f5f5;">
</div>
<div style="margin-bottom: 20px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
<label style="font-size: 14px; font-weight: 500; color: #666;"><span style="color: #ff4d4f;">*</span> 客户类型</label>
<button onclick="showTypeHelp()" style="width: 20px; height: 20px; border-radius: 50%; border: 1px solid #1890ff; background-color: white; color: #1890ff; cursor: pointer; font-size: 12px; display: flex; align-items: center; justify-content: center; padding: 0; transition: all 0.3s ease;">?</button>
</div>
<select id="followupType" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; cursor: pointer; transition: all 0.3s ease;">
<option value="">请选择客户类型</option>
<option value="wholesale">批发贸易类</option>
<option value="e-commerce">电商平台类</option>
<option value="delivery_retail">配送零售类</option>
<option value="defective_egg">次品蛋专项类</option>
<option value="other">其他类型</option>
</select>
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;"><span style="color: #ff4d4f;">*</span> 客户等级</label>
<select id="followupLevel" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; cursor: pointer; transition: all 0.3s ease;">
<option value="">请选择客户等级</option>
<option value="important">A-重要客户</option>
<option value="ordinary">B-普通客户</option>
<option value="low_value">C-低价值客户</option>
<option value="logistics">D-物流自提客户</option>
</select>
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;"><span style="color: #ff4d4f;">*</span> 客户需求</label>
<select id="followupDemand" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; cursor: pointer; transition: all 0.3s ease;">
<option value="">请选择客户需求</option>
<option value="粉蛋">粉蛋</option>
<option value="粉三">粉三</option>
<option value="红蛋">红蛋</option>
<option value="绿壳">绿壳</option>
<option value="土鸡蛋">土鸡蛋</option>
<option value="次品">次品</option>
<option value="白壳">白壳</option>
</select>
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;"><span style="color: #ff4d4f;">*</span> 客户地区</label>
<!-- 带搜索功能的地区选择组件 -->
<div class="search-select" style="position: relative; width: 100%;">
<div class="search-select-input" onclick="toggleSearchSelect('followupRegion')" style="
width: 100%;
padding: 10px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
justify-content: space-between;
align-items: center;
background-color: white;
">
<span id="followupRegionDisplay">请选择客户地区</span>
<span style="color: #999;"></span>
</div>
<input
type="text"
id="followupRegionSearch"
oninput="filterRegions()"
placeholder="搜索地区..."
style="
width: 100%;
padding: 10px;
border: 1px solid #d9d9d9;
border-top: none;
border-radius: 0 0 4px 4px;
font-size: 14px;
display: none;
box-sizing: border-box;
"
/>
<div class="search-select-dropdown" id="followupRegionDropdown" style="
position: absolute;
top: 100%;
left: 0;
right: 0;
max-height: 200px;
overflow-y: auto;
border: 1px solid #d9d9d9;
border-top: none;
border-radius: 0 0 4px 4px;
background-color: white;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
z-index: 1000;
display: none;
">
<div class="search-select-option" onclick="selectRegion('')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">请选择客户地区</div>
<div class="search-select-option" onclick="selectRegion('四川地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">四川地区</div>
<div class="search-select-option" onclick="selectRegion('成都地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">成都地区</div>
<div class="search-select-option" onclick="selectRegion('乐山地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">乐山地区</div>
<div class="search-select-option" onclick="selectRegion('贵州地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">贵州地区</div>
<div class="search-select-option" onclick="selectRegion('重庆地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">重庆地区</div>
<div class="search-select-option" onclick="selectRegion('云南地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">云南地区</div>
<div class="search-select-option" onclick="selectRegion('河南地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">河南地区</div>
<div class="search-select-option" onclick="selectRegion('河北地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">河北地区</div>
<div class="search-select-option" onclick="selectRegion('广西地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">广西地区</div>
<div class="search-select-option" onclick="selectRegion('广东地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">广东地区</div>
<div class="search-select-option" onclick="selectRegion('湖南地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">湖南地区</div>
<div class="search-select-option" onclick="selectRegion('湖北地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">湖北地区</div>
<div class="search-select-option" onclick="selectRegion('上海地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">上海地区</div>
<div class="search-select-option" onclick="selectRegion('山西地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">山西地区</div>
<div class="search-select-option" onclick="selectRegion('山东地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">山东地区</div>
<div class="search-select-option" onclick="selectRegion('陕西地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">陕西地区</div>
<div class="search-select-option" onclick="selectRegion('甘肃地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">甘肃地区</div>
<div class="search-select-option" onclick="selectRegion('黑龙江地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">黑龙江地区</div>
<div class="search-select-option" onclick="selectRegion('吉林地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">吉林地区</div>
<div class="search-select-option" onclick="selectRegion('辽宁地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">辽宁地区</div>
<div class="search-select-option" onclick="selectRegion('江苏地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">江苏地区</div>
<div class="search-select-option" onclick="selectRegion('浙江地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">浙江地区</div>
<div class="search-select-option" onclick="selectRegion('安徽地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">安徽地区</div>
<div class="search-select-option" onclick="selectRegion('福建地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">福建地区</div>
<div class="search-select-option" onclick="selectRegion('江西地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">江西地区</div>
<div class="search-select-option" onclick="selectRegion('北京地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">北京地区</div>
<div class="search-select-option" onclick="selectRegion('天津地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">天津地区</div>
<div class="search-select-option" onclick="selectRegion('内蒙古地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">内蒙古地区</div>
<div class="search-select-option" onclick="selectRegion('宁夏地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">宁夏地区</div>
<div class="search-select-option" onclick="selectRegion('青海地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">青海地区</div>
<div class="search-select-option" onclick="selectRegion('新疆地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">新疆地区</div>
<div class="search-select-option" onclick="selectRegion('西藏地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">西藏地区</div>
<div class="search-select-option" onclick="selectRegion('香港地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">香港地区</div>
<div class="search-select-option" onclick="selectRegion('澳门地区')" style="
padding: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
">澳门地区</div>
</div>
<input type="hidden" id="followupRegion" name="followupRegion" />
</div>
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">详细地址</label>
<input type="text" id="followupDetailedAddress" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; transition: all 0.3s ease;">
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;"><span style="color: #ff4d4f;">*</span> 客户公司</label>
<input type="text" id="followupCompany" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; transition: all 0.3s ease;">
</div>
2 months ago
<div style="margin-bottom: 24px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;"><span style="color: #ff4d4f;">*</span> 跟进内容</label>
<textarea id="followupContent" rows="3" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; resize: vertical; transition: all 0.3s ease;"></textarea>
2 months ago
</div>
<div style="text-align: right; margin-top: 24px;">
<button onclick="closeFollowupModal()" style="padding: 10px 16px; margin-right: 12px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; color: #666; background-color: white; cursor: pointer; transition: all 0.3s ease;">取消</button>
<button onclick="saveFollowup()" style="padding: 10px 16px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #1890ff; cursor: pointer; transition: all 0.3s ease;">保存</button>
</div>
</div>
</div>
`;
// 归还弹窗HTML
var returnModalHTML = `
<div id="returnModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; z-index: 1000; animation: fadeIn 0.3s ease;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 450px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease;">
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; text-align: center;">归还客户</h3>
<input type="hidden" id="returnUserId">
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">客户名称</label>
<input type="text" id="returnUserName" disabled style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; background-color: #f5f5f5;">
</div>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">电话号码</label>
<input type="text" id="returnPhone" disabled style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; background-color: #f5f5f5;">
</div>
<div style="margin-bottom: 24px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">客户类型</label>
<select id="returnType" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; cursor: pointer; transition: all 0.3s ease;">
<option value="buyer">大贸易客户</option>
<option value="seller">供应商</option>
<option value="both">两者都是</option>
<option value="smalls">小品种客户</option>
</select>
</div>
<div style="text-align: right; margin-top: 24px;">
<button onclick="closeReturnModal()" style="padding: 10px 16px; margin-right: 12px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; color: #666; background-color: white; cursor: pointer; transition: all 0.3s ease;">取消</button>
<button onclick="saveReturn()" style="padding: 10px 16px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #faad14; cursor: pointer; transition: all 0.3s ease;">归还</button>
</div>
</div>
</div>
`;
// 简道云弹窗HTML
var jianDaoYunModalHTML = `
<div id="jianDaoYunModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; z-index: 1000; animation: fadeIn 0.3s ease;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 400px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease;">
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; text-align: center;">简道云</h3>
<input type="hidden" id="jianDaoYunUserId">
<div style="margin-bottom: 24px; text-align: center;">
<p style="font-size: 14px; color: #666;">是否将客户拉入你的简道云?</p>
</div>
<div style="text-align: right; margin-top: 24px;">
<button onclick="closeJianDaoYunModal()" style="padding: 10px 16px; margin-right: 12px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; color: #666; background-color: white; cursor: pointer; transition: all 0.3s ease;">取消</button>
<button onclick="saveJianDaoYun()" style="padding: 10px 16px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #52c41a; cursor: pointer; transition: all 0.3s ease;">确认</button>
</div>
</div>
</div>
`;
// 详情弹窗HTML
var detailModalHTML = `
<div id="detailModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; z-index: 1000; animation: fadeIn 0.3s ease;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 600px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease; max-height: 90vh; overflow-y: auto;">
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; text-align: center;">客户详情</h3>
<div style="margin-bottom: 24px;">
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">客户ID:</span>
<span id="detailUserId" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">客户名称:</span>
<span id="detailUserName" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">电话号码:</span>
<span id="detailPhone" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">客户类型:</span>
<span id="detailType" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">创建时间:</span>
<span id="detailCreatedAt" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">跟进内容:</span>
<span id="detailFollowup" style="font-size: 14px; color: #333; max-width: 400px; text-align: right;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">响应时间:</span>
<span id="detailResponseTime" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">负责人:</span>
<span id="detailManagerName" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">简道云状态:</span>
<span id="detailSyncStatus" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">客户等级:</span>
<span id="detailLevel" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">客户地区:</span>
<span id="detailRegion" style="font-size: 14px; color: #333;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">详细地址:</span>
<span id="detailDetailedAddress" style="font-size: 14px; color: #333; max-width: 400px; text-align: right;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">客户公司:</span>
<span id="detailCompany" style="font-size: 14px; color: #333; max-width: 400px; text-align: right;"></span>
</div>
</div>
<div style="margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 14px; font-weight: 500; color: #666;">客户需求:</span>
<span id="detailDemand" style="font-size: 14px; color: #333;"></span>
</div>
</div>
</div>
<div style="text-align: center; margin-top: 24px;">
<button onclick="closeDetailModal()" style="padding: 10px 24px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #1890ff; cursor: pointer; transition: all 0.3s ease;">关闭</button>
</div>
</div>
</div>
`;
// 分配弹窗HTML
var assignModalHTML = `
<div id="assignModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; z-index: 1000; animation: fadeIn 0.3s ease;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 500px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease;">
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; text-align: center;">分配客户</h3>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">选中客户数量</label>
<input type="text" id="selectedCount" disabled style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; background-color: #f5f5f5;">
</div>
<div style="margin-bottom: 24px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">选择负责人</label>
<select id="managerSelect" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; cursor: pointer; transition: all 0.3s ease;">
<option value="">请选择负责人</option>
</select>
</div>
<div style="text-align: right; margin-top: 24px;">
<button onclick="closeAssignModal()" style="padding: 10px 16px; margin-right: 12px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; color: #666; background-color: white; cursor: pointer; transition: all 0.3s ease;">取消</button>
<button onclick="saveAssign()" style="padding: 10px 16px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #722ed1; cursor: pointer; transition: all 0.3s ease;">分配</button>
</div>
</div>
</div>
`;
// 提示弹窗HTML
var alertModalHTML = `
<div id="alertModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; z-index: 10000; animation: fadeIn 0.3s ease;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 350px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease;">
<h3 style="margin: 0 0 20px 0; font-size: 16px; font-weight: 600; color: #333; text-align: center;">提示</h3>
<div style="margin-bottom: 24px; text-align: center;">
<p id="alertMessage" style="font-size: 14px; color: #666;"></p>
</div>
<div style="text-align: center; margin-top: 24px;">
<button onclick="closeAlertModal()" style="padding: 10px 24px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #1890ff; cursor: pointer; transition: all 0.3s ease;">确定</button>
</div>
</div>
</div>
`;
// 客户类型说明弹窗HTML
var typeHelpModalHTML = `
<div id="typeHelpModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; z-index: 10000; animation: fadeIn 0.3s ease;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 500px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease; max-height: 80vh; overflow-y: auto;">
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; text-align: center;">客户类型说明</h3>
<div style="margin-bottom: 20px;">
<h4 style="font-size: 16px; font-weight: 600; color: #1890ff; margin-bottom: 10px;">批发贸易类</h4>
<p style="font-size: 14px; color: #666; margin-bottom: 8px;"><strong style="color: #333;">核心判断标准:</strong>1.单次采购为整车量级;2.车型规格涵盖 4.2 米、6.8 米、9.6米;3.采购量达对应车型满载/准满载标准</p>
<p style="font-size: 14px; color: #666;"><strong style="color: #333;">需求特点:</strong>1.采购量大,合作频次稳定;2.对供货时效、产品一致性要求高;3.重视批量采购价格优势与长期供货稳定</p>
</div>
<div style="margin-bottom: 20px;">
<h4 style="font-size: 16px; font-weight: 600; color: #1890ff; margin-bottom: 10px;">电商平台类</h4>
<p style="font-size: 14px; color: #666; margin-bottom: 8px;"><strong style="color: #333;">核心判断标准:</strong>1.单次采购为整车小码规格货品;2.货品需符合电商分装、物流、销售标准;3.订单具备持续性与稳定性</p>
<p style="font-size: 14px; color: #666;"><strong style="color: #333;">需求特点:</strong>1.对包装标准化、溯源信息完整性要求高;2.需匹配电商仓储入库、分拣发货流程;3.关注库存周转率与供货节奏同步</p>
</div>
<div style="margin-bottom: 20px;">
<h4 style="font-size: 16px; font-weight: 600; color: #1890ff; margin-bottom: 10px;">配送零售类</h4>
<p style="font-size: 14px; color: #666; margin-bottom: 8px;"><strong style="color: #333;">核心判断标准:</strong>1.采购辐射范围为周边鸡场;2.单次采购量 10-200 件;3.采购模式为小批量、多频次补货</p>
<p style="font-size: 14px; color: #666;"><strong style="color: #333;">需求特点:</strong>1.采购半径小,对配送时效要求极高;2.极度关注货品新鲜度与品质稳定性;3.需求存在应急补货场景</p>
</div>
<div style="margin-bottom: 20px;">
<h4 style="font-size: 16px; font-weight: 600; color: #1890ff; margin-bottom: 10px;">次品蛋专项类</h4>
<p style="font-size: 14px; color: #666; margin-bottom: 8px;"><strong style="color: #333;">核心判断标准:</strong>1.采购品类仅限次品蛋(下架蛋、裂纹蛋);2.不涉及任何合格商品蛋;3.采购用途为食品深加工/饲料原料等</p>
<p style="font-size: 14px; color: #666;"><strong style="color: #333;">需求特点:</strong>1.对价格敏感度极高;2.不关注货品外观品相;3.要求货源稳定、批次可控</p>
</div>
<div style="margin-bottom: 20px;">
<h4 style="font-size: 16px; font-weight: 600; color: #1890ff; margin-bottom: 10px;">其他类型</h4>
<p style="font-size: 14px; color: #666; margin-bottom: 8px;"><strong style="color: #333;">核心判断标准:</strong>其他核心判断标准</p>
<p style="font-size: 14px; color: #666;"><strong style="color: #333;">需求特点:</strong>其他需求特点</p>
</div>
<div style="text-align: center; margin-top: 24px;">
<button onclick="closeTypeHelpModal()" style="padding: 10px 24px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #1890ff; cursor: pointer; transition: all 0.3s ease;">知道了</button>
</div>
</div>
</div>
`;
2 months ago
// 添加弹窗到页面
document.body.insertAdjacentHTML('beforeend', followupModalHTML);
document.body.insertAdjacentHTML('beforeend', returnModalHTML);
document.body.insertAdjacentHTML('beforeend', jianDaoYunModalHTML);
document.body.insertAdjacentHTML('beforeend', detailModalHTML);
document.body.insertAdjacentHTML('beforeend', assignModalHTML);
document.body.insertAdjacentHTML('beforeend', alertModalHTML);
document.body.insertAdjacentHTML('beforeend', typeHelpModalHTML);
// 为模态框添加点击外部关闭功能
function addModalOutsideClose(modalId) {
const modal = document.getElementById(modalId);
if (modal) {
modal.addEventListener('click', function(e) {
// 点击的是模态框背景本身而不是内容
if (e.target === modal) {
// 根据不同模态框调用对应的关闭函数
if (modalId === 'followupModal') {
closeFollowupModal();
} else if (modalId === 'returnModal') {
closeReturnModal();
} else if (modalId === 'jianDaoYunModal') {
closeJianDaoYunModal();
} else if (modalId === 'alertModal') {
closeAlertModal();
} else if (modalId === 'assignModal') {
closeAssignModal();
} else if (modalId === 'typeHelpModal') {
closeTypeHelpModal();
} else if (modalId === 'detailModal') {
closeDetailModal();
}
}
});
}
}
// 为所有模态框添加点击外部关闭功能
addModalOutsideClose('followupModal');
addModalOutsideClose('returnModal');
addModalOutsideClose('jianDaoYunModal');
addModalOutsideClose('alertModal');
addModalOutsideClose('assignModal');
addModalOutsideClose('typeHelpModal');
addModalOutsideClose('detailModal');
function showTypeHelp() {
document.getElementById('typeHelpModal').style.display = 'block';
// 防止背景滚动
document.body.style.overflow = 'hidden';
}
function closeTypeHelpModal() {
document.getElementById('typeHelpModal').style.display = 'none';
// 恢复背景滚动
document.body.style.overflow = 'auto';
}
// 搜索选择组件相关函数
let currentOpenSelect = null;
// 切换搜索选择下拉框
function toggleSearchSelect(selectId) {
const dropdown = document.getElementById(selectId + 'Dropdown');
const searchInput = document.getElementById(selectId + 'Search');
// 关闭其他已打开的选择框
if (currentOpenSelect && currentOpenSelect !== selectId) {
closeSearchSelect(currentOpenSelect);
}
// 切换当前选择框
if (dropdown.style.display === 'block') {
closeSearchSelect(selectId);
currentOpenSelect = null;
} else {
dropdown.style.display = 'block';
searchInput.style.display = 'block';
searchInput.focus();
currentOpenSelect = selectId;
}
}
// 关闭搜索选择下拉框
function closeSearchSelect(selectId) {
const dropdown = document.getElementById(selectId + 'Dropdown');
const searchInput = document.getElementById(selectId + 'Search');
dropdown.style.display = 'none';
searchInput.style.display = 'none';
searchInput.value = '';
// 显示所有选项
const options = dropdown.querySelectorAll('.search-select-option');
options.forEach(option => {
option.style.display = 'block';
});
}
// 过滤地区选项
function filterRegions() {
const searchInput = document.getElementById('followupRegionSearch');
const filter = searchInput.value.toLowerCase();
const dropdown = document.getElementById('followupRegionDropdown');
const options = dropdown.querySelectorAll('.search-select-option');
options.forEach(option => {
const text = option.textContent.toLowerCase();
if (text.includes(filter)) {
option.style.display = 'block';
} else {
option.style.display = 'none';
}
});
}
// 选择地区
function selectRegion(region) {
const display = document.getElementById('followupRegionDisplay');
const hiddenInput = document.getElementById('followupRegion');
if (region) {
display.textContent = region;
display.style.color = '#333';
} else {
display.textContent = '请选择客户地区';
display.style.color = '#999';
}
hiddenInput.value = region;
closeSearchSelect('followupRegion');
currentOpenSelect = null;
}
// 点击外部关闭下拉框
document.addEventListener('click', function(event) {
if (!event.target.closest('.search-select')) {
if (currentOpenSelect) {
closeSearchSelect(currentOpenSelect);
currentOpenSelect = null;
}
}
});
2 months ago
function formatDateTime(dateTimeString) {
if (!dateTimeString) return '-';
var date = new Date(dateTimeString);
var year = date.getFullYear();
var month = (date.getMonth() + 1).toString().padStart(2, '0');
var day = date.getDate().toString().padStart(2, '0');
var hours = date.getHours().toString().padStart(2, '0');
var minutes = date.getMinutes().toString().padStart(2, '0');
var seconds = date.getSeconds().toString().padStart(2, '0');
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
}
function mapUserType(type) {
var typeMap = {
'buyer': '大贸易客户',
'seller': '供应商',
'both': '两者都是',
'smalls': '小品种客户',
'wholesale': '批发贸易类',
'e-commerce': '电商平台类',
'delivery_retail': '配送零售类',
'defective_egg': '次品蛋专项类',
'other': '其他类型'
2 months ago
};
return typeMap[type] || type;
}
function mapUserLevel(level) {
var levelMap = {
'important': 'A-重要客户',
'ordinary': 'B-普通客户',
'low_value': 'C-低价值客户',
'logistics': 'D-物流自提客户',
'unclassified': '-'
};
return levelMap[level] || level;
}
2 months ago
function calculateResponseTime(createdAt, followupAt) {
if (!createdAt || !followupAt) return '-';
2 months ago
var createTime = new Date(createdAt);
var followupTime = new Date(followupAt);
2 months ago
var diffMs = followupTime - createTime;
var diffMins = Math.floor(diffMs / 60000);
var diffHours = Math.floor(diffMins / 60);
var diffDays = Math.floor(diffHours / 24);
if (diffDays > 0) {
return diffDays + '天' + (diffHours % 24) + '小时';
} else if (diffHours > 0) {
return diffHours + '小时' + (diffMins % 60) + '分钟';
} else if (diffMins > 0) {
return diffMins + '分钟';
} else {
return '少于1分钟';
}
}
function displayPersonalData(data) {
var personalBody = document.getElementById('personalBody');
var personalEmpty = document.getElementById('personalEmpty');
var managerHeader = document.getElementById('managerHeader');
var personalPagination = document.getElementById('personalPagination');
var selectAllPersonal = document.getElementById('selectAllPersonal');
var personalTotalCount = document.getElementById('personalTotalCount');
2 months ago
personalBody.innerHTML = '';
// 检查用户角色,只对管理员显示负责人列和复选框列
var userRole = userInfo.loginInfo.projectName;
var isAdmin = userRole === '管理员';
if (isAdmin) {
managerHeader.style.display = 'table-cell';
if (selectAllPersonal) {
selectAllPersonal.style.display = 'block';
}
} else {
managerHeader.style.display = 'none';
if (selectAllPersonal) {
selectAllPersonal.style.display = 'none';
}
}
2 months ago
console.log('后端返回的数据量:', data.users ? data.users.length : 0);
console.log('总记录数:', data.total);
console.log('当前页码:', data.page);
console.log('每页大小:', data.size);
console.log('总页数:', data.pages);
// 缓存所有数据
if (personalFilter === 'all') {
allPersonalData = data.users || [];
}
2 months ago
if (data.users && data.users.length > 0) {
personalEmpty.style.display = 'none';
var filteredUsers = data.users.filter(function(user) {
// 过滤掉同事类型
if (user.type === 'Colleague') {
return false;
}
// 根据筛选条件过滤
if (personalFilter === 'followed') {
if (!(user.followup && user.followup !== '')) {
return false;
}
} else if (personalFilter === 'unfollowed') {
if (!(!user.followup || user.followup === '')) {
return false;
}
}
// 按负责人筛选
if (currentManagerFilter) {
return user.managerName === currentManagerFilter;
}
// 其他情况,不过滤
return true;
2 months ago
});
// 更新统计信息
personalTotalCount.textContent = data.total;
2 months ago
console.log('过滤后的数据量:', filteredUsers.length);
if (filteredUsers.length > 0) {
var displayUsers = filteredUsers;
var totalPages = data.pages;
// 对于已跟进和未跟进,使用自主分页
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
// 自主分页:根据过滤后的数据和当前页码计算显示数据
var startIndex = (personalPage - 1) * personalPageSize;
var endIndex = startIndex + personalPageSize;
displayUsers = filteredUsers.slice(startIndex, endIndex);
// 计算总页数
totalPages = Math.ceil(filteredUsers.length / personalPageSize);
}
for (var i = 0; i < displayUsers.length; i++) {
var user = displayUsers[i];
2 months ago
var responseTime = calculateResponseTime(user.created_at, user.followup_at);
var managerCell = '';
// 只对管理员显示负责人信息
if (userRole === '管理员') {
managerCell = '<td>' + (user.managerName || '-') + '</td>';
} else {
managerCell = '<td style="display: none;"></td>';
}
// 生成简道云按钮,根据sync_statuss字段决定状态
var jianDaoYunButton = '';
if (user.sync_statuss === 0 || user.sync_statuss === 1) {
// 已写入简道云,显示灰色不可点击按钮
jianDaoYunButton = '<button style="padding: 4px 8px; background-color: #ccc; color: #666; border: none; border-radius: 4px; font-size: 12px; cursor: not-allowed;" disabled>已写入简道云</button>';
} else {
// 未写入简道云,显示正常按钮
jianDaoYunButton = '<button onclick="openJianDaoYunModal(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', \'' + (user.followup || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #52c41a; color: white; border: none; border-radius: 4px; font-size: 12px;">简道云</button>';
}
// 只有管理员显示复选框
var checkboxCell = isAdmin ? '<td><input type="checkbox" class="userCheckbox" data-userid="' + (user.userId || '') + '"></td>' : '<td style="width: 40px;"></td>';
var row = '<tr onclick="openDetailModal(\'' + (user.userId || '') + '\')" style="cursor: pointer;">' +
checkboxCell +
2 months ago
'<td>' + (user.nickName || '-') + '</td>' +
'<td>' + (user.phoneNumber || '-') + '</td>' +
'<td>' + mapUserType(user.type) + '</td>' +
'<td>' + formatDateTime(user.created_at) + '</td>' +
'<td>' + (user.followup || '-') + '</td>' +
'<td>' + responseTime + '</td>' +
managerCell +
'<td><button onclick="openFollowupModal(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', \'' + (user.phoneNumber || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 12px; margin-right: 4px;">跟进</button> <button onclick="openReturnModal(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', \'' + (user.phoneNumber || '') + '\', \'' + (user.type || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #faad14; color: white; border: none; border-radius: 4px; font-size: 12px; margin-right: 4px;">归还</button> ' + jianDaoYunButton + '</td>' +
2 months ago
'</tr>';
personalBody.innerHTML += row;
// 有数据时显示分页控件
personalPagination.style.display = 'flex';
2 months ago
}
// 渲染分页控件
renderPersonalPagination(personalPage, totalPages);
2 months ago
} else {
personalEmpty.style.display = 'block';
// 没有数据时隐藏分页控件
personalPagination.style.display = 'none';
2 months ago
}
} else {
personalEmpty.style.display = 'block';
// 没有数据时隐藏分页控件
personalPagination.style.display = 'none';
2 months ago
}
}
function displayPublicData(data) {
var publicBody = document.getElementById('publicBody');
var publicEmpty = document.getElementById('publicEmpty');
var publicManagerHeader = document.getElementById('publicManagerHeader');
var publicPagination = document.getElementById('publicPagination');
var selectAllPublic = document.getElementById('selectAllPublic');
2 months ago
publicBody.innerHTML = '';
// 检查用户角色,只对管理员显示负责人列和复选框列
var userRole = userInfo.loginInfo.projectName;
var isAdmin = userRole === '管理员';
if (isAdmin) {
publicManagerHeader.style.display = 'table-cell';
if (selectAllPublic) {
selectAllPublic.style.display = 'block';
}
} else {
publicManagerHeader.style.display = 'none';
if (selectAllPublic) {
selectAllPublic.style.display = 'none';
}
}
2 months ago
if (data.users && data.users.length > 0) {
publicEmpty.style.display = 'none';
var filteredUsers = data.users.filter(function(user) {
if (user.type === 'Colleague') {
return false;
}
// 按负责人筛选
if (currentManagerFilter) {
return user.managerName === currentManagerFilter;
}
return true;
2 months ago
});
if (filteredUsers.length > 0) {
for (var i = 0; i < filteredUsers.length; i++) {
var user = filteredUsers[i];
var responseTime = calculateResponseTime(user.created_at, user.followup_at);
var managerCell = '';
// 只对管理员显示负责人信息
if (userRole === '管理员') {
managerCell = '<td>' + (user.managerName || '-') + '</td>';
} else {
managerCell = '<td style="display: none;"></td>';
}
var row = '<tr onclick="openDetailModal(\'' + (user.userId || '') + '\')" style="cursor: pointer;">' +
'<td><input type="checkbox" class="userCheckbox" data-userid="' + (user.userId || '') + '"></td>' +
2 months ago
'<td>' + (user.nickName || '-') + '</td>' +
'<td>' + (user.phoneNumber || '-') + '</td>' +
'<td>' + mapUserType(user.type) + '</td>' +
'<td>' + formatDateTime(user.created_at) + '</td>' +
'<td>' + (user.followup || '-') + '</td>' +
'<td>' + responseTime + '</td>' +
managerCell +
'<td><button onclick="claimCustomer(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', \'' + (user.phoneNumber || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #52c41a; color: white; border: none; border-radius: 4px; font-size: 12px;">认领</button></td>' +
2 months ago
'</tr>';
publicBody.innerHTML += row;
// 有数据时显示分页控件
publicPagination.style.display = 'flex';
2 months ago
}
} else {
publicEmpty.style.display = 'block';
// 没有数据时隐藏分页控件
publicPagination.style.display = 'none';
2 months ago
}
} else {
publicEmpty.style.display = 'block';
// 没有数据时隐藏分页控件
publicPagination.style.display = 'none';
2 months ago
}
}
function claimCustomer(userId, userName, phone) {
var usersManagements = userInfo.usersManagements;
var params = {
userId: userId,
userName: usersManagements.userName || '',
managercompany: usersManagements.managercompany || '',
managerdepartment: usersManagements.managerdepartment || '',
organization: usersManagements.organization || '',
role: usersManagements.role || ''
};
var url = '/KH/api/users/claim';
2 months ago
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
showAlert('认领成功');
2 months ago
// 重新加载数据
loadPublicData();
loadPersonalData();
} else {
showAlert('认领失败: ' + data.message);
2 months ago
}
}
};
xhr.send(JSON.stringify(params));
}
function openFollowupModal(userId, userName, phone) {
document.getElementById('followupUserId').value = userId;
document.getElementById('followupUserName').value = userName;
document.getElementById('followupPhone').value = phone;
document.getElementById('followupContent').value = '';
document.getElementById('followupModal').style.display = 'block';
// 防止背景滚动
document.body.style.overflow = 'hidden';
2 months ago
}
function closeFollowupModal() {
document.getElementById('followupModal').style.display = 'none';
// 恢复背景滚动
document.body.style.overflow = 'auto';
2 months ago
}
function saveFollowup() {
var userId = document.getElementById('followupUserId').value;
var content = document.getElementById('followupContent').value;
var type = document.getElementById('followupType').value;
var level = document.getElementById('followupLevel').value;
var detailedAddress = document.getElementById('followupDetailedAddress').value;
var company = document.getElementById('followupCompany').value;
var demand = document.getElementById('followupDemand').value;
var region = document.getElementById('followupRegion').value;
2 months ago
var usersManagements = userInfo.usersManagements;
// 验证必填字段
if (!type) {
showAlert('请选择客户类型');
return;
}
if (!level) {
showAlert('请选择客户等级');
return;
}
if (!demand) {
showAlert('请选择客户需求');
return;
}
if (!region) {
showAlert('请选择客户地区');
return;
}
if (!company) {
showAlert('请填写客户公司');
return;
}
2 months ago
if (!content) {
showAlert('请填写跟进内容');
2 months ago
return;
}
var params = {
userId: userId,
followup: content,
type: type,
level: level,
detailedaddress: detailedAddress,
company: company,
demand: demand,
region: region,
2 months ago
userName: usersManagements.userName || '',
managercompany: usersManagements.managercompany || '',
managerdepartment: usersManagements.managerdepartment || '',
organization: usersManagements.organization || '',
role: usersManagements.role || ''
};
var url = '/KH/api/users/followup';
2 months ago
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
showAlert('跟进成功');
2 months ago
closeFollowupModal();
// 重新加载数据
if (document.getElementById('personal').classList.contains('active')) {
loadPersonalData();
} else {
loadPublicData();
}
} else {
showAlert('跟进失败: ' + data.message);
2 months ago
}
}
};
xhr.send(JSON.stringify(params));
}
function openReturnModal(userId, userName, phone, type) {
document.getElementById('returnUserId').value = userId;
document.getElementById('returnUserName').value = userName;
document.getElementById('returnPhone').value = phone;
document.getElementById('returnType').value = type || '采购员';
document.getElementById('returnModal').style.display = 'block';
// 防止背景滚动
document.body.style.overflow = 'hidden';
2 months ago
}
function closeReturnModal() {
document.getElementById('returnModal').style.display = 'none';
// 恢复背景滚动
document.body.style.overflow = 'auto';
2 months ago
}
function openJianDaoYunModal(userId, userName, followup) {
// 检查是否已跟进
if (!followup || followup === '-') {
showAlert('需要先跟进才能点击领入简道云');
return;
}
2 months ago
document.getElementById('jianDaoYunUserId').value = userId;
document.getElementById('jianDaoYunModal').style.display = 'block';
// 防止背景滚动
document.body.style.overflow = 'hidden';
2 months ago
}
function closeJianDaoYunModal() {
document.getElementById('jianDaoYunModal').style.display = 'none';
// 恢复背景滚动
document.body.style.overflow = 'auto';
2 months ago
}
function showAlert(message) {
document.getElementById('alertMessage').textContent = message;
document.getElementById('alertModal').style.display = 'block';
// 防止背景滚动
document.body.style.overflow = 'hidden';
}
function updateManagerHeaderStyle() {
// 移除表头样式更新,保持默认样式
}
function closeAlertModal() {
document.getElementById('alertModal').style.display = 'none';
// 恢复背景滚动
document.body.style.overflow = 'auto';
}
function openDetailModal(userId) {
// 根据userId查找用户数据
var user = null;
// 首先在个人数据中查找
if (allPersonalData.length > 0) {
for (var i = 0; i < allPersonalData.length; i++) {
if (allPersonalData[i].userId === userId) {
user = allPersonalData[i];
break;
}
}
}
// 如果在个人数据中找不到,尝试在公海池数据中查找
if (!user && allPublicData.length > 0) {
for (var i = 0; i < allPublicData.length; i++) {
if (allPublicData[i].userId === userId) {
user = allPublicData[i];
break;
}
}
}
if (!user) {
// 如果在所有数据源中都找不到
showAlert('未找到该客户数据');
return;
}
// 填充客户详情数据
document.getElementById('detailUserId').textContent = user.userId || '-';
document.getElementById('detailUserName').textContent = user.nickName || '-';
document.getElementById('detailPhone').textContent = user.phoneNumber || '-';
document.getElementById('detailType').textContent = mapUserType(user.type) || '-';
document.getElementById('detailCreatedAt').textContent = formatDateTime(user.created_at) || '-';
document.getElementById('detailFollowup').textContent = user.followup || '-';
var responseTime = calculateResponseTime(user.created_at, user.followup_at);
document.getElementById('detailResponseTime').textContent = responseTime;
document.getElementById('detailManagerName').textContent = user.managerName || '-';
// 显示简道云状态
var syncStatus = '';
if (user.sync_statuss === 0 || user.sync_statuss === 1) {
syncStatus = '已写入简道云';
} else {
syncStatus = '未写入简道云';
}
document.getElementById('detailSyncStatus').textContent = syncStatus;
// 显示其他可能的字段
document.getElementById('detailLevel').textContent = mapUserLevel(user.level) || '-';
document.getElementById('detailRegion').textContent = user.region || '-';
document.getElementById('detailDetailedAddress').textContent = user.detailedaddress || '-';
document.getElementById('detailCompany').textContent = user.company || '-';
document.getElementById('detailDemand').textContent = user.demand || '-';
// 显示弹窗
document.getElementById('detailModal').style.display = 'block';
// 防止背景滚动
document.body.style.overflow = 'hidden';
}
function closeDetailModal() {
document.getElementById('detailModal').style.display = 'none';
// 恢复背景滚动
document.body.style.overflow = 'auto';
}
2 months ago
function saveJianDaoYun() {
var userId = document.getElementById('jianDaoYunUserId').value;
var usersManagements = userInfo.usersManagements;
2 months ago
var params = {
userId: userId,
userName: usersManagements.userName || '',
managercompany: usersManagements.managercompany || '',
managerdepartment: usersManagements.managerdepartment || '',
organization: usersManagements.organization || '',
role: usersManagements.role || ''
2 months ago
};
var url = '/KH/api/users/jianDaoYun';
2 months ago
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
showAlert('操作成功');
2 months ago
closeJianDaoYunModal();
// 重新加载数据
loadPersonalData();
} else {
showAlert('操作失败: ' + data.message);
2 months ago
}
}
};
xhr.send(JSON.stringify(params));
}
function saveReturn() {
var userId = document.getElementById('returnUserId').value;
var type = document.getElementById('returnType').value;
var usersManagements = userInfo.usersManagements;
2 months ago
var params = {
userId: userId,
type: type,
userName: usersManagements.userName || '',
managercompany: usersManagements.managercompany || '',
managerdepartment: usersManagements.managerdepartment || '',
organization: usersManagements.organization || '',
role: usersManagements.role || ''
2 months ago
};
var url = '/KH/api/users/return';
2 months ago
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
showAlert('归还成功');
2 months ago
closeReturnModal();
// 重新加载数据
loadPersonalData();
loadPublicData();
} else {
showAlert('归还失败: ' + data.message);
2 months ago
}
}
};
xhr.send(JSON.stringify(params));
}
function renderPersonalPagination(current, total) {
var pagination = document.getElementById('personalPagination');
pagination.innerHTML = '';
var prevBtn = document.createElement('button');
prevBtn.innerHTML = '上一页';
prevBtn.disabled = current == 1;
prevBtn.onclick = function() {
if (current > 1) {
personalPage = current - 1;
// 根据当前筛选条件决定调用哪个函数
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
displayFilteredPersonalData();
} else {
loadPersonalData();
}
2 months ago
}
};
pagination.appendChild(prevBtn);
for (var i = 1; i <= total; i++) {
var pageBtn = document.createElement('button');
pageBtn.innerHTML = i;
pageBtn.className = i == current ? 'active' : '';
pageBtn.onclick = function() {
personalPage = parseInt(this.innerHTML);
// 根据当前筛选条件决定调用哪个函数
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
displayFilteredPersonalData();
} else {
loadPersonalData();
}
2 months ago
};
pagination.appendChild(pageBtn);
}
var nextBtn = document.createElement('button');
nextBtn.innerHTML = '下一页';
nextBtn.disabled = current == total;
nextBtn.onclick = function() {
if (current < total) {
personalPage = current + 1;
// 根据当前筛选条件决定调用哪个函数
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
displayFilteredPersonalData();
} else {
loadPersonalData();
}
2 months ago
}
};
pagination.appendChild(nextBtn);
}
function renderPublicPagination(current, total) {
var pagination = document.getElementById('publicPagination');
pagination.innerHTML = '';
var prevBtn = document.createElement('button');
prevBtn.innerHTML = '上一页';
prevBtn.disabled = current == 1;
prevBtn.onclick = function() {
if (current > 1) {
publicPage = current - 1;
loadPublicData();
}
};
pagination.appendChild(prevBtn);
for (var i = 1; i <= total; i++) {
var pageBtn = document.createElement('button');
pageBtn.innerHTML = i;
pageBtn.className = i == current ? 'active' : '';
pageBtn.onclick = function() {
publicPage = parseInt(this.innerHTML);
loadPublicData();
};
pagination.appendChild(pageBtn);
}
var nextBtn = document.createElement('button');
nextBtn.innerHTML = '下一页';
nextBtn.disabled = current == total;
nextBtn.onclick = function() {
if (current < total) {
publicPage = current + 1;
loadPublicData();
}
};
pagination.appendChild(nextBtn);
}
function changePersonalPageSize() {
var select = document.getElementById('personalPageSize');
personalPageSize = parseInt(select.value);
personalPage = 1; // 重置为第一页
loadPersonalData();
}
function changePublicPageSize() {
var select = document.getElementById('publicPageSize');
publicPageSize = parseInt(select.value);
publicPage = 1; // 重置为第一页
loadPublicData();
}
function logout() {
localStorage.removeItem('userInfo');
window.location.href = 'login.html';
}
function selectAll(tableType) {
var checkboxes = document.querySelectorAll('.userCheckbox');
var selectAllCheckbox = document.getElementById('selectAll' + tableType.charAt(0).toUpperCase() + tableType.slice(1));
var checked = selectAllCheckbox.checked;
checkboxes.forEach(function(checkbox) {
checkbox.checked = checked;
});
}
function loadManagers() {
var url = '/KH/api/users/managers';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
managersList = JSON.parse(xhr.responseText);
populateManagerSelect();
} else if (xhr.readyState == 4) {
console.error('加载负责人列表失败:', xhr.status, xhr.statusText);
}
};
xhr.send();
}
function populateManagerSelect() {
var select = document.getElementById('managerSelect');
select.innerHTML = '<option value="">请选择负责人</option>';
// 清空并初始化负责人筛选下拉框
var personalManagerFilter = document.getElementById('personalManagerFilter');
var publicManagerFilter = document.getElementById('publicManagerFilter');
if (personalManagerFilter) {
personalManagerFilter.innerHTML = '<option value="">全部</option>';
}
if (publicManagerFilter) {
publicManagerFilter.innerHTML = '<option value="">全部</option>';
}
managersList.forEach(function(manager) {
// 填充分配模态框的下拉框
var option = document.createElement('option');
option.value = manager.managerId;
option.textContent = manager.userName;
option.setAttribute('data-managercompany', manager.managercompany);
option.setAttribute('data-managerdepartment', manager.managerdepartment);
option.setAttribute('data-organization', manager.organization);
option.setAttribute('data-role', manager.role);
option.setAttribute('data-root', manager.root);
option.setAttribute('data-assistant', manager.assistant);
select.appendChild(option);
// 填充个人数据标签页的负责人筛选下拉框
if (personalManagerFilter) {
var personalOption = document.createElement('option');
personalOption.value = manager.userName;
personalOption.textContent = manager.userName;
personalManagerFilter.appendChild(personalOption);
}
// 填充公海池数据标签页的负责人筛选下拉框
if (publicManagerFilter) {
var publicOption = document.createElement('option');
publicOption.value = manager.userName;
publicOption.textContent = manager.userName;
publicManagerFilter.appendChild(publicOption);
}
});
}
function openAssignModal() {
var checkboxes = document.querySelectorAll('.userCheckbox:checked');
var selectedCount = checkboxes.length;
if (selectedCount === 0) {
showAlert('请至少选择一个客户');
return;
}
document.getElementById('selectedCount').value = selectedCount;
document.getElementById('assignModal').style.display = 'block';
}
function closeAssignModal() {
document.getElementById('assignModal').style.display = 'none';
}
function saveAssign() {
var checkboxes = document.querySelectorAll('.userCheckbox:checked');
var selectedUserIds = [];
var usersManagements = userInfo.usersManagements;
checkboxes.forEach(function(checkbox) {
selectedUserIds.push(checkbox.getAttribute('data-userid'));
});
var managerSelect = document.getElementById('managerSelect');
var selectedOption = managerSelect.options[managerSelect.selectedIndex];
if (!selectedOption || selectedOption.value === '') {
showAlert('请选择负责人');
return;
}
var params = {
userIds: selectedUserIds,
managerId: selectedOption.value,
userName: selectedOption.textContent,
operatorUserName: usersManagements.userName || '',
managercompany: usersManagements.managercompany || '',
managerdepartment: usersManagements.managerdepartment || '',
organization: usersManagements.organization || '',
role: usersManagements.role || ''
};
var url = '/KH/api/users/assign';
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
if (data.success) {
showAlert('分配成功');
closeAssignModal();
// 重新加载数据
loadPersonalData();
loadPublicData();
} else {
showAlert('分配失败: ' + data.message);
}
}
};
xhr.send(JSON.stringify(params));
}
2 months ago
window.onload = init;
</script>
</body>
</html>