Browse Source

Initial commit

pull/1/head
Trae AI 2 months ago
commit
de0e52d1a5
  1. 34
      .gitignore
  2. 319
      init_deploy.sh
  3. 8
      web/.idea/.gitignore
  4. 27
      web/.idea/compiler.xml
  5. 31
      web/.idea/dataSources.xml
  6. 6
      web/.idea/encodings.xml
  7. 20
      web/.idea/jarRepositories.xml
  8. 19
      web/.idea/misc.xml
  9. 124
      web/.idea/uiDesigner.xml
  10. BIN
      web/.pom.xml.swp
  11. 164
      web/pom.xml
  12. 13
      web/src/main/java/com/example/web/ServletInitializer.java
  13. 19
      web/src/main/java/com/example/web/WebApplication.java
  14. 14
      web/src/main/java/com/example/web/annotation/DataSource.java
  15. 50
      web/src/main/java/com/example/web/aspect/DataSourceAspect.java
  16. 42
      web/src/main/java/com/example/web/config/DataSourceConfig.java
  17. 33
      web/src/main/java/com/example/web/config/DataSourceContextHolder.java
  18. 10
      web/src/main/java/com/example/web/config/DynamicDataSource.java
  19. 28
      web/src/main/java/com/example/web/config/SecurityConfig.java
  20. 22
      web/src/main/java/com/example/web/controller/LoginController.java
  21. 94
      web/src/main/java/com/example/web/controller/UserController.java
  22. 147
      web/src/main/java/com/example/web/entity/Contacts.java
  23. 88
      web/src/main/java/com/example/web/entity/Enterprise.java
  24. 51
      web/src/main/java/com/example/web/entity/Login.java
  25. 124
      web/src/main/java/com/example/web/entity/Managers.java
  26. 28
      web/src/main/java/com/example/web/entity/Personnel.java
  27. 233
      web/src/main/java/com/example/web/entity/Users.java
  28. 126
      web/src/main/java/com/example/web/entity/UsersManagements.java
  29. 9
      web/src/main/java/com/example/web/mapper/LoginMapper.java
  30. 9
      web/src/main/java/com/example/web/mapper/PersonnelMapper.java
  31. 14
      web/src/main/java/com/example/web/mapper/UsersManagementsMapper.java
  32. 60
      web/src/main/java/com/example/web/mapper/UsersMapper.java
  33. 13
      web/src/main/java/com/example/web/service/LoginService.java
  34. 17
      web/src/main/java/com/example/web/service/UserService.java
  35. 90
      web/src/main/java/com/example/web/service/impl/LoginServiceImpl.java
  36. 256
      web/src/main/java/com/example/web/service/impl/UserServiceImpl.java
  37. 48
      web/src/main/resources/application.yaml
  38. 7
      web/src/main/resources/mapper/LoginMapper.xml
  39. 7
      web/src/main/resources/mapper/PersonnelMapper.xml
  40. 10
      web/src/main/resources/mapper/UsersManagementsMapper.xml
  41. 193
      web/src/main/resources/mapper/UsersMapper.xml
  42. 1075
      web/src/main/resources/static/index.html
  43. 147
      web/src/main/resources/static/login.html
  44. 13
      web/src/test/java/com/example/WebApplicationTests.java

34
.gitignore

