Browse Source

完成分配功能和相关优化

pull/1/head
Trae AI 2 months ago
parent
commit
0936849f58
  1. 11
      web/src/main/java/com/example/web/controller/UserController.java
  2. 14
      web/src/main/java/com/example/web/mapper/ManagersMapper.java
  3. 10
      web/src/main/java/com/example/web/mapper/UsersManagementsMapper.java
  4. 3
      web/src/main/java/com/example/web/service/UserService.java
  5. 90
      web/src/main/java/com/example/web/service/impl/UserServiceImpl.java
  6. 14
      web/src/main/resources/mapper/ManagersMapper.xml
  7. 20
      web/src/main/resources/mapper/UsersManagementsMapper.xml
  8. 346
      web/src/main/resources/static/index.html

11
web/src/main/java/com/example/web/controller/UserController.java

@ -4,6 +4,7 @@ import com.example.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map; import java.util.Map;
@RestController @RestController
@ -91,4 +92,14 @@ public class UserController {
public Map<String, Object> jianDaoYun(@RequestBody Map<String, Object> params) { public Map<String, Object> jianDaoYun(@RequestBody Map<String, Object> params) {
return userService.jianDaoYun(params); return userService.jianDaoYun(params);
} }
@GetMapping("/users/managers")
public List<com.example.web.entity.Managers> getManagersList() {
return userService.getManagersList();
}
@PostMapping("/users/assign")
public Map<String, Object> assignCustomers(@RequestBody Map<String, Object> params) {
return userService.assignCustomers(params);
}
} }

14
web/src/main/java/com/example/web/mapper/ManagersMapper.java

@ -0,0 +1,14 @@
package com.example.web.mapper;
import com.example.web.entity.Managers;
import com.example.web.annotation.DataSource;
import java.util.List;
public interface ManagersMapper {
@DataSource("primary")
List<Managers> findAllManagers();
@DataSource("primary")
Managers findByManagerId(String managerId);
}

10
web/src/main/java/com/example/web/mapper/UsersManagementsMapper.java

@ -4,6 +4,7 @@ import com.example.web.entity.UsersManagements;
import com.example.web.annotation.DataSource; import com.example.web.annotation.DataSource;
import java.util.List; import java.util.List;
import java.util.Map;
public interface UsersManagementsMapper { public interface UsersManagementsMapper {
@DataSource("wechat") @DataSource("wechat")
@ -11,4 +12,13 @@ public interface UsersManagementsMapper {
@DataSource("wechat") @DataSource("wechat")
List<UsersManagements> findByUserNameList(String userName); List<UsersManagements> findByUserNameList(String userName);
@DataSource("wechat")
UsersManagements findByUserId(String userId);
@DataSource("wechat")
int insert(UsersManagements usersManagements);
@DataSource("wechat")
int update(UsersManagements usersManagements);
} }

3
web/src/main/java/com/example/web/service/UserService.java

@ -1,5 +1,6 @@
package com.example.web.service; package com.example.web.service;
import com.example.web.entity.Managers;
import com.example.web.entity.Users; import com.example.web.entity.Users;
import java.util.List; import java.util.List;
@ -14,4 +15,6 @@ public interface UserService {
Map<String, Object> jianDaoYun(Map<String, Object> params); Map<String, Object> jianDaoYun(Map<String, Object> params);
List<Users> getPersonalUsers(int page, int size, String userName); List<Users> getPersonalUsers(int page, int size, String userName);
List<Users> getPublicUsers(int page, int size); List<Users> getPublicUsers(int page, int size);
List<Managers> getManagersList();
Map<String, Object> assignCustomers(Map<String, Object> params);
} }

90
web/src/main/java/com/example/web/service/impl/UserServiceImpl.java

