commit
de0e52d1a5
44 changed files with 3842 additions and 0 deletions
@ -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 |
||||
@ -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" |
||||
@ -0,0 +1,8 @@ |
|||||
|
# 默认忽略的文件 |
||||
|
/shelf/ |
||||
|
/workspace.xml |
||||
|
# 基于编辑器的 HTTP 客户端请求 |
||||
|
/httpRequests/ |
||||
|
# Datasource local storage ignored files |
||||
|
/dataSources/ |
||||
|
/dataSources.local.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> |
||||
@ -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&useUnicode=true&characterEncoding=utf-8&useSSL=false&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> |
||||
@ -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> |
||||
@ -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> |
||||
@ -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> |
||||
@ -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> |
||||
Binary file not shown.
@ -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> |
||||
@ -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); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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"; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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; // 头像
|
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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 |
||||
|
|
||||
|
|
||||
@ -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> |
||||
@ -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> |
||||
@ -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> |
||||
@ -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> |
||||
File diff suppressed because it is too large
@ -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> |
||||
@ -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…
Reference in new issue