@ -0,0 +1,34 @@
# Maven
/target/
web/target/
/.m2/
# IDEs and editors
/.idea/
/*.iml
/.classpath
/.project
/.settings/
*.suo
*.ntvs*
*.njsproj
*.sln
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Environment variables
.env
.env.local
.env.production.local
.env.development.local
# Log files
logs
*.log

319
init_deploy.sh

@ -0,0 +1,319 @@
#!/bin/bash
# 初始化部署脚本 - 在云端服务器上生成部署文件并拉取代码
# 部署目录
deploy_dir="/opt/project_web"
mkdir -p "$deploy_dir"
cd "$deploy_dir"
echo "开始在云端服务器初始化部署环境..."
# 1. 创建Dockerfile
echo "创建Dockerfile..."
cat > Dockerfile << 'EOF'
# 使用官方Tomcat 10.1作为基础镜像,兼容Spring Boot 3.x和Java 17
FROM tomcat:10.1-jdk17-openjdk
# 维护者信息
LABEL maintainer="your-email@example.com"
# 删除Tomcat默认的ROOT应用
RUN rm -rf /usr/local/tomcat/webapps/ROOT
# 将构建好的WAR文件复制到Tomcat的webapps目录下,并命名为KH.war,与配置文件中的上下文路径一致
COPY web.war /usr/local/tomcat/webapps/KH.war
# 暴露Tomcat端口,与application.yaml中的端口一致
EXPOSE 8083
# 启动Tomcat服务
CMD ["catalina.sh", "run"]
EOF
# 2. 创建docker-compose.yml
echo "创建docker-compose.yml..."
cat > docker-compose.yml << 'EOF'
services:
tomcat-app:
image: web:latest
ports:
- "8083:8080"
environment:
- SPRING_DATASOURCE_PRIMARY_JDBC_URL=jdbc:mysql://1.95.162.61:3306/userlogin?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_PRIMARY_USERNAME=root
- SPRING_DATASOURCE_PRIMARY_PASSWORD=schl@2025
- SPRING_DATASOURCE_WECHAT_JDBC_URL=jdbc:mysql://1.95.162.61:3306/wechat_app?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_WECHAT_USERNAME=root
- SPRING_DATASOURCE_WECHAT_PASSWORD=schl@2025
- SERVER_SERVLET_CONTEXT_PATH=/KH
restart: always
container_name: followweb
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
EOF
# 3. 创建deploy.sh
echo "创建deploy.sh..."
cat > deploy.sh << 'EOF'
#!/bin/bash
# 修复后的部署脚本 - 解决Maven构建找不到pom.xml的问题
# 配置信息
GIT_REPO="http://8.137.125.67:4000/SwtTt29/web-follow.git"
BRANCH="KH"
PROJECT_NAME="web"
DOCKER_IMAGE="web"
CONTAINER_NAME="followweb"
PORT="8083"
# 颜色定义
GREEN="\033[0;32m"
RED="\033[0;31m"
YELLOW="\033[1;33m"
NC="\033[0m" # No Color
echo -e "${YELLOW}开始部署应用...${NC}"
# 1. 检查Git是否安装
if ! command -v git &> /dev/null; then
echo -e "${RED}错误: Git未安装,请先安装Git${NC}"
exit 1
fi
# 2. 检查Docker是否安装
if ! command -v docker &> /dev/null; then
echo -e "${RED}错误: Docker未安装,请先安装Docker${NC}"
exit 1
fi
# 3. 检查Docker Compose是否安装
if ! command -v docker-compose &> /dev/null; then
echo -e "${RED}错误: Docker Compose未安装,请先安装Docker Compose${NC}"
exit 1
fi
# 4. 拉取或更新代码
echo -e "${GREEN}1. 拉取/更新代码...${NC}"
if [ -d "$PROJECT_NAME" ]; then
cd "$PROJECT_NAME"
git pull origin "$BRANCH"
if [ $? -ne 0 ]; then
echo -e "${RED}错误: Git拉取失败${NC}"
exit 1
fi
else
git clone "$GIT_REPO" "$PROJECT_NAME"
if [ $? -ne 0 ]; then
echo -e "${RED}错误: Git克隆失败${NC}"
exit 1
fi
cd "$PROJECT_NAME"
fi
# 5. 查找pom.xml文件,确定正确的构建目录
echo -e "${GREEN}2. 查找pom.xml文件...${NC}"
pom_path=$(find . -name "pom.xml" -type f | head -1)
if [ -z "$pom_path" ]; then
echo -e "${RED}错误: 未找到pom.xml文件,请检查Git仓库结构${NC}"
exit 1
fi
# 获取pom.xml所在目录
maven_dir=$(dirname "$pom_path")
echo -e "${GREEN}3. 在目录 $maven_dir 中构建项目...${NC}"
# 6. 构建项目
cd "$maven_dir"
mvn clean package -DskipTests
if [ $? -ne 0 ]; then
echo -e "${RED}错误: Maven构建失败${NC}"
exit 1
fi
# 7. 查找生成的WAR文件(使用original版本,避免Spring Boot嵌入式Tomcat与外部Tomcat冲突)
war_path=$(find . -name "*.war.original" -type f | head -1)
# 如果没有找到original版本,使用普通WAR文件
if [ -z "$war_path" ]; then
war_path=$(find . -name "*.war" -type f | head -1)
fi
if [ -z "$war_path" ]; then
echo -e "${RED}错误: 未找到生成的WAR文件,请检查Maven构建结果${NC}"
exit 1
fi
# 8. 获取绝对路径的WAR文件路径
if [[ "$war_path" != /* ]]; then
war_path="$(pwd)/$war_path"
fi
# 9. 返回项目根目录(当前在maven_dir,需要返回到/opt/project_web目录)
cd /opt/project_web
# 9. 复制WAR文件到web子目录下,供Dockerfile使用
cp "$war_path" ./web/web.war
echo -e "${GREEN}4. 停止并移除旧容器...${NC}"
# 确保旧容器被完全移除,即使docker-compose down失败
old_container=$(docker ps -a -q -f name=followweb)
if [ ! -z "$old_container" ]; then
echo -e "${GREEN} 停止旧容器...${NC}"
docker stop "$old_container" > /dev/null 2>&1
echo -e "${GREEN} 移除旧容器...${NC}"
docker rm "$old_container" > /dev/null 2>&1
fi
# 使用docker-compose down确保所有相关资源都被清理
docker-compose down 2>/dev/null || true
# 10. 构建新的Docker镜像
echo -e "${GREEN}5. 构建Docker镜像...${NC}"
docker build -t web:latest ./web
if [ $? -ne 0 ]; then
echo -e "${RED}错误: Docker构建失败${NC}"
exit 1
fi
# 11. 启动新容器
echo -e "${GREEN}6. 启动新容器...${NC}"
docker-compose up -d
if [ $? -ne 0 ]; then
echo -e "${RED}错误: Docker容器启动失败${NC}"
exit 1
fi
# 12. 检查容器状态
echo -e "${GREEN}7. 检查容器状态...${NC}"
sleep 5 # 等待容器完全启动
docker ps -a | grep followweb
if [ $? -ne 0 ]; then
echo -e "${RED}错误: 容器未找到,请检查启动日志${NC}"
docker-compose logs
exit 1
fi
# 13. 查看容器日志
echo -e "${GREEN}8. 查看容器启动日志...${NC}"
docker logs followweb --tail 100
# 14. 检查应用健康状态
echo -e "${GREEN}9. 检查应用健康状态...${NC}"
sleep 10 # 等待应用完全启动
# 尝试访问应用的健康检查端点
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8083/KH)
if [ "$response" -eq 200 ] || [ "$response" -eq 302 ]; then
echo -e "${GREEN}应用健康检查通过,HTTP状态码: $response${NC}"
else
echo -e "${YELLOW}应用健康检查失败,HTTP状态码: $response${NC}"
echo -e "${YELLOW}尝试访问根路径...${NC}"
curl -s http://localhost:8083/KH || echo "无法访问应用根路径"
fi
# 15. 检查容器内部进程
echo -e "${GREEN}10. 检查容器内部进程...${NC}"
docker exec -it followweb ps aux | grep java
# 16. 检查Tomcat日志
echo -e "${GREEN}11. 检查Tomcat日志...${NC}"
docker exec -it followweb tail -n 100 /usr/local/tomcat/logs/catalina.out
# 17. 检查Spring Boot应用日志
echo -e "${GREEN}12. 检查Spring Boot应用日志...${NC}"
docker exec -it followweb find /usr/local/tomcat/webapps/KH -name "*.log" -type f | xargs -l1 echo "找到日志文件: {}"
# 18. 检查应用部署状态
echo -e "${GREEN}13. 检查应用部署状态...${NC}"
docker exec -it followweb ls -la /usr/local/tomcat/webapps/
echo -e "${GREEN}14. 检查应用目录结构...${NC}"
docker exec -it followweb ls -la /usr/local/tomcat/webapps/KH/
# 19. 检查Tomcat端口配置
echo -e "${GREEN}15. 检查Tomcat端口配置...${NC}"
docker exec -it followweb cat /usr/local/tomcat/conf/server.xml | grep -A 5 -B 5 "Connector"
# 20. 检查防火墙设置
echo -e "${GREEN}16. 检查防火墙设置...${NC}"
sudo firewall-cmd --list-ports || echo "无法检查防火墙设置"
# 12. 清理临时WAR文件
rm -f ./web/web.war
# 13. 设置日志自动清理任务
echo -e "${GREEN}7. 设置日志自动清理任务...${NC}"
# 创建日志清理脚本
cat > /opt/project_web/cleanup_logs.sh << 'CLEANUP_EOF'
#!/bin/bash
# 清理Docker容器日志
container_name="followweb"
# 检查容器是否存在
if docker ps -a --format '{{.Names}}' | grep -q "^$container_name$"; then
# 清理容器日志
docker logs $container_name > /dev/null 2>&1
echo "日志清理完成: $(date)"
else
echo "容器 $container_name 不存在,跳过日志清理"
fi
# 检查日志大小,超过50MB立即清理
log_size=$(docker inspect --format '{{.LogPath}}' $container_name 2>/dev/null)
if [ -n "$log_size" ] && [ -f "$log_size" ]; then
current_size=$(du -m "$log_size" 2>/dev/null | cut -f1)
if [ "$current_size" -gt 50 ]; then
echo "日志大小超过50MB ($current_size MB),立即清理"
docker logs $container_name > /dev/null 2>&1
echo "日志清理完成: $(date)"
fi
fi
CLEANUP_EOF
# 设置脚本执行权限
chmod +x /opt/project_web/cleanup_logs.sh
# 设置cron任务,每三天执行一次
(crontab -l 2>/dev/null | grep -v "cleanup_logs.sh"; echo "0 0 */3 * * /opt/project_web/cleanup_logs.sh >> /opt/project_web/cleanup.log 2>&1") | crontab -
if [ $? -eq 0 ]; then
echo -e "${GREEN}日志自动清理任务已设置,每三天执行一次${NC}"
else
echo -e "${YELLOW}警告: 无法设置cron任务,请手动添加${NC}"
echo -e "${YELLOW}手动添加命令: (crontab -l 2>/dev/null | grep -v \"cleanup_logs.sh\"; echo \"0 0 */3 * * /opt/project_web/cleanup_logs.sh >> /opt/project_web/cleanup.log 2>&1\") | crontab -${NC}"
fi
echo -e "${GREEN}部署完成!${NC}"
echo -e "${YELLOW}应用访问地址: http://8.137.125.67:${PORT}/KH${NC}"
echo -e "${YELLOW}容器名称: ${CONTAINER_NAME}${NC}"
echo -e "${YELLOW}查看日志命令: docker logs -f ${CONTAINER_NAME}${NC}"
echo -e "${YELLOW}日志清理脚本: /opt/project_web/cleanup_logs.sh${NC}"
echo -e "${YELLOW}日志清理日志: /opt/project_web/cleanup.log${NC}"
EOF
# 4. 设置脚本执行权限
echo "设置脚本执行权限..."
chmod +x deploy.sh
# 5. 拉取Git代码
echo "拉取Git代码..."
git clone http://8.137.125.67:4000/SwtTt29/web-follow.git web
# 6. 将Dockerfile复制到web目录
cp Dockerfile web/
echo "初始化完成!"
echo "部署文件已生成在: $deploy_dir"
echo "Git代码已拉取到: $deploy_dir/web"
echo "可以通过以下命令执行部署:"
echo " cd $deploy_dir"
echo " ./deploy.sh"

