实现单用户多部门支持:创建中间表、实体类、Mapper和多部门操作方法,修改钉钉登录逻辑支持匹配多个部门

This commit is contained in:
Your Name 2026-01-02 14:29:48 +08:00
parent f36ec495a2
commit 9dc5b1d9ee
8 changed files with 561 additions and 77 deletions

View File

@ -0,0 +1,49 @@
package com.designhub.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 用户部门关联实体类
*/
@Data
@TableName("sys_user_department")
public class UserDepartment implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 部门ID
*/
private Long deptId;
/**
* 是否为主部门:0-否,1-是
*/
private Integer isPrimary;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,12 @@
package com.designhub.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.designhub.entity.UserDepartment;
import org.apache.ibatis.annotations.Mapper;
/**
* 用户部门关联Mapper接口
*/
@Mapper
public interface UserDepartmentMapper extends BaseMapper<UserDepartment> {
}

View File

@ -7,13 +7,16 @@ import com.designhub.dto.LoginDTO;
import com.designhub.dto.RegisterDTO;
import com.designhub.entity.Department;
import com.designhub.entity.User;
import com.designhub.entity.UserDepartment;
import com.designhub.exception.BusinessException;
import com.designhub.mapper.UserMapper;
import com.designhub.mapper.DepartmentMapper;
import com.designhub.mapper.UserDepartmentMapper;
import com.designhub.common.ResultCode;
import com.designhub.util.JwtUtil;
import com.designhub.vo.LoginVO;
import com.designhub.vo.UserInfoVO;
import com.designhub.vo.UserDepartmentVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@ -25,6 +28,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.HashMap;
import java.util.stream.Collectors;
/**
@ -37,6 +41,7 @@ public class UserService {
private final UserMapper userMapper;
private final DepartmentMapper departmentMapper;
private final UserDepartmentMapper userDepartmentMapper;
private final TeamScorePoolService teamScorePoolService;
private final RoleService roleService;
private final DingTalkService dingTalkService;
@ -487,73 +492,52 @@ public class UserService {
needUpdate = true;
}
// 3. 检查部门是否需要更新
// 3. 同步部门(支持多部门)
if (dingDepartments != null && !dingDepartments.isEmpty()) {
if (user.getDeptId() != null) {
// 用户已有部门:检查是否需要更新
Department currentDept = departmentMapper.selectById(user.getDeptId());
if (currentDept != null && StringUtils.hasText(currentDept.getDingDeptId())) {
// 检查用户是否还在原部门
boolean stillInDept = dingDepartments.stream()
.anyMatch(d -> currentDept.getDingDeptId().equals(d.get("dept_id").toString()));
// 匹配多个部门
List<Long> matchedDeptIds = matchSystemDepartments(dingDepartments);
if (!stillInDept) {
String newDeptNames = dingDepartments.stream()
.map(d -> String.valueOf(d.get("name")))
.collect(Collectors.joining(","));
log.warn("用户钉钉部门已变化: userId={}, 原部门={}, 钉钉部门={}",
user.getId(), currentDept.getDeptName(), newDeptNames);
if (!matchedDeptIds.isEmpty()) {
// 同步多个部门到sys_user_department表
// 第一个匹配的部门作为主部门
Long primaryDeptId = matchedDeptIds.get(0);
setUserDepartments(user.getId(), matchedDeptIds, primaryDeptId);
// 尝试重新匹配部门
Long newDeptId = matchSystemDepartment(dingDepartments);
if (newDeptId != null && !newDeptId.equals(user.getDeptId())) {
Department newDept = departmentMapper.selectById(newDeptId);
user.setDeptId(newDeptId);
user.setDeptName(newDept.getDeptName());
// 根据部门类型设置角色
user.setRoleIds("receiving".equals(newDept.getDeptType()) ? "5" : "6");
user.setStatus(1); // 启用用户
needUpdate = true;
log.info("自动同步到新部门: userId={}, 新部门={}",
user.getId(), newDept.getDeptName());
}
}
}
} else {
// 用户没有部门:尝试匹配部门
Long matchedDeptId = matchSystemDepartment(dingDepartments);
if (matchedDeptId != null) {
Department dept = departmentMapper.selectById(matchedDeptId);
user.setDeptId(matchedDeptId);
user.setDeptName(dept.getDeptName());
user.setRoleIds("receiving".equals(dept.getDeptType()) ? "5" : "6");
// 更新sys_user表的主部门(向后兼容)
Department primaryDept = departmentMapper.selectById(primaryDeptId);
if (primaryDept != null) {
user.setDeptId(primaryDeptId);
user.setDeptName(primaryDept.getDeptName());
// 根据主部门类型设置角色
user.setRoleIds("receiving".equals(primaryDept.getDeptType()) ? "5" : "6");
user.setStatus(1); // 启用用户
needUpdate = true;
log.info("已有用户匹配到部门: userId={}, deptId={}, deptName={}",
user.getId(), matchedDeptId, dept.getDeptName());
} else {
// 无法匹配,使用第一个可用部门作为默认值
List<Department> availableDepts = departmentMapper.selectList(
new LambdaQueryWrapper<Department>()
.eq(Department::getStatus, 1)
.eq(Department::getDeleted, 0)
.orderByAsc(Department::getSortOrder)
.orderByAsc(Department::getId)
);
log.info("同步用户多个部门: userId={}, 部门数量={}, 主部门={}",
user.getId(), matchedDeptIds.size(), primaryDept.getDeptName());
}
} else {
// 无法匹配,使用第一个可用部门作为默认值
List<Department> availableDepts = departmentMapper.selectList(
new LambdaQueryWrapper<Department>()
.eq(Department::getStatus, 1)
.eq(Department::getDeleted, 0)
.orderByAsc(Department::getSortOrder)
.orderByAsc(Department::getId)
);
if (!availableDepts.isEmpty()) {
Department defaultDept = availableDepts.get(0);
user.setDeptId(defaultDept.getId());
user.setDeptName(defaultDept.getDeptName());
user.setRoleIds("receiving".equals(defaultDept.getDeptType()) ? "5" : "6");
user.setStatus(1); // 启用用户
needUpdate = true;
log.warn("已有用户无法匹配,使用默认部门: userId={}, deptId={}, deptName={}, 钉钉部门: {}",
user.getId(), defaultDept.getId(), defaultDept.getDeptName(),
dingDepartments.stream()
.map(d -> String.valueOf(d.get("name")))
.collect(Collectors.joining(", ")));
}
if (!availableDepts.isEmpty()) {
Department defaultDept = availableDepts.get(0);
setUserDepartments(user.getId(), List.of(defaultDept.getId()), defaultDept.getId());
user.setDeptId(defaultDept.getId());
user.setDeptName(defaultDept.getDeptName());
user.setRoleIds("receiving".equals(defaultDept.getDeptType()) ? "5" : "6");
user.setStatus(1); // 启用用户
needUpdate = true;
log.warn("已有用户无法匹配,使用默认部门: userId={}, deptId={}, deptName={}, 钉钉部门: {}",
user.getId(), defaultDept.getId(), defaultDept.getDeptName(),
dingDepartments.stream()
.map(d -> String.valueOf(d.get("name")))
.collect(Collectors.joining(", ")));
}
}
}
@ -624,8 +608,8 @@ public class UserService {
// 需要用户手动选择部门类型和具体部门
log.info("钉钉用户首次登录,创建临时账号: email={}", email);
// 尝试匹配系统部门
Long matchedDeptId = matchSystemDepartment(dingDepartments);
// 尝试匹配系统部门(支持多部门)
List<Long> matchedDeptIds = matchSystemDepartments(dingDepartments);
String username = detailedInfo != null && detailedInfo.get("job_number") != null
? (String) detailedInfo.get("job_number") : "DT_" + unionId.substring(0, 8);
@ -642,15 +626,16 @@ public class UserService {
user.setStatus(1);
user.setDeleted(0);
if (matchedDeptId != null) {
// 自动匹配到部门
Department dept = departmentMapper.selectById(matchedDeptId);
user.setDeptId(matchedDeptId);
user.setDeptName(dept.getDeptName());
// 根据部门类型设置默认角色
user.setRoleIds("receiving".equals(dept.getDeptType()) ? "5" : "6");
log.info("自动匹配到系统部门: deptId={}, deptName={}, type={}",
matchedDeptId, dept.getDeptName(), dept.getDeptType());
if (!matchedDeptIds.isEmpty()) {
// 自动匹配到多个部门,第一个作为主部门
Long primaryDeptId = matchedDeptIds.get(0);
Department primaryDept = departmentMapper.selectById(primaryDeptId);
user.setDeptId(primaryDeptId);
user.setDeptName(primaryDept.getDeptName());
// 根据主部门类型设置默认角色
user.setRoleIds("receiving".equals(primaryDept.getDeptType()) ? "5" : "6");
log.info("自动匹配到系统部门(多部门): userId={}, 部门数量={}, 主部门={}",
username, matchedDeptIds.size(), primaryDept.getDeptName());
} else {
// 无法自动匹配,使用第一个可用部门作为默认值
List<Department> availableDepts = departmentMapper.selectList(
@ -667,6 +652,7 @@ public class UserService {
user.setDeptId(defaultDept.getId());
user.setDeptName(defaultDept.getDeptName());
user.setRoleIds("receiving".equals(defaultDept.getDeptType()) ? "5" : "6");
matchedDeptIds = List.of(defaultDept.getId());
log.warn("无法自动匹配系统部门,使用默认部门: deptId={}, deptName={}, 钉钉部门: {}",
defaultDept.getId(), defaultDept.getDeptName(),
dingDepartments.stream()
@ -686,6 +672,12 @@ public class UserService {
}
userMapper.insert(user);
// 同步多个部门到sys_user_department表
if (!matchedDeptIds.isEmpty()) {
Long primaryDeptId = matchedDeptIds.get(0);
setUserDepartments(user.getId(), matchedDeptIds, primaryDeptId);
}
log.info("钉钉用户创建成功: userId={}, username={}, needSelectDept={}",
user.getId(), user.getUsername(), matchedDeptId == null);
@ -861,6 +853,43 @@ public class UserService {
log.warn("检查部门负责人状态失败: userId={}, error={}", user.getId(), e.getMessage());
}
// 获取用户的所有部门列表
List<UserDepartmentVO> departments = List.of();
try {
List<UserDepartment> userDepts = userDepartmentMapper.selectList(
new LambdaQueryWrapper<UserDepartment>()
.eq(UserDepartment::getUserId, user.getId())
);
if (!userDepts.isEmpty()) {
List<Long> deptIds = userDepts.stream()
.map(UserDepartment::getDeptId)
.collect(Collectors.toList());
List<Department> depts = departmentMapper.selectBatchIds(deptIds);
// 构建部门VO列表,保持isPrimary顺序
Map<Long, Department> deptMap = depts.stream()
.collect(Collectors.toMap(Department::getId, d -> d));
departments = userDepts.stream()
.map(ud -> {
Department dept = deptMap.get(ud.getDeptId());
if (dept != null) {
return UserDepartmentVO.builder()
.deptId(dept.getId())
.deptName(dept.getDeptName())
.isPrimary(ud.getIsPrimary())
.build();
}
return null;
})
.filter(d -> d != null)
.collect(Collectors.toList());
}
} catch (Exception e) {
log.warn("获取用户部门列表失败: userId={}, error={}", user.getId(), e.getMessage());
}
UserInfoVO userInfoVO = UserInfoVO.builder()
.id(user.getId())
.username(user.getUsername())
@ -870,6 +899,7 @@ public class UserService {
.avatar(user.getAvatar())
.deptId(user.getDeptId())
.deptName(user.getDeptName())
.departments(departments)
.roleIds(user.getRoleIds())
.roles(roleCodes)
.status(user.getStatus())
@ -918,4 +948,217 @@ public class UserService {
.roleIds(user.getRoleIds())
.build();
}
// ==================== 多部门支持方法 ====================
/**
* 获取用户的所有部门ID列表
*/
public List<Long> getUserDepartmentIds(Long userId) {
List<UserDepartment> userDepts = userDepartmentMapper.selectList(
new LambdaQueryWrapper<UserDepartment>()
.eq(UserDepartment::getUserId, userId)
);
return userDepts.stream()
.map(UserDepartment::getDeptId)
.collect(Collectors.toList());
}
/**
* 获取用户的所有部门信息
*/
public List<Department> getUserDepartments(Long userId) {
List<Long> deptIds = getUserDepartmentIds(userId);
if (deptIds.isEmpty()) {
return List.of();
}
return departmentMapper.selectBatchIds(deptIds);
}
/**
* 添加用户到部门(如果不存在则添加)
*/
@Transactional(rollbackFor = Exception.class)
public void addUserToDepartment(Long userId, Long deptId, boolean isPrimary) {
// 检查是否已存在
UserDepartment exist = userDepartmentMapper.selectOne(
new LambdaQueryWrapper<UserDepartment>()
.eq(UserDepartment::getUserId, userId)
.eq(UserDepartment::getDeptId, deptId)
);
if (exist == null) {
UserDepartment userDept = new UserDepartment();
userDept.setUserId(userId);
userDept.setDeptId(deptId);
userDept.setIsPrimary(isPrimary ? 1 : 0);
userDepartmentMapper.insert(userDept);
log.info("添加用户到部门: userId={}, deptId={}, isPrimary={}", userId, deptId, isPrimary);
} else if (isPrimary && exist.getIsPrimary() == 0) {
// 更新为主部门
exist.setIsPrimary(1);
userDepartmentMapper.updateById(exist);
log.info("设置为主部门: userId={}, deptId={}", userId, deptId);
}
// 如果设置为主部门,需要更新sys_user表的dept_id
if (isPrimary) {
Department dept = departmentMapper.selectById(deptId);
if (dept != null) {
User user = userMapper.selectById(userId);
if (user != null) {
user.setDeptId(deptId);
user.setDeptName(dept.getDeptName());
userMapper.updateById(user);
}
}
// 将其他部门设置为非主部门
userDepartmentMapper.update(null,
new LambdaUpdateWrapper<UserDepartment>()
.eq(UserDepartment::getUserId, userId)
.ne(UserDepartment::getDeptId, deptId)
.set(UserDepartment::getIsPrimary, 0)
);
}
}
/**
* 从部门中移除用户
*/
@Transactional(rollbackFor = Exception.class)
public void removeUserFromDepartment(Long userId, Long deptId) {
// 检查是否为主部门
UserDepartment userDept = userDepartmentMapper.selectOne(
new LambdaQueryWrapper<UserDepartment>()
.eq(UserDepartment::getUserId, userId)
.eq(UserDepartment::getDeptId, deptId)
);
if (userDept != null && userDept.getIsPrimary() == 1) {
// 如果是主部门,需要设置另一个部门为主部门,或清空主部门
List<UserDepartment> otherDepts = userDepartmentMapper.selectList(
new LambdaQueryWrapper<UserDepartment>()
.eq(UserDepartment::getUserId, userId)
.ne(UserDepartment::getDeptId, deptId)
.last("LIMIT 1")
);
if (!otherDepts.isEmpty()) {
// 设置第一个其他部门为主部门
UserDepartment newPrimary = otherDepts.get(0);
newPrimary.setIsPrimary(1);
userDepartmentMapper.updateById(newPrimary);
Department newDept = departmentMapper.selectById(newPrimary.getDeptId());
if (newDept != null) {
User user = userMapper.selectById(userId);
if (user != null) {
user.setDeptId(newDept.getId());
user.setDeptName(newDept.getDeptName());
userMapper.updateById(user);
}
}
} else {
// 没有其他部门,清空主部门
User user = userMapper.selectById(userId);
if (user != null) {
user.setDeptId(null);
user.setDeptName(null);
userMapper.updateById(user);
}
}
}
// 删除关联
userDepartmentMapper.delete(
new LambdaQueryWrapper<UserDepartment>()
.eq(UserDepartment::getUserId, userId)
.eq(UserDepartment::getDeptId, deptId)
);
log.info("从部门移除用户: userId={}, deptId={}", userId, deptId);
}
/**
* 设置用户的部门列表(替换现有部门)
*/
@Transactional(rollbackFor = Exception.class)
public void setUserDepartments(Long userId, List<Long> deptIds, Long primaryDeptId) {
// 删除所有现有关联
userDepartmentMapper.delete(
new LambdaQueryWrapper<UserDepartment>()
.eq(UserDepartment::getUserId, userId)
);
// 添加新关联
if (deptIds != null && !deptIds.isEmpty()) {
for (Long deptId : deptIds) {
boolean isPrimary = deptId.equals(primaryDeptId);
addUserToDepartment(userId, deptId, isPrimary);
}
} else {
// 清空部门
User user = userMapper.selectById(userId);
if (user != null) {
user.setDeptId(null);
user.setDeptName(null);
userMapper.updateById(user);
}
}
}
/**
* 匹配多个系统部门(根据钉钉部门列表)
*/
private List<Long> matchSystemDepartments(List<Map<String, Object>> dingDepartments) {
if (dingDepartments == null || dingDepartments.isEmpty()) {
return List.of();
}
// 获取所有系统部门
List<Department> systemDepts = departmentMapper.selectList(
new LambdaQueryWrapper<Department>()
.eq(Department::getStatus, 1)
.eq(Department::getDeleted, 0)
);
List<Long> matchedDeptIds = new ArrayList<>();
for (Map<String, Object> dingDept : dingDepartments) {
String dingDeptName = (String) dingDept.get("name");
Object dingDeptIdObj = dingDept.get("dept_id");
String dingDeptId = dingDeptIdObj != null ? dingDeptIdObj.toString() : null;
Department matched = null;
// 1. 优先通过钉钉部门ID精确匹配
if (dingDeptId != null) {
matched = systemDepts.stream()
.filter(d -> dingDeptId.equals(d.getDingDeptId()))
.findFirst()
.orElse(null);
if (matched != null) {
log.info("通过钉钉部门ID精确匹配: {} -> {}", dingDeptId, matched.getDeptName());
}
}
// 2. 通过部门名称模糊匹配
if (matched == null && dingDeptName != null) {
matched = systemDepts.stream()
.filter(d -> d.getDeptName().contains(dingDeptName) ||
dingDeptName.contains(d.getDeptName()))
.findFirst()
.orElse(null);
if (matched != null) {
log.info("通过部门名称模糊匹配: {} -> {}", dingDeptName, matched.getDeptName());
}
}
if (matched != null && !matchedDeptIds.contains(matched.getId())) {
matchedDeptIds.add(matched.getId());
}
}
return matchedDeptIds;
}
}

