result = new HashMap<>();
result.put("success", true);
diff --git a/src/main/java/com/example/web/entity/InformationTra.java b/src/main/java/com/example/web/entity/InformationTra.java
new file mode 100644
index 0000000..39c6248
--- /dev/null
+++ b/src/main/java/com/example/web/entity/InformationTra.java
@@ -0,0 +1,115 @@
+package com.example.web.entity;
+
+import java.time.LocalDateTime;
+
+public class InformationTra {
+ private Integer id;
+ private String tracompany;
+ private String tradepartment;
+ private String traorganization;
+ private String trarole;
+ private String trauserName;
+ private String traassistant;
+ private String userId;
+ private String operationEvent;
+ private LocalDateTime operationTime;
+ private LocalDateTime createdAt;
+ private LocalDateTime updatedAt;
+
+ // Getters and Setters
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getTracompany() {
+ return tracompany;
+ }
+
+ public void setTracompany(String tracompany) {
+ this.tracompany = tracompany;
+ }
+
+ public String getTradepartment() {
+ return tradepartment;
+ }
+
+ public void setTradepartment(String tradepartment) {
+ this.tradepartment = tradepartment;
+ }
+
+ public String getTraorganization() {
+ return traorganization;
+ }
+
+ public void setTraorganization(String traorganization) {
+ this.traorganization = traorganization;
+ }
+
+ public String getTrarole() {
+ return trarole;
+ }
+
+ public void setTrarole(String trarole) {
+ this.trarole = trarole;
+ }
+
+ public String getTrauserName() {
+ return trauserName;
+ }
+
+ public void setTrauserName(String trauserName) {
+ this.trauserName = trauserName;
+ }
+
+ public String getTraassistant() {
+ return traassistant;
+ }
+
+ public void setTraassistant(String traassistant) {
+ this.traassistant = traassistant;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getOperationEvent() {
+ return operationEvent;
+ }
+
+ public void setOperationEvent(String operationEvent) {
+ this.operationEvent = operationEvent;
+ }
+
+ public LocalDateTime getOperationTime() {
+ return operationTime;
+ }
+
+ public void setOperationTime(LocalDateTime operationTime) {
+ this.operationTime = operationTime;
+ }
+
+ public LocalDateTime getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(LocalDateTime createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public LocalDateTime getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(LocalDateTime updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/web/mapper/InformationTraMapper.java b/src/main/java/com/example/web/mapper/InformationTraMapper.java
new file mode 100644
index 0000000..2261831
--- /dev/null
+++ b/src/main/java/com/example/web/mapper/InformationTraMapper.java
@@ -0,0 +1,18 @@
+package com.example.web.mapper;
+
+import com.example.web.entity.InformationTra;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface InformationTraMapper {
+ /**
+ * 插入操作记录
+ */
+ int insertInformationTra(InformationTra informationTra);
+
+ /**
+ * 根据userId查询操作记录
+ */
+ InformationTra selectByUserId(@Param("userId") String userId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/web/service/FollowUpService.java b/src/main/java/com/example/web/service/FollowUpService.java
index 9727376..826b83f 100644
--- a/src/main/java/com/example/web/service/FollowUpService.java
+++ b/src/main/java/com/example/web/service/FollowUpService.java
@@ -11,7 +11,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
-@RequiredArgsConstructor
public class FollowUpService {
private final ContactsMapper contactsMapper;
@@ -19,6 +18,13 @@ public class FollowUpService {
private final SupplyContactsMapper supplyContactsMapper;
private final SupplyUsersMapper supplyUsersMapper;
+ public FollowUpService(ContactsMapper contactsMapper, UsersMapper usersMapper, SupplyContactsMapper supplyContactsMapper, SupplyUsersMapper supplyUsersMapper) {
+ this.contactsMapper = contactsMapper;
+ this.usersMapper = usersMapper;
+ this.supplyContactsMapper = supplyContactsMapper;
+ this.supplyUsersMapper = supplyUsersMapper;
+ }
+
/**
* 根据电话号码查询跟进信息
* @param phoneNumber 电话号码
diff --git a/src/main/java/com/example/web/service/InformationTraService.java b/src/main/java/com/example/web/service/InformationTraService.java
new file mode 100644
index 0000000..4c6f57d
--- /dev/null
+++ b/src/main/java/com/example/web/service/InformationTraService.java
@@ -0,0 +1,105 @@
+package com.example.web.service;
+
+import com.example.web.dto.UserProductCartDTO;
+import com.example.web.entity.Contacts;
+import com.example.web.entity.InformationTra;
+import com.example.web.mapper.*;
+import com.example.web.config.DynamicDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+
+@Service
+public class InformationTraService {
+
+ @Autowired
+ private InformationTraMapper informationTraMapper;
+
+ @Autowired
+ private UsersMapper usersMapper;
+
+ @Autowired
+ private ContactsMapper contactsMapper;
+
+ /**
+ * 记录操作事件
+ */
+ public boolean recordOperationEvent(String phoneNumber, String customerName, String operationEvent,
+ String managerCompany, String managerDepartment, String organization,
+ String role, String userName, String assistant) {
+ // 保存原始数据源,以便在finally块中恢复
+ String originalDataSource = DynamicDataSource.getCurrentDataSourceKey();
+ try {
+ // 1. 从两个数据源查询客户信息
+ String userId = null;
+
+ // 查询wechat数据源的users表
+ DynamicDataSource.setDataSourceKey("wechat");
+ UserProductCartDTO wechatUser = usersMapper.selectByPhone(phoneNumber);
+
+ if (wechatUser != null) {
+ userId = wechatUser.getUserId();
+ System.out.println("ℹ️ 从wechat数据源获取到userId: " + userId);
+ } else {
+ System.out.println("ℹ️ 在wechat数据源中未找到客户");
+ // 查询primary数据源的contacts表
+ DynamicDataSource.setDataSourceKey("primary");
+ Contacts contact = contactsMapper.selectByPhoneNumber(phoneNumber);
+
+ if (contact != null) {
+ System.out.println("✅ 在primary数据源中找到客户: " + contact.getNickName());
+ userId = contact.getId();
+ System.out.println("ℹ️ 使用primary数据源的contact.id作为userId: " + userId);
+ }
+ }
+
+ // 如果都没找到,返回失败
+ if (userId == null) {
+ System.err.println("❌ 无法获取客户ID,操作记录失败");
+ return false;
+ }
+
+ // 2. 获取当前时间
+ LocalDateTime now = LocalDateTime.now();
+
+ // 3. 构造操作记录
+ InformationTra informationTra = new InformationTra();
+ informationTra.setTracompany(managerCompany);
+ informationTra.setTradepartment(managerDepartment);
+ informationTra.setTraorganization(organization);
+ informationTra.setTrarole(role);
+ informationTra.setTrauserName(userName);
+ informationTra.setTraassistant(assistant);
+ informationTra.setUserId(userId);
+ informationTra.setOperationEvent(operationEvent);
+ informationTra.setOperationTime(now);
+ informationTra.setCreatedAt(now);
+ informationTra.setUpdatedAt(now);
+
+ // 4. 始终写入wechat数据源的informationtra表
+ DynamicDataSource.setDataSourceKey("wechat");
+ System.out.println("🔄 设置数据源为wechat,准备插入信息跟踪记录");
+ int result = informationTraMapper.insertInformationTra(informationTra);
+ if (result > 0) {
+ System.out.println("✅ 插入信息跟踪记录成功,影响行数: " + result);
+ return true;
+ } else {
+ System.err.println("❌ 插入信息跟踪记录失败,影响行数: " + result);
+ return false;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.err.println("❌ 操作记录异常: " + e.getMessage());
+ return false;
+ } finally {
+ // 恢复原始数据源,避免线程池复用问题
+ if (originalDataSource != null) {
+ DynamicDataSource.setDataSourceKey(originalDataSource);
+ } else {
+ DynamicDataSource.clearDataSourceKey();
+ }
+ System.out.println("🔄 恢复数据源为原始值: " + (originalDataSource != null ? originalDataSource : "默认数据源"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index fab977f..7e4eaa7 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -22,6 +22,7 @@ app:
organization-to-department-days: 30
server:
+ port: 8081
servlet:
context-path: /DL
# 在Tomcat中部署时,端口由Tomcat配置决定,这里不需要指定
diff --git a/src/main/resources/mapper/InformationTraMapper.xml b/src/main/resources/mapper/InformationTraMapper.xml
new file mode 100644
index 0000000..adf8e24
--- /dev/null
+++ b/src/main/resources/mapper/InformationTraMapper.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ INSERT INTO informationtra (
+ tracompany, tradepartment, traorganization, trarole,
+ trauserName, traassistant, userId, operationEvent,
+ operationTime, created_at, updated_at
+ ) VALUES (
+ #{tracompany}, #{tradepartment}, #{traorganization}, #{trarole},
+ #{trauserName}, #{traassistant}, #{userId}, #{operationEvent},
+ #{operationTime}, #{createdAt}, #{updatedAt}
+ )
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/static/loginmm.html b/src/main/resources/static/loginmm.html
index 5a72bbd..4576522 100644
--- a/src/main/resources/static/loginmm.html
+++ b/src/main/resources/static/loginmm.html
@@ -520,7 +520,7 @@
errorElement.classList.remove('show');
}
- const API_BASE_URL = 'http://8.137.125.67:8080/DL'; // 服务器API地址
+ const API_BASE_URL = 'http://localhost:8080/DL'; // 服务器API地址
async function sendLoginRequest(projectName, userName, password) {
try {
// 使用URL编码的表单数据
diff --git a/src/main/resources/static/mainapp-sells.html b/src/main/resources/static/mainapp-sells.html
index 4136926..86db328 100644
--- a/src/main/resources/static/mainapp-sells.html
+++ b/src/main/resources/static/mainapp-sells.html
@@ -590,6 +590,189 @@
padding: 15px 25px;
}
+ /* 通知铃铛按钮样式 */
+ .notification-btn {
+ background-color: #f8f9fa;
+ border: 1px solid #e0e0e0;
+ border-radius: 50%;
+ width: 40px;
+ height: 40px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ margin-right: 10px;
+ color: #666;
+ }
+
+ .notification-btn:hover {
+ background-color: #e9ecef;
+ border-color: #adb5bd;
+ color: #495057;
+ transform: scale(1.05);
+ }
+
+ .notification-btn i {
+ font-size: 18px;
+ }
+
+ /* 头部操作容器样式 */
+ .header-actions-container {
+ display: flex;
+ align-items: center;
+ }
+
+ /* 用户信息容器样式 */
+ .user-info-container {
+ position: relative;
+ }
+
+ /* 用户信息按钮样式 */
+ .user-info-btn {
+ display: flex;
+ align-items: center;
+ background-color: #f8f9fa;
+ border: 1px solid #e0e0e0;
+ border-radius: 4px;
+ padding: 8px 12px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ color: #666;
+ }
+
+ .user-info-btn:hover {
+ background-color: #e9ecef;
+ border-color: #adb5bd;
+ color: #495057;
+ }
+
+ .user-info-btn i {
+ margin: 0 5px;
+ }
+
+ /* 用户头像样式 */
+ .user-avatar-large {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 24px;
+ height: 24px;
+ background-color: #4CAF50;
+ color: white;
+ border-radius: 50%;
+ margin-right: 8px;
+ }
+
+ /* 用户信息下拉菜单样式 */
+ .user-info-dropdown {
+ position: absolute;
+ top: 100%;
+ right: 0;
+ background-color: white;
+ border: 1px solid #e0e0e0;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ padding: 10px 0;
+ min-width: 250px;
+ z-index: 1000;
+ opacity: 0;
+ visibility: hidden;
+ transition: all 0.3s ease;
+ transform: translateY(-5px);
+ }
+
+ .user-info-dropdown.active {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+ }
+
+ /* 用户信息头部样式 */
+ .user-info-header {
+ display: flex;
+ align-items: center;
+ padding: 0 15px 10px;
+ border-bottom: 1px solid #e0e0e0;
+ }
+
+ /* 用户信息主要内容样式 */
+ .user-info-main {
+ margin-left: 10px;
+ }
+
+ /* 用户名字样式 */
+ .user-name {
+ font-weight: bold;
+ font-size: 14px;
+ }
+
+ /* 用户角色样式 */
+ .user-role {
+ font-size: 12px;
+ color: #666;
+ }
+
+ /* 用户信息详情样式 */
+ .user-info-details {
+ padding: 10px 0;
+ }
+
+ /* 用户信息项样式 */
+ .user-info-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 15px;
+ font-size: 13px;
+ }
+
+ .user-info-item:hover {
+ background-color: #f8f9fa;
+ }
+
+ /* 用户信息标签样式 */
+ .user-info-label {
+ display: flex;
+ align-items: center;
+ color: #666;
+ }
+
+ .user-info-label i {
+ margin-right: 5px;
+ font-size: 12px;
+ }
+
+ /* 用户信息值样式 */
+ .user-info-value {
+ color: #333;
+ font-weight: normal;
+ }
+
+ /* 退出按钮样式 */
+ .logout-btn {
+ width: 100%;
+ padding: 10px;
+ background-color: transparent;
+ border: none;
+ border-top: 1px solid #e0e0e0;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #666;
+ }
+
+ .logout-btn:hover {
+ background-color: #f8f9fa;
+ color: #dc3545;
+ }
+
+ .logout-btn i {
+ margin-right: 5px;
+ }
+
.header-content {
display: flex;
align-items: center;
@@ -1917,8 +2100,7 @@
border-bottom: 2px solid #f0f2f5;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
- margin-bottom: 20px;
- }
+
.follow-up-details-table th,
.follow-up-details-table td {
@@ -2548,6 +2730,9 @@
Welcome, hope you have a nice day
+
@@ -4438,7 +4623,9 @@
// 从URL参数获取认证信息
function getAuthInfoFromURL() {
const urlParams = new URLSearchParams(window.location.search);
- const authInfo = {
+
+ // 先从URL中获取认证信息
+ let authInfo = {
managerId: decodeURIComponent(urlParams.get('managerId') || ''),
managercompany: decodeURIComponent(urlParams.get('managercompany') || ''),
managerdepartment: decodeURIComponent(urlParams.get('managerdepartment') || ''),
@@ -4449,6 +4636,30 @@
token: urlParams.get('token') || '',
isSupplySide: urlParams.get('isSupplySide') === 'true'
};
+
+ // 如果URL中没有获取到完整的认证信息,从localStorage中获取
+ if (!authInfo.userName || !authInfo.managerId) {
+ console.log('URL中认证信息不完整,尝试从localStorage获取');
+ try {
+ const currentUser = localStorage.getItem('currentUser');
+ if (currentUser) {
+ const user = JSON.parse(currentUser);
+ authInfo = {
+ managerId: authInfo.managerId || user.managerId || '',
+ managercompany: authInfo.managercompany || user.managercompany || '',
+ managerdepartment: authInfo.managerdepartment || user.managerdepartment || '',
+ organization: authInfo.organization || user.organization || '',
+ role: authInfo.role || user.role || '',
+ userName: authInfo.userName || user.userName || '',
+ assistant: authInfo.assistant || user.assistant || '',
+ token: authInfo.token || localStorage.getItem('authToken') || '',
+ isSupplySide: urlParams.get('isSupplySide') === 'true'
+ };
+ }
+ } catch (error) {
+ console.error('从localStorage获取认证信息失败:', error);
+ }
+ }
console.log('=== 从URL参数获取认证信息 ===');
console.log('认证信息:', authInfo);
@@ -4478,6 +4689,9 @@
// 修改登录按钮
const loginButton = document.getElementById('loginButton');
if (loginButton && authInfo.userName) {
+ // 找到通知按钮
+ const notificationButton = document.getElementById('notificationButton');
+
// 创建用户信息容器
const userInfoContainer = document.createElement('div');
userInfoContainer.className = 'user-info-container';
@@ -4548,10 +4762,18 @@
`;
- // 替换原来的登录按钮
+ // 创建包含通知按钮和用户信息按钮的容器
+ const headerActionsContainer = document.createElement('div');
+ headerActionsContainer.className = 'header-actions-container';
+
+ // 先添加通知按钮,再添加用户信息按钮和下拉菜单
+ headerActionsContainer.appendChild(notificationButton);
userInfoContainer.appendChild(userInfoBtn);
userInfoContainer.appendChild(userInfoDropdown);
- loginButton.parentNode.replaceChild(userInfoContainer, loginButton);
+ headerActionsContainer.appendChild(userInfoContainer);
+
+ // 替换原来的登录按钮
+ loginButton.parentNode.replaceChild(headerActionsContainer, loginButton);
// 绑定显示/隐藏下拉菜单事件
userInfoBtn.addEventListener('click', function (e) {
@@ -10729,7 +10951,7 @@
console.log('获取跟进信息:', phoneNumber);
// 发送请求获取跟进信息,不再需要指定数据源
- fetch(`/DL/api/followup/get?phoneNumber=${encodeURIComponent(phoneNumber)}`)
+ fetch(appendAuthParams(`/DL/api/followup/get?phoneNumber=${encodeURIComponent(phoneNumber)}`))
.then(response => response.text())
.then(followup => {
console.log('获取到的跟进信息:', followup);
@@ -10754,7 +10976,7 @@
const followup = document.getElementById('follow-up-content').value;
// 发送请求保存跟进信息,不再需要指定数据源
- fetch(`/DL/api/followup/save?phoneNumber=${encodeURIComponent(phoneNumber)}&followup=${encodeURIComponent(followup)}`, {
+ fetch(appendAuthParams(`/DL/api/followup/save?phoneNumber=${encodeURIComponent(phoneNumber)}&followup=${encodeURIComponent(followup)}`), {
method: 'POST'
})
.then(response => response.text())
diff --git a/src/main/resources/static/mainapp-supplys.html b/src/main/resources/static/mainapp-supplys.html
index fd51b96..9f3d38c 100644
--- a/src/main/resources/static/mainapp-supplys.html
+++ b/src/main/resources/static/mainapp-supplys.html
@@ -590,6 +590,189 @@
padding: 15px 25px;
}
+ /* 通知铃铛按钮样式 */
+ .notification-btn {
+ background-color: #f8f9fa;
+ border: 1px solid #e0e0e0;
+ border-radius: 50%;
+ width: 40px;
+ height: 40px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ margin-right: 10px;
+ color: #666;
+ }
+
+ .notification-btn:hover {
+ background-color: #e9ecef;
+ border-color: #adb5bd;
+ color: #495057;
+ transform: scale(1.05);
+ }
+
+ .notification-btn i {
+ font-size: 18px;
+ }
+
+ /* 头部操作容器样式 */
+ .header-actions-container {
+ display: flex;
+ align-items: center;
+ }
+
+ /* 用户信息容器样式 */
+ .user-info-container {
+ position: relative;
+ }
+
+ /* 用户信息按钮样式 */
+ .user-info-btn {
+ display: flex;
+ align-items: center;
+ background-color: #f8f9fa;
+ border: 1px solid #e0e0e0;
+ border-radius: 4px;
+ padding: 8px 12px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ color: #666;
+ }
+
+ .user-info-btn:hover {
+ background-color: #e9ecef;
+ border-color: #adb5bd;
+ color: #495057;
+ }
+
+ .user-info-btn i {
+ margin: 0 5px;
+ }
+
+ /* 用户头像样式 */
+ .user-avatar-large {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 24px;
+ height: 24px;
+ background-color: #4CAF50;
+ color: white;
+ border-radius: 50%;
+ margin-right: 8px;
+ }
+
+ /* 用户信息下拉菜单样式 */
+ .user-info-dropdown {
+ position: absolute;
+ top: 100%;
+ right: 0;
+ background-color: white;
+ border: 1px solid #e0e0e0;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ padding: 10px 0;
+ min-width: 250px;
+ z-index: 1000;
+ opacity: 0;
+ visibility: hidden;
+ transition: all 0.3s ease;
+ transform: translateY(-5px);
+ }
+
+ .user-info-dropdown.active {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+ }
+
+ /* 用户信息头部样式 */
+ .user-info-header {
+ display: flex;
+ align-items: center;
+ padding: 0 15px 10px;
+ border-bottom: 1px solid #e0e0e0;
+ }
+
+ /* 用户信息主要内容样式 */
+ .user-info-main {
+ margin-left: 10px;
+ }
+
+ /* 用户名字样式 */
+ .user-name {
+ font-weight: bold;
+ font-size: 14px;
+ }
+
+ /* 用户角色样式 */
+ .user-role {
+ font-size: 12px;
+ color: #666;
+ }
+
+ /* 用户信息详情样式 */
+ .user-info-details {
+ padding: 10px 0;
+ }
+
+ /* 用户信息项样式 */
+ .user-info-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 15px;
+ font-size: 13px;
+ }
+
+ .user-info-item:hover {
+ background-color: #f8f9fa;
+ }
+
+ /* 用户信息标签样式 */
+ .user-info-label {
+ display: flex;
+ align-items: center;
+ color: #666;
+ }
+
+ .user-info-label i {
+ margin-right: 5px;
+ font-size: 12px;
+ }
+
+ /* 用户信息值样式 */
+ .user-info-value {
+ color: #333;
+ font-weight: normal;
+ }
+
+ /* 退出按钮样式 */
+ .logout-btn {
+ width: 100%;
+ padding: 10px;
+ background-color: transparent;
+ border: none;
+ border-top: 1px solid #e0e0e0;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #666;
+ }
+
+ .logout-btn:hover {
+ background-color: #f8f9fa;
+ color: #dc3545;
+ }
+
+ .logout-btn i {
+ margin-right: 5px;
+ }
+
.header-content {
display: flex;
align-items: center;
@@ -1917,8 +2100,7 @@
border-bottom: 2px solid #f0f2f5;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
- margin-bottom: 20px;
- }
+
.follow-up-details-table th,
.follow-up-details-table td {
@@ -2548,6 +2730,9 @@
Welcome, hope you have a nice day
+
@@ -4426,7 +4611,9 @@
// 从URL参数获取认证信息
function getAuthInfoFromURL() {
const urlParams = new URLSearchParams(window.location.search);
- const authInfo = {
+
+ // 先从URL中获取认证信息
+ let authInfo = {
managerId: decodeURIComponent(urlParams.get('managerId') || ''),
managercompany: decodeURIComponent(urlParams.get('managercompany') || ''),
managerdepartment: decodeURIComponent(urlParams.get('managerdepartment') || ''),
@@ -4437,6 +4624,30 @@
token: urlParams.get('token') || '',
isSupplySide: urlParams.get('isSupplySide') === 'true'
};
+
+ // 如果URL中没有获取到完整的认证信息,从localStorage中获取
+ if (!authInfo.userName || !authInfo.managerId) {
+ console.log('URL中认证信息不完整,尝试从localStorage获取');
+ try {
+ const currentUser = localStorage.getItem('currentUser');
+ if (currentUser) {
+ const user = JSON.parse(currentUser);
+ authInfo = {
+ managerId: authInfo.managerId || user.managerId || '',
+ managercompany: authInfo.managercompany || user.managercompany || '',
+ managerdepartment: authInfo.managerdepartment || user.managerdepartment || '',
+ organization: authInfo.organization || user.organization || '',
+ role: authInfo.role || user.role || '',
+ userName: authInfo.userName || user.userName || '',
+ assistant: authInfo.assistant || user.assistant || '',
+ token: authInfo.token || localStorage.getItem('authToken') || '',
+ isSupplySide: urlParams.get('isSupplySide') === 'true'
+ };
+ }
+ } catch (error) {
+ console.error('从localStorage获取认证信息失败:', error);
+ }
+ }
console.log('=== 从URL参数获取认证信息 ===');
console.log('认证信息:', authInfo);
@@ -4466,6 +4677,9 @@
// 修改登录按钮
const loginButton = document.getElementById('loginButton');
if (loginButton && authInfo.userName) {
+ // 找到通知按钮
+ const notificationButton = document.getElementById('notificationButton');
+
// 创建用户信息容器
const userInfoContainer = document.createElement('div');
userInfoContainer.className = 'user-info-container';
@@ -4536,10 +4750,18 @@
`;
- // 替换原来的登录按钮
+ // 创建包含通知按钮和用户信息按钮的容器
+ const headerActionsContainer = document.createElement('div');
+ headerActionsContainer.className = 'header-actions-container';
+
+ // 先添加通知按钮,再添加用户信息按钮和下拉菜单
+ headerActionsContainer.appendChild(notificationButton);
userInfoContainer.appendChild(userInfoBtn);
userInfoContainer.appendChild(userInfoDropdown);
- loginButton.parentNode.replaceChild(userInfoContainer, loginButton);
+ headerActionsContainer.appendChild(userInfoContainer);
+
+ // 替换原来的登录按钮
+ loginButton.parentNode.replaceChild(headerActionsContainer, loginButton);
// 绑定显示/隐藏下拉菜单事件
userInfoBtn.addEventListener('click', function (e) {
@@ -10555,7 +10777,7 @@
console.log('获取跟进信息:', phoneNumber);
// 发送请求获取跟进信息,不再需要指定数据源
- fetch(`/DL/api/followup/get?phoneNumber=${encodeURIComponent(phoneNumber)}`)
+ fetch(appendAuthParams(`/DL/api/followup/get?phoneNumber=${encodeURIComponent(phoneNumber)}`))
.then(response => response.text())
.then(followup => {
console.log('获取到的跟进信息:', followup);
@@ -10580,7 +10802,7 @@
const followup = document.getElementById('follow-up-content').value;
// 发送请求保存跟进信息,不再需要指定数据源
- fetch(`/DL/api/followup/save?phoneNumber=${encodeURIComponent(phoneNumber)}&followup=${encodeURIComponent(followup)}`, {
+ fetch(appendAuthParams(`/DL/api/followup/save?phoneNumber=${encodeURIComponent(phoneNumber)}&followup=${encodeURIComponent(followup)}`), {
method: 'POST'
})
.then(response => response.text())