8
web/.idea/.gitignore

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

27
web/.idea/compiler.xml

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
</profile>
<profile name="Annotation profile for web" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/unknown/lombok-unknown.jar" />
</processorPath>
<module name="web" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="web" options="-parameters" />
</option>
</component>
</project>

31
web/.idea/dataSources.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="wechat_app@1.95.162.61" uuid="a88ad06e-9faf-4ec8-930d-e9088229eb52">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://1.95.162.61:3306/wechat_app?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;allowPublicKeyRetrieval=true</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="userlogin@1.95.162.61" uuid="f929f8ce-e18a-4e40-9a92-7bfb9e965a6c">
<driver-ref>mysql_aurora_aws</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>software.aws.rds.jdbc.mysql.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql:aws://1.95.162.61:3306/userlogin</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

6
web/.idea/encodings.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
</component>
</project>

20
web/.idea/jarRepositories.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

19
web/.idea/misc.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<list size="1">
<item index="0" class="java.lang.String" itemvalue="org.springframework.beans.factory.annotation.Autowired" />
</list>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="ms-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

124
web/.idea/uiDesigner.xml

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

BIN
web/.pom.xml.swp

Binary file not shown.

164
web/pom.xml

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>web</name>
<description>web</description>
<properties>
<java.version>17</java.version>
<lombok.version>1.18.30</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>me.paulschwarz</groupId>
<artifactId>spring-dotenv</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- 与Spring Boot 3.x兼容的版本 -->
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
<!-- Druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.20</version>
</dependency>
<!-- SpringDoc OpenAPI -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>
<!-- 配置处理器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- AOP 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Spring Security 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- .env 文件支持 -->
<dependency>
<groupId>me.paulschwarz</groupId>
<artifactId>spring-dotenv</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.4.10</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

13
web/src/main/java/com/example/web/ServletInitializer.java

@ -0,0 +1,13 @@
package com.example.web;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WebApplication.class);
}
}

19
web/src/main/java/com/example/web/WebApplication.java

@ -0,0 +1,19 @@
package com.example.web;
import me.paulschwarz.springdotenv.DotenvPropertySource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@MapperScan("com.example.web.mapper")
@EnableScheduling//定时任务
/*@PropertySource(value = "classpath:.env", factory = DotenvPropertySource.class)*/
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}

14
web/src/main/java/com/example/web/annotation/DataSource.java

@ -0,0 +1,14 @@
// DataSource.java
package com.example.web.annotation;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
// 数据源名称,对应配置中的"primary"和"wechat"
String value() default "primary";
}

50
web/src/main/java/com/example/web/aspect/DataSourceAspect.java

@ -0,0 +1,50 @@
package com.example.web.aspect;
import com.example.web.annotation.DataSource;
import com.example.web.config.DynamicDataSource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
@Order(1) // 设置Order为1,确保在事务切面之前执行
public class DataSourceAspect {
// 拦截所有标注了 @DataSource 注解的类或方法
@Pointcut("@annotation(com.example.web.annotation.DataSource) || @within(com.example.web.annotation.DataSource)")
public void dataSourcePointCut() {}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取目标方法和类上的 @DataSource 注解
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
DataSource methodAnnotation = method.getAnnotation(DataSource.class);
DataSource classAnnotation = AnnotationUtils.findAnnotation(joinPoint.getTarget().getClass(), DataSource.class);
// 方法注解优先于类注解
String dataSourceKey = methodAnnotation != null ? methodAnnotation.value() :
(classAnnotation != null ? classAnnotation.value() : "primary");
try {
// 切换数据源
com.example.web.config.DataSourceContextHolder.setDataSource(dataSourceKey);
// 执行目标方法
System.out.println("切换到数据源: " + dataSourceKey);
return joinPoint.proceed();
} finally {
// 清除数据源,避免线程池复用导致的问题
com.example.web.config.DataSourceContextHolder.clearDataSource();
}
}
}

42
web/src/main/java/com/example/web/config/DataSourceConfig.java

@ -0,0 +1,42 @@
package com.example.web.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DataSourceConfig {
// 主数据源(userlogin)
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
// 第二个数据源(wechat_app)
@Bean(name = "wechatDataSource")
@ConfigurationProperties(prefix = "spring.datasource.wechat")
public DataSource wechatDataSource() {
return DataSourceBuilder.create().build();
}
// 动态数据源配置
@Primary
@Bean(name = "dynamicDataSource")
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setDefaultTargetDataSource(primaryDataSource());
Map<Object, Object> dataSources = new HashMap<>();
dataSources.put("primary", primaryDataSource());
dataSources.put("wechat", wechatDataSource());
dynamicDataSource.setTargetDataSources(dataSources);
return dynamicDataSource;
}
}

33
web/src/main/java/com/example/web/config/DataSourceContextHolder.java

@ -0,0 +1,33 @@
package com.example.web.config;
import org.springframework.stereotype.Component;
/**
* 数据源上下文持有者
*/
@Component
public class DataSourceContextHolder {
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
/**
* 设置数据源
*/
public static void setDataSource(String dataSource) {
CONTEXT_HOLDER.set(dataSource);
}
/**
* 获取数据源
*/
public static String getDataSource() {
return CONTEXT_HOLDER.get();
}
/**
* 清除数据源
*/
public static void clearDataSource() {
CONTEXT_HOLDER.remove();
}
}