@ -1,7 +1,11 @@
package com.example.web.service.impl; package com.example.web.service.impl;
import com.example.web.entity.Managers;
import com.example.web.entity.Users; import com.example.web.entity.Users;
import com.example.web.entity.UsersManagements;
import com.example.web.mapper.ManagersMapper;
import com.example.web.mapper.UsersMapper; import com.example.web.mapper.UsersMapper;
import com.example.web.mapper.UsersManagementsMapper;
import com.example.web.service.UserService; import com.example.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -16,6 +20,12 @@ public class UserServiceImpl implements UserService {
@Autowired @Autowired
private UsersMapper usersMapper; private UsersMapper usersMapper;
@Autowired
private ManagersMapper managersMapper;
@Autowired
private UsersManagementsMapper usersManagementsMapper;
@Override @Override
public Map<String, Object> getUserList(Map<String, Object> requestParams) { public Map<String, Object> getUserList(Map<String, Object> requestParams) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
@ -253,4 +263,84 @@ public class UserServiceImpl implements UserService {
return result; return result;
} }
@Override
public List<Managers> getManagersList() {
return managersMapper.findAllManagers();
}
@Override
public Map<String, Object> assignCustomers(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
try {
List<String> userIds = (List<String>) params.get("userIds");
String managerId = (String) params.get("managerId");
String userName = (String) params.get("userName");
if (userIds == null || userIds.isEmpty() || managerId == null || userName == null) {
result.put("success", false);
result.put("message", "缺少必要参数");
return result;
}
// 1. 到managers表获取完整的负责人信息
Managers selectedManager = managersMapper.findByManagerId(managerId);
if (selectedManager == null) {
result.put("success", false);
result.put("message", "未找到负责人信息");
return result;
}
// 2. 遍历客户ID列表,为每个客户分配负责人
for (String userId : userIds) {
// 3. 检查客户是否已经在usersmanagements表中有记录
UsersManagements existingRecord = usersManagementsMapper.findByUserId(userId);
if (existingRecord != null) {
// 4. 如果有记录,更新记录
existingRecord.setManagerId(selectedManager.getManagerId());
existingRecord.setUserName(selectedManager.getUserName());
existingRecord.setManagercompany(selectedManager.getManagercompany());
existingRecord.setManagerdepartment(selectedManager.getManagerdepartment());
existingRecord.setOrganization(selectedManager.getOrganization());
existingRecord.setRole(selectedManager.getRole());
existingRecord.setRoot(selectedManager.getRoot());
existingRecord.setAssistant(selectedManager.getAssistant());
usersManagementsMapper.update(existingRecord);
} else {
// 5. 如果没有记录,插入新记录
UsersManagements newRecord = new UsersManagements();
newRecord.setUserId(userId);
newRecord.setManagerId(selectedManager.getManagerId());
newRecord.setUserName(selectedManager.getUserName());
newRecord.setManagercompany(selectedManager.getManagercompany());
newRecord.setManagerdepartment(selectedManager.getManagerdepartment());
newRecord.setOrganization(selectedManager.getOrganization());
newRecord.setRole(selectedManager.getRole());
newRecord.setRoot(selectedManager.getRoot());
newRecord.setAssistant(selectedManager.getAssistant());
usersManagementsMapper.insert(newRecord);
}
// 不需要更新users表,因为我们已经通过UsersManagementsMapper更新了所有必要的字段
// Map<String, Object> updateParams = new HashMap<>();
// updateParams.put("userId", userId);
// updateParams.put("userName", selectedManager.getUserName());
// usersMapper.updateUsersManagements(updateParams);
// 不更新users表的sync_status,保持原始值
// usersMapper.updateSyncStatus(updateParams);
}
result.put("success", true);
result.put("message", "分配成功");
} catch (Exception e) {
result.put("success", false);
result.put("message", "分配失败: " + e.getMessage());
}
return result;
}
} }

14
web/src/main/resources/mapper/ManagersMapper.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.web.mapper.ManagersMapper">
<select id="findAllManagers" resultType="com.example.web.entity.Managers">
SELECT * FROM managers
WHERE userName IS NOT NULL AND userName != ''
</select>
<select id="findByManagerId" parameterType="String" resultType="com.example.web.entity.Managers">
SELECT * FROM managers
WHERE managerId = #{managerId}
LIMIT 1
</select>
</mapper>

20
web/src/main/resources/mapper/UsersManagementsMapper.xml

