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.
6686 lines
330 KiB
6686 lines
330 KiB
<!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;
|
|
background: rgba(255, 255, 255, 0.1);
|
|
padding: 8px 16px;
|
|
border-radius: 20px;
|
|
backdrop-filter: blur(10px);
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.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%;
|
|
}
|
|
|
|
.user-details {
|
|
background: white;
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.user-details h2 {
|
|
font-size: 16px;
|
|
font-weight: bold;
|
|
margin-bottom: 12px;
|
|
color: #333;
|
|
}
|
|
|
|
.detail-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
gap: 12px;
|
|
}
|
|
|
|
.detail-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.detail-label {
|
|
font-size: 12px;
|
|
color: #999;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.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: 10px;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
align-content: flex-start;
|
|
}
|
|
|
|
.filter-bar > *:nth-child(-n+8) {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.filter-bar > span:nth-child(9),
|
|
.filter-bar > select:nth-child(10),
|
|
.filter-bar > span:nth-child(11),
|
|
.filter-bar > select:nth-child(12) {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.filter-bar > span:nth-child(13) {
|
|
flex-basis: 100%;
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.filter-bar span {
|
|
white-space: nowrap;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.filter-bar input[type="date"] {
|
|
white-space: nowrap;
|
|
min-width: 120px;
|
|
padding: 6px 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.filter-bar select {
|
|
white-space: nowrap;
|
|
min-width: 90px;
|
|
padding: 6px 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.filter-bar input[type="text"] {
|
|
white-space: nowrap;
|
|
min-width: 140px;
|
|
padding: 6px 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.filter-bar button {
|
|
padding: 6px 10px;
|
|
background-color: #1890ff;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 13px;
|
|
transition: all 0.3s ease;
|
|
white-space: nowrap;
|
|
min-width: 70px;
|
|
}
|
|
|
|
.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);
|
|
}
|
|
|
|
.data-section {
|
|
background: white;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.section-content {
|
|
padding: 0;
|
|
}
|
|
|
|
.filter-bar {
|
|
margin: 0;
|
|
padding: 15px 20px;
|
|
background-color: #fafafa;
|
|
border-bottom: 1px solid #e8e8e8;
|
|
}
|
|
|
|
.pagination {
|
|
margin: 0;
|
|
padding: 15px 20px;
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
background-color: #fafafa;
|
|
border-top: 1px solid #e8e8e8;
|
|
}
|
|
|
|
.pagination button {
|
|
padding: 8px 14px;
|
|
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;
|
|
}
|
|
|
|
.pagination button.active {
|
|
background-color: #1890ff;
|
|
color: white;
|
|
border-color: #1890ff;
|
|
}
|
|
|
|
.pagination button:disabled {
|
|
color: #ccc;
|
|
cursor: not-allowed;
|
|
border-color: #e8e8e8;
|
|
}
|
|
|
|
.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 {
|
|
0% {
|
|
opacity: 0;
|
|
transform: translate(-50%, -50%) scale(0.9);
|
|
}
|
|
70% {
|
|
opacity: 1;
|
|
transform: translate(-50%, -50%) scale(1.02);
|
|
}
|
|
100% {
|
|
opacity: 1;
|
|
transform: translate(-50%, -50%) scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes slideOut {
|
|
from {
|
|
opacity: 1;
|
|
transform: translate(-50%, -50%) scale(1);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translate(-50%, -50%) scale(0.95);
|
|
}
|
|
}
|
|
|
|
@keyframes scaleIn {
|
|
0% {
|
|
opacity: 0;
|
|
transform: scale(0.9);
|
|
}
|
|
70% {
|
|
opacity: 1;
|
|
transform: scale(1.02);
|
|
}
|
|
100% {
|
|
opacity: 1;
|
|
transform: 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%;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<h1>客户管理系统</h1>
|
|
<div class="user-info">
|
|
<span id="userRole"></span>
|
|
<span id="userName"></span>
|
|
<div style="position: relative; display: inline-block; margin-right: 10px;">
|
|
<button id="applyButton" onclick="openApplyModal()" style="display: none; padding: 5px 10px; background-color: #722ed1; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer;">申请管理</button>
|
|
<span id="applyBadge" style="position: absolute; top: -5px; right: -5px; background-color: #ff4d4f; color: white; border-radius: 50%; width: 18px; height: 18px; font-size: 12px; display: flex; align-items: center; justify-content: center; font-weight: bold; opacity: 0; transition: opacity 0.3s ease;">0</span>
|
|
</div>
|
|
<button id="employeeApplyButton" onclick="openEmployeeApplyModal()" style="display: none; margin-right: 10px; padding: 5px 10px; background-color: #722ed1; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer;">申请记录</button>
|
|
<button id="permissionButton" onclick="openPermissionModal()" style="display: none; margin-right: 10px; padding: 5px 10px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer;">权限管理</button>
|
|
<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">
|
|
<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>
|
|
</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('products', this)">货源浏览</button>
|
|
<button class="tab-button" onclick="switchTab('public', this)">公海池数据</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 个人数据标签页 -->
|
|
<div class="section-content">
|
|
<div id="personal" class="tab-content active">
|
|
<div class="filter-container">
|
|
<div class="filter-bar">
|
|
<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>
|
|
</div>
|
|
<div class="filter-bar" style="margin-top: 8px;">
|
|
<span style="font-size: 14px;">负责人:</span>
|
|
<select id="personalManagerFilter" onchange="filterPersonalByManager()" style="padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
|
|
<option value="">全部</option>
|
|
<option value="李文涛">李文涛</option>
|
|
<option value="代斯磊">代斯磊</option>
|
|
<option value="杨率">杨率</option>
|
|
<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="seller">供应商</option>
|
|
<option value="buyer">大贸易客户</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>
|
|
</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>
|
|
<div id="personalEmpty" class="empty-state">暂无个人数据</div>
|
|
<div class="pagination" id="personalPagination">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 货源浏览标签页 -->
|
|
<div id="products" class="tab-content">
|
|
<div class="filter-container">
|
|
<div class="filter-bar">
|
|
<span style="font-size: 14px;">种类:</span>
|
|
<select id="categoryFilter" onchange="filterProducts()" style="padding: 6px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
|
|
<option value="">全部</option>
|
|
<option value="粉壳">粉壳</option>
|
|
<option value="褐壳">褐壳</option>
|
|
<option value="绿壳">绿壳</option>
|
|
<option value="白壳">白壳</option>
|
|
</select>
|
|
<span style="margin-left: 20px; font-size: 14px;">商品名称:</span>
|
|
<select id="productNameFilter" onchange="filterProducts()" style="padding: 6px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
|
|
<option value="">全部</option>
|
|
<option value="罗曼粉">罗曼粉</option>
|
|
<option value="伊莎粉">伊莎粉</option>
|
|
<option value="罗曼灰">罗曼灰</option>
|
|
<option value="海蓝灰">海蓝灰</option>
|
|
<option value="海蓝褐">海蓝褐</option>
|
|
<option value="绿壳">绿壳</option>
|
|
<option value="粉一">粉一</option>
|
|
<option value="粉三">粉三</option>
|
|
<option value="粉六">粉六</option>
|
|
<option value="粉八">粉八</option>
|
|
<option value="京粉1号">京粉1号</option>
|
|
<option value="京红">京红</option>
|
|
<option value="京粉6号">京粉6号</option>
|
|
<option value="京粉3号">京粉3号</option>
|
|
<option value="农二">农二</option>
|
|
<option value="农三">农三</option>
|
|
<option value="农五">农五</option>
|
|
<option value="农六">农六</option>
|
|
<option value="黑鸡土蛋">黑鸡土蛋</option>
|
|
<option value="大午金凤">大午金凤</option>
|
|
<option value="黑凤">黑凤</option>
|
|
</select>
|
|
<span style="margin-left: 20px; font-size: 14px;">蛋黄:</span>
|
|
<select id="yolkFilter" onchange="filterProducts()" style="padding: 6px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
|
|
<option value="">全部</option>
|
|
<option value="红心">红心</option>
|
|
<option value="黄心">黄心</option>
|
|
<option value="双色">双色</option>
|
|
<option value="未知">未知</option>
|
|
</select>
|
|
<span style="margin-left: 20px; font-size: 14px;">销售负责人:</span>
|
|
<select id="salesManagerFilter" onchange="filterProducts()" style="padding: 6px 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="creatorFilter" onchange="filterProducts()" style="padding: 6px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;">
|
|
<option value="">全部</option>
|
|
</select>
|
|
<span style="margin-left: 20px; font-size: 14px;">搜索:</span>
|
|
<input type="text" id="productSearch" placeholder="搜索商品名称或地区" style="padding: 6px 8px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; width: 200px;">
|
|
<button onclick="searchProducts()" style="margin-left: 8px; padding: 6px 12px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 14px;">搜索</button>
|
|
<button onclick="resetProductFilters()" style="margin-left: 10px; padding: 6px 12px; background-color: #666; color: white; border: none; border-radius: 4px; font-size: 14px;">重置筛选</button>
|
|
<button onclick="loadProducts()" style="margin-left: 10px; background-color: #1890ff; color: white; border: none; border-radius: 4px; padding: 6px 16px; cursor: pointer; font-size: 14px;">刷新货源</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-container">
|
|
<table id="productsTable">
|
|
<thead>
|
|
<tr>
|
|
<th>商品名称</th>
|
|
<th>价格</th>
|
|
<th>库存</th>
|
|
<th>地区</th>
|
|
<th>创建时间</th>
|
|
<th>销售负责人</th>
|
|
<th>货源状态</th>
|
|
<th>浏览次数</th>
|
|
<th>创建人</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="productsBody">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div id="productsEmpty" class="empty-state">暂无货源数据</div>
|
|
<div class="pagination" id="productsPagination">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 公海池数据标签页 -->
|
|
<div id="public" class="tab-content">
|
|
<div class="filter-container">
|
|
<div class="filter-bar">
|
|
<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>
|
|
</div>
|
|
<div class="filter-bar" style="margin-top: 8px;">
|
|
<span style="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>
|
|
<option value="李文涛">李文涛</option>
|
|
<option value="代斯磊">代斯磊</option>
|
|
<option value="杨率">杨率</option>
|
|
<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="seller">供应商</option>
|
|
<option value="buyer">大贸易客户</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>
|
|
</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>
|
|
<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 productsPage = 1;
|
|
var personalPageSize = 10;
|
|
var publicPageSize = 10;
|
|
var productsPageSize = 10;
|
|
var personalFilter = 'all'; // all, followed, unfollowed
|
|
var productFilters = {
|
|
category: '',
|
|
productName: '',
|
|
yolk: '',
|
|
salesManager: '',
|
|
creator: '',
|
|
search: ''
|
|
};
|
|
var salesManagers = [];
|
|
var creators = [];
|
|
|
|
var managersList = [];
|
|
var allPersonalData = [];
|
|
var allPublicData = [];
|
|
var allProducts = [];
|
|
var productsTotal = 0;
|
|
var productsTotalPages = 0;
|
|
var isLoadingAllData = false;
|
|
var isLoadingProducts = false;
|
|
var currentManagerFilter = null;
|
|
var currentFilterTable = 'personal';
|
|
var currentPhoneSearch = null;
|
|
var currentStartDate = null;
|
|
var currentEndDate = null;
|
|
var currentTypeFilter = null;
|
|
|
|
// 数据缓存对象
|
|
var dataCache = {
|
|
products: {
|
|
all: null, // 所有数据
|
|
filtered: {}, // 筛选结果缓存,key为筛选条件字符串
|
|
pages: {}, // 分页数据缓存,key为页码
|
|
timestamp: 0 // 缓存时间戳
|
|
},
|
|
personal: {
|
|
all: null,
|
|
filtered: {},
|
|
pages: {},
|
|
timestamp: 0
|
|
},
|
|
public: {
|
|
pages: {}, // 分页数据缓存,key为页码
|
|
timestamp: 0
|
|
}
|
|
};
|
|
|
|
// 缓存有效期(毫秒)
|
|
var CACHE_DURATION = 5 * 60 * 1000; // 5分钟
|
|
|
|
// 防抖函数
|
|
function debounce(func, wait) {
|
|
var timeout;
|
|
return function() {
|
|
var context = this;
|
|
var args = arguments;
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(function() {
|
|
func.apply(context, args);
|
|
}, wait);
|
|
};
|
|
}
|
|
|
|
// 节流函数
|
|
function throttle(func, limit) {
|
|
var inThrottle;
|
|
return function() {
|
|
var args = arguments;
|
|
var context = this;
|
|
if (!inThrottle) {
|
|
func.apply(context, args);
|
|
inThrottle = true;
|
|
setTimeout(function() {
|
|
inThrottle = false;
|
|
}, limit);
|
|
}
|
|
};
|
|
}
|
|
|
|
// 缓存管理函数
|
|
function getCachedData(type, key) {
|
|
var now = Date.now();
|
|
if (dataCache[type] && dataCache[type][key] && (now - dataCache[type].timestamp) < CACHE_DURATION) {
|
|
return dataCache[type][key];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function setCachedData(type, key, data) {
|
|
if (!dataCache[type]) {
|
|
dataCache[type] = {};
|
|
}
|
|
dataCache[type][key] = data;
|
|
dataCache[type].timestamp = Date.now();
|
|
}
|
|
|
|
// 防抖版本的筛选和搜索函数
|
|
var debouncedFilterProducts = debounce(function() {
|
|
productFilters.category = document.getElementById('categoryFilter').value;
|
|
productFilters.productName = document.getElementById('productNameFilter').value;
|
|
productFilters.yolk = document.getElementById('yolkFilter').value;
|
|
productFilters.salesManager = document.getElementById('salesManagerFilter').value;
|
|
productFilters.creator = document.getElementById('creatorFilter').value;
|
|
applyProductFilters();
|
|
}, 300);
|
|
|
|
var debouncedSearchProducts = debounce(function() {
|
|
productFilters.search = document.getElementById('productSearch').value;
|
|
applyProductFilters();
|
|
}, 300);
|
|
|
|
function init() {
|
|
// 检查URL是否包含登录参数
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const projectNameFromUrl = urlParams.get('projectName');
|
|
const userNameFromUrl = urlParams.get('userName');
|
|
const passwordFromUrl = urlParams.get('password');
|
|
|
|
// 如果URL包含登录参数,清除旧的userInfo并跳转到login.html处理新的登录
|
|
if (userNameFromUrl && passwordFromUrl) {
|
|
console.log('URL包含登录参数,清除旧的用户信息并跳转到登录页面');
|
|
localStorage.removeItem('userInfo');
|
|
// 保留URL参数,让login.html处理
|
|
window.location.href = 'login.html' + window.location.search;
|
|
return;
|
|
}
|
|
|
|
var savedUserInfo = localStorage.getItem('userInfo');
|
|
if (!savedUserInfo) {
|
|
window.location.href = 'login.html';
|
|
return;
|
|
}
|
|
userInfo = JSON.parse(savedUserInfo);
|
|
displayUserInfo();
|
|
loadManagers();
|
|
loadPersonnelData();
|
|
loadPersonalData();
|
|
|
|
// 检查申请状态
|
|
var userRole = userInfo.loginInfo.projectName;
|
|
if (userRole === '管理员') {
|
|
checkApplyStatus();
|
|
}
|
|
|
|
// 预加载货源浏览数据
|
|
preloadProductsData();
|
|
|
|
// 设置每五分钟更新一次缓存
|
|
setInterval(updateProductsCache, 5 * 60 * 1000);
|
|
}
|
|
|
|
// 预加载货源浏览数据
|
|
function preloadProductsData() {
|
|
console.log('开始预加载货源浏览数据...');
|
|
|
|
// 设置分页参数,先加载50条数据
|
|
var oldPageSize = productsPageSize;
|
|
var preloadSize = 50; // 先加载50条数据
|
|
productsPage = 1;
|
|
|
|
var userRole = userInfo.loginInfo.projectName;
|
|
var userName = userInfo.loginInfo.userName;
|
|
|
|
// 构建查询参数
|
|
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=' + productsPage + '&size=' + preloadSize;
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url, true);
|
|
xhr.onreadystatechange = function() {
|
|
// 恢复原来的页面大小
|
|
productsPageSize = oldPageSize;
|
|
|
|
if (xhr.readyState == 4 && xhr.status == 200) {
|
|
var data = JSON.parse(xhr.responseText);
|
|
if (data.success) {
|
|
var products = data.products || [];
|
|
var total = data.total || 0;
|
|
var pages = Math.ceil(total / productsPageSize);
|
|
|
|
// 缓存数据
|
|
setCachedData('products', 'all', {
|
|
products: products,
|
|
total: total,
|
|
pages: pages
|
|
});
|
|
|
|
// 将20条数据分为两页,每页10条
|
|
var page1Products = products.slice(0, productsPageSize);
|
|
var page2Products = products.slice(productsPageSize, productsPageSize * 2);
|
|
|
|
// 缓存第一页数据(前10条)
|
|
setCachedData('products', 'page_1_size_' + productsPageSize, {
|
|
products: page1Products,
|
|
total: total,
|
|
pages: pages
|
|
});
|
|
|
|
// 缓存第二页数据(后10条)
|
|
setCachedData('products', 'page_2_size_' + productsPageSize, {
|
|
products: page2Products,
|
|
total: total,
|
|
pages: pages
|
|
});
|
|
|
|
console.log('预加载货源浏览数据完成,共', products.length, '条数据,分为', pages, '页');
|
|
console.log('第一页缓存', page1Products.length, '条数据,第二页缓存', page2Products.length, '条数据');
|
|
|
|
// 后台加载剩余数据并放入缓存
|
|
loadRemainingProductsData(userRole, userName, total);
|
|
} else {
|
|
console.error('预加载货源浏览数据失败:', data.message);
|
|
}
|
|
} else if (xhr.readyState == 4) {
|
|
console.error('预加载货源浏览数据失败:', xhr.status, xhr.statusText);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
// 后台加载剩余货源数据
|
|
function loadRemainingProductsData(userRole, userName, total) {
|
|
console.log('开始在后台加载剩余货源数据...');
|
|
|
|
// 计算需要加载的剩余数据量
|
|
var remainingSize = Math.min(1000, total); // 最多加载1000条
|
|
|
|
// 构建查询参数
|
|
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=1&size=' + remainingSize;
|
|
|
|
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.success) {
|
|
var allProducts = data.products || [];
|
|
var totalCount = data.total || 0;
|
|
var pages = Math.ceil(totalCount / productsPageSize);
|
|
|
|
// 更新缓存
|
|
setCachedData('products', 'all', {
|
|
products: allProducts,
|
|
total: totalCount,
|
|
pages: pages
|
|
});
|
|
|
|
// 缓存所有页面数据
|
|
for (var i = 1; i <= pages && i <= 100; i++) { // 最多缓存100页
|
|
var startIndex = (i - 1) * productsPageSize;
|
|
var endIndex = startIndex + productsPageSize;
|
|
var pageProducts = allProducts.slice(startIndex, endIndex);
|
|
|
|
setCachedData('products', 'page_' + i, {
|
|
products: pageProducts,
|
|
total: totalCount,
|
|
pages: pages
|
|
});
|
|
}
|
|
|
|
console.log('后台加载剩余货源数据完成,共', allProducts.length, '条数据,分为', pages, '页');
|
|
console.log('已缓存', Math.min(pages, 100), '页数据');
|
|
} else {
|
|
console.error('后台加载剩余货源数据失败:', data.message);
|
|
}
|
|
} else if (xhr.readyState == 4) {
|
|
console.error('后台加载剩余货源数据失败:', xhr.status, xhr.statusText);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
// 更新货源浏览数据缓存
|
|
function updateProductsCache() {
|
|
console.log('开始更新货源浏览数据缓存...');
|
|
|
|
var userRole = userInfo.loginInfo.projectName;
|
|
var userName = userInfo.loginInfo.userName;
|
|
|
|
// 构建查询参数,使用阈值1000条
|
|
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=1&size=1000';
|
|
|
|
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.success) {
|
|
var products = data.products || [];
|
|
var total = data.total || 0;
|
|
var pages = Math.ceil(total / productsPageSize);
|
|
|
|
// 更新缓存
|
|
setCachedData('products', 'all', {
|
|
products: products,
|
|
total: total,
|
|
pages: pages
|
|
});
|
|
|
|
// 更新第一页缓存
|
|
setCachedData('products', 'page_1_size_' + productsPageSize, {
|
|
products: products,
|
|
total: total,
|
|
pages: pages
|
|
});
|
|
|
|
console.log('货源浏览数据缓存更新完成,共', products.length, '条数据');
|
|
|
|
// 检查当前是否在货源浏览页面,如果是则重新渲染
|
|
var activeTab = document.querySelector('.tab.active');
|
|
if (activeTab && activeTab.id === 'products') {
|
|
displayProducts(products);
|
|
}
|
|
} else {
|
|
console.error('更新货源浏览数据缓存失败:', data.message);
|
|
}
|
|
} else if (xhr.readyState == 4) {
|
|
console.error('更新货源浏览数据缓存失败:', xhr.status, xhr.statusText);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
function loadPersonnelData() {
|
|
// 加载销售负责人和创建人数据
|
|
var url = '/KH/api/personnel';
|
|
|
|
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.success) {
|
|
var personnelList = data.personnel || [];
|
|
console.log('获取到的人员列表:', personnelList);
|
|
|
|
// 筛选销售负责人(projectName为销售员)
|
|
salesManagers = personnelList.filter(item => item && item.projectName && (item.projectName === '销售员' || item.projectName.includes('销售'))).map(item => item.name);
|
|
// 筛选创建人(projectName为采购员)
|
|
creators = personnelList.filter(item => item && item.projectName && (item.projectName === '采购员' || item.projectName.includes('采购'))).map(item => item.name);
|
|
|
|
// 去重
|
|
salesManagers = [...new Set(salesManagers)].filter(name => name);
|
|
creators = [...new Set(creators)].filter(name => name);
|
|
|
|
console.log('筛选后的销售负责人:', salesManagers);
|
|
console.log('筛选后的创建人:', creators);
|
|
|
|
// 填充销售负责人下拉框
|
|
populateSalesManagers();
|
|
// 填充创建人下拉框
|
|
populateCreators();
|
|
} else {
|
|
console.error('获取人员列表失败:', data.message);
|
|
}
|
|
} else if (xhr.readyState == 4) {
|
|
console.error('获取人员列表失败:', xhr.status, xhr.statusText);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
function populateSalesManagers() {
|
|
var select = document.getElementById('salesManagerFilter');
|
|
if (select) {
|
|
// 清空现有选项(保留第一个全部选项)
|
|
while (select.options.length > 1) {
|
|
select.remove(1);
|
|
}
|
|
|
|
// 添加销售负责人选项
|
|
salesManagers.forEach(name => {
|
|
var option = document.createElement('option');
|
|
option.value = name;
|
|
option.textContent = name;
|
|
select.appendChild(option);
|
|
});
|
|
}
|
|
}
|
|
|
|
function populateCreators() {
|
|
var select = document.getElementById('creatorFilter');
|
|
if (select) {
|
|
// 清空现有选项(保留第一个全部选项)
|
|
while (select.options.length > 1) {
|
|
select.remove(1);
|
|
}
|
|
|
|
// 添加创建人选项
|
|
creators.forEach(name => {
|
|
var option = document.createElement('option');
|
|
option.value = name;
|
|
option.textContent = name;
|
|
select.appendChild(option);
|
|
});
|
|
}
|
|
}
|
|
|
|
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');
|
|
var permissionButton = document.getElementById('permissionButton');
|
|
var applyButton = document.getElementById('applyButton');
|
|
var employeeApplyButton = document.getElementById('employeeApplyButton');
|
|
if (assignButton) {
|
|
assignButton.style.display = isAdmin ? 'inline-block' : 'none';
|
|
}
|
|
if (publicAssignButton) {
|
|
publicAssignButton.style.display = isAdmin ? 'inline-block' : 'none';
|
|
}
|
|
if (permissionButton) {
|
|
permissionButton.style.display = isAdmin ? 'inline-block' : 'none';
|
|
}
|
|
if (applyButton) {
|
|
applyButton.style.display = isAdmin ? 'inline-block' : 'none';
|
|
}
|
|
if (employeeApplyButton) {
|
|
employeeApplyButton.style.display = isAdmin ? 'none' : 'inline-block';
|
|
}
|
|
}
|
|
|
|
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();
|
|
} else if (tabName === 'products') {
|
|
loadProducts();
|
|
}
|
|
} 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 || ''
|
|
};
|
|
|
|
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);
|
|
}
|
|
};
|
|
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) {
|
|
console.log('筛选负责人:', currentManagerFilter, '用户负责人:', user.managerName);
|
|
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) {
|
|
var userType = user.type || '';
|
|
console.log('筛选类型:', currentTypeFilter, '用户类型:', userType);
|
|
|
|
// 特殊处理seller和buyer类型,直接比较英文
|
|
if (currentTypeFilter === 'seller') {
|
|
if (userType !== 'seller' && userType !== '供应商') {
|
|
return false;
|
|
}
|
|
} else if (currentTypeFilter === 'buyer') {
|
|
if (userType !== 'buyer' && userType !== '大贸易客户') {
|
|
return false;
|
|
}
|
|
} else {
|
|
// 其他类型的映射
|
|
var typeMap = {
|
|
'wholesale': '批发贸易类',
|
|
'e-commerce': '电商平台类',
|
|
'delivery_retail': '配送零售类',
|
|
'defective_egg': '次品蛋专项类',
|
|
'other': '其他类型'
|
|
};
|
|
var filterValue = typeMap[currentTypeFilter] || currentTypeFilter;
|
|
if (userType !== filterValue) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 其他情况,不过滤
|
|
return true;
|
|
});
|
|
|
|
// 更新统计信息
|
|
if (personalTotalCount) {
|
|
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 applyButton = '';
|
|
if (!isAdmin) {
|
|
applyButton = ' <button onclick="applyCustomer(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', this); event.stopPropagation();" style="padding: 4px 8px; background-color: #722ed1; color: white; border: none; border-radius: 4px; font-size: 12px; margin-right: 4px;">申请</button>';
|
|
|
|
}
|
|
|
|
// 只有管理员显示复选框
|
|
var checkboxCell = isAdmin ? '<td><input type="checkbox" class="userCheckbox" data-userid="' + (user.userId || '') + '"></td>' : '<td style="width: 40px;"></td>';
|
|
|
|
var row = '<tr style="cursor: default;">' +
|
|
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="openDetailModal(\'' + (user.userId || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #13c2c2; 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, filteredUsers.length);
|
|
} 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 loadRemainingProductsData(userRole, userName, total) {
|
|
console.log('开始在后台加载剩余货源数据...');
|
|
|
|
// 计算需要加载的剩余数据量
|
|
var remainingSize = Math.min(1000, total); // 最多加载1000条
|
|
|
|
// 构建查询参数
|
|
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=1&size=' + remainingSize;
|
|
|
|
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.success) {
|
|
var allProducts = data.products || [];
|
|
var totalCount = data.total || 0;
|
|
var pages = Math.ceil(totalCount / productsPageSize);
|
|
|
|
// 更新缓存
|
|
setCachedData('products', 'all', {
|
|
products: allProducts,
|
|
total: totalCount,
|
|
pages: pages
|
|
});
|
|
|
|
// 缓存所有页面数据
|
|
for (var i = 1; i <= pages && i <= 100; i++) { // 最多缓存100页
|
|
var startIndex = (i - 1) * productsPageSize;
|
|
var endIndex = startIndex + productsPageSize;
|
|
var pageProducts = allProducts.slice(startIndex, endIndex);
|
|
|
|
setCachedData('products', 'page_' + i + '_size_' + productsPageSize, {
|
|
products: pageProducts,
|
|
total: totalCount,
|
|
pages: pages
|
|
});
|
|
}
|
|
|
|
console.log('后台加载剩余货源数据完成,共', allProducts.length, '条数据,分为', pages, '页');
|
|
console.log('已缓存', Math.min(pages, 100), '页数据');
|
|
} else {
|
|
console.error('后台加载剩余货源数据失败:', data.message);
|
|
}
|
|
} else if (xhr.readyState == 4) {
|
|
console.error('后台加载剩余货源数据失败:', xhr.status, xhr.statusText);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
|
|
// 重置公海池数据创建时间筛选
|
|
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');
|
|
}
|
|
|
|
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 || ''
|
|
};
|
|
|
|
var url = '/KH/api/users/public?' + 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);
|
|
// 保存公海池数据到全局变量
|
|
if (data.users) {
|
|
allPublicData = data.users;
|
|
}
|
|
displayPublicData(data);
|
|
// 确保传递正确的参数给分页函数
|
|
var page = data.page || 1;
|
|
var pages = data.pages || 1;
|
|
var total = data.total || 0;
|
|
renderPublicPagination(page, pages, total);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
function objectToQueryString(obj) {
|
|
return Object.keys(obj)
|
|
.map(key => key + '=' + encodeURIComponent(obj[key]))
|
|
.join('&');
|
|
}
|
|
|
|
// 添加表单元素悬停样式
|
|
var formHoverStyles = `
|
|
<style>
|
|
/* 美化所有下拉选择框 */
|
|
select {
|
|
appearance: none !important;
|
|
-webkit-appearance: none !important;
|
|
-moz-appearance: none !important;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23999' d='M6 9L1 4h10z'/%3E%3C/svg%3E") !important;
|
|
background-repeat: no-repeat !important;
|
|
background-position: right 12px center !important;
|
|
background-size: 12px 12px !important;
|
|
padding-right: 36px !important;
|
|
border: 1px solid #d9d9d9 !important;
|
|
border-radius: 8px !important;
|
|
font-size: 14px !important;
|
|
font-weight: 400 !important;
|
|
color: #333 !important;
|
|
background-color: white !important;
|
|
cursor: pointer !important;
|
|
transition: all 0.3s ease !important;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05) !important;
|
|
}
|
|
|
|
/* 为跟进模态框中的表单元素添加悬停效果 */
|
|
#followupType:hover,
|
|
#followupLevel:hover,
|
|
#followupDemand:hover,
|
|
#followupDetailedAddress:hover,
|
|
#followupCompany:hover,
|
|
#followupContent:hover {
|
|
border-color: #1890ff !important;
|
|
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15) !important;
|
|
}
|
|
|
|
/* 下拉选择框聚焦样式 */
|
|
select:focus {
|
|
outline: none !important;
|
|
border-color: #1890ff !important;
|
|
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2) !important;
|
|
}
|
|
|
|
/* 下拉选择框禁用样式 */
|
|
select:disabled {
|
|
background-color: #f5f5f5 !important;
|
|
cursor: not-allowed !important;
|
|
opacity: 0.6 !important;
|
|
}
|
|
|
|
/* 为所有按钮添加更明显的悬停效果 */
|
|
button:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
|
|
}
|
|
|
|
/* 为搜索选择组件添加悬停效果 */
|
|
.search-select-input:hover {
|
|
border-color: #1890ff !important;
|
|
}
|
|
|
|
/* 为搜索选择下拉选项添加悬停效果 */
|
|
.search-select-option:hover {
|
|
background-color: #e6f7ff !important;
|
|
color: #1890ff !important;
|
|
}
|
|
|
|
/* 输入框统一美化 */
|
|
input[type="text"],
|
|
textarea {
|
|
border: 1px solid #d9d9d9 !important;
|
|
border-radius: 8px !important;
|
|
font-size: 14px !important;
|
|
font-weight: 400 !important;
|
|
color: #333 !important;
|
|
background-color: white !important;
|
|
transition: all 0.3s ease !important;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05) !important;
|
|
}
|
|
|
|
/* 输入框聚焦样式 */
|
|
input[type="text"]:focus,
|
|
textarea:focus {
|
|
outline: none !important;
|
|
border-color: #1890ff !important;
|
|
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2) !important;
|
|
}
|
|
</style>
|
|
`;
|
|
|
|
// 加载货源数据
|
|
function loadProducts() {
|
|
var userRole = userInfo.loginInfo.projectName;
|
|
var userName = userInfo.loginInfo.userName;
|
|
|
|
// 检查是否正在加载
|
|
if (isLoadingProducts) return;
|
|
isLoadingProducts = true;
|
|
|
|
// 检查是否有筛选条件
|
|
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
|
|
productFilters.salesManager || productFilters.creator || productFilters.search;
|
|
|
|
// 如果有筛选条件,优先使用缓存中的完整数据
|
|
if (hasFilters) {
|
|
var cachedAllData = getCachedData('products', 'all');
|
|
if (cachedAllData && cachedAllData.products.length > 0) {
|
|
console.log('使用缓存中的完整数据进行筛选');
|
|
applyProductFilters();
|
|
isLoadingProducts = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 先检查缓存数据
|
|
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
|
|
if (cachedData) {
|
|
console.log('使用缓存数据加载货源,页码:', productsPage, '每页条数:', productsPageSize);
|
|
allProducts = cachedData.products || [];
|
|
productsTotal = cachedData.total || 0;
|
|
productsTotalPages = cachedData.pages || Math.ceil(productsTotal / productsPageSize);
|
|
// 显示当前页数据
|
|
displayProducts(allProducts);
|
|
// 确保使用当前的productsPageSize值渲染分页组件
|
|
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
|
|
isLoadingProducts = false;
|
|
return;
|
|
}
|
|
|
|
// 如果没有对应每页显示条数的缓存数据,尝试使用缓存中的完整数据集
|
|
var cachedAllData = getCachedData('products', 'all');
|
|
if (cachedAllData && cachedAllData.products.length > 0) {
|
|
console.log('使用缓存中的完整数据生成对应每页显示条数的数据');
|
|
var allProductsData = cachedAllData.products;
|
|
productsTotal = cachedAllData.total || allProductsData.length;
|
|
productsTotalPages = Math.ceil(productsTotal / productsPageSize);
|
|
|
|
// 根据当前页码和每页显示条数计算数据范围
|
|
var startIndex = (productsPage - 1) * productsPageSize;
|
|
var endIndex = startIndex + productsPageSize;
|
|
allProducts = allProductsData.slice(startIndex, endIndex);
|
|
|
|
// 缓存生成的数据
|
|
setCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize, {
|
|
products: allProducts,
|
|
total: productsTotal,
|
|
pages: productsTotalPages
|
|
});
|
|
|
|
// 显示当前页数据
|
|
displayProducts(allProducts);
|
|
// 确保使用当前的productsPageSize值渲染分页组件
|
|
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
|
|
isLoadingProducts = false;
|
|
return;
|
|
}
|
|
|
|
// 构建查询参数,使用当前页和每页显示条数
|
|
var url = '/KH/api/products?userName=' + encodeURIComponent(userName) + '&userRole=' + encodeURIComponent(userRole) + '&page=' + productsPage + '&size=' + productsPageSize;
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url, true);
|
|
xhr.onreadystatechange = function() {
|
|
isLoadingProducts = false;
|
|
if (xhr.readyState == 4 && xhr.status == 200) {
|
|
var data = JSON.parse(xhr.responseText);
|
|
if (data.success) {
|
|
allProducts = data.products || [];
|
|
productsTotal = data.total || 0;
|
|
productsTotalPages = data.pages || Math.ceil(productsTotal / productsPageSize);
|
|
// 显示当前页数据
|
|
displayProducts(allProducts);
|
|
// 确保使用当前的productsPageSize值渲染分页组件
|
|
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
|
|
|
|
// 缓存当前页数据
|
|
setCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize, {
|
|
products: allProducts,
|
|
total: productsTotal,
|
|
pages: productsTotalPages
|
|
});
|
|
} else {
|
|
showAlert('加载货源失败: ' + data.message);
|
|
}
|
|
} else if (xhr.readyState == 4) {
|
|
console.error('加载货源失败:', xhr.status, xhr.statusText);
|
|
showAlert('加载货源失败,请刷新页面重试');
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
// 获取当前页的产品数据
|
|
function getCurrentPageProducts() {
|
|
var startIndex = (productsPage - 1) * productsPageSize;
|
|
var endIndex = startIndex + productsPageSize;
|
|
return allProducts.slice(startIndex, endIndex);
|
|
}
|
|
|
|
// 显示货源数据
|
|
function displayProducts(products) {
|
|
var productsBody = document.getElementById('productsBody');
|
|
var productsEmpty = document.getElementById('productsEmpty');
|
|
var productsPagination = document.getElementById('productsPagination');
|
|
productsBody.innerHTML = '';
|
|
|
|
if (products && products.length > 0) {
|
|
productsEmpty.style.display = 'none';
|
|
productsPagination.style.display = 'flex';
|
|
|
|
for (var i = 0; i < products.length; i++) {
|
|
var product = products[i];
|
|
var row = '<tr>' +
|
|
'<td>' + (product.productName || '-') + '</td>' +
|
|
'<td>' + (product.price || '-') + '</td>' +
|
|
'<td>' + (product.quantity || '-') + '</td>' +
|
|
'<td>' + (product.fullRegion || product.region || '-') + '</td>' +
|
|
'<td>' + formatDateTime(product.created_at) + '</td>' +
|
|
'<td>' + (product.salesManager || '-') + '</td>' +
|
|
'<td>' + ((product.status === 'hidden' || product.status === 'sold_out') ? '已下架' : (product.status === 'published' ? '已上架' : '-')) + '</td>' +
|
|
'<td>' + (product.viewCount || 0) + '</td>' +
|
|
'<td>' + (product.creator || '-') + '</td>' +
|
|
'<td><button onclick="openProductDetailModal(\'' + (product.productId || '') + '\')" style="padding: 4px 8px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 12px;">查看详情</button></td>' +
|
|
'</tr>';
|
|
productsBody.innerHTML += row;
|
|
}
|
|
} else {
|
|
productsEmpty.style.display = 'block';
|
|
productsPagination.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
// 打开商品详情弹窗
|
|
function openProductDetailModal(productId) {
|
|
var url = '/KH/api/products/detail?productId=' + encodeURIComponent(productId);
|
|
|
|
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.success) {
|
|
showProductDetail(data.product, data.traces);
|
|
} else {
|
|
showAlert('获取商品详情失败: ' + data.message);
|
|
}
|
|
} else if (xhr.readyState == 4) {
|
|
console.error('获取商品详情失败:', xhr.status, xhr.statusText);
|
|
showAlert('获取商品详情失败,请重试');
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
// 筛选货源
|
|
function filterProducts() {
|
|
// 使用防抖版本的筛选函数
|
|
debouncedFilterProducts();
|
|
}
|
|
|
|
// 搜索货源
|
|
function searchProducts() {
|
|
// 使用防抖版本的搜索函数
|
|
debouncedSearchProducts();
|
|
}
|
|
|
|
// 重置货源筛选
|
|
function resetProductFilters() {
|
|
// 重置筛选值
|
|
document.getElementById('categoryFilter').value = '';
|
|
document.getElementById('productNameFilter').value = '';
|
|
document.getElementById('yolkFilter').value = '';
|
|
document.getElementById('salesManagerFilter').value = '';
|
|
document.getElementById('creatorFilter').value = '';
|
|
document.getElementById('productSearch').value = '';
|
|
|
|
// 重置筛选对象
|
|
productFilters = {
|
|
category: '',
|
|
productName: '',
|
|
yolk: '',
|
|
salesManager: '',
|
|
creator: '',
|
|
search: ''
|
|
};
|
|
|
|
// 重新加载数据
|
|
loadProducts();
|
|
}
|
|
|
|
// 应用货源筛选
|
|
function applyProductFilters() {
|
|
// 优先使用缓存中的完整数据
|
|
var cachedAllData = getCachedData('products', 'all');
|
|
var sourceProducts = cachedAllData ? cachedAllData.products : allProducts;
|
|
|
|
if (sourceProducts.length === 0) {
|
|
// 如果还没有数据,先加载
|
|
loadProducts();
|
|
return;
|
|
}
|
|
|
|
// 应用筛选
|
|
var filteredProducts = sourceProducts.filter(product => {
|
|
// 种类筛选
|
|
if (productFilters.category && product.category !== productFilters.category) {
|
|
return false;
|
|
}
|
|
|
|
// 商品名称筛选
|
|
if (productFilters.productName && product.productName !== productFilters.productName) {
|
|
return false;
|
|
}
|
|
|
|
// 蛋黄筛选
|
|
if (productFilters.yolk && product.yolk !== productFilters.yolk) {
|
|
return false;
|
|
}
|
|
|
|
// 销售负责人筛选
|
|
if (productFilters.salesManager && product.salesManager !== productFilters.salesManager) {
|
|
return false;
|
|
}
|
|
|
|
// 创建人筛选
|
|
if (productFilters.creator && product.creator !== productFilters.creator) {
|
|
return false;
|
|
}
|
|
|
|
// 搜索筛选
|
|
if (productFilters.search) {
|
|
var searchLower = productFilters.search.toLowerCase();
|
|
var productNameLower = (product.productName || '').toLowerCase();
|
|
var regionLower = (product.fullRegion || product.region || '').toLowerCase();
|
|
if (!productNameLower.includes(searchLower) && !regionLower.includes(searchLower)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
// 计算筛选后的总页数
|
|
var filteredTotal = filteredProducts.length;
|
|
var filteredTotalPages = Math.ceil(filteredTotal / productsPageSize);
|
|
|
|
// 确保当前页码不超过总页数
|
|
if (productsPage > filteredTotalPages) {
|
|
productsPage = Math.max(1, filteredTotalPages);
|
|
}
|
|
|
|
// 显示当前页的筛选结果
|
|
var startIndex = (productsPage - 1) * productsPageSize;
|
|
var endIndex = startIndex + productsPageSize;
|
|
var currentPageProducts = filteredProducts.slice(startIndex, endIndex);
|
|
|
|
// 显示数据
|
|
displayProducts(currentPageProducts);
|
|
|
|
// 重新渲染分页
|
|
renderProductsPagination(productsPage, filteredTotalPages, filteredTotal);
|
|
}
|
|
|
|
// 显示商品详情
|
|
function showProductDetail(product, traces) {
|
|
// 对traces数据进行分组,按用户ID分组
|
|
var groupedTraces = {};
|
|
if (traces && traces.length > 0) {
|
|
traces.forEach(trace => {
|
|
var key = trace.userId || (trace.phoneNumber || trace.nickName);
|
|
if (!groupedTraces[key]) {
|
|
groupedTraces[key] = {
|
|
userId: trace.userId,
|
|
traceId: trace.id, // 保存traceId
|
|
nickName: trace.nickName,
|
|
phoneNumber: trace.phoneNumber,
|
|
followup: trace.followup,
|
|
responseTime: trace.responseTime,
|
|
managerName: trace.managerName,
|
|
operationTimes: []
|
|
};
|
|
}
|
|
groupedTraces[key].operationTimes.push(trace.operationTime);
|
|
});
|
|
}
|
|
|
|
// 将分组后的数据转换为数组
|
|
var mergedTraces = Object.values(groupedTraces);
|
|
|
|
// 计算响应时间:跟进时间减去创建时间
|
|
mergedTraces.forEach(trace => {
|
|
if (trace.phoneNumber) {
|
|
// 根据电话号码获取用户信息
|
|
var url = '/KH/api/users/public?phoneNumber=' + encodeURIComponent(trace.phoneNumber) + '&userRole=管理员';
|
|
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 && data.users.length > 0) {
|
|
// 根据电话号码筛选正确的用户
|
|
var user = data.users.find(u =>
|
|
u.phoneNumber === trace.phoneNumber ||
|
|
u.phoneNumber === trace.phoneNumber.replace(/\s/g, '')
|
|
) || data.users[0];
|
|
// 统一使用正确的字段名
|
|
var createTime = user.created_at || user.create_time;
|
|
var followupTime = user.followup_at || user.followup_time;
|
|
|
|
if (createTime && followupTime) {
|
|
// 计算响应时间
|
|
var createDate = new Date(createTime);
|
|
var followupDate = new Date(followupTime);
|
|
var responseTimeMs = followupDate - createDate;
|
|
|
|
// 转换为人类可读的格式
|
|
var minutes = Math.floor(responseTimeMs / 60000);
|
|
var hours = Math.floor(minutes / 60);
|
|
var days = Math.floor(hours / 24);
|
|
|
|
var responseTimeStr = '';
|
|
if (days > 0) {
|
|
responseTimeStr += days + '天';
|
|
}
|
|
if (hours % 24 > 0) {
|
|
responseTimeStr += (hours % 24) + '小时';
|
|
}
|
|
if (minutes % 60 > 0) {
|
|
responseTimeStr += (minutes % 60) + '分钟';
|
|
}
|
|
|
|
if (responseTimeStr) {
|
|
trace.responseTime = responseTimeStr;
|
|
// 更新页面上的响应时间
|
|
var tables = document.querySelectorAll('table');
|
|
tables.forEach(table => {
|
|
var header = table.querySelector('th');
|
|
if (header && header.textContent === '昵称') {
|
|
var tbody = table.querySelector('tbody');
|
|
if (tbody) {
|
|
var rows = tbody.querySelectorAll('tr');
|
|
rows.forEach((row) => {
|
|
var phoneCell = row.querySelector('td:nth-child(2)');
|
|
if (phoneCell && phoneCell.textContent.trim() === trace.phoneNumber) {
|
|
var responseCell = row.querySelector('td:nth-child(5)');
|
|
if (responseCell) {
|
|
responseCell.textContent = responseTimeStr;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
});
|
|
|
|
// 检查是否为管理员
|
|
var isAdmin = userInfo && userInfo.loginInfo && userInfo.loginInfo.projectName === '管理员';
|
|
|
|
// 创建详情弹窗
|
|
var modal = document.createElement('div');
|
|
modal.style.cssText = `
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0,0,0,0.5);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1000;
|
|
animation: fadeIn 0.4s ease;
|
|
`;
|
|
|
|
var modalContent = document.createElement('div');
|
|
modalContent.style.cssText = `
|
|
position: relative;
|
|
background: white;
|
|
border-radius: 8px;
|
|
width: 90%;
|
|
max-width: 1400px;
|
|
max-height: 80%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
box-shadow: 0 8px 32px rgba(0,0,0,0.2);
|
|
animation: scaleIn 0.4s ease;
|
|
transform-origin: center;
|
|
`;
|
|
|
|
// 固定导航栏
|
|
var navBar = `
|
|
<div style="padding: 16px 20px; border-bottom: 1px solid #e8e8e8; display: flex; justify-content: space-between; align-items: center; background-color: white; border-radius: 8px 8px 0 0;">
|
|
<h3 style="margin: 0; color: #1890ff;">商品详情</h3>
|
|
<button onclick="this.parentElement.parentElement.parentElement.remove()" style="padding: 6px 12px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">
|
|
关闭
|
|
</button>
|
|
</div>
|
|
`;
|
|
|
|
// 滚动内容区域
|
|
var contentArea = document.createElement('div');
|
|
contentArea.style.cssText = `
|
|
padding: 20px;
|
|
overflow-y: auto;
|
|
flex: 1;
|
|
`;
|
|
|
|
// 商品基本信息
|
|
var productInfo = `
|
|
<div style="margin-bottom: 20px;">
|
|
<h4 style="margin-bottom: 10px;">基本信息</h4>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px;">
|
|
<div><strong>商品名称:</strong> ${product.productName || '-'}</div>
|
|
<div><strong>价格:</strong> ${product.price || '-'}</div>
|
|
<div><strong>成本价:</strong> ${product.costprice || '-'}</div>
|
|
<div><strong>库存:</strong> ${product.quantity || '-'}</div>
|
|
<div><strong>地区:</strong> ${product.fullRegion || product.region || '-'}</div>
|
|
<div><strong>分类:</strong> ${product.category || '-'}</div>
|
|
<div><strong>来源类型:</strong> ${product.sourceType || '-'}</div>
|
|
<div><strong>供应状态:</strong> ${product.supplyStatus || '-'}</div>
|
|
<div><strong>规格:</strong> ${product.displaySpecification || product.specification || '-'}</div>
|
|
<div><strong>蛋黄:</strong> ${product.displayYolk || product.yolk || '-'}</div>
|
|
<div><strong>创建时间:</strong> ${formatDateTime(product.created_at)}</div>
|
|
</div>
|
|
</div>
|
|
<div style="margin-bottom: 20px;">
|
|
<h4 style="margin-bottom: 10px;">商品描述</h4>
|
|
<div style="padding: 10px; border: 1px solid #e8e8e8; border-radius: 4px; background-color: #fafafa;">
|
|
${product.description || '-'}
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// 浏览记录
|
|
var traceInfo = `
|
|
<div style="margin-bottom: 20px;">
|
|
<h4 style="margin-bottom: 10px;">浏览记录 (${traces ? traces.length : 0}次)</h4>
|
|
${traces && traces.length > 0 ? `
|
|
<table style="width: 100%; border-collapse: collapse; font-size: 14px;">
|
|
<thead>
|
|
<tr style="background-color: #f5f5f5;">
|
|
<th style="padding: 8px; border: 1px solid #e8e8e8;">昵称</th>
|
|
<th style="padding: 8px; border: 1px solid #e8e8e8;">手机号</th>
|
|
<th style="padding: 8px; border: 1px solid #e8e8e8;">浏览时间</th>
|
|
<th style="padding: 8px; border: 1px solid #e8e8e8;">跟进内容</th>
|
|
<th style="padding: 8px; border: 1px solid #e8e8e8;">响应时间</th>
|
|
<th style="padding: 8px; border: 1px solid #e8e8e8;">负责人</th>
|
|
<th style="padding: 8px; border: 1px solid #e8e8e8;">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
${mergedTraces.map((trace, index) => `
|
|
<tr data-trace-id="${trace.traceId || ''}" data-user-id="${trace.userId || ''}">
|
|
<td style="padding: 8px; border: 1px solid #e8e8e8; white-space: nowrap; vertical-align: top;">${trace.nickName || '-'}</td>
|
|
<td style="padding: 8px; border: 1px solid #e8e8e8; white-space: nowrap; vertical-align: top;">${trace.phoneNumber || '-'}</td>
|
|
<td style="padding: 8px; border: 1px solid #e8e8e8; vertical-align: top;">
|
|
${trace.operationTimes.map(time => formatDateTime(time)).join('<br>')}
|
|
</td>
|
|
<td style="padding: 8px; border: 1px solid #e8e8e8; white-space: normal; word-wrap: break-word; max-width: 300px; vertical-align: top;">${trace.followup || '-'}</td>
|
|
<td style="padding: 8px; border: 1px solid #e8e8e8; white-space: nowrap; vertical-align: top;">${trace.responseTime || '-'}</td>
|
|
<td style="padding: 8px; border: 1px solid #e8e8e8; white-space: nowrap; vertical-align: top;">${trace.managerName || '-'}</td>
|
|
<td style="padding: 8px; border: 1px solid #e8e8e8; white-space: nowrap; vertical-align: top;">
|
|
${!isAdmin ? `<button onclick="applyCustomer('${trace.userId || ''}', '${trace.nickName || ''}', this, '${trace.traceId || ''}'); event.stopPropagation();" style="padding: 4px 8px; background-color: #722ed1; color: white; border: none; border-radius: 4px; font-size: 12px;">申请</button>` : '-'}
|
|
</td>
|
|
</tr>
|
|
`).join('')}
|
|
</tbody>
|
|
</table>
|
|
` : '<div style="padding: 10px; border: 1px solid #e8e8e8; border-radius: 4px; background-color: #fafafa;">暂无浏览记录</div>'}
|
|
</div>
|
|
`;
|
|
|
|
// 组装弹窗内容
|
|
modalContent.innerHTML = navBar;
|
|
contentArea.innerHTML = productInfo + traceInfo;
|
|
modalContent.appendChild(contentArea);
|
|
modal.appendChild(modalContent);
|
|
document.body.appendChild(modal);
|
|
|
|
// 加载申请状态并更新按钮
|
|
loadApplyStatusForTraces(mergedTraces);
|
|
|
|
// 弹窗创建完成后,调用函数计算响应时间
|
|
calculateResponseTimes(mergedTraces);
|
|
|
|
// 弹窗创建完成后,计算响应时间:跟进时间减去创建时间
|
|
mergedTraces.forEach(trace => {
|
|
if (trace.phoneNumber) {
|
|
// 根据电话号码获取用户信息
|
|
var url = '/KH/api/users/public?phoneNumber=' + encodeURIComponent(trace.phoneNumber) + '&userRole=admin';
|
|
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 && data.users.length > 0) {
|
|
var user = data.users[0];
|
|
var createTime = user.create_time;
|
|
var followupTime = user.followup_time;
|
|
|
|
if (createTime && followupTime) {
|
|
// 计算响应时间
|
|
var createDate = new Date(createTime);
|
|
var followupDate = new Date(followupTime);
|
|
var responseTimeMs = followupDate - createDate;
|
|
|
|
// 转换为人类可读的格式
|
|
var minutes = Math.floor(responseTimeMs / 60000);
|
|
var hours = Math.floor(minutes / 60);
|
|
var days = Math.floor(hours / 24);
|
|
|
|
var responseTimeStr = '';
|
|
if (days > 0) {
|
|
responseTimeStr += days + '天';
|
|
}
|
|
if (hours % 24 > 0) {
|
|
responseTimeStr += (hours % 24) + '小时';
|
|
}
|
|
if (minutes % 60 > 0) {
|
|
responseTimeStr += (minutes % 60) + '分钟';
|
|
}
|
|
|
|
if (responseTimeStr) {
|
|
trace.responseTime = responseTimeStr;
|
|
// 更新页面上的响应时间
|
|
var tables = document.querySelectorAll('table');
|
|
tables.forEach(table => {
|
|
var header = table.querySelector('th');
|
|
if (header && header.textContent === '昵称') {
|
|
var tbody = table.querySelector('tbody');
|
|
if (tbody) {
|
|
var rows = tbody.querySelectorAll('tr');
|
|
rows.forEach((row) => {
|
|
var phoneCell = row.querySelector('td:nth-child(2)');
|
|
if (phoneCell && phoneCell.textContent.trim() === trace.phoneNumber) {
|
|
var responseCell = row.querySelector('td:nth-child(5)');
|
|
if (responseCell) {
|
|
responseCell.textContent = responseTimeStr;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
});
|
|
}
|
|
|
|
// 加载浏览记录中客户的申请状态
|
|
function loadApplyStatusForTraces(traces) {
|
|
if (!traces || traces.length === 0) return;
|
|
|
|
var url = '/KH/api/users/apply/list';
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url, true);
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState == 4 && xhr.status == 200) {
|
|
var applyList = JSON.parse(xhr.responseText);
|
|
if (applyList && applyList.length > 0) {
|
|
// 创建申请状态映射,使用user_id和sales_id的组合作为键
|
|
var applyStatusMap = {};
|
|
applyList.forEach(apply => {
|
|
if (apply.user_id && apply.sales_id) {
|
|
var key = apply.user_id + '_' + apply.sales_id;
|
|
applyStatusMap[key] = apply.status;
|
|
}
|
|
});
|
|
|
|
// 更新按钮状态
|
|
// 查找所有包含浏览记录的表格
|
|
var tables = document.querySelectorAll('table');
|
|
tables.forEach(table => {
|
|
// 检查表格是否包含浏览记录
|
|
var header = table.querySelector('th');
|
|
if (header && header.textContent === '昵称') {
|
|
var tbody = table.querySelector('tbody');
|
|
if (tbody) {
|
|
var rows = tbody.querySelectorAll('tr');
|
|
rows.forEach((row) => {
|
|
// 从row的data属性获取userId
|
|
var userId = row.dataset.userId;
|
|
if (userId) {
|
|
// 遍历所有申请记录,查找匹配的记录
|
|
applyList.forEach(apply => {
|
|
if (apply.user_id === userId) {
|
|
var button = row.querySelector('button[onclick^="applyCustomer"]');
|
|
if (button) {
|
|
if (apply.status === 0) {
|
|
// 申请中
|
|
button.textContent = '申请中';
|
|
button.disabled = true;
|
|
button.style.backgroundColor = '#faad14';
|
|
} else if (apply.status === 1) {
|
|
// 申请通过
|
|
button.textContent = '申请通过';
|
|
button.disabled = true;
|
|
button.style.backgroundColor = '#52c41a';
|
|
} else if (apply.status === 2) {
|
|
// 申请失败
|
|
button.textContent = '申请失败';
|
|
button.disabled = false;
|
|
button.style.backgroundColor = '#722ed1';
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
// 加载普通员工的申请记录
|
|
function loadEmployeeApplyRecords() {
|
|
if (!userInfo || (!userInfo.personnel && !userInfo.usersManagements)) return;
|
|
|
|
var salesName = userInfo.personnel ? userInfo.personnel.name : (userInfo.usersManagements ? userInfo.usersManagements.userName : '');
|
|
if (!salesName) return;
|
|
|
|
var url = '/KH/api/users/apply/list';
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url, true);
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState == 4 && xhr.status == 200) {
|
|
var applyList = JSON.parse(xhr.responseText);
|
|
if (applyList && applyList.length > 0) {
|
|
// 过滤出当前员工的申请记录
|
|
var employeeApplies = applyList.filter(apply => apply.sales_name === salesName);
|
|
if (employeeApplies.length > 0) {
|
|
// 显示申请记录
|
|
showEmployeeApplyRecords(employeeApplies);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
// 显示普通员工的申请记录
|
|
function showEmployeeApplyRecords(applies) {
|
|
var container = document.getElementById('employeeApplyRecords');
|
|
if (!container) {
|
|
// 创建申请记录容器
|
|
container = document.createElement('div');
|
|
container.id = 'employeeApplyRecords';
|
|
container.style.cssText = `
|
|
margin: 20px 0;
|
|
padding: 15px;
|
|
background-color: #f9f9f9;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
`;
|
|
|
|
// 添加到页面
|
|
var containerElement = document.querySelector('.container');
|
|
if (containerElement) {
|
|
var userDetailsContainer = containerElement.querySelector('.user-details-container');
|
|
if (userDetailsContainer) {
|
|
containerElement.insertBefore(container, userDetailsContainer.nextSibling);
|
|
} else {
|
|
containerElement.insertBefore(container, containerElement.firstChild);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 清空容器
|
|
container.innerHTML = '';
|
|
|
|
// 添加标题
|
|
var title = document.createElement('h3');
|
|
title.textContent = '我的申请记录';
|
|
title.style.cssText = `
|
|
margin-top: 0;
|
|
margin-bottom: 15px;
|
|
color: #333;
|
|
font-size: 18px;
|
|
`;
|
|
container.appendChild(title);
|
|
|
|
// 创建表格
|
|
var table = document.createElement('table');
|
|
table.style.cssText = `
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
background-color: white;
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
`;
|
|
|
|
// 添加表头
|
|
var thead = document.createElement('thead');
|
|
thead.innerHTML = `
|
|
<tr style="background-color: #f5f5f5;">
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left;">客户ID</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left;">申请时间</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left;">状态</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left;">审批时间</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left;">审批人</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left;">备注</th>
|
|
</tr>
|
|
`;
|
|
table.appendChild(thead);
|
|
|
|
// 添加表体
|
|
var tbody = document.createElement('tbody');
|
|
applies.forEach(apply => {
|
|
var statusText = '';
|
|
var statusColor = '';
|
|
switch (apply.status) {
|
|
case 0:
|
|
statusText = '申请中';
|
|
statusColor = '#faad14';
|
|
break;
|
|
case 1:
|
|
statusText = '申请通过';
|
|
statusColor = '#52c41a';
|
|
break;
|
|
case 2:
|
|
statusText = '申请失败';
|
|
statusColor = '#ff4d4f';
|
|
break;
|
|
}
|
|
|
|
var row = document.createElement('tr');
|
|
row.innerHTML = `
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">${apply.user_id || '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">${apply.apply_time ? new Date(apply.apply_time).toLocaleString() : '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">
|
|
<span style="color: ${statusColor}; font-weight: bold;">${statusText}</span>
|
|
</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">${apply.approve_time ? new Date(apply.approve_time).toLocaleString() : '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">${apply.approve_by || '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">${apply.reason || '-'}</td>
|
|
`;
|
|
tbody.appendChild(row);
|
|
});
|
|
table.appendChild(tbody);
|
|
|
|
container.appendChild(table);
|
|
}
|
|
|
|
// 显示提示信息
|
|
function showAlert(message) {
|
|
var alert = document.createElement('div');
|
|
alert.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
background-color: #ff4d4f;
|
|
color: white;
|
|
padding: 12px 20px;
|
|
border-radius: 4px;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
z-index: 1001;
|
|
animation: slideIn 0.3s ease;
|
|
`;
|
|
alert.textContent = message;
|
|
document.body.appendChild(alert);
|
|
|
|
setTimeout(function() {
|
|
alert.style.animation = 'fadeOut 0.3s ease';
|
|
setTimeout(function() {
|
|
alert.remove();
|
|
}, 300);
|
|
}, 3000);
|
|
}
|
|
|
|
// 渲染商品分页控件
|
|
function renderProductsPagination(currentPage, totalPages, totalItems) {
|
|
// 更新全局变量,确保事件处理函数能获取到最新值
|
|
productsTotalPages = totalPages;
|
|
productsTotal = totalItems;
|
|
var paginationContainer = document.getElementById('productsPagination');
|
|
paginationContainer.innerHTML = '';
|
|
paginationContainer.style.display = 'flex';
|
|
paginationContainer.style.justifyContent = 'center';
|
|
paginationContainer.style.alignItems = 'center';
|
|
paginationContainer.style.gap = '8px';
|
|
paginationContainer.style.flexWrap = 'wrap';
|
|
|
|
// 当总页数大于1时显示分页组件
|
|
// 或者当用户选择的每页显示条数不等于默认值时也显示分页组件
|
|
// 或者当用户进行了筛选或搜索时也显示分页组件
|
|
var defaultPageSize = 10;
|
|
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
|
|
productFilters.salesManager || productFilters.creator || productFilters.search;
|
|
|
|
if (totalPages <= 1 && totalItems <= productsPageSize && productsPageSize === defaultPageSize && !hasFilters) {
|
|
paginationContainer.style.display = 'none';
|
|
return;
|
|
}
|
|
|
|
// 首页按钮
|
|
var firstButton = document.createElement('button');
|
|
firstButton.textContent = '首页';
|
|
firstButton.disabled = currentPage === 1;
|
|
firstButton.onclick = function() {
|
|
if (productsPage > 1) {
|
|
productsPage = 1;
|
|
// 检查是否有筛选条件
|
|
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
|
|
productFilters.salesManager || productFilters.creator || productFilters.search;
|
|
if (hasFilters) {
|
|
// 如果有筛选条件,重新应用筛选
|
|
applyProductFilters();
|
|
} else {
|
|
// 检查缓存
|
|
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
|
|
if (cachedData) {
|
|
// 使用缓存数据
|
|
allProducts = cachedData.products || [];
|
|
productsTotal = cachedData.total || 0;
|
|
productsTotalPages = cachedData.pages || totalPages;
|
|
displayProducts(allProducts);
|
|
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
|
|
console.log('使用缓存的第', productsPage, '页数据,每页条数:', productsPageSize);
|
|
} else {
|
|
// 如果没有缓存,重新加载数据
|
|
loadProducts();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
paginationContainer.appendChild(firstButton);
|
|
|
|
// 上一页按钮
|
|
var prevButton = document.createElement('button');
|
|
prevButton.textContent = '上一页';
|
|
prevButton.disabled = currentPage === 1;
|
|
prevButton.onclick = function() {
|
|
if (productsPage > 1) {
|
|
productsPage = productsPage - 1;
|
|
// 检查是否有筛选条件
|
|
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
|
|
productFilters.salesManager || productFilters.creator || productFilters.search;
|
|
if (hasFilters) {
|
|
// 如果有筛选条件,重新应用筛选
|
|
applyProductFilters();
|
|
} else {
|
|
// 检查缓存
|
|
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
|
|
if (cachedData) {
|
|
// 使用缓存数据
|
|
allProducts = cachedData.products || [];
|
|
productsTotal = cachedData.total || 0;
|
|
productsTotalPages = cachedData.pages || totalPages;
|
|
displayProducts(allProducts);
|
|
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
|
|
console.log('使用缓存的第', productsPage, '页数据,每页条数:', productsPageSize);
|
|
} else {
|
|
// 如果没有缓存,重新加载数据
|
|
loadProducts();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
paginationContainer.appendChild(prevButton);
|
|
|
|
// 页码信息显示
|
|
var pageInfo = document.createElement('span');
|
|
pageInfo.textContent = '第' + currentPage + '页,共' + totalPages + '页';
|
|
pageInfo.style.margin = '0 10px';
|
|
paginationContainer.appendChild(pageInfo);
|
|
|
|
// 下一页按钮
|
|
var nextButton = document.createElement('button');
|
|
nextButton.textContent = '下一页';
|
|
nextButton.disabled = currentPage === totalPages;
|
|
nextButton.onclick = function() {
|
|
if (productsPage < totalPages) {
|
|
productsPage = productsPage + 1;
|
|
// 检查是否有筛选条件
|
|
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
|
|
productFilters.salesManager || productFilters.creator || productFilters.search;
|
|
if (hasFilters) {
|
|
// 如果有筛选条件,重新应用筛选
|
|
applyProductFilters();
|
|
} else {
|
|
// 检查缓存
|
|
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
|
|
if (cachedData) {
|
|
// 使用缓存数据
|
|
allProducts = cachedData.products || [];
|
|
productsTotal = cachedData.total || 0;
|
|
productsTotalPages = cachedData.pages || totalPages;
|
|
displayProducts(allProducts);
|
|
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
|
|
console.log('使用缓存的第', productsPage, '页数据,每页条数:', productsPageSize);
|
|
} else {
|
|
// 如果没有缓存,重新加载数据
|
|
loadProducts();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
paginationContainer.appendChild(nextButton);
|
|
|
|
// 末页按钮
|
|
var lastButton = document.createElement('button');
|
|
lastButton.textContent = '末页';
|
|
lastButton.disabled = currentPage === totalPages;
|
|
lastButton.onclick = function() {
|
|
if (productsPage < totalPages) {
|
|
productsPage = totalPages;
|
|
// 检查是否有筛选条件
|
|
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
|
|
productFilters.salesManager || productFilters.creator || productFilters.search;
|
|
if (hasFilters) {
|
|
// 如果有筛选条件,重新应用筛选
|
|
applyProductFilters();
|
|
} else {
|
|
// 检查缓存
|
|
var cachedData = getCachedData('products', 'page_' + productsPage + '_size_' + productsPageSize);
|
|
if (cachedData) {
|
|
// 使用缓存数据
|
|
allProducts = cachedData.products || [];
|
|
productsTotal = cachedData.total || 0;
|
|
productsTotalPages = cachedData.pages || totalPages;
|
|
displayProducts(allProducts);
|
|
renderProductsPagination(productsPage, productsTotalPages, productsTotal);
|
|
console.log('使用缓存的第', productsPage, '页数据,每页条数:', productsPageSize);
|
|
} else {
|
|
// 如果没有缓存,重新加载数据
|
|
loadProducts();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
paginationContainer.appendChild(lastButton);
|
|
|
|
// 总数显示
|
|
var totalInfo = document.createElement('span');
|
|
totalInfo.textContent = '总数:' + totalItems + '条';
|
|
totalInfo.style.margin = '0 10px';
|
|
paginationContainer.appendChild(totalInfo);
|
|
|
|
// 每页显示条数选择
|
|
var pageSizeInfo = document.createElement('span');
|
|
pageSizeInfo.textContent = '每页';
|
|
paginationContainer.appendChild(pageSizeInfo);
|
|
|
|
var pageSizeSelect = document.createElement('select');
|
|
var pageSizes = [10, 20, 50, 100];
|
|
for (var i = 0; i < pageSizes.length; i++) {
|
|
var option = document.createElement('option');
|
|
option.value = pageSizes[i];
|
|
option.textContent = pageSizes[i] + '条';
|
|
pageSizeSelect.appendChild(option);
|
|
}
|
|
// 先添加option元素,然后再设置select元素的value属性
|
|
pageSizeSelect.value = productsPageSize;
|
|
console.log('Setting pageSizeSelect value to:', productsPageSize);
|
|
// 使用闭包确保正确获取select元素
|
|
(function(selectElement) {
|
|
selectElement.onchange = function() {
|
|
// 确保正确更新全局变量
|
|
var selectedSize = parseInt(selectElement.value);
|
|
console.log('Selected page size:', selectedSize);
|
|
productsPageSize = selectedSize;
|
|
console.log('Updated productsPageSize to:', productsPageSize);
|
|
productsPage = 1; // 重置为第一页
|
|
|
|
// 检查是否有筛选条件
|
|
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
|
|
productFilters.salesManager || productFilters.creator || productFilters.search;
|
|
|
|
if (hasFilters) {
|
|
// 如果有筛选条件,重新应用筛选
|
|
applyProductFilters();
|
|
} else {
|
|
// 否则重新加载数据
|
|
loadProducts();
|
|
}
|
|
};
|
|
})(pageSizeSelect);
|
|
paginationContainer.appendChild(pageSizeSelect);
|
|
|
|
// 跳转功能
|
|
var jumpInfo = document.createElement('span');
|
|
jumpInfo.textContent = '跳转';
|
|
jumpInfo.style.margin = '0 10px';
|
|
paginationContainer.appendChild(jumpInfo);
|
|
|
|
var jumpInput = document.createElement('input');
|
|
jumpInput.type = 'number';
|
|
jumpInput.value = currentPage;
|
|
jumpInput.min = 1;
|
|
jumpInput.max = totalPages;
|
|
jumpInput.style.width = '60px';
|
|
jumpInput.style.padding = '4px';
|
|
paginationContainer.appendChild(jumpInput);
|
|
|
|
var jumpButton = document.createElement('button');
|
|
jumpButton.textContent = '确定';
|
|
jumpButton.onclick = function() {
|
|
// 直接获取输入框的当前值
|
|
var jumpInputElement = document.querySelector('#productsPagination input[type="number"]');
|
|
if (jumpInputElement) {
|
|
var jumpPage = parseInt(jumpInputElement.value);
|
|
if (jumpPage >= 1 && jumpPage <= totalPages) {
|
|
productsPage = jumpPage;
|
|
// 检查是否有筛选条件
|
|
var hasFilters = productFilters.category || productFilters.productName || productFilters.yolk ||
|
|
productFilters.salesManager || productFilters.creator || productFilters.search;
|
|
if (hasFilters) {
|
|
// 如果有筛选条件,重新应用筛选
|
|
applyProductFilters();
|
|
} else {
|
|
// 如果没有筛选条件,重新加载数据
|
|
loadProducts();
|
|
}
|
|
} else {
|
|
showAlert('请输入有效的页码');
|
|
}
|
|
}
|
|
};
|
|
paginationContainer.appendChild(jumpButton);
|
|
}
|
|
|
|
// 渲染商品分页控件(旧版,已废弃)
|
|
function renderProductsPaginationOld(currentPage, totalPages, totalItems) {
|
|
var paginationContainer = document.getElementById('productsPagination');
|
|
paginationContainer.innerHTML = '';
|
|
|
|
if (totalPages <= 1) {
|
|
return;
|
|
}
|
|
|
|
// 上一页按钮
|
|
var prevButton = document.createElement('button');
|
|
prevButton.textContent = '上一页';
|
|
prevButton.disabled = currentPage === 1;
|
|
prevButton.onclick = function() {
|
|
if (currentPage > 1) {
|
|
productsPage = currentPage - 1;
|
|
loadProducts();
|
|
}
|
|
};
|
|
paginationContainer.appendChild(prevButton);
|
|
|
|
// 页码按钮
|
|
var startPage = Math.max(1, currentPage - 2);
|
|
var endPage = Math.min(totalPages, startPage + 4);
|
|
|
|
if (startPage > 1) {
|
|
var firstButton = document.createElement('button');
|
|
firstButton.textContent = '1';
|
|
firstButton.onclick = function() {
|
|
productsPage = 1;
|
|
loadProducts();
|
|
};
|
|
paginationContainer.appendChild(firstButton);
|
|
|
|
if (startPage > 2) {
|
|
var ellipsis = document.createElement('span');
|
|
ellipsis.textContent = '...';
|
|
ellipsis.style.padding = '0 10px';
|
|
paginationContainer.appendChild(ellipsis);
|
|
}
|
|
}
|
|
|
|
for (var i = startPage; i <= endPage; i++) {
|
|
var pageButton = document.createElement('button');
|
|
pageButton.textContent = i;
|
|
pageButton.classList.toggle('active', i === currentPage);
|
|
pageButton.onclick = function() {
|
|
productsPage = parseInt(this.textContent);
|
|
loadProducts();
|
|
};
|
|
paginationContainer.appendChild(pageButton);
|
|
}
|
|
|
|
if (endPage < totalPages) {
|
|
if (endPage < totalPages - 1) {
|
|
var ellipsis = document.createElement('span');
|
|
ellipsis.textContent = '...';
|
|
ellipsis.style.padding = '0 10px';
|
|
paginationContainer.appendChild(ellipsis);
|
|
}
|
|
|
|
var lastButton = document.createElement('button');
|
|
lastButton.textContent = totalPages;
|
|
lastButton.onclick = function() {
|
|
productsPage = totalPages;
|
|
loadProducts();
|
|
};
|
|
paginationContainer.appendChild(lastButton);
|
|
}
|
|
|
|
// 下一页按钮
|
|
var nextButton = document.createElement('button');
|
|
nextButton.textContent = '下一页';
|
|
nextButton.disabled = currentPage === totalPages;
|
|
nextButton.onclick = function() {
|
|
if (currentPage < totalPages) {
|
|
productsPage = currentPage + 1;
|
|
loadProducts();
|
|
}
|
|
};
|
|
paginationContainer.appendChild(nextButton);
|
|
|
|
// 显示总条数
|
|
var totalInfo = document.createElement('span');
|
|
totalInfo.textContent = '共 ' + totalItems + ' 条';
|
|
totalInfo.style.marginLeft = '20px';
|
|
totalInfo.style.fontSize = '14px';
|
|
totalInfo.style.color = '#666';
|
|
paginationContainer.appendChild(totalInfo);
|
|
}
|
|
|
|
// 淡入淡出动画
|
|
var style = document.createElement('style');
|
|
style.textContent = `
|
|
@keyframes fadeOut {
|
|
from {
|
|
opacity: 1;
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
|
|
// 将样式添加到页面头部
|
|
document.head.insertAdjacentHTML('beforeend', formHoverStyles);
|
|
|
|
// 跟进弹窗HTML
|
|
var followupModalHTML = `
|
|
<div id="followupModal" style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); 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: 12px; width: 450px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.18); animation: slideIn 0.3s ease; max-height: 90vh; overflow-y: auto; transition: all 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="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; background-color: white;">
|
|
<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>
|
|
<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; background-color: white;">
|
|
<option value="">请选择客户等级</option>
|
|
<option value="A-重要客户">A-重要客户</option>
|
|
<option value="B-普通客户">B-普通客户</option>
|
|
<option value="C-低价值客户">C-低价值客户</option>
|
|
<option value="D-物流自提客户">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; background-color: white;">
|
|
<option value="">请选择客户需求</option>
|
|
<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 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" placeholder="请输入详细地址" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; transition: all 0.3s ease; background-color: white;">
|
|
</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" placeholder="请输入客户公司" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; transition: all 0.3s ease; background-color: white;">
|
|
</div>
|
|
<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" placeholder="请输入跟进内容" rows="3" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; resize: vertical; transition: all 0.3s ease; background-color: white;"></textarea>
|
|
</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; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">取消</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; box-shadow: 0 2px 4px rgba(24,144,255,0.3);">保存</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// 归还弹窗HTML
|
|
var returnModalHTML = `
|
|
<div id="returnModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); 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: 12px; width: 450px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.18); animation: slideIn 0.3s ease; transition: all 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; background-color: white;">
|
|
<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: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); 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: 12px; width: 400px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.18); animation: slideIn 0.3s ease; transition: all 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; margin-bottom: 16px;">选择要拉入的系统:</p>
|
|
<div style="text-align: left; margin-left: 80px;">
|
|
<label style="display: block; margin-bottom: 12px; font-size: 14px; color: #333;">
|
|
<input type="radio" name="systemType" value="大贸易系统" checked style="margin-right: 8px;"> 大贸易系统
|
|
</label>
|
|
<label style="display: block; margin-bottom: 12px; font-size: 14px; color: #333;">
|
|
<input type="radio" name="systemType" value="小品种系统" style="margin-right: 8px;"> 小品种系统
|
|
</label>
|
|
</div>
|
|
</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: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); 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: 12px; width: 600px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.18); animation: slideIn 0.3s ease; max-height: 90vh; overflow-y: auto; transition: all 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: 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: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); 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: 12px; width: 500px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.18); animation: slideIn 0.3s ease; transition: all 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; background-color: white;">
|
|
<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 applyModalHTML = `
|
|
<div id="applyModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); display: none; z-index: 1000; animation: fadeIn 0.3s ease;">
|
|
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; width: 95%; max-width: 1400px; max-height: 80vh; overflow: hidden; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease;">
|
|
<div style="padding: 16px 20px; border-bottom: 1px solid #e8e8e8; display: flex; justify-content: space-between; align-items: center; background-color: white; border-radius: 8px 8px 0 0;">
|
|
<h3 style="margin: 0; color: #722ed1;">申请管理</h3>
|
|
<button onclick="closeApplyModal()" style="padding: 6px 12px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">
|
|
关闭
|
|
</button>
|
|
</div>
|
|
<div style="padding: 20px; overflow-y: auto; max-height: calc(80vh - 120px);">
|
|
<div class="filter-container" style="margin-bottom: 20px;">
|
|
<div class="filter-bar" style="display: flex; gap: 10px; flex-wrap: wrap;">
|
|
<button onclick="loadApplyList()" style="padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">刷新申请</button>
|
|
<button onclick="filterApplyList('all')" style="padding: 8px 16px; background-color: #52c41a; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">全部</button>
|
|
<button onclick="filterApplyList('0')" style="padding: 8px 16px; background-color: #faad14; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">申请中</button>
|
|
<button onclick="filterApplyList('1')" style="padding: 8px 16px; background-color: #52c41a; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">已通过</button>
|
|
<button onclick="filterApplyList('2')" style="padding: 8px 16px; background-color: #ff4d4f; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">已拒绝</button>
|
|
</div>
|
|
</div>
|
|
<div id="applyList" style="overflow-x: auto;">
|
|
<table style="width: 100%; border-collapse: collapse; font-size: 14px;">
|
|
<thead>
|
|
<tr style="background-color: #f5f5f5;">
|
|
<th style="padding: 12px; border: 1px solid #e8e8e8; text-align: left;">申请ID</th>
|
|
<th style="padding: 12px; border: 1px solid #e8e8e8; text-align: left;">电话号码</th>
|
|
<th style="padding: 12px; border: 1px solid #e8e8e8; text-align: left;">申请人</th>
|
|
<th style="padding: 12px; border: 1px solid #e8e8e8; text-align: left;">原负责人</th>
|
|
<th style="padding: 12px; border: 1px solid #e8e8e8; text-align: left;">申请时间</th>
|
|
<th style="padding: 12px; border: 1px solid #e8e8e8; text-align: left;">状态</th>
|
|
<th style="padding: 12px; border: 1px solid #e8e8e8; text-align: left;">申请理由</th>
|
|
<th style="padding: 12px; border: 1px solid #e8e8e8; text-align: left;">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="applyTableBody">
|
|
<tr>
|
|
<td colspan="8" style="padding: 20px; text-align: center; color: #999;">暂无申请记录</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// 权限管理模态框HTML
|
|
var permissionModalHTML = `
|
|
<div id="permissionModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); 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: 12px; width: 700px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.18); animation: slideIn 0.3s ease; transition: all 0.3s ease;">
|
|
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; text-align: center;">权限管理</h3>
|
|
<div style="overflow-x: auto; margin-bottom: 20px;">
|
|
<table style="width: 100%; border-collapse: collapse; font-size: 14px;">
|
|
<thead>
|
|
<tr style="background-color: #f5f5f5;">
|
|
<th style="padding: 12px; text-align: left; border-bottom: 1px solid #e8e8e8; font-weight: 600;">负责人ID</th>
|
|
<th style="padding: 12px; text-align: left; border-bottom: 1px solid #e8e8e8; font-weight: 600;">负责人姓名</th>
|
|
<th style="padding: 12px; text-align: left; border-bottom: 1px solid #e8e8e8; font-weight: 600;">负责公司</th>
|
|
<th style="padding: 12px; text-align: left; border-bottom: 1px solid #e8e8e8; font-weight: 600;">分配状态</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="permissionTableBody">
|
|
<!-- 权限管理表格内容将通过JavaScript动态生成 -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div style="text-align: right; margin-top: 24px;">
|
|
<button onclick="closePermissionModal()" 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="savePermissions()" 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: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); 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: 12px; width: 350px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.18); animation: slideIn 0.3s ease; transition: all 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: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); 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: 12px; width: 500px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.18); animation: slideIn 0.3s ease; max-height: 80vh; overflow-y: auto; transition: all 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;">
|
|
<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>
|
|
`;
|
|
|
|
// 添加弹窗到页面
|
|
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', permissionModalHTML);
|
|
document.body.insertAdjacentHTML('beforeend', applyModalHTML);
|
|
|
|
// 员工申请记录模态框HTML
|
|
var employeeApplyModalHTML = `
|
|
<div id="employeeApplyModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.7) 100%); backdrop-filter: blur(5px); display: none; z-index: 1000; animation: fadeIn 0.3s ease;">
|
|
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.15); width: 95%; max-width: 1200px; max-height: 80vh; overflow: hidden; display: flex; flex-direction: column; animation: slideIn 0.3s ease;">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 1px solid #e8e8e8;">
|
|
<h3 style="margin: 0; color: #722ed1;">我的申请记录</h3>
|
|
<button onclick="closeEmployeeApplyModal()" style="background: none; border: none; font-size: 20px; cursor: pointer; color: #999;">×</button>
|
|
</div>
|
|
|
|
<div style="flex: 1; overflow-y: auto; margin-bottom: 15px;">
|
|
<div style="margin-bottom: 15px; display: flex; gap: 10px; flex-wrap: wrap;">
|
|
<button onclick="filterEmployeeApplyList('all')" style="padding: 6px 12px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer;">全部</button>
|
|
<button onclick="filterEmployeeApplyList('0')" style="padding: 6px 12px; background-color: #faad14; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer;">申请中</button>
|
|
<button onclick="filterEmployeeApplyList('1')" style="padding: 6px 12px; background-color: #52c41a; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer;">已通过</button>
|
|
<button onclick="filterEmployeeApplyList('2')" style="padding: 6px 12px; background-color: #ff4d4f; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer;">已拒绝</button>
|
|
</div>
|
|
|
|
<div style="overflow-x: auto;">
|
|
<table style="width: 100%; border-collapse: collapse; table-layout: fixed;">
|
|
<thead>
|
|
<tr style="background-color: #f5f5f5;">
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left; width: 80px; white-space: nowrap;">申请ID</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left; width: 180px; white-space: nowrap;">电话号码</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left; width: 140px; white-space: nowrap;">申请时间</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left; width: 80px; white-space: nowrap;">状态</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left; width: 140px; white-space: nowrap;">审批时间</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left; width: 80px; white-space: nowrap;">审批人</th>
|
|
<th style="padding: 10px; border: 1px solid #e8e8e8; text-align: left; flex: 1;">备注</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="employeeApplyTableBody">
|
|
<!-- 申请记录将通过JavaScript动态添加 -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div id="employeeApplyEmpty" style="text-align: center; padding: 40px 20px; color: #999; display: none;">
|
|
暂无申请记录
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: flex; justify-content: flex-end; padding-top: 15px; border-top: 1px solid #e8e8e8;">
|
|
<button onclick="closeEmployeeApplyModal()" style="padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; font-size: 14px; cursor: pointer;">关闭</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
document.body.insertAdjacentHTML('beforeend', employeeApplyModalHTML);
|
|
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;
|
|
}
|
|
}
|
|
});
|
|
|
|
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 chineseTypes = ['大贸易客户', '供应商', '两者都是', '小品种客户', '批发贸易类', '电商平台类', '配送零售类', '次品蛋专项类', '其他类型'];
|
|
if (chineseTypes.includes(type)) {
|
|
return type;
|
|
}
|
|
|
|
var typeMap = {
|
|
'buyer': '大贸易客户',
|
|
'seller': '供应商',
|
|
'both': '两者都是',
|
|
'smalls': '小品种客户',
|
|
'wholesale': '批发贸易类',
|
|
'e-commerce': '电商平台类',
|
|
'delivery_retail': '配送零售类',
|
|
'defective_egg': '次品蛋专项类',
|
|
'other': '其他类型'
|
|
};
|
|
return typeMap[type] || type;
|
|
}
|
|
|
|
function mapUserLevel(level) {
|
|
// 如果已经是中文,则直接返回
|
|
var chineseLevels = ['A-重要客户', 'B-普通客户', 'C-低价值客户', 'D-物流自提客户', '-'];
|
|
if (chineseLevels.includes(level)) {
|
|
return level;
|
|
}
|
|
|
|
var levelMap = {
|
|
'important': 'A-重要客户',
|
|
'ordinary': 'B-普通客户',
|
|
'low_value': 'C-低价值客户',
|
|
'logistics': 'D-物流自提客户',
|
|
'unclassified': '-'
|
|
};
|
|
return levelMap[level] || level;
|
|
}
|
|
|
|
function calculateResponseTime(createdAt, followupAt) {
|
|
if (!createdAt || !followupAt) return '-';
|
|
var createTime = new Date(createdAt);
|
|
var followupTime = new Date(followupAt);
|
|
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');
|
|
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';
|
|
}
|
|
}
|
|
|
|
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 || [];
|
|
}
|
|
|
|
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;
|
|
});
|
|
|
|
// 更新统计信息
|
|
if (personalTotalCount) {
|
|
personalTotalCount.textContent = data.total;
|
|
}
|
|
|
|
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];
|
|
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, filteredUsers.length);
|
|
} else {
|
|
personalEmpty.style.display = 'block';
|
|
// 没有数据时隐藏分页控件
|
|
personalPagination.style.display = 'none';
|
|
}
|
|
} else {
|
|
personalEmpty.style.display = 'block';
|
|
// 没有数据时隐藏分页控件
|
|
personalPagination.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
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');
|
|
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';
|
|
}
|
|
}
|
|
|
|
if (data.users && data.users.length > 0) {
|
|
publicEmpty.style.display = 'none';
|
|
allPublicData = data.users;
|
|
var filteredUsers = allPublicData.filter(function(user) {
|
|
// 过滤掉同事类型
|
|
if (user.type === 'Colleague') {
|
|
return false;
|
|
}
|
|
|
|
// 按负责人筛选
|
|
if (currentManagerFilter) {
|
|
console.log('公海池筛选负责人:', currentManagerFilter, '用户负责人:', user.managerName);
|
|
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) {
|
|
var userType = user.type || '';
|
|
console.log('公海池筛选类型:', currentTypeFilter, '用户类型:', userType);
|
|
|
|
// 特殊处理seller和buyer类型,直接比较英文
|
|
if (currentTypeFilter === 'seller') {
|
|
if (userType !== 'seller' && userType !== '供应商') {
|
|
return false;
|
|
}
|
|
} else if (currentTypeFilter === 'buyer') {
|
|
if (userType !== 'buyer' && userType !== '大贸易客户') {
|
|
return false;
|
|
}
|
|
} else {
|
|
// 其他类型的映射
|
|
var typeMap = {
|
|
'wholesale': '批发贸易类',
|
|
'e-commerce': '电商平台类',
|
|
'delivery_retail': '配送零售类',
|
|
'defective_egg': '次品蛋专项类',
|
|
'other': '其他类型'
|
|
};
|
|
var filterValue = typeMap[currentTypeFilter] || currentTypeFilter;
|
|
if (userType !== filterValue) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 其他情况,不过滤
|
|
return true;
|
|
});
|
|
|
|
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 style="cursor: default;">' +
|
|
'<td><input type="checkbox" class="userCheckbox" data-userid="' + (user.userId || '') + '"></td>' +
|
|
'<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="openDetailModal(\'' + (user.userId || '') + '\'); event.stopPropagation();" style="padding: 4px 8px; background-color: #13c2c2; color: white; border: none; border-radius: 4px; font-size: 12px; margin-right: 4px;">详情</button> <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>' +
|
|
'</tr>';
|
|
publicBody.innerHTML += row;
|
|
|
|
// 有数据时显示分页控件
|
|
publicPagination.style.display = 'flex';
|
|
}
|
|
} else {
|
|
publicEmpty.style.display = 'block';
|
|
// 没有数据时隐藏分页控件
|
|
publicPagination.style.display = 'none';
|
|
}
|
|
} else {
|
|
publicEmpty.style.display = 'block';
|
|
// 没有数据时隐藏分页控件
|
|
publicPagination.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function claimCustomer(userId, userName, phone) {
|
|
// 显示确认弹窗
|
|
if (confirm('确认认领该客户吗?')) {
|
|
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';
|
|
|
|
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('认领成功');
|
|
// 重新加载数据
|
|
loadPublicData();
|
|
loadPersonalData();
|
|
} else {
|
|
showAlert('认领失败: ' + data.message);
|
|
}
|
|
}
|
|
};
|
|
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;
|
|
|
|
// 查找用户数据
|
|
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) {
|
|
// 客户类型 - 处理中英文映射
|
|
var typeValue = user.type || '';
|
|
// 检查是否为英文值,如果是则转换为中文
|
|
var typeMap = {
|
|
'buyer': '大贸易客户',
|
|
'seller': '供应商',
|
|
'both': '两者都是',
|
|
'smalls': '小品种客户',
|
|
'wholesale': '批发贸易类',
|
|
'e-commerce': '电商平台类',
|
|
'delivery_retail': '配送零售类',
|
|
'defective_egg': '次品蛋专项类',
|
|
'other': '其他类型'
|
|
};
|
|
typeValue = typeMap[typeValue] || typeValue;
|
|
// 检查是否在下拉选项中存在,如果不存在则设为空
|
|
var typeOptions = ['批发贸易类', '电商平台类', '配送零售类', '次品蛋专项类', '其他类型'];
|
|
if (!typeOptions.includes(typeValue)) {
|
|
typeValue = '';
|
|
}
|
|
document.getElementById('followupType').value = typeValue;
|
|
|
|
// 客户等级 - 处理中英文映射
|
|
var levelValue = user.level || '';
|
|
// 检查是否为英文值,如果是则转换为中文
|
|
var levelMap = {
|
|
'important': 'A-重要客户',
|
|
'ordinary': 'B-普通客户',
|
|
'low_value': 'C-低价值客户',
|
|
'logistics': 'D-物流自提客户',
|
|
'unclassified': ''
|
|
};
|
|
levelValue = levelMap[levelValue] || levelValue;
|
|
// 检查是否在下拉选项中存在,如果不存在则设为空
|
|
var levelOptions = ['A-重要客户', 'B-普通客户', 'C-低价值客户', 'D-物流自提客户'];
|
|
if (!levelOptions.includes(levelValue)) {
|
|
levelValue = '';
|
|
}
|
|
document.getElementById('followupLevel').value = levelValue;
|
|
|
|
// 客户需求
|
|
var demandValue = user.demand || '';
|
|
// 检查是否在下拉选项中存在,如果不存在则设为空
|
|
var demandOptions = ['粉蛋', '粉三', '红蛋', '绿壳', '土鸡蛋', '次品', '白壳', '其他需求'];
|
|
if (!demandOptions.includes(demandValue)) {
|
|
demandValue = '';
|
|
}
|
|
document.getElementById('followupDemand').value = demandValue;
|
|
|
|
// 客户地区(特殊处理)
|
|
if (user.region) {
|
|
document.getElementById('followupRegion').value = user.region;
|
|
document.getElementById('followupRegionDisplay').textContent = user.region;
|
|
document.getElementById('followupRegionDisplay').style.color = '#333';
|
|
} else {
|
|
document.getElementById('followupRegion').value = '';
|
|
document.getElementById('followupRegionDisplay').textContent = '请选择客户地区';
|
|
document.getElementById('followupRegionDisplay').style.color = '#999';
|
|
}
|
|
|
|
// 详细地址
|
|
document.getElementById('followupDetailedAddress').value = user.detailedaddress || '';
|
|
|
|
// 客户公司
|
|
document.getElementById('followupCompany').value = user.company || '';
|
|
|
|
// 跟进内容
|
|
document.getElementById('followupContent').value = user.followup || '';
|
|
} else {
|
|
// 如果没有找到用户数据,清空表单
|
|
document.getElementById('followupType').value = '';
|
|
document.getElementById('followupLevel').value = '';
|
|
document.getElementById('followupDemand').value = '';
|
|
document.getElementById('followupRegion').value = '';
|
|
document.getElementById('followupRegionDisplay').textContent = '请选择客户地区';
|
|
document.getElementById('followupRegionDisplay').style.color = '#999';
|
|
document.getElementById('followupDetailedAddress').value = '';
|
|
document.getElementById('followupCompany').value = '';
|
|
document.getElementById('followupContent').value = '';
|
|
}
|
|
|
|
document.getElementById('followupModal').style.display = 'block';
|
|
// 防止背景滚动
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
function closeFollowupModal() {
|
|
document.getElementById('followupModal').style.display = 'none';
|
|
// 恢复背景滚动
|
|
document.body.style.overflow = 'auto';
|
|
}
|
|
|
|
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;
|
|
var usersManagements = userInfo.usersManagements;
|
|
|
|
// 验证必填字段
|
|
if (!type) {
|
|
showAlert('请选择客户类型');
|
|
return;
|
|
}
|
|
if (!level) {
|
|
showAlert('请选择客户等级');
|
|
return;
|
|
}
|
|
if (!demand) {
|
|
showAlert('请选择客户需求');
|
|
return;
|
|
}
|
|
if (!region) {
|
|
showAlert('请选择客户地区');
|
|
return;
|
|
}
|
|
if (!company) {
|
|
showAlert('请填写客户公司');
|
|
return;
|
|
}
|
|
if (!content) {
|
|
showAlert('请填写跟进内容');
|
|
return;
|
|
}
|
|
|
|
var params = {
|
|
userId: userId,
|
|
followup: content,
|
|
type: type,
|
|
level: level,
|
|
detailedaddress: detailedAddress,
|
|
company: company,
|
|
demand: demand,
|
|
region: region,
|
|
userName: usersManagements.userName || '',
|
|
managercompany: usersManagements.managercompany || '',
|
|
managerdepartment: usersManagements.managerdepartment || '',
|
|
organization: usersManagements.organization || '',
|
|
role: usersManagements.role || ''
|
|
};
|
|
|
|
var url = '/KH/api/users/followup';
|
|
|
|
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('跟进成功');
|
|
closeFollowupModal();
|
|
// 重新加载数据
|
|
if (document.getElementById('personal').classList.contains('active')) {
|
|
loadPersonalData();
|
|
} else {
|
|
loadPublicData();
|
|
}
|
|
} else {
|
|
showAlert('跟进失败: ' + data.message);
|
|
}
|
|
}
|
|
};
|
|
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';
|
|
}
|
|
|
|
function closeReturnModal() {
|
|
document.getElementById('returnModal').style.display = 'none';
|
|
// 恢复背景滚动
|
|
document.body.style.overflow = 'auto';
|
|
}
|
|
|
|
function openJianDaoYunModal(userId, userName, followup) {
|
|
// 检查是否已跟进
|
|
if (!followup || followup === '-') {
|
|
showAlert('需要先跟进才能点击领入简道云');
|
|
return;
|
|
}
|
|
document.getElementById('jianDaoYunUserId').value = userId;
|
|
document.getElementById('jianDaoYunModal').style.display = 'block';
|
|
// 防止背景滚动
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
function closeJianDaoYunModal() {
|
|
document.getElementById('jianDaoYunModal').style.display = 'none';
|
|
// 恢复背景滚动
|
|
document.body.style.overflow = 'auto';
|
|
}
|
|
|
|
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 openPermissionModal() {
|
|
// 加载负责人列表
|
|
loadManagersForPermission();
|
|
|
|
var modal = document.getElementById('permissionModal');
|
|
modal.style.display = 'block';
|
|
// 禁止背景滚动
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
function closePermissionModal() {
|
|
var modal = document.getElementById('permissionModal');
|
|
modal.style.display = 'none';
|
|
// 恢复背景滚动
|
|
document.body.style.overflow = 'auto';
|
|
}
|
|
|
|
function loadManagersForPermission() {
|
|
// 调用API获取负责人列表
|
|
fetch('/KH/api/users/managers')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
var tableBody = document.getElementById('permissionTableBody');
|
|
tableBody.innerHTML = '';
|
|
|
|
data.forEach(function(manager) {
|
|
var row = document.createElement('tr');
|
|
row.innerHTML = `
|
|
<td>${manager.managerId}</td>
|
|
<td>${manager.userName}</td>
|
|
<td>${manager.managercompany || '-'}</td>
|
|
<td>
|
|
<div class="allocation-status-toggle" style="display: flex; align-items: center; gap: 10px;">
|
|
<label style="display: flex; align-items: center; gap: 5px; cursor: pointer;">
|
|
<input type="radio" name="allocation_${manager.managerId}" value="1" ${(manager.allocationstatus || 0) === 1 ? 'checked' : ''} class="allocation-status-radio" data-managerid="${manager.managerId}">
|
|
<span style="color: #52c41a;">✓ 允许分配</span>
|
|
</label>
|
|
<label style="display: flex; align-items: center; gap: 5px; cursor: pointer;">
|
|
<input type="radio" name="allocation_${manager.managerId}" value="0" ${(manager.allocationstatus || 0) === 0 ? 'checked' : ''} class="allocation-status-radio" data-managerid="${manager.managerId}">
|
|
<span style="color: #ff4d4f;">× 不允许分配</span>
|
|
</label>
|
|
</div>
|
|
</td>
|
|
`;
|
|
tableBody.appendChild(row);
|
|
});
|
|
})
|
|
.catch(error => {
|
|
console.error('获取负责人列表失败:', error);
|
|
showAlert('获取负责人列表失败');
|
|
});
|
|
}
|
|
|
|
function savePermissions() {
|
|
var radioGroups = {};
|
|
var permissions = [];
|
|
|
|
// 收集每个负责人的选中状态
|
|
var radioElements = document.querySelectorAll('.allocation-status-radio:checked');
|
|
radioElements.forEach(function(radio) {
|
|
var managerId = radio.getAttribute('data-managerid');
|
|
permissions.push({
|
|
managerId: managerId,
|
|
allocationstatus: parseInt(radio.value)
|
|
});
|
|
});
|
|
|
|
// 调用API保存权限设置
|
|
fetch('/KH/api/users/updateAllocationStatus', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(permissions)
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showAlert('权限设置保存成功');
|
|
closePermissionModal();
|
|
} else {
|
|
showAlert('权限设置保存失败: ' + (data.message || ''));
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('保存权限设置失败:', error);
|
|
showAlert('保存权限设置失败');
|
|
});
|
|
}
|
|
|
|
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';
|
|
}
|
|
|
|
function saveJianDaoYun() {
|
|
var userId = document.getElementById('jianDaoYunUserId').value;
|
|
var usersManagements = userInfo.usersManagements;
|
|
|
|
// 获取选中的系统类型
|
|
var systemType = document.querySelector('input[name="systemType"]:checked').value;
|
|
|
|
var params = {
|
|
userId: userId,
|
|
systemType: systemType,
|
|
userName: usersManagements.userName || '',
|
|
managercompany: usersManagements.managercompany || '',
|
|
managerdepartment: usersManagements.managerdepartment || '',
|
|
organization: usersManagements.organization || '',
|
|
role: usersManagements.role || ''
|
|
};
|
|
|
|
var url = '/KH/api/users/jianDaoYun';
|
|
|
|
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('操作成功');
|
|
closeJianDaoYunModal();
|
|
// 重新加载数据
|
|
loadPersonalData();
|
|
} else {
|
|
showAlert('操作失败: ' + data.message);
|
|
}
|
|
}
|
|
};
|
|
xhr.send(JSON.stringify(params));
|
|
}
|
|
|
|
function saveReturn() {
|
|
var userId = document.getElementById('returnUserId').value;
|
|
var type = document.getElementById('returnType').value;
|
|
var usersManagements = userInfo.usersManagements;
|
|
|
|
var params = {
|
|
userId: userId,
|
|
type: type,
|
|
userName: usersManagements.userName || '',
|
|
managercompany: usersManagements.managercompany || '',
|
|
managerdepartment: usersManagements.managerdepartment || '',
|
|
organization: usersManagements.organization || '',
|
|
role: usersManagements.role || '',
|
|
assistant: usersManagements.assistant || ''
|
|
};
|
|
|
|
var url = '/KH/api/users/return';
|
|
|
|
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('归还成功');
|
|
closeReturnModal();
|
|
// 重新加载数据
|
|
loadPersonalData();
|
|
loadPublicData();
|
|
} else {
|
|
showAlert('归还失败: ' + data.message);
|
|
}
|
|
}
|
|
};
|
|
xhr.send(JSON.stringify(params));
|
|
}
|
|
|
|
function renderPersonalPagination(current, total, totalRecords) {
|
|
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();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(prevBtn);
|
|
|
|
// 只显示4个页码
|
|
if (total <= 4) {
|
|
// 总页数小于等于4时,显示所有页码
|
|
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();
|
|
}
|
|
};
|
|
pagination.appendChild(pageBtn);
|
|
}
|
|
} else {
|
|
// 总页数大于4时,显示当前页附近的4个页码
|
|
var startPage, endPage;
|
|
if (current <= 2) {
|
|
// 当前页在前面,显示前4个
|
|
startPage = 1;
|
|
endPage = 4;
|
|
} else if (current >= total - 1) {
|
|
// 当前页在后面,显示最后4个
|
|
startPage = total - 3;
|
|
endPage = total;
|
|
} else {
|
|
// 当前页在中间,显示当前页附近的4个
|
|
startPage = current - 1;
|
|
endPage = current + 2;
|
|
}
|
|
|
|
for (var i = startPage; i <= endPage; 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();
|
|
}
|
|
};
|
|
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();
|
|
}
|
|
}
|
|
};
|
|
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);
|
|
|
|
// 只显示4个页码
|
|
if (total <= 4) {
|
|
// 总页数小于等于4时,显示所有页码
|
|
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);
|
|
}
|
|
} else {
|
|
// 总页数大于4时,显示当前页附近的4个页码
|
|
var startPage, endPage;
|
|
if (current <= 2) {
|
|
// 当前页在前面,显示前4个
|
|
startPage = 1;
|
|
endPage = 4;
|
|
} else if (current >= total - 1) {
|
|
// 当前页在后面,显示最后4个
|
|
startPage = total - 3;
|
|
endPage = total;
|
|
} else {
|
|
// 当前页在中间,显示当前页附近的4个
|
|
startPage = current - 1;
|
|
endPage = current + 2;
|
|
}
|
|
|
|
for (var i = startPage; i <= endPage; 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 tableId = tableType === 'personal' ? 'personalTable' : 'publicTable';
|
|
var checkboxes = document.querySelectorAll('#' + tableId + ' .userCheckbox');
|
|
var selectAllCheckbox = document.getElementById('selectAll' + tableType.charAt(0).toUpperCase() + tableType.slice(1));
|
|
var checked = selectAllCheckbox.checked;
|
|
|
|
checkboxes.forEach(function(checkbox) {
|
|
checkbox.checked = checked;
|
|
// 添加点击事件监听器,当取消选中时取消全选
|
|
checkbox.onclick = function() {
|
|
updateSelectAllStatus(tableType);
|
|
};
|
|
});
|
|
}
|
|
|
|
// 更新全选复选框状态
|
|
function updateSelectAllStatus(tableType) {
|
|
var tableId = tableType === 'personal' ? 'personalTable' : 'publicTable';
|
|
var checkboxes = document.querySelectorAll('#' + tableId + ' .userCheckbox');
|
|
var selectAllCheckbox = document.getElementById('selectAll' + tableType.charAt(0).toUpperCase() + tableType.slice(1));
|
|
var allChecked = true;
|
|
|
|
checkboxes.forEach(function(checkbox) {
|
|
if (!checkbox.checked) {
|
|
allChecked = false;
|
|
}
|
|
});
|
|
|
|
if (selectAllCheckbox) {
|
|
selectAllCheckbox.checked = allChecked;
|
|
}
|
|
}
|
|
|
|
// 新的分页函数实现
|
|
function renderPersonalPagination(current, total) {
|
|
var pagination = document.getElementById('personalPagination');
|
|
pagination.innerHTML = '';
|
|
|
|
// 首页按钮
|
|
var firstBtn = document.createElement('button');
|
|
firstBtn.innerHTML = '首页';
|
|
firstBtn.disabled = current == 1;
|
|
firstBtn.onclick = function() {
|
|
if (current > 1) {
|
|
personalPage = 1;
|
|
// 根据当前筛选条件决定调用哪个函数
|
|
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
|
|
displayFilteredPersonalData();
|
|
} else {
|
|
loadPersonalData();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(firstBtn);
|
|
|
|
// 上一页按钮
|
|
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();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(prevBtn);
|
|
|
|
// 页码信息
|
|
var pageInfo = document.createElement('span');
|
|
pageInfo.style.cssText = 'margin: 0 10px; padding: 8px 0; font-size: 14px; color: #666;';
|
|
pageInfo.innerHTML = '第 ' + current + ' 页,共 ' + total + ' 页';
|
|
pagination.appendChild(pageInfo);
|
|
|
|
// 下一页按钮
|
|
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();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(nextBtn);
|
|
|
|
// 末页按钮
|
|
var lastBtn = document.createElement('button');
|
|
lastBtn.innerHTML = '末页';
|
|
lastBtn.disabled = current == total;
|
|
lastBtn.onclick = function() {
|
|
if (current < total) {
|
|
personalPage = total;
|
|
// 根据当前筛选条件决定调用哪个函数
|
|
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
|
|
displayFilteredPersonalData();
|
|
} else {
|
|
loadPersonalData();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(lastBtn);
|
|
|
|
// 总数分页选择器
|
|
var pageSizeContainer = document.createElement('div');
|
|
pageSizeContainer.style.cssText = 'margin-left: 15px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var pageSizeText = document.createElement('span');
|
|
pageSizeText.innerHTML = '每页';
|
|
pageSizeText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
var pageSizeSelect = document.createElement('select');
|
|
pageSizeSelect.style.cssText = 'padding: 6px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;';
|
|
|
|
var pageSizes = [10, 20, 50, 100];
|
|
pageSizes.forEach(function(size) {
|
|
var option = document.createElement('option');
|
|
option.value = size;
|
|
option.textContent = size + '条';
|
|
if (personalPageSize === size) {
|
|
option.selected = true;
|
|
}
|
|
pageSizeSelect.appendChild(option);
|
|
});
|
|
|
|
pageSizeSelect.onchange = function() {
|
|
personalPageSize = parseInt(this.value);
|
|
personalPage = 1;
|
|
// 根据当前筛选条件决定调用哪个函数
|
|
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
|
|
displayFilteredPersonalData();
|
|
} else {
|
|
loadPersonalData();
|
|
}
|
|
};
|
|
|
|
pageSizeContainer.appendChild(pageSizeText);
|
|
pageSizeContainer.appendChild(pageSizeSelect);
|
|
pagination.appendChild(pageSizeContainer);
|
|
|
|
// 跳转功能
|
|
var jumpContainer = document.createElement('div');
|
|
jumpContainer.style.cssText = 'margin-left: 15px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var jumpText = document.createElement('span');
|
|
jumpText.innerHTML = '跳转';
|
|
jumpText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
var jumpInput = document.createElement('input');
|
|
jumpInput.type = 'number';
|
|
jumpInput.min = '1';
|
|
jumpInput.max = total;
|
|
jumpInput.value = current;
|
|
jumpInput.style.cssText = 'width: 60px; padding: 6px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; text-align: center;';
|
|
|
|
var jumpBtn = document.createElement('button');
|
|
jumpBtn.innerHTML = '确定';
|
|
jumpBtn.onclick = function() {
|
|
var jumpPage = parseInt(jumpInput.value);
|
|
if (jumpPage >= 1 && jumpPage <= total) {
|
|
personalPage = jumpPage;
|
|
// 根据当前筛选条件决定调用哪个函数
|
|
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
|
|
displayFilteredPersonalData();
|
|
} else {
|
|
loadPersonalData();
|
|
}
|
|
}
|
|
};
|
|
|
|
jumpContainer.appendChild(jumpText);
|
|
jumpContainer.appendChild(jumpInput);
|
|
jumpContainer.appendChild(jumpBtn);
|
|
pagination.appendChild(jumpContainer);
|
|
}
|
|
|
|
function renderPublicPagination(current, total) {
|
|
var pagination = document.getElementById('publicPagination');
|
|
pagination.innerHTML = '';
|
|
|
|
// 首页按钮
|
|
var firstBtn = document.createElement('button');
|
|
firstBtn.innerHTML = '首页';
|
|
firstBtn.disabled = current == 1;
|
|
firstBtn.onclick = function() {
|
|
if (current > 1) {
|
|
publicPage = 1;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
pagination.appendChild(firstBtn);
|
|
|
|
// 上一页按钮
|
|
var prevBtn = document.createElement('button');
|
|
prevBtn.innerHTML = '上一页';
|
|
prevBtn.disabled = current == 1;
|
|
prevBtn.onclick = function() {
|
|
if (current > 1) {
|
|
publicPage = current - 1;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
pagination.appendChild(prevBtn);
|
|
|
|
// 页码信息
|
|
var pageInfo = document.createElement('span');
|
|
pageInfo.style.cssText = 'margin: 0 10px; padding: 8px 0; font-size: 14px; color: #666;';
|
|
pageInfo.innerHTML = '第 ' + current + ' 页,共 ' + total + ' 页';
|
|
pagination.appendChild(pageInfo);
|
|
|
|
// 下一页按钮
|
|
var nextBtn = document.createElement('button');
|
|
nextBtn.innerHTML = '下一页';
|
|
nextBtn.disabled = current == total;
|
|
nextBtn.onclick = function() {
|
|
if (current < total) {
|
|
publicPage = current + 1;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
pagination.appendChild(nextBtn);
|
|
|
|
// 末页按钮
|
|
var lastBtn = document.createElement('button');
|
|
lastBtn.innerHTML = '末页';
|
|
lastBtn.disabled = current == total;
|
|
lastBtn.onclick = function() {
|
|
if (current < total) {
|
|
publicPage = total;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
pagination.appendChild(lastBtn);
|
|
|
|
// 总数分页选择器
|
|
var pageSizeContainer = document.createElement('div');
|
|
pageSizeContainer.style.cssText = 'margin-left: 15px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var pageSizeText = document.createElement('span');
|
|
pageSizeText.innerHTML = '每页';
|
|
pageSizeText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
var pageSizeSelect = document.createElement('select');
|
|
pageSizeSelect.style.cssText = 'padding: 6px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;';
|
|
|
|
var pageSizes = [10, 20, 50, 100];
|
|
pageSizes.forEach(function(size) {
|
|
var option = document.createElement('option');
|
|
option.value = size;
|
|
option.textContent = size + '条';
|
|
if (publicPageSize === size) {
|
|
option.selected = true;
|
|
}
|
|
pageSizeSelect.appendChild(option);
|
|
});
|
|
|
|
pageSizeSelect.onchange = function() {
|
|
publicPageSize = parseInt(this.value);
|
|
publicPage = 1;
|
|
loadPublicData();
|
|
};
|
|
|
|
pageSizeContainer.appendChild(pageSizeText);
|
|
pageSizeContainer.appendChild(pageSizeSelect);
|
|
pagination.appendChild(pageSizeContainer);
|
|
|
|
// 跳转功能
|
|
var jumpContainer = document.createElement('div');
|
|
jumpContainer.style.cssText = 'margin-left: 15px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var jumpText = document.createElement('span');
|
|
jumpText.innerHTML = '跳转';
|
|
jumpText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
var jumpInput = document.createElement('input');
|
|
jumpInput.type = 'number';
|
|
jumpInput.min = '1';
|
|
jumpInput.max = total;
|
|
jumpInput.value = current;
|
|
jumpInput.style.cssText = 'width: 60px; padding: 6px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; text-align: center;';
|
|
|
|
var jumpBtn = document.createElement('button');
|
|
jumpBtn.innerHTML = '确定';
|
|
jumpBtn.onclick = function() {
|
|
var jumpPage = parseInt(jumpInput.value);
|
|
if (jumpPage >= 1 && jumpPage <= total) {
|
|
publicPage = jumpPage;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
|
|
jumpContainer.appendChild(jumpText);
|
|
jumpContainer.appendChild(jumpInput);
|
|
jumpContainer.appendChild(jumpBtn);
|
|
pagination.appendChild(jumpContainer);
|
|
}
|
|
|
|
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);
|
|
option.setAttribute('data-allocationstatus', manager.allocationstatus || 0);
|
|
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));
|
|
}
|
|
|
|
// 修改后的个人客户分页函数
|
|
function renderPersonalPagination(current, total, totalRecords) {
|
|
var pagination = document.getElementById('personalPagination');
|
|
pagination.innerHTML = '';
|
|
|
|
// 首页按钮
|
|
var firstBtn = document.createElement('button');
|
|
firstBtn.innerHTML = '首页';
|
|
firstBtn.disabled = current == 1;
|
|
firstBtn.onclick = function() {
|
|
if (current > 1) {
|
|
personalPage = 1;
|
|
// 根据当前筛选条件决定调用哪个函数
|
|
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
|
|
displayFilteredPersonalData();
|
|
} else {
|
|
loadPersonalData();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(firstBtn);
|
|
|
|
// 上一页按钮
|
|
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();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(prevBtn);
|
|
|
|
// 页码信息
|
|
var pageInfo = document.createElement('span');
|
|
pageInfo.style.cssText = 'margin: 0 10px; padding: 8px 0; font-size: 14px; color: #666;';
|
|
pageInfo.innerHTML = '第 ' + current + ' 页,共 ' + total + ' 页';
|
|
pagination.appendChild(pageInfo);
|
|
|
|
// 下一页按钮
|
|
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();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(nextBtn);
|
|
|
|
// 末页按钮
|
|
var lastBtn = document.createElement('button');
|
|
lastBtn.innerHTML = '末页';
|
|
lastBtn.disabled = current == total;
|
|
lastBtn.onclick = function() {
|
|
if (current < total) {
|
|
personalPage = total;
|
|
// 根据当前筛选条件决定调用哪个函数
|
|
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
|
|
displayFilteredPersonalData();
|
|
} else {
|
|
loadPersonalData();
|
|
}
|
|
}
|
|
};
|
|
pagination.appendChild(lastBtn);
|
|
|
|
// 总数显示
|
|
var totalContainer = document.createElement('div');
|
|
totalContainer.style.cssText = 'margin-left: 15px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var totalText = document.createElement('span');
|
|
totalText.innerHTML = '总数: ' + totalRecords + ' 条';
|
|
totalText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
totalContainer.appendChild(totalText);
|
|
pagination.appendChild(totalContainer);
|
|
|
|
// 分页选择器
|
|
var pageSizeContainer = document.createElement('div');
|
|
pageSizeContainer.style.cssText = 'margin-left: 10px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var pageSizeText = document.createElement('span');
|
|
pageSizeText.innerHTML = '每页';
|
|
pageSizeText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
var pageSizeSelect = document.createElement('select');
|
|
pageSizeSelect.style.cssText = 'padding: 6px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;';
|
|
|
|
var pageSizes = [10, 20, 50, 100];
|
|
pageSizes.forEach(function(size) {
|
|
var option = document.createElement('option');
|
|
option.value = size;
|
|
option.textContent = size + '条';
|
|
if (personalPageSize === size) {
|
|
option.selected = true;
|
|
}
|
|
pageSizeSelect.appendChild(option);
|
|
});
|
|
|
|
pageSizeSelect.onchange = function() {
|
|
personalPageSize = parseInt(this.value);
|
|
personalPage = 1;
|
|
// 根据当前筛选条件决定调用哪个函数
|
|
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
|
|
displayFilteredPersonalData();
|
|
} else {
|
|
loadPersonalData();
|
|
}
|
|
};
|
|
|
|
pageSizeContainer.appendChild(pageSizeText);
|
|
pageSizeContainer.appendChild(pageSizeSelect);
|
|
pagination.appendChild(pageSizeContainer);
|
|
|
|
// 跳转功能
|
|
var jumpContainer = document.createElement('div');
|
|
jumpContainer.style.cssText = 'margin-left: 15px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var jumpText = document.createElement('span');
|
|
jumpText.innerHTML = '跳转';
|
|
jumpText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
var jumpInput = document.createElement('input');
|
|
jumpInput.type = 'number';
|
|
jumpInput.min = '1';
|
|
jumpInput.max = total;
|
|
jumpInput.value = current;
|
|
jumpInput.style.cssText = 'width: 60px; padding: 6px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; text-align: center;';
|
|
|
|
var jumpBtn = document.createElement('button');
|
|
jumpBtn.innerHTML = '确定';
|
|
jumpBtn.onclick = function() {
|
|
var jumpPage = parseInt(jumpInput.value);
|
|
if (jumpPage >= 1 && jumpPage <= total) {
|
|
personalPage = jumpPage;
|
|
// 根据当前筛选条件决定调用哪个函数
|
|
if (personalFilter === 'followed' || personalFilter === 'unfollowed') {
|
|
displayFilteredPersonalData();
|
|
} else {
|
|
loadPersonalData();
|
|
}
|
|
}
|
|
};
|
|
|
|
jumpContainer.appendChild(jumpText);
|
|
jumpContainer.appendChild(jumpInput);
|
|
jumpContainer.appendChild(jumpBtn);
|
|
pagination.appendChild(jumpContainer);
|
|
}
|
|
|
|
// 修改后的公共客户分页函数
|
|
function renderPublicPagination(current, total, totalRecords) {
|
|
var pagination = document.getElementById('publicPagination');
|
|
pagination.innerHTML = '';
|
|
|
|
// 首页按钮
|
|
var firstBtn = document.createElement('button');
|
|
firstBtn.innerHTML = '首页';
|
|
firstBtn.disabled = current == 1;
|
|
firstBtn.onclick = function() {
|
|
if (current > 1) {
|
|
publicPage = 1;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
pagination.appendChild(firstBtn);
|
|
|
|
// 上一页按钮
|
|
var prevBtn = document.createElement('button');
|
|
prevBtn.innerHTML = '上一页';
|
|
prevBtn.disabled = current == 1;
|
|
prevBtn.onclick = function() {
|
|
if (current > 1) {
|
|
publicPage = current - 1;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
pagination.appendChild(prevBtn);
|
|
|
|
// 页码信息
|
|
var pageInfo = document.createElement('span');
|
|
pageInfo.style.cssText = 'margin: 0 10px; padding: 8px 0; font-size: 14px; color: #666;';
|
|
pageInfo.innerHTML = '第 ' + current + ' 页,共 ' + total + ' 页';
|
|
pagination.appendChild(pageInfo);
|
|
|
|
// 下一页按钮
|
|
var nextBtn = document.createElement('button');
|
|
nextBtn.innerHTML = '下一页';
|
|
nextBtn.disabled = current == total;
|
|
nextBtn.onclick = function() {
|
|
if (current < total) {
|
|
publicPage = current + 1;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
pagination.appendChild(nextBtn);
|
|
|
|
// 末页按钮
|
|
var lastBtn = document.createElement('button');
|
|
lastBtn.innerHTML = '末页';
|
|
lastBtn.disabled = current == total;
|
|
lastBtn.onclick = function() {
|
|
if (current < total) {
|
|
publicPage = total;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
pagination.appendChild(lastBtn);
|
|
|
|
// 总数显示
|
|
var totalContainer = document.createElement('div');
|
|
totalContainer.style.cssText = 'margin-left: 15px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var totalText = document.createElement('span');
|
|
totalText.innerHTML = '总数: ' + totalRecords + ' 条';
|
|
totalText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
totalContainer.appendChild(totalText);
|
|
pagination.appendChild(totalContainer);
|
|
|
|
// 分页选择器
|
|
var pageSizeContainer = document.createElement('div');
|
|
pageSizeContainer.style.cssText = 'margin-left: 10px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var pageSizeText = document.createElement('span');
|
|
pageSizeText.innerHTML = '每页';
|
|
pageSizeText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
var pageSizeSelect = document.createElement('select');
|
|
pageSizeSelect.style.cssText = 'padding: 6px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px;';
|
|
|
|
var pageSizes = [10, 20, 50, 100];
|
|
pageSizes.forEach(function(size) {
|
|
var option = document.createElement('option');
|
|
option.value = size;
|
|
option.textContent = size + '条';
|
|
if (publicPageSize === size) {
|
|
option.selected = true;
|
|
}
|
|
pageSizeSelect.appendChild(option);
|
|
});
|
|
|
|
pageSizeSelect.onchange = function() {
|
|
publicPageSize = parseInt(this.value);
|
|
publicPage = 1;
|
|
loadPublicData();
|
|
};
|
|
|
|
pageSizeContainer.appendChild(pageSizeText);
|
|
pageSizeContainer.appendChild(pageSizeSelect);
|
|
pagination.appendChild(pageSizeContainer);
|
|
|
|
// 跳转功能
|
|
var jumpContainer = document.createElement('div');
|
|
jumpContainer.style.cssText = 'margin-left: 15px; display: flex; align-items: center; gap: 5px;';
|
|
|
|
var jumpText = document.createElement('span');
|
|
jumpText.innerHTML = '跳转';
|
|
jumpText.style.cssText = 'font-size: 14px; color: #666;';
|
|
|
|
var jumpInput = document.createElement('input');
|
|
jumpInput.type = 'number';
|
|
jumpInput.min = '1';
|
|
jumpInput.max = total;
|
|
jumpInput.value = current;
|
|
jumpInput.style.cssText = 'width: 60px; padding: 6px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; text-align: center;';
|
|
|
|
var jumpBtn = document.createElement('button');
|
|
jumpBtn.innerHTML = '确定';
|
|
jumpBtn.onclick = function() {
|
|
var jumpPage = parseInt(jumpInput.value);
|
|
if (jumpPage >= 1 && jumpPage <= total) {
|
|
publicPage = jumpPage;
|
|
loadPublicData();
|
|
}
|
|
};
|
|
|
|
jumpContainer.appendChild(jumpText);
|
|
jumpContainer.appendChild(jumpInput);
|
|
jumpContainer.appendChild(jumpBtn);
|
|
pagination.appendChild(jumpContainer);
|
|
}
|
|
|
|
function applyCustomer(userId, userName, button, traceId) {
|
|
// 显示确认弹窗
|
|
if (confirm('确认申请该客户吗?')) {
|
|
// 获取当前按钮元素
|
|
var buttons = [];
|
|
if (button) {
|
|
buttons.push(button);
|
|
// 保存原始状态
|
|
button.dataset.originalText = button.textContent;
|
|
button.dataset.originalDisabled = button.disabled;
|
|
// 更改为申请中状态
|
|
button.textContent = '申请中';
|
|
button.disabled = true;
|
|
button.style.backgroundColor = '#faad14';
|
|
} else {
|
|
// 尝试通过选择器查找按钮(兼容旧格式)
|
|
var btnElements = document.querySelectorAll('button[onclick*="applyCustomer(\'" + userId + "\'")]');
|
|
btnElements.forEach(function(btn) {
|
|
buttons.push(btn);
|
|
// 保存原始状态
|
|
btn.dataset.originalText = btn.textContent;
|
|
btn.dataset.originalDisabled = btn.disabled;
|
|
// 更改为申请中状态
|
|
btn.textContent = '申请中';
|
|
btn.disabled = true;
|
|
btn.style.backgroundColor = '#faad14';
|
|
});
|
|
}
|
|
|
|
var personnel = userInfo.personnel;
|
|
var usersManagements = userInfo.usersManagements;
|
|
|
|
var params = {
|
|
traceId: traceId,
|
|
salesName: personnel.name || usersManagements.userName || '',
|
|
reason: '申请成为该客户的负责人'
|
|
};
|
|
|
|
var url = '/KH/api/users/apply';
|
|
|
|
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('申请提交成功,请等待管理员审批');
|
|
// 保持申请中状态
|
|
} else {
|
|
showAlert('申请失败: ' + data.message);
|
|
// 恢复按钮状态
|
|
buttons.forEach(function(button) {
|
|
button.textContent = button.dataset.originalText;
|
|
button.disabled = button.dataset.originalDisabled === 'true';
|
|
button.style.backgroundColor = '#722ed1';
|
|
});
|
|
}
|
|
} else if (xhr.readyState == 4) {
|
|
// 请求失败,恢复按钮状态
|
|
showAlert('申请提交失败,请重试');
|
|
buttons.forEach(function(button) {
|
|
button.textContent = button.dataset.originalText;
|
|
button.disabled = button.dataset.originalDisabled === 'true';
|
|
button.style.backgroundColor = '#722ed1';
|
|
});
|
|
}
|
|
};
|
|
xhr.send(JSON.stringify(params));
|
|
}
|
|
}
|
|
|
|
// 检查申请状态并更新角标
|
|
function checkApplyStatus() {
|
|
var url = '/KH/api/users/apply/list?status=0'; // 只获取申请中的数据
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url, true);
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState == 4 && xhr.status == 200) {
|
|
var applies = JSON.parse(xhr.responseText);
|
|
var applyCount = applies.length || 0;
|
|
var badge = document.getElementById('applyBadge');
|
|
|
|
if (badge) {
|
|
if (applyCount > 0) {
|
|
badge.textContent = applyCount;
|
|
badge.style.opacity = '1';
|
|
} else {
|
|
badge.style.opacity = '0';
|
|
}
|
|
}
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
// 申请管理相关函数
|
|
function openApplyModal() {
|
|
document.getElementById('applyModal').style.display = 'block';
|
|
// 加载申请列表
|
|
loadApplyList();
|
|
// 打开后更新角标(可选,因为打开后用户会处理申请)
|
|
checkApplyStatus();
|
|
}
|
|
|
|
function closeApplyModal() {
|
|
document.getElementById('applyModal').style.display = 'none';
|
|
}
|
|
|
|
function loadApplyList() {
|
|
var url = '/KH/api/users/apply/list';
|
|
|
|
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);
|
|
displayApplyList(data);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
function filterApplyList(status) {
|
|
var url = '/KH/api/users/apply/list';
|
|
if (status !== 'all') {
|
|
url += '?status=' + status;
|
|
}
|
|
|
|
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);
|
|
displayApplyList(data);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
function displayApplyList(applies) {
|
|
var tbody = document.getElementById('applyTableBody');
|
|
tbody.innerHTML = '';
|
|
|
|
if (applies && applies.length > 0) {
|
|
for (var i = 0; i < applies.length; i++) {
|
|
var apply = applies[i];
|
|
var statusText = '';
|
|
var statusColor = '';
|
|
|
|
switch (apply.status) {
|
|
case 0:
|
|
statusText = '申请中';
|
|
statusColor = '#faad14';
|
|
break;
|
|
case 1:
|
|
statusText = '已通过';
|
|
statusColor = '#52c41a';
|
|
break;
|
|
case 2:
|
|
statusText = '已拒绝';
|
|
statusColor = '#ff4d4f';
|
|
break;
|
|
}
|
|
|
|
var actionButtons = '';
|
|
if (apply.status == 0) {
|
|
actionButtons = `
|
|
<button onclick="approveApply(${apply.id}, 1, '${apply.user_id}', '${apply.sales_id}');" style="padding: 4px 8px; background-color: #52c41a; color: white; border: none; border-radius: 4px; font-size: 12px; margin-right: 4px;">通过</button>
|
|
<button onclick="approveApply(${apply.id}, 2, '${apply.user_id}', '${apply.sales_id}');" style="padding: 4px 8px; background-color: #ff4d4f; color: white; border: none; border-radius: 4px; font-size: 12px;">拒绝</button>
|
|
`;
|
|
}
|
|
|
|
var row = `
|
|
<tr>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${apply.id}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${apply.phone || '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">${apply.sales_name}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">${apply.original_manager_name || '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${formatDateTime(apply.apply_time)}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">
|
|
<span style="display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; color: white; background-color: ${statusColor};">${statusText}</span>
|
|
</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${apply.reason || '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8;">${actionButtons}</td>
|
|
</tr>
|
|
`;
|
|
|
|
tbody.innerHTML += row;
|
|
}
|
|
} else {
|
|
tbody.innerHTML = '<tr><td colspan="8" style="padding: 20px; text-align: center; color: #999;">暂无申请记录</td></tr>';
|
|
}
|
|
}
|
|
|
|
function approveApply(id, status, userId, salesId) {
|
|
var action = status == 1 ? '通过' : '拒绝';
|
|
if (confirm(`确认${action}该申请吗?`)) {
|
|
var reason = '';
|
|
if (status == 2) {
|
|
reason = prompt('请输入拒绝原因:');
|
|
if (!reason) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
var params = {
|
|
id: id,
|
|
status: status,
|
|
approve_by: userInfo.loginInfo.userName,
|
|
reason: reason,
|
|
userId: userId,
|
|
salesId: salesId
|
|
};
|
|
|
|
var url = '/KH/api/users/approve';
|
|
|
|
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(`${action}成功`);
|
|
loadApplyList();
|
|
// 更新申请状态角标
|
|
checkApplyStatus();
|
|
} else {
|
|
showAlert(`${action}失败: ` + data.message);
|
|
}
|
|
}
|
|
};
|
|
xhr.send(JSON.stringify(params));
|
|
}
|
|
}
|
|
|
|
window.onload = init;
|
|
|
|
// 员工申请记录相关函数
|
|
function openEmployeeApplyModal() {
|
|
document.getElementById('employeeApplyModal').style.display = 'block';
|
|
// 加载员工申请列表
|
|
loadEmployeeApplyList();
|
|
}
|
|
|
|
function closeEmployeeApplyModal() {
|
|
document.getElementById('employeeApplyModal').style.display = 'none';
|
|
}
|
|
|
|
function loadEmployeeApplyList() {
|
|
var url = '/KH/api/users/apply/list';
|
|
|
|
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);
|
|
// 过滤出当前员工的申请记录
|
|
var salesName = userInfo.personnel ? userInfo.personnel.name : (userInfo.usersManagements ? userInfo.usersManagements.userName : '');
|
|
var employeeApplies = data.filter(apply => apply.sales_name === salesName);
|
|
displayEmployeeApplyList(employeeApplies);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
function filterEmployeeApplyList(status) {
|
|
var url = '/KH/api/users/apply/list';
|
|
if (status !== 'all') {
|
|
url += '?status=' + status;
|
|
}
|
|
|
|
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);
|
|
// 过滤出当前员工的申请记录
|
|
var salesName = userInfo.personnel ? userInfo.personnel.name : (userInfo.usersManagements ? userInfo.usersManagements.userName : '');
|
|
var employeeApplies = data.filter(apply => apply.sales_name === salesName);
|
|
displayEmployeeApplyList(employeeApplies);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
function displayEmployeeApplyList(applies) {
|
|
var tbody = document.getElementById('employeeApplyTableBody');
|
|
tbody.innerHTML = '';
|
|
|
|
if (applies && applies.length > 0) {
|
|
for (var i = 0; i < applies.length; i++) {
|
|
var apply = applies[i];
|
|
var statusText = '';
|
|
var statusColor = '';
|
|
|
|
switch (apply.status) {
|
|
case 0:
|
|
statusText = '申请中';
|
|
statusColor = '#faad14';
|
|
break;
|
|
case 1:
|
|
statusText = '申请通过';
|
|
statusColor = '#52c41a';
|
|
break;
|
|
case 2:
|
|
statusText = '申请失败';
|
|
statusColor = '#ff4d4f';
|
|
break;
|
|
}
|
|
|
|
var row = `
|
|
<tr>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${apply.id}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${apply.phone || '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${formatDateTime(apply.apply_time)}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">
|
|
<span style="display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; color: white; background-color: ${statusColor};">${statusText}</span>
|
|
</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${apply.approve_time ? formatDateTime(apply.approve_time) : '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${apply.approve_by || '-'}</td>
|
|
<td style="padding: 10px; border: 1px solid #e8e8e8; white-space: nowrap;">${apply.reason || '-'}</td>
|
|
</tr>
|
|
`;
|
|
|
|
tbody.innerHTML += row;
|
|
}
|
|
document.getElementById('employeeApplyEmpty').style.display = 'none';
|
|
} else {
|
|
document.getElementById('employeeApplyEmpty').style.display = 'block';
|
|
}
|
|
}
|
|
|
|
// 页面加载完成后初始化
|
|
window.onload = function() {
|
|
init();
|
|
};
|
|
|
|
// 计算响应时间的函数
|
|
function calculateResponseTimes(traces) {
|
|
console.log('开始计算响应时间,traces长度:', traces.length);
|
|
traces.forEach(trace => {
|
|
console.log('处理trace:', trace);
|
|
if (trace.phoneNumber) {
|
|
console.log('处理电话号码:', trace.phoneNumber);
|
|
// 根据电话号码获取用户信息
|
|
var url = '/KH/api/users/public?phoneNumber=' + encodeURIComponent(trace.phoneNumber) + '&userRole=管理员';
|
|
console.log('API请求URL:', url);
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url, true);
|
|
xhr.onreadystatechange = function() {
|
|
console.log('API请求状态:', xhr.readyState, xhr.status);
|
|
if (xhr.readyState == 4) {
|
|
if (xhr.status == 200) {
|
|
try {
|
|
var data = JSON.parse(xhr.responseText);
|
|
console.log('API响应数据:', data);
|
|
if (data.users && data.users.length > 0) {
|
|
// 根据电话号码筛选正确的用户
|
|
var user = data.users.find(u =>
|
|
u.phoneNumber === trace.phoneNumber ||
|
|
u.phoneNumber === trace.phoneNumber.replace(/\s/g, '')
|
|
) || data.users[0];
|
|
console.log('用户信息:', user);
|
|
console.log('电话号码匹配:', user.phoneNumber === trace.phoneNumber);
|
|
// 统一使用正确的字段名
|
|
var createTime = user.created_at || user.create_time || user.createTime;
|
|
var followupTime = user.followup_at || user.followup_time || user.followupTime;
|
|
console.log('创建时间:', createTime, '跟进时间:', followupTime);
|
|
console.log('用户对象所有字段:', Object.keys(user));
|
|
console.log('trace对象:', trace);
|
|
|
|
// 尝试从trace对象中获取跟进时间
|
|
var traceFollowupTime = trace.followupTime || trace.followUpTime;
|
|
console.log('trace中的跟进时间:', traceFollowupTime);
|
|
|
|
// 优先使用用户对象中的跟进时间,其次使用trace对象中的
|
|
var finalFollowupTime = followupTime || traceFollowupTime;
|
|
console.log('最终使用的跟进时间:', finalFollowupTime);
|
|
|
|
if (createTime && finalFollowupTime) {
|
|
// 计算响应时间
|
|
var createDate = new Date(createTime);
|
|
var followupDate = new Date(finalFollowupTime);
|
|
console.log('创建日期:', createDate, '跟进日期:', followupDate);
|
|
var responseTimeMs = followupDate - createDate;
|
|
console.log('响应时间毫秒:', responseTimeMs);
|
|
|
|
// 转换为人类可读的格式
|
|
var minutes = Math.floor(responseTimeMs / 60000);
|
|
var hours = Math.floor(minutes / 60);
|
|
var days = Math.floor(hours / 24);
|
|
|
|
var responseTimeStr = '';
|
|
if (days > 0) {
|
|
responseTimeStr += days + '天';
|
|
}
|
|
if (hours % 24 > 0) {
|
|
responseTimeStr += (hours % 24) + '小时';
|
|
}
|
|
if (minutes % 60 > 0) {
|
|
responseTimeStr += (minutes % 60) + '分钟';
|
|
}
|
|
|
|
console.log('响应时间字符串:', responseTimeStr);
|
|
|
|
if (responseTimeStr) {
|
|
trace.responseTime = responseTimeStr;
|
|
// 更新页面上的响应时间
|
|
var tables = document.querySelectorAll('table');
|
|
console.log('找到表格数量:', tables.length);
|
|
tables.forEach(table => {
|
|
var header = table.querySelector('th');
|
|
if (header) {
|
|
console.log('表格标题:', header.textContent);
|
|
if (header.textContent === '昵称') {
|
|
var tbody = table.querySelector('tbody');
|
|
if (tbody) {
|
|
var rows = tbody.querySelectorAll('tr');
|
|
console.log('找到行数量:', rows.length);
|
|
rows.forEach((row, index) => {
|
|
console.log('处理行:', index);
|
|
var cells = row.querySelectorAll('td');
|
|
if (cells.length >= 5) {
|
|
var phoneCell = cells[1]; // 第二列是手机号
|
|
console.log('手机号单元格内容:', phoneCell.textContent.trim(), '预期:', trace.phoneNumber);
|
|
if (phoneCell.textContent.trim() === trace.phoneNumber) {
|
|
var responseCell = cells[4]; // 第五列是响应时间
|
|
console.log('更新响应时间单元格:', responseTimeStr);
|
|
responseCell.textContent = responseTimeStr;
|
|
console.log('更新后单元格内容:', responseCell.textContent);
|
|
}
|
|
} else {
|
|
console.log('行单元格数量不足:', cells.length);
|
|
}
|
|
});
|
|
} else {
|
|
console.log('表格体未找到');
|
|
}
|
|
}
|
|
} else {
|
|
console.log('表格标题未找到');
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
console.log('创建时间或跟进时间不存在');
|
|
}
|
|
} else {
|
|
console.log('API响应中没有用户数据');
|
|
}
|
|
} catch (e) {
|
|
console.log('解析JSON失败:', e);
|
|
}
|
|
} else {
|
|
console.log('API请求失败,状态码:', xhr.status);
|
|
console.log('API响应内容:', xhr.responseText);
|
|
}
|
|
}
|
|
};
|
|
xhr.send();
|
|
} else {
|
|
console.log('电话号码不存在:', trace);
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|