10
web/src/main/java/com/example/web/config/DynamicDataSource.java

@ -0,0 +1,10 @@
package com.example.web.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}

28
web/src/main/java/com/example/web/config/SecurityConfig.java

@ -0,0 +1,28 @@
package com.example.web.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.requestMatchers("/login.html", "/index.html", "/api/login", "/api/users/**").permitAll()
.requestMatchers("/static/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.disable()
.csrf()
.disable();
return http.build();
}
}

22
web/src/main/java/com/example/web/controller/LoginController.java

@ -0,0 +1,22 @@
package com.example.web.controller;
import com.example.web.entity.Login;
import com.example.web.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*")
public class LoginController {
@Autowired
private LoginService loginService;
@PostMapping("/login")
public Map<String, Object> login(@RequestBody Login login) {
return loginService.login(login);
}
}

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

@ -0,0 +1,94 @@
package com.example.web.controller;
import com.example.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public Map<String, Object> getUserList(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(required = false) String type,
@RequestParam(required = false) String followup,
@RequestParam String userRole,
@RequestParam(required = false) String userName,
@RequestParam(required = false) String managercompany,
@RequestParam(required = false) String managerdepartment,
@RequestParam(required = false) String organization,
@RequestParam(required = false) String role) {
Map<String, Object> params = new java.util.HashMap<>();
params.put("page", page);
params.put("size", size);
params.put("type", type);
params.put("followup", followup);
params.put("userRole", userRole);
params.put("userName", userName);
params.put("managercompany", managercompany);
params.put("managerdepartment", managerdepartment);
params.put("organization", organization);
params.put("role", role);
return userService.getUserList(params);
}
@GetMapping("/users/personal")
public Map<String, Object> getPersonalUsers(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam String userName) {
Map<String, Object> result = new java.util.HashMap<>();
result.put("users", userService.getPersonalUsers(page, size, userName));
return result;
}
@GetMapping("/users/public")
public Map<String, Object> getPublicUsers(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam String userRole,
@RequestParam(required = false) String userName,
@RequestParam(required = false) String managercompany,
@RequestParam(required = false) String managerdepartment,
@RequestParam(required = false) String organization,
@RequestParam(required = false) String role) {
Map<String, Object> params = new java.util.HashMap<>();
params.put("page", page);
params.put("size", size);
params.put("userRole", userRole);
params.put("userName", userName);
params.put("managercompany", managercompany);
params.put("managerdepartment", managerdepartment);
params.put("organization", organization);
params.put("role", role);
return userService.getPublicUserList(params);
}
@PostMapping("/users/followup")
public Map<String, Object> followup(@RequestBody Map<String, Object> params) {
return userService.followup(params);
}
@PostMapping("/users/claim")
public Map<String, Object> claim(@RequestBody Map<String, Object> params) {
return userService.claim(params);
}
@PostMapping("/users/return")
public Map<String, Object> returnCustomer(@RequestBody Map<String, Object> params) {
return userService.returnCustomer(params);
}
@PostMapping("/users/jianDaoYun")
public Map<String, Object> jianDaoYun(@RequestBody Map<String, Object> params) {
return userService.jianDaoYun(params);
}
}

147
web/src/main/java/com/example/web/entity/Contacts.java