@ -7,4 +7,24 @@
<select id="findByUserNameList" parameterType="String" resultType="com.example.web.entity.UsersManagements"> <select id="findByUserNameList" parameterType="String" resultType="com.example.web.entity.UsersManagements">
SELECT * FROM usermanagements WHERE userName = #{userName} SELECT * FROM usermanagements WHERE userName = #{userName}
</select> </select>
<select id="findByUserId" parameterType="String" resultType="com.example.web.entity.UsersManagements">
SELECT * FROM usermanagements WHERE userId = #{userId}
</select>
<insert id="insert" parameterType="com.example.web.entity.UsersManagements">
INSERT INTO usermanagements (userId, managerId, managercompany, managerdepartment, organization, role, root, created_at, updated_at, userName, assistant)
VALUES (#{userId}, #{managerId}, #{managercompany}, #{managerdepartment}, #{organization}, #{role}, #{root}, NOW(), NOW(), #{userName}, #{assistant})
</insert>
<update id="update" parameterType="com.example.web.entity.UsersManagements">
UPDATE usermanagements SET
managerId = #{managerId},
managercompany = #{managercompany},
managerdepartment = #{managerdepartment},
organization = #{organization},
role = #{role},
root = #{root},
updated_at = NOW(),
userName = #{userName},
assistant = #{assistant}
WHERE userId = #{userId}
</update>
</mapper> </mapper>

346
web/src/main/resources/static/index.html

@ -57,9 +57,18 @@
} }
.container { .container {
max-width: 1200px; width: 100%;
margin: 30px auto; margin: 30px 0;
padding: 0 30px; padding: 0 20px;
box-sizing: border-box;
}
.data-section {
width: 100%;
}
table {
width: 100%;
} }
.user-details { .user-details {
@ -217,84 +226,98 @@
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
font-size: 14px; font-size: 14px;
table-layout: fixed; table-layout: auto;
} }
/* 复选框列 */
th:nth-child(1), td:nth-child(1) { th:nth-child(1), td:nth-child(1) {
max-width: 120px; width: 40px;
width: 120px; text-align: center;
} }
th:nth-child(2), td:nth-child(2) { /* 跟进内容列 */
max-width: 100px; th:nth-child(6), td:nth-child(6) {
width: 100px; min-width: 200px;
} }
th:nth-child(3), td:nth-child(3) { /* 操作列 */
max-width: 80px; th:nth-child(9), td:nth-child(9) {
width: 80px; min-width: 100px;
} }
th:nth-child(4), td:nth-child(4) { th {
max-width: 130px; background-color: #1890ff;
width: 130px; color: white;
padding: 14px 12px;
text-align: left;
font-weight: bold;
border-bottom: 2px solid #1890ff;
font-size: 14px;
} }
th:nth-child(5), td:nth-child(5) { td {
max-width: 100px; padding: 12px;
width: 100px; border-bottom: 1px solid #e8e8e8;
color: #333;
word-wrap: break-word;
word-break: break-all;
font-size: 14px;
} }
th:nth-child(6), td:nth-child(6) { tr:hover {
max-width: 100px; background-color: #f0f7ff;
width: 100px;
} }
th:nth-child(7), td:nth-child(7) { tr:nth-child(even) {
max-width: 100px; background-color: #fafafa;
width: 100px;
} }
th:nth-child(8), td:nth-child(8) { table {
max-width: 120px; border-collapse: collapse;
width: 120px; box-shadow: 0 2px 8px rgba(0,0,0,0.08);
} }
th { .data-section {
background-color: #fafafa; background: white;
padding: 12px; border-radius: 8px;
text-align: left; box-shadow: 0 2px 8px rgba(0,0,0,0.1);
font-weight: bold; overflow: hidden;
color: #333;
border-bottom: 1px solid #e8e8e8;
} }
td { .section-content {
padding: 12px; padding: 0;
border-bottom: 1px solid #f0f0f0;
color: #666;
word-wrap: break-word;
word-break: break-all;
} }
tr:hover { .filter-bar {
background-color: #f5f5f5; margin: 0;
padding: 15px 20px;
background-color: #fafafa;
border-bottom: 1px solid #e8e8e8;
} }
.pagination { .pagination {
margin-top: 20px; margin: 0;
padding: 15px 20px;
display: flex; display: flex;
justify-content: center; justify-content: center;
gap: 5px; gap: 8px;
background-color: #fafafa;
border-top: 1px solid #e8e8e8;
} }
.pagination button { .pagination button {
padding: 6px 12px; padding: 8px 14px;
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
background-color: white; background-color: white;
border-radius: 4px; border-radius: 4px;
cursor: pointer; cursor: pointer;
font-size: 14px; font-size: 14px;
transition: all 0.3s ease;
}
.pagination button:hover:not(:disabled) {
border-color: #1890ff;
color: #1890ff;
} }
.pagination button.active { .pagination button.active {
@ -306,6 +329,7 @@
.pagination button:disabled { .pagination button:disabled {
color: #ccc; color: #ccc;
cursor: not-allowed; cursor: not-allowed;
border-color: #e8e8e8;
} }
.empty-state { .empty-state {
@ -444,6 +468,7 @@
<button onclick="filterPersonalData('all')" style="background-color: #52c41a;">全部</button> <button onclick="filterPersonalData('all')" style="background-color: #52c41a;">全部</button>
<button onclick="filterPersonalData('followed')" style="background-color: #faad14;">已跟进</button> <button onclick="filterPersonalData('followed')" style="background-color: #faad14;">已跟进</button>
<button onclick="filterPersonalData('unfollowed')" style="background-color: #ff4d4f;">未跟进</button> <button onclick="filterPersonalData('unfollowed')" style="background-color: #ff4d4f;">未跟进</button>
<button id="assignButton" onclick="openAssignModal()" style="background-color: #722ed1;">分配</button>
<select id="personalPageSize" onchange="changePersonalPageSize()"> <select id="personalPageSize" onchange="changePersonalPageSize()">
<option value="10">10条/页</option> <option value="10">10条/页</option>
<option value="50">50条/页</option> <option value="50">50条/页</option>
@ -453,6 +478,7 @@
<table id="personalTable"> <table id="personalTable">
<thead> <thead>
<tr> <tr>
<th><input type="checkbox" id="selectAllPersonal" onclick="selectAll('personal')"></th>
<th>昵称</th> <th>昵称</th>
<th>手机号</th> <th>手机号</th>
<th>类型</th> <th>类型</th>
@ -475,6 +501,7 @@
<div id="public" class="tab-content"> <div id="public" class="tab-content">
<div class="filter-bar"> <div class="filter-bar">
<button onclick="loadPublicData()">刷新数据</button> <button onclick="loadPublicData()">刷新数据</button>
<button id="publicAssignButton" onclick="openAssignModal()" style="background-color: #722ed1;">分配</button>
<select id="publicPageSize" onchange="changePublicPageSize()"> <select id="publicPageSize" onchange="changePublicPageSize()">
<option value="10">10条/页</option> <option value="10">10条/页</option>
<option value="50">50条/页</option> <option value="50">50条/页</option>
@ -484,6 +511,7 @@
<table id="publicTable"> <table id="publicTable">
<thead> <thead>
<tr> <tr>
<th><input type="checkbox" id="selectAllPublic" onclick="selectAll('public')"></th>
<th>昵称</th> <th>昵称</th>
<th>手机号</th> <th>手机号</th>
<th>类型</th> <th>类型</th>
@ -513,6 +541,8 @@
var publicPageSize = 10; var publicPageSize = 10;
var personalFilter = 'all'; // all, followed, unfollowed var personalFilter = 'all'; // all, followed, unfollowed
var managersList = [];
function init() { function init() {
var savedUserInfo = localStorage.getItem('userInfo'); var savedUserInfo = localStorage.getItem('userInfo');
if (!savedUserInfo) { if (!savedUserInfo) {
@ -521,6 +551,7 @@
} }
userInfo = JSON.parse(savedUserInfo); userInfo = JSON.parse(savedUserInfo);
displayUserInfo(); displayUserInfo();
loadManagers();
loadPersonalData(); loadPersonalData();
} }
@ -537,6 +568,17 @@
document.getElementById('managerDepartment').innerHTML = personnel ? personnel.managerdepartment : '-'; document.getElementById('managerDepartment').innerHTML = personnel ? personnel.managerdepartment : '-';
document.getElementById('organization').innerHTML = personnel ? personnel.organization : '-'; document.getElementById('organization').innerHTML = personnel ? personnel.organization : '-';
document.getElementById('role').innerHTML = usersManagements ? usersManagements.role : '-'; document.getElementById('role').innerHTML = usersManagements ? usersManagements.role : '-';
// 只有管理员显示分配按钮
var isAdmin = loginInfo.projectName === '管理员';
var assignButton = document.getElementById('assignButton');
var publicAssignButton = document.getElementById('publicAssignButton');
if (assignButton) {
assignButton.style.display = isAdmin ? 'inline-block' : 'none';
}
if (publicAssignButton) {
publicAssignButton.style.display = isAdmin ? 'inline-block' : 'none';
}
} }
function switchTab(tabName, button) { function switchTab(tabName, button) {
@ -736,10 +778,50 @@
</div> </div>
`; `;
// 分配弹窗HTML
var assignModalHTML = `
<div id="assignModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; z-index: 1000; animation: fadeIn 0.3s ease;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 500px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease;">
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; text-align: center;">分配客户</h3>
<div style="margin-bottom: 20px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">选中客户数量</label>
<input type="text" id="selectedCount" disabled style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; background-color: #f5f5f5;">
</div>
<div style="margin-bottom: 24px;">
<label style="display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: #666;">选择负责人</label>
<select id="managerSelect" style="width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; cursor: pointer; transition: all 0.3s ease;">
<option value="">请选择负责人</option>
</select>
</div>
<div style="text-align: right; margin-top: 24px;">
<button onclick="closeAssignModal()" style="padding: 10px 16px; margin-right: 12px; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; color: #666; background-color: white; cursor: pointer; transition: all 0.3s ease;">取消</button>
<button onclick="saveAssign()" style="padding: 10px 16px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #722ed1; cursor: pointer; transition: all 0.3s ease;">分配</button>
</div>
</div>
</div>
`;
// 提示弹窗HTML
var alertModalHTML = `
<div id="alertModal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; z-index: 1000; animation: fadeIn 0.3s ease;">
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 24px; border-radius: 8px; width: 350px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease;">
<h3 style="margin: 0 0 20px 0; font-size: 16px; font-weight: 600; color: #333; text-align: center;">提示</h3>
<div style="margin-bottom: 24px; text-align: center;">
<p id="alertMessage" style="font-size: 14px; color: #666;"></p>
</div>
<div style="text-align: center; margin-top: 24px;">
<button onclick="closeAlertModal()" style="padding: 10px 24px; border: none; border-radius: 4px; font-size: 14px; color: white; background-color: #1890ff; cursor: pointer; transition: all 0.3s ease;">确定</button>
</div>
</div>
</div>
`;
// 添加弹窗到页面 // 添加弹窗到页面
document.body.insertAdjacentHTML('beforeend', followupModalHTML); document.body.insertAdjacentHTML('beforeend', followupModalHTML);
document.body.insertAdjacentHTML('beforeend', returnModalHTML); document.body.insertAdjacentHTML('beforeend', returnModalHTML);
document.body.insertAdjacentHTML('beforeend', jianDaoYunModalHTML); document.body.insertAdjacentHTML('beforeend', jianDaoYunModalHTML);
document.body.insertAdjacentHTML('beforeend', assignModalHTML);
document.body.insertAdjacentHTML('beforeend', alertModalHTML);
function formatDateTime(dateTimeString) { function formatDateTime(dateTimeString) {
if (!dateTimeString) return '-'; if (!dateTimeString) return '-';
@ -788,14 +870,23 @@
var personalEmpty = document.getElementById('personalEmpty'); var personalEmpty = document.getElementById('personalEmpty');
var managerHeader = document.getElementById('managerHeader'); var managerHeader = document.getElementById('managerHeader');
var personalPagination = document.getElementById('personalPagination'); var personalPagination = document.getElementById('personalPagination');
var selectAllPersonal = document.getElementById('selectAllPersonal');
personalBody.innerHTML = ''; personalBody.innerHTML = '';
// 检查用户角色,只对管理员显示负责人列 // 检查用户角色,只对管理员显示负责人列和复选框列
var userRole = userInfo.loginInfo.projectName; var userRole = userInfo.loginInfo.projectName;
if (userRole === '管理员') { var isAdmin = userRole === '管理员';
if (isAdmin) {
managerHeader.style.display = 'table-cell'; managerHeader.style.display = 'table-cell';
if (selectAllPersonal) {
selectAllPersonal.style.display = 'block';
}
} else { } else {
managerHeader.style.display = 'none'; managerHeader.style.display = 'none';
if (selectAllPersonal) {
selectAllPersonal.style.display = 'none';
}
} }
console.log('后端返回的数据量:', data.users ? data.users.length : 0); console.log('后端返回的数据量:', data.users ? data.users.length : 0);
@ -844,10 +935,14 @@
jianDaoYunButton = '<button style="padding: 4px 8px; background-color: #ccc; color: #666; border: none; border-radius: 4px; font-size: 12px; cursor: not-allowed;" disabled>已写入简道云</button>'; 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 { } else {
// 未写入简道云,显示正常按钮 // 未写入简道云,显示正常按钮
jianDaoYunButton = '<button onclick="openJianDaoYunModal(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\')" style="padding: 4px 8px; background-color: #52c41a; color: white; border: none; border-radius: 4px; font-size: 12px;">简道云</button>'; jianDaoYunButton = '<button onclick="openJianDaoYunModal(\'' + (user.userId || '') + '\', \'' + (user.nickName || '') + '\', \'' + (user.followup || '') + '\')" 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>' + var row = '<tr>' +
checkboxCell +
'<td>' + (user.nickName || '-') + '</td>' + '<td>' + (user.nickName || '-') + '</td>' +
'<td>' + (user.phoneNumber || '-') + '</td>' + '<td>' + (user.phoneNumber || '-') + '</td>' +
'<td>' + mapUserType(user.type) + '</td>' + '<td>' + mapUserType(user.type) + '</td>' +
@ -878,15 +973,24 @@
var publicBody = document.getElementById('publicBody'); var publicBody = document.getElementById('publicBody');
var publicEmpty = document.getElementById('publicEmpty'); var publicEmpty = document.getElementById('publicEmpty');
var publicManagerHeader = document.getElementById('publicManagerHeader'); var publicManagerHeader = document.getElementById('publicManagerHeader');
var publicPagination = document.getElementById('publicPagination'); // New: Get pagination element var publicPagination = document.getElementById('publicPagination');
var selectAllPublic = document.getElementById('selectAllPublic');
publicBody.innerHTML = ''; publicBody.innerHTML = '';
// 检查用户角色,只对管理员显示负责人列 // 检查用户角色,只对管理员显示负责人列和复选框列
var userRole = userInfo.loginInfo.projectName; var userRole = userInfo.loginInfo.projectName;
if (userRole === '管理员') { var isAdmin = userRole === '管理员';
if (isAdmin) {
publicManagerHeader.style.display = 'table-cell'; publicManagerHeader.style.display = 'table-cell';
if (selectAllPublic) {
selectAllPublic.style.display = 'block';
}
} else { } else {
publicManagerHeader.style.display = 'none'; publicManagerHeader.style.display = 'none';
if (selectAllPublic) {
selectAllPublic.style.display = 'none';
}
} }
if (data.users && data.users.length > 0) { if (data.users && data.users.length > 0) {
@ -909,6 +1013,7 @@
} }
var row = '<tr>' + var row = '<tr>' +
'<td><input type="checkbox" class="userCheckbox" data-userid="' + (user.userId || '') + '"></td>' +
'<td>' + (user.nickName || '-') + '</td>' + '<td>' + (user.nickName || '-') + '</td>' +
'<td>' + (user.phoneNumber || '-') + '</td>' + '<td>' + (user.phoneNumber || '-') + '</td>' +
'<td>' + mapUserType(user.type) + '</td>' + '<td>' + mapUserType(user.type) + '</td>' +
@ -956,12 +1061,12 @@
if (xhr.readyState == 4 && xhr.status == 200) { if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText); var data = JSON.parse(xhr.responseText);
if (data.success) { if (data.success) {
alert('认领成功'); showAlert('认领成功');
// 重新加载数据 // 重新加载数据
loadPublicData(); loadPublicData();
loadPersonalData(); loadPersonalData();
} else { } else {
alert('认领失败: ' + data.message); showAlert('认领失败: ' + data.message);
} }
} }
}; };
@ -986,7 +1091,7 @@
var usersManagements = userInfo.usersManagements; var usersManagements = userInfo.usersManagements;
if (!content) { if (!content) {
alert('请填写跟进内容'); showAlert('请填写跟进内容');
return; return;
} }
@ -1009,7 +1114,7 @@
if (xhr.readyState == 4 && xhr.status == 200) { if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText); var data = JSON.parse(xhr.responseText);
if (data.success) { if (data.success) {
alert('跟进成功'); showAlert('跟进成功');
closeFollowupModal(); closeFollowupModal();
// 重新加载数据 // 重新加载数据
if (document.getElementById('personal').classList.contains('active')) { if (document.getElementById('personal').classList.contains('active')) {
@ -1018,7 +1123,7 @@
loadPublicData(); loadPublicData();
} }
} else { } else {
alert('跟进失败: ' + data.message); showAlert('跟进失败: ' + data.message);
} }
} }
}; };
@ -1037,7 +1142,12 @@
document.getElementById('returnModal').style.display = 'none'; document.getElementById('returnModal').style.display = 'none';
} }
function openJianDaoYunModal(userId, userName) { function openJianDaoYunModal(userId, userName, followup) {
// 检查是否已跟进
if (!followup || followup === '-') {
showAlert('需要先跟进才能点击领入简道云');
return;
}
document.getElementById('jianDaoYunUserId').value = userId; document.getElementById('jianDaoYunUserId').value = userId;
document.getElementById('jianDaoYunModal').style.display = 'block'; document.getElementById('jianDaoYunModal').style.display = 'block';
} }
@ -1046,6 +1156,15 @@
document.getElementById('jianDaoYunModal').style.display = 'none'; document.getElementById('jianDaoYunModal').style.display = 'none';
} }
function showAlert(message) {
document.getElementById('alertMessage').textContent = message;
document.getElementById('alertModal').style.display = 'block';
}
function closeAlertModal() {
document.getElementById('alertModal').style.display = 'none';
}
function saveJianDaoYun() { function saveJianDaoYun() {
var userId = document.getElementById('jianDaoYunUserId').value; var userId = document.getElementById('jianDaoYunUserId').value;
@ -1062,12 +1181,12 @@
if (xhr.readyState == 4 && xhr.status == 200) { if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText); var data = JSON.parse(xhr.responseText);
if (data.success) { if (data.success) {
alert('操作成功'); showAlert('操作成功');
closeJianDaoYunModal(); closeJianDaoYunModal();
// 重新加载数据 // 重新加载数据
loadPersonalData(); loadPersonalData();
} else { } else {
alert('操作失败: ' + data.message); showAlert('操作失败: ' + data.message);
} }
} }
}; };
@ -1092,13 +1211,13 @@
if (xhr.readyState == 4 && xhr.status == 200) { if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText); var data = JSON.parse(xhr.responseText);
if (data.success) { if (data.success) {
alert('归还成功'); showAlert('归还成功');
closeReturnModal(); closeReturnModal();
// 重新加载数据 // 重新加载数据
loadPersonalData(); loadPersonalData();
loadPublicData(); loadPublicData();
} else { } else {
alert('归还失败: ' + data.message); showAlert('归还失败: ' + data.message);
} }
} }
}; };
@ -1200,6 +1319,111 @@
window.location.href = 'login.html'; window.location.href = 'login.html';
} }
function selectAll(tableType) {
var checkboxes = document.querySelectorAll('.userCheckbox');
var selectAllCheckbox = document.getElementById('selectAll' + tableType.charAt(0).toUpperCase() + tableType.slice(1));
var checked = selectAllCheckbox.checked;
checkboxes.forEach(function(checkbox) {
checkbox.checked = checked;
});
}
function loadManagers() {
var url = '/KH/api/users/managers';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
managersList = JSON.parse(xhr.responseText);
populateManagerSelect();
} else if (xhr.readyState == 4) {
console.error('加载负责人列表失败:', xhr.status, xhr.statusText);
}
};
xhr.send();
}
function populateManagerSelect() {
var select = document.getElementById('managerSelect');
select.innerHTML = '<option value="">请选择负责人</option>';
managersList.forEach(function(manager) {
var option = document.createElement('option');
option.value = manager.managerId;
option.textContent = manager.userName;
option.setAttribute('data-managercompany', manager.managercompany);
option.setAttribute('data-managerdepartment', manager.managerdepartment);
option.setAttribute('data-organization', manager.organization);
option.setAttribute('data-role', manager.role);
option.setAttribute('data-root', manager.root);
option.setAttribute('data-assistant', manager.assistant);
select.appendChild(option);
});
}
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 = [];
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
};
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));
}
window.onload = init; window.onload = init;
</script> </script>
</body> </body>

Loading…
Cancel
Save