From 26bb317baa6db595ac033f791ea6879902240591 Mon Sep 17 00:00:00 2001 From: Trae AI Date: Tue, 27 Jan 2026 17:01:25 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E8=A6=86=E7=9B=96KH=E5=88=86?= =?UTF-8?q?=E6=94=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/web/config/SecurityConfig.java | 2 +- .../web/controller/UserController.java | 5 + .../com/example/web/entity/CustomerApply.java | 4 +- .../web/mapper/CustomerApplyMapper.java | 2 + .../example/web/mapper/PersonnelMapper.java | 3 + .../example/web/mapper/UserTraceMapper.java | 3 + .../com/example/web/mapper/UsersMapper.java | 3 + .../com/example/web/service/UserService.java | 3 + .../impl/CustomerApplyServiceImpl.java | 124 ++- .../web/service/impl/UserServiceImpl.java | 86 +- .../resources/mapper/CustomerApplyMapper.xml | 4 +- .../main/resources/mapper/PersonnelMapper.xml | 4 + .../main/resources/mapper/UserTraceMapper.xml | 8 + web/src/main/resources/mapper/UsersMapper.xml | 4 + web/src/main/resources/static/index.html | 797 ++++++++++++++++-- web/src/main/resources/static/login.html | 2 +- 16 files changed, 936 insertions(+), 118 deletions(-) diff --git a/web/src/main/java/com/example/web/config/SecurityConfig.java b/web/src/main/java/com/example/web/config/SecurityConfig.java index e01a429..181ad5a 100644 --- a/web/src/main/java/com/example/web/config/SecurityConfig.java +++ b/web/src/main/java/com/example/web/config/SecurityConfig.java @@ -14,7 +14,7 @@ public class SecurityConfig { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeRequests() - .requestMatchers("/login.html", "/index.html", "/api/login", "/api/users/**", "/api/products/**").permitAll() + .requestMatchers("/login.html", "/index.html", "/api/login", "/api/users/**", "/api/products/**", "/api/personnel/**").permitAll() .requestMatchers("/static/**").permitAll() .anyRequest().authenticated() .and() diff --git a/web/src/main/java/com/example/web/controller/UserController.java b/web/src/main/java/com/example/web/controller/UserController.java index 3778380..5729f96 100644 --- a/web/src/main/java/com/example/web/controller/UserController.java +++ b/web/src/main/java/com/example/web/controller/UserController.java @@ -139,4 +139,9 @@ public class UserController { @RequestParam String productId) { return userService.getProductDetail(productId); } + + @GetMapping("/personnel") + public Map getPersonnelList() { + return userService.getPersonnelList(); + } } diff --git a/web/src/main/java/com/example/web/entity/CustomerApply.java b/web/src/main/java/com/example/web/entity/CustomerApply.java index 06f1f3d..18609e0 100644 --- a/web/src/main/java/com/example/web/entity/CustomerApply.java +++ b/web/src/main/java/com/example/web/entity/CustomerApply.java @@ -16,16 +16,18 @@ public class CustomerApply { private String user_id; // 客户ID private String sales_id; // 业务员ID private String sales_name; // 业务员姓名 + private String original_manager_name; // 原始负责人姓名 private Integer status; // 申请状态:0-申请中,1-通过,2-失败 private LocalDateTime apply_time; // 申请时间 private LocalDateTime approve_time; // 审批时间 private String approve_by; // 审批人 private String reason; // 申请理由/失败原因 - public CustomerApply(String user_id, String sales_id, String sales_name, String reason) { + public CustomerApply(String user_id, String sales_id, String sales_name, String original_manager_name, String reason) { this.user_id = user_id; this.sales_id = sales_id; this.sales_name = sales_name; + this.original_manager_name = original_manager_name; this.status = 0; // 默认状态为申请中 this.apply_time = LocalDateTime.now(); this.reason = reason; diff --git a/web/src/main/java/com/example/web/mapper/CustomerApplyMapper.java b/web/src/main/java/com/example/web/mapper/CustomerApplyMapper.java index 08f81be..115f71c 100644 --- a/web/src/main/java/com/example/web/mapper/CustomerApplyMapper.java +++ b/web/src/main/java/com/example/web/mapper/CustomerApplyMapper.java @@ -1,5 +1,6 @@ package com.example.web.mapper; +import com.example.web.annotation.DataSource; import com.example.web.entity.CustomerApply; import java.util.List; @@ -8,6 +9,7 @@ import java.util.Map; /** * 客户申请Mapper接口 */ +@DataSource("wechat") public interface CustomerApplyMapper { /** diff --git a/web/src/main/java/com/example/web/mapper/PersonnelMapper.java b/web/src/main/java/com/example/web/mapper/PersonnelMapper.java index 06e4b30..1bc5cee 100644 --- a/web/src/main/java/com/example/web/mapper/PersonnelMapper.java +++ b/web/src/main/java/com/example/web/mapper/PersonnelMapper.java @@ -12,6 +12,9 @@ public interface PersonnelMapper { @DataSource("primary") Personnel findByNameAndProjectName(String name, String projectName); + @DataSource("primary") + Personnel findByPhoneNumber(String phoneNumber); + @DataSource("primary") List findAll(); } diff --git a/web/src/main/java/com/example/web/mapper/UserTraceMapper.java b/web/src/main/java/com/example/web/mapper/UserTraceMapper.java index 8662c49..23778bc 100644 --- a/web/src/main/java/com/example/web/mapper/UserTraceMapper.java +++ b/web/src/main/java/com/example/web/mapper/UserTraceMapper.java @@ -9,4 +9,7 @@ public interface UserTraceMapper { @DataSource("wechat") List getProductTraces(String productId); + + @DataSource("wechat") + UserTrace findById(Integer id); } diff --git a/web/src/main/java/com/example/web/mapper/UsersMapper.java b/web/src/main/java/com/example/web/mapper/UsersMapper.java index 9fd2c8b..0832334 100644 --- a/web/src/main/java/com/example/web/mapper/UsersMapper.java +++ b/web/src/main/java/com/example/web/mapper/UsersMapper.java @@ -75,4 +75,7 @@ public interface UsersMapper { @DataSource("wechat") List findAllUsers(); + + @DataSource("wechat") + Users findByPhoneNumber(String phoneNumber); } diff --git a/web/src/main/java/com/example/web/service/UserService.java b/web/src/main/java/com/example/web/service/UserService.java index 69487bd..fa3b995 100644 --- a/web/src/main/java/com/example/web/service/UserService.java +++ b/web/src/main/java/com/example/web/service/UserService.java @@ -32,4 +32,7 @@ public interface UserService { Map applyCustomer(Map params); Map approveApply(Map params); List getApplyList(Integer status); + + // 获取人员列表 + Map getPersonnelList(); } diff --git a/web/src/main/java/com/example/web/service/impl/CustomerApplyServiceImpl.java b/web/src/main/java/com/example/web/service/impl/CustomerApplyServiceImpl.java index bba3b0e..da8ed6a 100644 --- a/web/src/main/java/com/example/web/service/impl/CustomerApplyServiceImpl.java +++ b/web/src/main/java/com/example/web/service/impl/CustomerApplyServiceImpl.java @@ -1,13 +1,17 @@ package com.example.web.service.impl; import com.example.web.entity.CustomerApply; +import com.example.web.entity.InformationTra; import com.example.web.entity.Personnel; +import com.example.web.entity.UserTrace; import com.example.web.entity.Users; import com.example.web.mapper.CustomerApplyMapper; import com.example.web.mapper.PersonnelMapper; +import com.example.web.mapper.UserTraceMapper; import com.example.web.mapper.UsersMapper; import com.example.web.mapper.UsersManagementsMapper; import com.example.web.service.CustomerApplyService; +import com.example.web.service.InformationTraService; import com.example.web.config.DataSourceContextHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -35,26 +39,61 @@ public class CustomerApplyServiceImpl implements CustomerApplyService { @Autowired private UsersMapper usersMapper; + @Autowired + private UserTraceMapper userTraceMapper; + + @Autowired + private InformationTraService informationTraService; + @Override public Map submitApply(Map params) { Map result = new HashMap<>(); try { - // 切换到wechat数据源 - DataSourceContextHolder.setDataSource("wechat"); - - String userId = (String) params.get("userId"); - String salesId = (String) params.get("salesId"); + // 获取当前登录信息 String salesName = (String) params.get("salesName"); String reason = (String) params.get("reason"); + String traceId = (String) params.get("traceId"); // 从前端传递的浏览记录ID - if (userId == null || salesId == null || salesName == null) { + if (salesName == null || traceId == null) { result.put("success", false); result.put("message", "缺少必要参数"); return result; } - // 检查是否已经有申请记录 + // 1. 到primary数据源的personnel表里获取业务员的信息 + DataSourceContextHolder.setDataSource("primary"); + Personnel personnel = personnelMapper.findByName(salesName); + if (personnel == null || personnel.getPhoneNumber() == null) { + result.put("success", false); + result.put("message", "未找到业务员信息"); + return result; + } + String phoneNumber = personnel.getPhoneNumber(); + + // 2. 到wechat数据源的users表里查询业务员的userId + DataSourceContextHolder.setDataSource("wechat"); + Users salesUser = usersMapper.findByPhoneNumber(phoneNumber); + if (salesUser == null || salesUser.getUserId() == null) { + result.put("success", false); + result.put("message", "未找到业务员的用户ID"); + return result; + } + String salesId = salesUser.getUserId(); // 业务员的ID + + // 3. 到wechat数据源的usertraces表里获取相应的客户userId + UserTrace trace = userTraceMapper.findById(Integer.parseInt(traceId)); + if (trace == null || trace.getUserId() == null) { + result.put("success", false); + result.put("message", "未找到浏览记录信息"); + return result; + } + String userId = trace.getUserId(); // 客户的ID + + // 允许自己申请自己,这是合理的测试场景 + // 如果需要防止这种情况,可以在此处添加验证 + + // 4. 检查是否已经有申请记录 CustomerApply existingApply = customerApplyMapper.findByUserIdAndSalesId(userId, salesId); if (existingApply != null && existingApply.getStatus() == 0) { result.put("success", false); @@ -62,8 +101,15 @@ public class CustomerApplyServiceImpl implements CustomerApplyService { return result; } - // 创建新的申请记录 - CustomerApply apply = new CustomerApply(userId, salesId, salesName, reason); + // 5. 获取客户的原始负责人信息 + String original_manager_name = null; + com.example.web.entity.UsersManagements existingManagements = usersManagementsMapper.findByUserId(userId); + if (existingManagements != null) { + original_manager_name = existingManagements.getUserName(); + } + + // 6. 创建新的申请记录 + CustomerApply apply = new CustomerApply(userId, salesId, salesName, original_manager_name, reason); int count = customerApplyMapper.insert(apply); if (count > 0) { @@ -121,20 +167,28 @@ public class CustomerApplyServiceImpl implements CustomerApplyService { // 根据id查询完整的申请记录 CustomerApply apply = customerApplyMapper.findById(id); if (apply != null) { - // 实现更新客户负责人的逻辑 + // 1. 使用wechat数据源的customer_apply表里的user_id到usermanagements表里查询 com.example.web.entity.UsersManagements usersManagements = usersManagementsMapper.findByUserId(apply.getUser_id()); - // 切换到primary数据源查询personnel表 + // 2. 将customer_apply表里的original_manager_name的值放到primary数据源的personnel数据源里获取信息 DataSourceContextHolder.setDataSource("primary"); + Personnel originalPersonnel = null; + if (apply.getOriginal_manager_name() != null) { + try { + originalPersonnel = personnelMapper.findByName(apply.getOriginal_manager_name()); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("查询原始负责人信息时发生错误: " + e.getMessage()); + } + } - // 从personnel表中查询业务员的详细信息 - Personnel personnel = null; + // 3. 从personnel表中查询业务员的详细信息 + Personnel salesPersonnel = null; try { - // 只通过name查询业务员信息 - personnel = personnelMapper.findByName(apply.getSales_name()); + salesPersonnel = personnelMapper.findByName(apply.getSales_name()); } catch (Exception e) { e.printStackTrace(); - System.out.println("查询Personnel时发生错误: " + e.getMessage()); + System.out.println("查询业务员信息时发生错误: " + e.getMessage()); } // 切换回wechat数据源 @@ -144,11 +198,11 @@ public class CustomerApplyServiceImpl implements CustomerApplyService { // 更新现有记录 usersManagements.setManagerId(apply.getSales_id()); usersManagements.setUserName(apply.getSales_name()); - if (personnel != null) { - usersManagements.setManagercompany(personnel.getManagercompany()); - usersManagements.setManagerdepartment(personnel.getManagerdepartment()); - usersManagements.setOrganization(personnel.getOrganization()); - usersManagements.setRole(personnel.getProjectName()); // projectName与role同值 + if (salesPersonnel != null) { + usersManagements.setManagercompany(salesPersonnel.getManagercompany()); + usersManagements.setManagerdepartment(salesPersonnel.getManagerdepartment()); + usersManagements.setOrganization(salesPersonnel.getOrganization()); + usersManagements.setRole(salesPersonnel.getProjectName()); // role与projectName同值 } usersManagements.setUpdated_at(LocalDateTime.now()); usersManagementsMapper.update(usersManagements); @@ -167,11 +221,11 @@ public class CustomerApplyServiceImpl implements CustomerApplyService { newUsersManagements.setUserId(apply.getUser_id()); newUsersManagements.setManagerId(apply.getSales_id()); newUsersManagements.setUserName(apply.getSales_name()); - if (personnel != null) { - newUsersManagements.setManagercompany(personnel.getManagercompany()); - newUsersManagements.setManagerdepartment(personnel.getManagerdepartment()); - newUsersManagements.setOrganization(personnel.getOrganization()); - newUsersManagements.setRole(personnel.getProjectName()); // projectName与role同值 + if (salesPersonnel != null) { + newUsersManagements.setManagercompany(salesPersonnel.getManagercompany()); + newUsersManagements.setManagerdepartment(salesPersonnel.getManagerdepartment()); + newUsersManagements.setOrganization(salesPersonnel.getOrganization()); + newUsersManagements.setRole(salesPersonnel.getProjectName()); // role与projectName同值 } newUsersManagements.setCreated_at(LocalDateTime.now()); newUsersManagements.setUpdated_at(LocalDateTime.now()); @@ -185,6 +239,24 @@ public class CustomerApplyServiceImpl implements CustomerApplyService { System.out.println("客户ID " + apply.getUser_id() + " 在users表中不存在,无法创建usermanagements记录"); } } + + // 记录分配操作 + try { + com.example.web.entity.InformationTra tra = new com.example.web.entity.InformationTra(); + if (salesPersonnel != null) { + tra.setTracompany(salesPersonnel.getManagercompany()); + tra.setTradepartment(salesPersonnel.getManagerdepartment()); + tra.setTraorganization(salesPersonnel.getOrganization()); + tra.setTrarole(salesPersonnel.getProjectName()); + } + tra.setTrauserName(apply.getSales_name()); + tra.setUserId(apply.getUser_id()); + tra.setOperationEvent("申请通过分配客户: " + apply.getSales_name()); + informationTraService.recordUserOperation(tra); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("记录分配操作时发生错误: " + e.getMessage()); + } } } diff --git a/web/src/main/java/com/example/web/service/impl/UserServiceImpl.java b/web/src/main/java/com/example/web/service/impl/UserServiceImpl.java index 8dc44a1..a34aee8 100644 --- a/web/src/main/java/com/example/web/service/impl/UserServiceImpl.java +++ b/web/src/main/java/com/example/web/service/impl/UserServiceImpl.java @@ -718,8 +718,76 @@ public class UserServiceImpl implements UserService { } } + // 处理产品列表,添加销售负责人和创建人信息 + List> processedProducts = new ArrayList<>(); + for (Product product : products) { + Map productMap = new HashMap<>(); + // 复制原有字段 + productMap.put("id", product.getId()); + productMap.put("productId", product.getProductId()); + productMap.put("sellerId", product.getSellerId()); + productMap.put("productName", product.getProductName()); + productMap.put("price", product.getPrice()); + productMap.put("costprice", product.getCostprice()); + productMap.put("quantity", product.getQuantity()); + productMap.put("grossWeight", product.getGrossWeight()); + productMap.put("yolk", product.getYolk()); + productMap.put("specification", product.getSpecification()); + productMap.put("created_at", product.getCreated_at()); + productMap.put("updated_at", product.getUpdated_at()); + productMap.put("status", product.getStatus()); + productMap.put("region", product.getRegion()); + productMap.put("sourceType", product.getSourceType()); + productMap.put("supplyStatus", product.getSupplyStatus()); + productMap.put("category", product.getCategory()); + productMap.put("producting", product.getProducting()); + productMap.put("description", product.getDescription()); + productMap.put("frequency", product.getFrequency()); + productMap.put("contact_phone", product.getContact_phone()); + productMap.put("product_contact", product.getProduct_contact()); + productMap.put("negotiateStatus", product.getNegotiateStatus()); + productMap.put("fullRegion", product.getFullRegion()); + productMap.put("createdAt", product.getCreatedAt()); + productMap.put("reservedCount", product.getReservedCount()); + productMap.put("reservedCountDisplay", product.getReservedCountDisplay()); + productMap.put("sales", product.getSales()); + productMap.put("totalStock", product.getTotalStock()); + productMap.put("originalTotalStock", product.getOriginalTotalStock()); + productMap.put("displaySpecification", product.getDisplaySpecification()); + productMap.put("displayYolk", product.getDisplayYolk()); + + // 计算销售负责人 + if (product.getContact_phone() != null && !product.getContact_phone().isEmpty()) { + try { + Personnel salesPersonnel = personnelMapper.findByPhoneNumber(product.getContact_phone()); + if (salesPersonnel != null) { + productMap.put("salesManager", salesPersonnel.getName()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + // 计算创建人 + if (product.getSellerId() != null && !product.getSellerId().isEmpty()) { + try { + Users seller = usersMapper.findByUserId(product.getSellerId()); + if (seller != null && seller.getPhoneNumber() != null) { + Personnel creatorPersonnel = personnelMapper.findByPhoneNumber(seller.getPhoneNumber()); + if (creatorPersonnel != null) { + productMap.put("creator", creatorPersonnel.getName()); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + processedProducts.add(productMap); + } + result.put("success", true); - result.put("products", products); + result.put("products", processedProducts); result.put("total", total); result.put("page", page); result.put("size", size); @@ -778,4 +846,20 @@ public class UserServiceImpl implements UserService { public List getApplyList(Integer status) { return customerApplyService.getApplyList(status); } + + @Override + public Map getPersonnelList() { + Map result = new HashMap<>(); + try { + // 从primary数据源的personnel表获取所有人员 + List personnelList = personnelMapper.findAll(); + result.put("success", true); + result.put("personnel", personnelList); + } catch (Exception e) { + e.printStackTrace(); + result.put("success", false); + result.put("message", "获取人员列表失败: " + e.getMessage()); + } + return result; + } } diff --git a/web/src/main/resources/mapper/CustomerApplyMapper.xml b/web/src/main/resources/mapper/CustomerApplyMapper.xml index bf173a1..8c69e08 100644 --- a/web/src/main/resources/mapper/CustomerApplyMapper.xml +++ b/web/src/main/resources/mapper/CustomerApplyMapper.xml @@ -6,8 +6,8 @@ - INSERT INTO customer_apply (user_id, sales_id, sales_name, status, apply_time, reason) - VALUES (#{user_id}, #{sales_id}, #{sales_name}, #{status}, #{apply_time}, #{reason}) + INSERT INTO customer_apply (user_id, sales_id, sales_name, original_manager_name, status, apply_time, reason) + VALUES (#{user_id}, #{sales_id}, #{sales_name}, #{original_manager_name}, #{status}, #{apply_time}, #{reason}) diff --git a/web/src/main/resources/mapper/PersonnelMapper.xml b/web/src/main/resources/mapper/PersonnelMapper.xml index 5422209..757997b 100644 --- a/web/src/main/resources/mapper/PersonnelMapper.xml +++ b/web/src/main/resources/mapper/PersonnelMapper.xml @@ -12,4 +12,8 @@ + + \ No newline at end of file diff --git a/web/src/main/resources/mapper/UserTraceMapper.xml b/web/src/main/resources/mapper/UserTraceMapper.xml index 30eb739..e84c916 100644 --- a/web/src/main/resources/mapper/UserTraceMapper.xml +++ b/web/src/main/resources/mapper/UserTraceMapper.xml @@ -10,4 +10,12 @@ WHERE ut.originalData LIKE CONCAT('%', #{productId}, '%') ORDER BY ut.operationTime DESC + + diff --git a/web/src/main/resources/mapper/UsersMapper.xml b/web/src/main/resources/mapper/UsersMapper.xml index 307213e..90be5d8 100644 --- a/web/src/main/resources/mapper/UsersMapper.xml +++ b/web/src/main/resources/mapper/UsersMapper.xml @@ -281,4 +281,8 @@ + + \ No newline at end of file diff --git a/web/src/main/resources/static/index.html b/web/src/main/resources/static/index.html index 66079c1..cdc7d50 100644 --- a/web/src/main/resources/static/index.html +++ b/web/src/main/resources/static/index.html @@ -421,13 +421,43 @@ } @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); } - to { + } + + @keyframes scaleIn { + 0% { + opacity: 0; + transform: scale(0.9); + } + 70% { opacity: 1; - transform: translate(-50%, -50%) scale(1); + transform: scale(1.02); + } + 100% { + opacity: 1; + transform: scale(1); } } @@ -571,12 +601,16 @@

客户管理系统

+ + +
+ + 0 +
+ + + +
@@ -653,6 +687,8 @@ + + 创建时间: @@ -694,7 +730,60 @@
- + 种类: + + 商品名称: + + 蛋黄: + + 销售负责人: + + 创建人: + + 搜索: + + + +
@@ -707,6 +796,8 @@ 库存 地区 创建时间 + 销售负责人 + 创建人 操作 @@ -745,6 +836,8 @@ + + 创建时间: @@ -794,6 +887,16 @@ 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 = []; @@ -833,7 +936,89 @@ userInfo = JSON.parse(savedUserInfo); displayUserInfo(); loadManagers(); + loadPersonnelData(); loadPersonalData(); + + // 检查申请状态 + var userRole = userInfo.loginInfo.projectName; + if (userRole === '管理员') { + checkApplyStatus(); + } + } + + 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() { @@ -856,6 +1041,7 @@ 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'; } @@ -868,6 +1054,9 @@ if (applyButton) { applyButton.style.display = isAdmin ? 'inline-block' : 'none'; } + if (employeeApplyButton) { + employeeApplyButton.style.display = isAdmin ? 'none' : 'inline-block'; + } } function switchTab(tabName, button) { @@ -1049,17 +1238,29 @@ if (currentTypeFilter) { var userType = user.type || ''; console.log('筛选类型:', currentTypeFilter, '用户类型:', userType); - // 如果筛选值是英文,需要转换为中文进行比较 - var typeMap = { - 'wholesale': '批发贸易类', - 'e-commerce': '电商平台类', - 'delivery_retail': '配送零售类', - 'defective_egg': '次品蛋专项类', - 'other': '其他类型' - }; - var filterValue = typeMap[currentTypeFilter] || currentTypeFilter; - if (userType !== filterValue) { - return false; + + // 特殊处理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; + } } } @@ -1781,8 +1982,8 @@ // 构建查询参数,获取所有数据 var params = { - page: 1, - size: 1000, // 假设最多1000条数据 + page: publicPage, + size: publicPageSize, userRole: userRole, userName: usersManagements.userName || '', managercompany: usersManagements.managercompany || '', @@ -1803,7 +2004,11 @@ allPublicData = data.users; } displayPublicData(data); - renderPublicPagination(data.page, data.pages, data.total); + // 确保传递正确的参数给分页函数 + var page = data.page || 1; + var pages = data.pages || 1; + var total = data.total || 0; + renderPublicPagination(page, pages, total); } }; xhr.send(); @@ -1953,6 +2158,8 @@ '' + (product.quantity || '-') + '' + '' + (product.fullRegion || product.region || '-') + '' + '' + formatDateTime(product.created_at) + '' + + '' + (product.salesManager || '-') + '' + + '' + (product.creator || '-') + '' + '' + ''; productsBody.innerHTML += row; @@ -1985,6 +2192,105 @@ xhr.send(); } + // 筛选货源 + function filterProducts() { + // 获取筛选值 + 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(); + } + + // 搜索货源 + function searchProducts() { + productFilters.search = document.getElementById('productSearch').value; + applyProductFilters(); + } + + // 重置货源筛选 + 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() { + if (allProducts.length === 0) { + // 如果还没有数据,先加载 + loadProducts(); + return; + } + + // 应用筛选 + var filteredProducts = allProducts.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; + }); + + // 显示筛选结果 + displayProducts(filteredProducts); + + // 重新渲染分页(筛选后的数据可能更少) + var totalPages = Math.ceil(filteredProducts.length / productsPageSize); + renderProductsPagination(1, totalPages, filteredProducts.length); + } + // 显示商品详情 function showProductDetail(product, traces) { // 对traces数据进行分组,按用户ID分组 @@ -2025,10 +2331,12 @@ 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%; @@ -2036,7 +2344,9 @@ max-height: 80%; display: flex; flex-direction: column; - box-shadow: 0 4px 12px rgba(0,0,0,0.15); + box-shadow: 0 8px 32px rgba(0,0,0,0.2); + animation: scaleIn 0.4s ease; + transform-origin: center; `; // 固定导航栏 @@ -2101,8 +2411,8 @@ - ${mergedTraces.map(trace => ` - + ${mergedTraces.map((trace, index) => ` + ${trace.nickName || '-'} ${trace.phoneNumber || '-'} @@ -2112,7 +2422,7 @@ ${trace.responseTime || '-'} ${trace.managerName || '-'} - ${!isAdmin ? `` : '-'} + ${!isAdmin ? `` : '-'} `).join('')} @@ -2137,10 +2447,6 @@ function loadApplyStatusForTraces(traces) { if (!traces || traces.length === 0) return; - // 获取所有客户ID - var userIds = traces.map(trace => trace.userId).filter(Boolean); - if (userIds.length === 0) return; - var url = '/KH/api/users/apply/list'; var xhr = new XMLHttpRequest(); @@ -2149,11 +2455,12 @@ 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) { - applyStatusMap[apply.user_id] = apply.status; + if (apply.user_id && apply.sales_id) { + var key = apply.user_id + '_' + apply.sales_id; + applyStatusMap[key] = apply.status; } }); @@ -2167,30 +2474,34 @@ var tbody = table.querySelector('tbody'); if (tbody) { var rows = tbody.querySelectorAll('tr'); - rows.forEach((row, index) => { - // 获取对应的trace - var trace = traces[index]; - if (trace && trace.userId) { - var status = applyStatusMap[trace.userId]; - var button = row.querySelector('button[onclick^="applyCustomer"]'); - if (button && status !== undefined) { - if (status === 0) { - // 申请中 - button.textContent = '申请中'; - button.disabled = true; - button.style.backgroundColor = '#faad14'; - } else if (status === 1) { - // 申请通过 - button.textContent = '申请通过'; - button.disabled = true; - button.style.backgroundColor = '#52c41a'; - } else if (status === 2) { - // 申请失败 - button.textContent = '申请失败'; - button.disabled = false; - button.style.backgroundColor = '#722ed1'; + 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'; + } + } } - } + }); } }); } @@ -2202,6 +2513,135 @@ 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 = ` + + 客户ID + 申请时间 + 状态 + 审批时间 + 审批人 + 备注 + + `; + 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 = ` + ${apply.user_id || '-'} + ${apply.apply_time ? new Date(apply.apply_time).toLocaleString() : '-'} + + ${statusText} + + ${apply.approve_time ? new Date(apply.approve_time).toLocaleString() : '-'} + ${apply.approve_by || '-'} + ${apply.reason || '-'} + `; + tbody.appendChild(row); + }); + table.appendChild(tbody); + + container.appendChild(table); + } + // 显示提示信息 function showAlert(message) { var alert = document.createElement('div'); @@ -2466,16 +2906,6 @@ // 淡入淡出动画 var style = document.createElement('style'); style.textContent = ` - @keyframes slideIn { - from { - transform: translateX(100%); - opacity: 0; - } - to { - transform: translateX(0); - opacity: 1; - } - } @keyframes fadeOut { from { opacity: 1; @@ -3013,7 +3443,7 @@ // 申请管理模态框HTML var applyModalHTML = `