@ -0,0 +1,147 @@
package com.example.web.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* @Description: 联系人实体类
*/
@Data
public class Contacts {
private String contact_id;//联系人id
private String id;//用户id
private String nickName;//联系人姓名
private String phoneNumber;//联系人电话
private String wechat;//联系人微信
private String account;//联系人账号
private String accountNumber;//联系人账号
private String bank;//联系人银行
private String address;//联系人地址
private String followup;//跟进信息
private String notice;//通知状态(new/old/banold)
private LocalDateTime created_at;//创建时间
private LocalDateTime updated_at;//更新时间
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
public LocalDateTime getUpdated_at() {
return updated_at;
}
public void setUpdated_at(LocalDateTime updated_at) {
this.updated_at = updated_at;
}
public Contacts() {
}
public Contacts(String contact_id, String id, String nickName, String phoneNumber, String wechat, String account, String accountNumber, String bank, String address, String followup) {
this.contact_id = contact_id;
this.id = id;
this.nickName = nickName;
this.phoneNumber = phoneNumber;
this.wechat = wechat;
this.account = account;
this.accountNumber = accountNumber;
this.bank = bank;
this.address = address;
this.followup = followup;
}
public String getContact_id() {
return contact_id;
}
public void setContact_id(String contact_id) {
this.contact_id = contact_id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getWechat() {
return wechat;
}
public void setWechat(String wechat) {
this.wechat = wechat;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public String getBank() {
return bank;
}
public void setBank(String bank) {
this.bank = bank;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getFollowup() {
return followup;
}
public void setFollowup(String followup) {
this.followup = followup;
}
public String getNotice() {
return notice;
}
public void setNotice(String notice) {
this.notice = notice;
}
}

88
web/src/main/java/com/example/web/entity/Enterprise.java

@ -0,0 +1,88 @@
package com.example.web.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Description: 企业实体类
*/
@Data
public class Enterprise {
private String id;//企业id
private String company;//企业名称
private String region;//地区
private String level;//企业等级
private String type;//企业类型
private String demand;//企业需求
private String spec;//规格
// 无参构造器
public Enterprise() {
}
public Enterprise(String id, String company, String region, String level, String type, String demand, String spec) {
this.id = id;
this.company = company;
this.region = region;
this.level = level;
this.type = type;
this.demand = demand;
this.spec = spec;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDemand() {
return demand;
}
public void setDemand(String demand) {
this.demand = demand;
}
public String getSpec() {
return spec;
}
public void setSpec(String spec) {
this.spec = spec;
}
}

51
web/src/main/java/com/example/web/entity/Login.java

@ -0,0 +1,51 @@
package com.example.web.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Description: 登录实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Login {
private String projectName;//职位名称
private String userName;//用户名
private String password;//密码
private Integer id;//用户id
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}

124
web/src/main/java/com/example/web/entity/Managers.java

@ -0,0 +1,124 @@
package com.example.web.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* @Description: 管理员实体类
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Managers {
private Integer manager_id;//管理员id
private String id;//企业id
private String managerId; // 负责人id
private String managercompany; // 负责公司
private String managerdepartment; // 负责部门
private String organization; // 负责小组
private String role; // 角色
private String root; // 权限
private LocalDateTime created_at; // 创建时间
private LocalDateTime updated_at; // 更新时间
private String userName;//负责人姓名
private String assistant;//协助人
public Integer getManager_id() {
return manager_id;
}
public void setManager_id(Integer manager_id) {
this.manager_id = manager_id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getManagerId() {
return managerId;
}
public void setManagerId(String managerId) {
this.managerId = managerId;
}
public String getManagercompany() {
return managercompany;
}
public void setManagercompany(String managercompany) {
this.managercompany = managercompany;
}
public String getManagerdepartment() {
return managerdepartment;
}
public void setManagerdepartment(String managerdepartment) {
this.managerdepartment = managerdepartment;
}
public String getOrganization() {
return organization;
}
public void setOrganization(String organization) {
this.organization = organization;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getRoot() {
return root;
}
public void setRoot(String root) {
this.root = root;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
public LocalDateTime getUpdated_at() {
return updated_at;
}
public void setUpdated_at(LocalDateTime updated_at) {
this.updated_at = updated_at;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAssistant() {
return assistant;
}
public void setAssistant(String assistant) {
this.assistant = assistant;
}
}

28
web/src/main/java/com/example/web/entity/Personnel.java

@ -0,0 +1,28 @@
package com.example.web.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Timestamp;
/**
* @Description: 员工信息实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Personnel {
private Integer id; // 员工ID
private String managerId; // 负责人ID
private String managercompany; // 负责公司
private String managerdepartment; // 负责部门
private String organization; // 负责小组
private String projectName; // 职位名称
private String alias; // 负责人别名
private String name; // 负责人名
private String phoneNumber; // 负责人电话
private Timestamp createdAt; // 创建时间
private Timestamp updatedAt; // 更新时间
private String avatarUrl; // 头像
}

233
web/src/main/java/com/example/web/entity/Users.java

@ -0,0 +1,233 @@
package com.example.web.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 用户实体类
*/
@Data
@NoArgsConstructor
public class Users {
private Integer id;//用户id
private String openid;//用户唯一标识
private String userId;//用户id
private String nickName;//用户昵称
private String avatarUrl;//用户头像
private String phoneNumber;//用户手机号
private String type;//用户类型
private Integer gender;//用户性别
private String country;//国家
private String province;//省份
private String city;//城市
private String language;//语言
private String session_key;//会话密钥
private LocalDateTime created_at;//创建时间
private LocalDateTime updated_at;//更新时间
private String company;//客户公司
private String region;//客户地区
private String level;//客户等级
private String demand;//客户需求
private String spec;//规格
private String followup;//跟进信息
private String notice;//通知状态(new/old/banold)
private String userlog;//用户操作日志
private Integer sync_statuss;//同步状态
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getSession_key() {
return session_key;
}
public void setSession_key(String session_key) {
this.session_key = session_key;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
public LocalDateTime getUpdated_at() {
return updated_at;
}
public void setUpdated_at(LocalDateTime updated_at) {
this.updated_at = updated_at;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getDemand() {
return demand;
}
public void setDemand(String demand) {
this.demand = demand;
}
public String getSpec() {
return spec;
}
public void setSpec(String spec) {
this.spec = spec;
}
public String getFollowup() {
return followup;
}
public void setFollowup(String followup) {
this.followup = followup;
}
public String getNotice() {
return notice;
}
public void setNotice(String notice) {
this.notice = notice;
}
public String getUserlog() {
return userlog;
}
public void setUserlog(String userlog) {
this.userlog = userlog;
}
public Integer getSync_statuss() {
return sync_statuss;
}
public void setSync_statuss(Integer sync_statuss) {
this.sync_statuss = sync_statuss;
}
}

126
web/src/main/java/com/example/web/entity/UsersManagements.java

@ -0,0 +1,126 @@
package com.example.web.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 负责人信息实体类
* 对应wechat_app数据源中的用户管理表
* 存储微信小程序用户的负责人信息
*/
@Data
@NoArgsConstructor
public class UsersManagements {
private Integer id; // 自增主键id
private String userId; // 用户id
private String managerId; // 负责人id
private String managercompany; // 负责公司
private String managerdepartment; // 负责部门
private String organization; // 负责小组
private String role; // 角色
private String root; // 权限
private LocalDateTime created_at; // 创建时间
private LocalDateTime updated_at; // 更新时间
private String userName;//负责人姓名
private String assistant;//协助人
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getManagerId() {
return managerId;
}
public void setManagerId(String managerId) {
this.managerId = managerId;
}
public String getManagercompany() {
return managercompany;
}
public void setManagercompany(String managercompany) {
this.managercompany = managercompany;
}
public String getManagerdepartment() {
return managerdepartment;
}
public void setManagerdepartment(String managerdepartment) {
this.managerdepartment = managerdepartment;
}
public String getOrganization() {
return organization;
}
public void setOrganization(String organization) {
this.organization = organization;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getRoot() {
return root;
}
public void setRoot(String root) {
this.root = root;
}
public LocalDateTime getCreated_at() {
return created_at;
}
public void setCreated_at(LocalDateTime created_at) {
this.created_at = created_at;
}
public LocalDateTime getUpdated_at() {
return updated_at;
}
public void setUpdated_at(LocalDateTime updated_at) {
this.updated_at = updated_at;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAssistant() {
return assistant;
}
public void setAssistant(String assistant) {
this.assistant = assistant;
}
}

9
web/src/main/java/com/example/web/mapper/LoginMapper.java

@ -0,0 +1,9 @@
package com.example.web.mapper;
import com.example.web.entity.Login;
import com.example.web.annotation.DataSource;
public interface LoginMapper {
@DataSource("primary")
Login findByUsernameAndPassword(Login login);
}

9
web/src/main/java/com/example/web/mapper/PersonnelMapper.java

@ -0,0 +1,9 @@
package com.example.web.mapper;
import com.example.web.entity.Personnel;
import com.example.web.annotation.DataSource;
public interface PersonnelMapper {
@DataSource("primary")
Personnel findByName(String name);
}

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

@ -0,0 +1,14 @@
package com.example.web.mapper;
import com.example.web.entity.UsersManagements;
import com.example.web.annotation.DataSource;
import java.util.List;
public interface UsersManagementsMapper {
@DataSource("wechat")
UsersManagements findByUserName(String userName);
@DataSource("wechat")
List<UsersManagements> findByUserNameList(String userName);
}

60
web/src/main/java/com/example/web/mapper/UsersMapper.java

@ -0,0 +1,60 @@
package com.example.web.mapper;
import com.example.web.entity.Users;
import com.example.web.annotation.DataSource;
import java.util.List;
import java.util.Map;
public interface UsersMapper {
@DataSource("wechat")
List<Users> findWithPagination(Map<String, Object> params);
@DataSource("wechat")
Integer count(Map<String, Object> params);
@DataSource("wechat")
List<Users> findByUserIds(Map<String, Object> params);
@DataSource("wechat")
Integer countByUserIds(Map<String, Object> params);
@DataSource("wechat")
List<Users> findAllWithPagination(Map<String, Object> params);
@DataSource("wechat")
Integer countAll(Map<String, Object> params);
@DataSource("wechat")
List<Users> findPublicWithPagination(Map<String, Object> params);
@DataSource("wechat")
Integer countPublic(Map<String, Object> params);
@DataSource("wechat")
List<Users> findPersonalWithPagination(Map<String, Object> params);
@DataSource("wechat")
Integer countPersonal(Map<String, Object> params);
@DataSource("wechat")
List<Users> findPublicAllWithPagination(Map<String, Object> params);
@DataSource("wechat")
Integer countPublicAll(Map<String, Object> params);
@DataSource("wechat")
int updateFollowup(Map<String, Object> params);
@DataSource("wechat")
int updateUsersManagements(Map<String, Object> params);
@DataSource("wechat")
int updateSyncStatus(Map<String, Object> params);
@DataSource("wechat")
int updateUserTypeAndClearFollowup(Map<String, Object> params);
@DataSource("wechat")
int clearUsersManagements(Map<String, Object> params);
}

13
web/src/main/java/com/example/web/service/LoginService.java

@ -0,0 +1,13 @@
package com.example.web.service;
import com.example.web.entity.Login;
import com.example.web.entity.Personnel;
import com.example.web.entity.UsersManagements;
import java.util.Map;
public interface LoginService {
Map<String, Object> login(Login login);
Personnel getPersonnelInfo(String name);
UsersManagements getUsersManagementsInfo(String userName);
}

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

@ -0,0 +1,17 @@
package com.example.web.service;
import com.example.web.entity.Users;
import java.util.List;
import java.util.Map;
public interface UserService {
Map<String, Object> getUserList(Map<String, Object> params);
Map<String, Object> getPublicUserList(Map<String, Object> params);
Map<String, Object> followup(Map<String, Object> params);
Map<String, Object> claim(Map<String, Object> params);
Map<String, Object> returnCustomer(Map<String, Object> params);
Map<String, Object> jianDaoYun(Map<String, Object> params);
List<Users> getPersonalUsers(int page, int size, String userName);
List<Users> getPublicUsers(int page, int size);
}

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

@ -0,0 +1,90 @@
package com.example.web.service.impl;
import com.example.web.entity.Login;
import com.example.web.entity.Personnel;
import com.example.web.entity.UsersManagements;
import com.example.web.mapper.LoginMapper;
import com.example.web.mapper.PersonnelMapper;
import com.example.web.mapper.UsersManagementsMapper;
import com.example.web.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class LoginServiceImpl implements LoginService {
@Autowired
private LoginMapper loginMapper;
@Autowired
private PersonnelMapper personnelMapper;
@Autowired
private UsersManagementsMapper usersManagementsMapper;
@Override
public Map<String, Object> login(Login login) {
Map<String, Object> result = new HashMap<>();
// 1. 验证登录信息
Login loginInfo = loginMapper.findByUsernameAndPassword(login);
if (loginInfo == null) {
result.put("success", false);
result.put("message", "用户名或密码错误");
return result;
}
// 2. 查询Personnel信息
Personnel personnel = personnelMapper.findByName(loginInfo.getUserName());
if (personnel == null) {
result.put("success", false);
result.put("message", "未找到员工信息");
return result;
}
// 3. 查询UsersManagements信息(容错处理)
UsersManagements usersManagements = null;
try {
// 使用findByUserNameList方法获取所有结果
List<UsersManagements> usersManagementsList = usersManagementsMapper.findByUserNameList(personnel.getName());
if (usersManagementsList != null && !usersManagementsList.isEmpty()) {
// 只取第一个结果
usersManagements = usersManagementsList.get(0);
}
} catch (Exception e) {
// 表不存在或其他错误,不影响登录
System.out.println("查询UsersManagements时发生错误: " + e.getMessage());
}
if (usersManagements == null) {
// 创建默认的用户管理信息
usersManagements = new UsersManagements();
usersManagements.setUserName(personnel.getName());
usersManagements.setRole(personnel.getProjectName());
usersManagements.setManagercompany(personnel.getManagercompany());
usersManagements.setManagerdepartment(personnel.getManagerdepartment());
usersManagements.setOrganization(personnel.getOrganization());
}
// 4. 构建返回结果
result.put("success", true);
result.put("loginInfo", loginInfo);
result.put("personnel", personnel);
result.put("usersManagements", usersManagements);
return result;
}
@Override
public Personnel getPersonnelInfo(String name) {
return personnelMapper.findByName(name);
}
@Override
public UsersManagements getUsersManagementsInfo(String userName) {
return usersManagementsMapper.findByUserName(userName);
}
}

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

@ -0,0 +1,256 @@
package com.example.web.service.impl;
import com.example.web.entity.Users;
import com.example.web.mapper.UsersMapper;
import com.example.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UsersMapper usersMapper;
@Override
public Map<String, Object> getUserList(Map<String, Object> requestParams) {
Map<String, Object> result = new HashMap<>();
Map<String, Object> params = new HashMap<>();
// 提取参数
int page = (int) requestParams.getOrDefault("page", 1);
int size = (int) requestParams.getOrDefault("size", 10);
String type = (String) requestParams.getOrDefault("type", "");
String followup = (String) requestParams.getOrDefault("followup", "");
String userRole = (String) requestParams.getOrDefault("userRole", "");
String userName = (String) requestParams.getOrDefault("userName", "");
String managercompany = (String) requestParams.getOrDefault("managercompany", "");
String managerdepartment = (String) requestParams.getOrDefault("managerdepartment", "");
String organization = (String) requestParams.getOrDefault("organization", "");
String role = (String) requestParams.getOrDefault("role", "");
// 计算偏移量
int offset = (page - 1) * size;
params.put("offset", offset);
params.put("limit", size);
// 设置认证参数过滤
params.put("userName", userName);
params.put("managercompany", managercompany);
params.put("managerdepartment", managerdepartment);
params.put("organization", organization);
params.put("role", role);
// 查询数据
List<Users> usersList;
int total;
// 管理员可以查看全部数据
if ("管理员".equals(userRole)) {
// 管理员查看所有客户
usersList = usersMapper.findAllWithPagination(params);
total = usersMapper.countAll(params);
} else {
// 普通用户查看数据
usersList = usersMapper.findByUserIds(params);
total = usersMapper.countByUserIds(params);
}
// 构建返回结果
result.put("users", usersList);
result.put("total", total);
result.put("page", page);
result.put("size", size);
result.put("pages", (total + size - 1) / size);
return result;
}
@Override
public Map<String, Object> getPublicUserList(Map<String, Object> requestParams) {
Map<String, Object> result = new HashMap<>();
Map<String, Object> params = new HashMap<>();
// 提取参数
int page = (int) requestParams.getOrDefault("page", 1);
int size = (int) requestParams.getOrDefault("size", 10);
String userRole = (String) requestParams.getOrDefault("userRole", "");
String userName = (String) requestParams.getOrDefault("userName", "");
String managercompany = (String) requestParams.getOrDefault("managercompany", "");
String managerdepartment = (String) requestParams.getOrDefault("managerdepartment", "");
String organization = (String) requestParams.getOrDefault("organization", "");
String role = (String) requestParams.getOrDefault("role", "");
// 计算偏移量
int offset = (page - 1) * size;
params.put("offset", offset);
params.put("limit", size);
// 设置认证参数过滤
params.put("userName", userName);
params.put("managercompany", managercompany);
params.put("managerdepartment", managerdepartment);
params.put("organization", organization);
params.put("role", role);
// 查询数据
List<Users> usersList;
int total;
// 管理员可以查看全部公海池数据
if ("管理员".equals(userRole)) {
usersList = usersMapper.findPublicAllWithPagination(params);
total = usersMapper.countPublicAll(params);
} else {
// 普通用户只能查看自己权限范围内的公海池数据
usersList = usersMapper.findPublicWithPagination(params);
total = usersMapper.countPublic(params);
}
// 构建返回结果
result.put("users", usersList);
result.put("total", total);
result.put("page", page);
result.put("size", size);
result.put("pages", (total + size - 1) / size);
return result;
}
@Override
public List<Users> getPersonalUsers(int page, int size, String userName) {
Map<String, Object> params = new HashMap<>();
int offset = (page - 1) * size;
params.put("offset", offset);
params.put("limit", size);
params.put("followup", userName); // 个人数据有负责人信息
return usersMapper.findWithPagination(params);
}
@Override
public List<Users> getPublicUsers(int page, int size) {
Map<String, Object> params = new HashMap<>();
int offset = (page - 1) * size;
params.put("offset", offset);
params.put("limit", size);
params.put("followup", ""); // 公海池数据没有负责人信息
return usersMapper.findWithPagination(params);
}
@Override
public Map<String, Object> followup(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
try {
String userId = (String) params.get("userId");
String followup = (String) params.get("followup");
if (userId == null || followup == null) {
result.put("success", false);
result.put("message", "缺少必要参数");
return result;
}
// 更新跟进信息
usersMapper.updateFollowup(params);
result.put("success", true);
result.put("message", "跟进成功");
} catch (Exception e) {
result.put("success", false);
result.put("message", "跟进失败: " + e.getMessage());
}
return result;
}
@Override
public Map<String, Object> claim(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
try {
String userId = (String) params.get("userId");
String userName = (String) params.get("userName");
if (userId == null || userName == null) {
result.put("success", false);
result.put("message", "缺少必要参数");
return result;
}
// 1. 更新 usermanagements 表,为客户添加认领人信息
usersMapper.updateUsersManagements(params);
// 2. 更新 users 表,设置 sync_status 为 0
usersMapper.updateSyncStatus(params);
result.put("success", true);
result.put("message", "认领成功");
} catch (Exception e) {
result.put("success", false);
result.put("message", "认领失败: " + e.getMessage());
}
return result;
}
@Override
public Map<String, Object> returnCustomer(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
try {
String userId = (String) params.get("userId");
String type = (String) params.get("type");
if (userId == null || type == null) {
result.put("success", false);
result.put("message", "缺少必要参数");
return result;
}
// 1. 更新 users 表,修改 type 字段并清空 followup 字段
usersMapper.updateUserTypeAndClearFollowup(params);
// 2. 清除 usermanagements 表中的记录
usersMapper.clearUsersManagements(params);
result.put("success", true);
result.put("message", "归还成功");
} catch (Exception e) {
result.put("success", false);
result.put("message", "归还失败: " + e.getMessage());
}
return result;
}
@Override
public Map<String, Object> jianDaoYun(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
try {
String userId = (String) params.get("userId");
if (userId == null) {
result.put("success", false);
result.put("message", "缺少必要参数");
return result;
}
// 更新 users 表,设置 sync_statuss 字段值为 0
usersMapper.updateSyncStatus(params);
result.put("success", true);
result.put("message", "操作成功");
} catch (Exception e) {
result.put("success", false);
result.put("message", "操作失败: " + e.getMessage());
}
return result;
}
}

48
web/src/main/resources/application.yaml

@ -0,0 +1,48 @@
spring:
datasource:
# userlogin数据库
primary:
jdbc-url: jdbc:mysql://1.95.162.61:3306/userlogin?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: schl@2025
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
max-lifetime: 1200000
idle-timeout: 600000
minimum-idle: 5
maximum-pool-size: 20
# wechat_app数据库
wechat:
jdbc-url: jdbc:mysql://1.95.162.61:3306/wechat_app?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: schl@2025
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
max-lifetime: 1200000
idle-timeout: 600000
minimum-idle: 5
maximum-pool-size: 20
server:
port: 8083
servlet:
context-path: /KH
# 在Tomcat中部署时,端口由Tomcat配置决定,这里不需要指定
# address属性在Tomcat部署中不生效,由容器控制
mybatis:
type-aliases-package: com.example.web.entity
mapper-locations: classpath:mapper/*.xml
configuration:
# 确保这些配置存在
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
call-setters-on-nulls: true
jdbc-type-for-null: null
logging:
level:
com.example.web.mapper: DEBUG
com.example.web.config: DEBUG
com.example.web.aspect: DEBUG

7
web/src/main/resources/mapper/LoginMapper.xml

@ -0,0 +1,7 @@
<?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.LoginMapper">
<select id="findByUsernameAndPassword" parameterType="com.example.web.entity.Login" resultType="com.example.web.entity.Login">
SELECT * FROM login WHERE userName = #{userName} AND password = #{password}
</select>
</mapper>

7
web/src/main/resources/mapper/PersonnelMapper.xml

@ -0,0 +1,7 @@
<?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.PersonnelMapper">
<select id="findByName" parameterType="String" resultType="com.example.web.entity.Personnel">
SELECT * FROM personnel WHERE name = #{name}
</select>
</mapper>

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

@ -0,0 +1,10 @@
<?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.UsersManagementsMapper">
<select id="findByUserName" parameterType="String" resultType="com.example.web.entity.UsersManagements">
SELECT * FROM usermanagements WHERE userName = #{userName}
</select>
<select id="findByUserNameList" parameterType="String" resultType="com.example.web.entity.UsersManagements">
SELECT * FROM usermanagements WHERE userName = #{userName}
</select>
</mapper>

193
web/src/main/resources/mapper/UsersMapper.xml

@ -0,0 +1,193 @@
<?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.UsersMapper">
<select id="findWithPagination" resultType="com.example.web.entity.Users">
SELECT u.* FROM users u
JOIN usermanagements um ON u.userId = um.userId
<where>
<if test="followup != null and followup != ''">
AND u.followup = #{followup}
</if>
<if test="type != null and type != ''">
AND u.type = #{type}
</if>
<if test="userName != null and userName != ''">
AND um.userName = #{userName}
</if>
<if test="managercompany != null and managercompany != ''">
AND um.managercompany = #{managercompany}
</if>
<if test="managerdepartment != null and managerdepartment != ''">
AND um.managerdepartment = #{managerdepartment}
</if>
<if test="organization != null and organization != ''">
AND um.organization = #{organization}
</if>
<if test="role != null and role != ''">
AND um.role = #{role}
</if>
AND (u.sync_statuss IS NULL OR u.sync_statuss NOT IN (0, 1))
</where>
LIMIT #{offset}, #{limit}
</select>
<select id="count" resultType="java.lang.Integer">
SELECT COUNT(*) FROM users u
JOIN usermanagements um ON u.userId = um.userId
<where>
<if test="followup != null and followup != ''">
AND u.followup = #{followup}
</if>
<if test="type != null and type != ''">
AND u.type = #{type}
</if>
<if test="userName != null and userName != ''">
AND um.userName = #{userName}
</if>
<if test="managercompany != null and managercompany != ''">
AND um.managercompany = #{managercompany}
</if>
<if test="managerdepartment != null and managerdepartment != ''">
AND um.managerdepartment = #{managerdepartment}
</if>
<if test="organization != null and organization != ''">
AND um.organization = #{organization}
</if>
<if test="role != null and role != ''">
AND um.role = #{role}
</if>
AND (u.sync_statuss IS NULL OR u.sync_statuss NOT IN (0, 1))
</where>
</select>
<select id="findByUserIds" resultType="com.example.web.entity.Users">
SELECT * FROM users
WHERE userId IN
(
SELECT userId FROM usermanagements
WHERE userName = #{userName}
AND managercompany = #{managercompany}
AND managerdepartment = #{managerdepartment}
AND organization = #{organization}
AND role = #{role}
)
AND (sync_statuss IS NULL OR sync_statuss NOT IN (0, 1))
LIMIT #{offset}, #{limit}
</select>
<select id="countByUserIds" resultType="java.lang.Integer">
SELECT COUNT(*) FROM users
WHERE userId IN
(
SELECT userId FROM usermanagements
WHERE userName = #{userName}
AND managercompany = #{managercompany}
AND managerdepartment = #{managerdepartment}
AND organization = #{organization}
AND role = #{role}
)
AND (sync_statuss IS NULL OR sync_statuss NOT IN (0, 1))
</select>
<select id="findPublicWithPagination" resultType="com.example.web.entity.Users">
SELECT u.* FROM users u
JOIN usermanagements um ON u.userId = um.userId
WHERE (um.managercompany IS NULL OR um.managercompany = '')
AND (um.managerdepartment IS NULL OR um.managerdepartment = '')
AND (um.organization IS NULL OR um.organization = '')
AND (um.role IS NULL OR um.role = '')
AND (um.userName IS NULL OR um.userName = '')
LIMIT #{offset}, #{limit}
</select>
<select id="countPublic" resultType="java.lang.Integer">
SELECT COUNT(*) FROM users u
JOIN usermanagements um ON u.userId = um.userId
WHERE (um.managercompany IS NULL OR um.managercompany = '')
AND (um.managerdepartment IS NULL OR um.managerdepartment = '')
AND (um.organization IS NULL OR um.organization = '')
AND (um.role IS NULL OR um.role = '')
AND (um.userName IS NULL OR um.userName = '')
</select>
<select id="findAllWithPagination" resultType="com.example.web.entity.Users">
SELECT * FROM users
LIMIT #{offset}, #{limit}
</select>
<select id="countAll" resultType="java.lang.Integer">
SELECT COUNT(*) FROM users
</select>
<select id="findPersonalWithPagination" resultType="com.example.web.entity.Users">
SELECT * FROM users
WHERE followup IS NOT NULL AND followup != ''
AND (sync_statuss IS NULL OR sync_statuss NOT IN (0, 1))
LIMIT #{offset}, #{limit}
</select>
<select id="countPersonal" resultType="java.lang.Integer">
SELECT COUNT(*) FROM users
WHERE followup IS NOT NULL AND followup != ''
AND (sync_statuss IS NULL OR sync_statuss NOT IN (0, 1))
</select>
<select id="findPublicAllWithPagination" resultType="com.example.web.entity.Users">
SELECT u.* FROM users u
JOIN usermanagements um ON u.userId = um.userId
WHERE (um.managercompany IS NULL OR um.managercompany = '')
AND (um.managerdepartment IS NULL OR um.managerdepartment = '')
AND (um.organization IS NULL OR um.organization = '')
AND (um.role IS NULL OR um.role = '')
AND (um.userName IS NULL OR um.userName = '')
LIMIT #{offset}, #{limit}
</select>
<select id="countPublicAll" resultType="java.lang.Integer">
SELECT COUNT(*) FROM users u
JOIN usermanagements um ON u.userId = um.userId
WHERE (um.managercompany IS NULL OR um.managercompany = '')
AND (um.managerdepartment IS NULL OR um.managerdepartment = '')
AND (um.organization IS NULL OR um.organization = '')
AND (um.role IS NULL OR um.role = '')
AND (um.userName IS NULL OR um.userName = '')
</select>
<update id="updateFollowup" parameterType="java.util.Map">
UPDATE users
SET followup = #{followup},
followup_at = NOW()
WHERE userId = #{userId}
</update>
<update id="updateUsersManagements" parameterType="java.util.Map">
INSERT INTO usermanagements (userId, userName, managercompany, managerdepartment, organization, role, managerId)
VALUES (#{userId}, #{userName}, #{managercompany}, #{managerdepartment}, #{organization}, #{role}, #{userId})
ON DUPLICATE KEY UPDATE
userName = #{userName},
managercompany = #{managercompany},
managerdepartment = #{managerdepartment},
organization = #{organization},
role = #{role},
managerId = #{userId}
</update>
<update id="updateSyncStatus" parameterType="java.util.Map">
UPDATE users
SET sync_statuss = 0
WHERE userId = #{userId}
</update>
<update id="updateUserTypeAndClearFollowup" parameterType="java.util.Map">
UPDATE users
SET type = #{type},
followup = NULL
WHERE userId = #{userId}
</update>
<update id="clearUsersManagements" parameterType="java.util.Map">
UPDATE usermanagements
SET managercompany = NULL,
managerdepartment = NULL,
organization = NULL,
role = NULL,
userName = NULL
WHERE userId = #{userId}
</update>
</mapper>

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

File diff suppressed because it is too large

147
web/src/main/resources/static/login.html

@ -0,0 +1,147 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.login-container {
background-color: white;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
}
h2 {
text-align: center;
margin-bottom: 30px;
color: #333;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
color: #666;
font-weight: bold;
}
input {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
input:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
button {
width: 100%;
padding: 12px;
background-color: #1890ff;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
margin-top: 20px;
}
button:hover {
background-color: #40a9ff;
}
.error-message {
color: #ff4d4f;
text-align: center;
margin-top: 15px;
}
</style>
</head>
<body>
<div class="login-container">
<h2>用户登录</h2>
<form id="loginForm">
<div class="form-group">
<label for="projectName">职位名称</label>
<input type="text" id="projectName" name="projectName" required>
</div>
<div class="form-group">
<label for="userName">用户名</label>
<input type="text" id="userName" name="userName" required>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">登录</button>
<div id="errorMessage" class="error-message"></div>
</form>
</div>
<script>
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const projectName = document.getElementById('projectName').value;
const userName = document.getElementById('userName').value;
const password = document.getElementById('password').value;
const errorMessage = document.getElementById('errorMessage');
errorMessage.textContent = '';
// 发送登录请求
fetch('http://localhost:8083/KH/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
projectName: projectName,
userName: userName,
password: password
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
// 登录成功,存储用户信息并跳转到主页面
localStorage.setItem('userInfo', JSON.stringify(data));
window.location.href = 'index.html';
} else {
errorMessage.textContent = data.message;
}
})
.catch(error => {
console.error('登录失败:', error);
errorMessage.textContent = '登录失败,请重试';
});
});
</script>
</body>
</html>

13
web/src/test/java/com/example/WebApplicationTests.java

@ -0,0 +1,13 @@
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class WebApplicationTests {
@Test
void contextLoads() {
}
}
Loading…
Cancel
Save