View File

@ -0,0 +1,26 @@
package com.designhub.vo;
import lombok.Data;
import lombok.Builder;
/**
* 用户部门信息VO
*/
@Data
@Builder
public class UserDepartmentVO {
/**
* 部门ID
*/
private Long deptId;
/**
* 部门名称
*/
private String deptName;
/**
* 是否为主部门:0-否,1-是
*/
private Integer isPrimary;
}

View File

@ -42,15 +42,20 @@ public class UserInfoVO {
private String avatar;
/**
* 部门ID
* 部门ID(主部门,向后兼容)
*/
private Long deptId;
/**
* 部门名称
* 部门名称(主部门,向后兼容)
*/
private String deptName;
/**
* 用户的所有部门列表(多部门支持)
*/
private List<UserDepartmentVO> departments;
/**
* 角色ID列表(逗号分隔)
*/

View File

@ -0,0 +1,25 @@
-- 用户部门关联表(支持多部门)
-- 创建时间: 2026-01-02
-- 说明: 支持单用户属于多个部门
CREATE TABLE IF NOT EXISTS `sys_user_department` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` BIGINT NOT NULL COMMENT '用户ID',
`dept_id` BIGINT NOT NULL COMMENT '部门ID',
`is_primary` TINYINT DEFAULT 0 COMMENT '是否为主部门:0-否,1-是',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_dept` (`user_id`, `dept_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_dept_id` (`dept_id`),
CONSTRAINT `fk_user_dept_user` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_user_dept_dept` FOREIGN KEY (`dept_id`) REFERENCES `sys_dept` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户部门关联表';
-- 数据迁移:将现有sys_user表中的dept_id迁移到sys_user_department表
INSERT INTO `sys_user_department` (`user_id`, `dept_id`, `is_primary`)
SELECT `id`, `dept_id`, 1
FROM `sys_user`
WHERE `dept_id` IS NOT NULL AND `dept_id` > 0
ON DUPLICATE KEY UPDATE `is_primary` = 1;

89
deploy_from_git.sh Executable file
View File

@ -0,0 +1,89 @@
#!/bin/bash
###############################################################################
# 从Git拉取代码并部署到服务器
# 服务器: 45.192.99.48
###############################################################################
SERVER_IP="45.192.99.48"
SERVER_USER="root"
SERVER_PASSWORD="1blZllMIp7"
APP_DIR="/opt/designhub"
GIT_REPO="http://chenpei:jsjj654321@git.1080p.hk/chenpei/qiangdanxitong.git"
# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m'
echo "========================================"
echo -e "${GREEN}从Git拉取代码并部署${NC}"
echo "========================================"
echo ""
echo "服务器: ${SERVER_IP}"
echo "Git仓库: ${GIT_REPO}"
echo ""
# 检查sshpass
if ! command -v sshpass &> /dev/null; then
echo "正在安装sshpass..."
if [[ "$OSTYPE" == "darwin"* ]]; then
brew install hudochenkov/sshpass/sshpass 2>/dev/null || {
echo -e "${RED}请先安装sshpass: brew install hudochenkov/sshpass/sshpass${NC}"
exit 1
}
fi
fi
# 在服务器上执行部署
sshpass -p "${SERVER_PASSWORD}" ssh -o StrictHostKeyChecking=no ${SERVER_USER}@${SERVER_IP} << ENDSSH
set -e
echo -e "${BLUE}[1/6] 检查Git仓库...${NC}"
cd ${APP_DIR}
if [ ! -d ".git" ]; then
echo "初始化Git仓库..."
# 先暂存现有文件
git init
git remote add origin ${GIT_REPO} 2>/dev/null || git remote set-url origin ${GIT_REPO}
# 添加现有文件到Git
git add -A 2>/dev/null || true
git commit -m "Backup existing files" 2>/dev/null || true
# 拉取最新代码(允许合并)
git pull origin main --allow-unrelated-histories || git fetch origin main:main && git checkout main
else
echo "拉取最新代码..."
git fetch origin
git reset --hard origin/main
fi
echo -e "${BLUE}[2/6] 备份当前JAR文件...${NC}"
if [ -f "${APP_DIR}/designhub.jar" ]; then
cp ${APP_DIR}/designhub.jar ${APP_DIR}/designhub.jar.backup.\$(date +%Y%m%d_%H%M%S) || true
fi
echo -e "${BLUE}[3/6] 构建后端...${NC}"
cd ${APP_DIR}/backend
mvn clean package -DskipTests
echo -e "${BLUE}[4/6] 复制JAR文件...${NC}"
cp target/designhub-backend-1.0.0.jar ${APP_DIR}/designhub.jar
echo -e "${BLUE}[5/6] 重启服务...${NC}"
systemctl restart designhub
echo ""
echo -e "${GREEN}等待服务启动...${NC}"
sleep 5
echo ""
echo -e "${BLUE}[6/6] 检查服务状态...${NC}"
systemctl status designhub --no-pager | head -15
echo ""
echo -e "${GREEN}✅ 部署完成!${NC}"
ENDSSH
echo ""
echo -e "${GREEN}✅ 部署脚本执行完成!${NC}"

35
服务器部署命令.txt Normal file
View File

@ -0,0 +1,35 @@
# 在服务器上执行以下命令部署最新代码
# 1. 连接到服务器
ssh root@45.192.99.48
# 密码: 1blZllMIp7
# 2. 进入项目目录
cd /opt/designhub
# 3. 如果还没有Git仓库,先初始化
if [ ! -d ".git" ]; then
git init
git remote add origin http://chenpei:jsjj654321@git.1080p.hk/chenpei/qiangdanxitong.git
git fetch origin
git checkout -b main origin/main
else
# 拉取最新代码
git pull origin main
fi
# 4. 构建后端
cd backend
mvn clean package -DskipTests
# 5. 复制JAR文件
cp target/designhub-backend-1.0.0.jar /opt/designhub/designhub.jar
# 6. 重启服务
systemctl restart designhub
# 7. 检查服务状态
systemctl status designhub
# 8. 查看日志(可选)
tail -f /opt/designhub/logs/application.log