develop #2
@@ -8,6 +8,7 @@ const __filename = fileURLToPath(import.meta.url);
|
|||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
let backendProcess: ChildProcess | null = null;
|
let backendProcess: ChildProcess | null = null;
|
||||||
|
let gatewayProcess: ChildProcess | null = null;
|
||||||
let frontendProcess: ChildProcess | null = null;
|
let frontendProcess: ChildProcess | null = null;
|
||||||
let healthCheckInterval: NodeJS.Timeout | null = null;
|
let healthCheckInterval: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
@@ -118,6 +119,72 @@ async function globalSetup(config: FullConfig) {
|
|||||||
console.log('⏳ 等待后端服务就绪...');
|
console.log('⏳ 等待后端服务就绪...');
|
||||||
await waitForBackendReady();
|
await waitForBackendReady();
|
||||||
|
|
||||||
|
const gatewayDir = path.resolve(__dirname, '../../novalon-manage-api/manage-gateway');
|
||||||
|
const gatewayJarFile = path.join(gatewayDir, 'target/manage-gateway-1.0.0.jar');
|
||||||
|
|
||||||
|
let gatewayCommand: string;
|
||||||
|
let gatewayArgs: string[];
|
||||||
|
|
||||||
|
if (existsSync(gatewayJarFile)) {
|
||||||
|
console.log('🚪 使用JAR文件启动网关服务...');
|
||||||
|
console.log(` JAR文件: ${gatewayJarFile}`);
|
||||||
|
gatewayCommand = 'java';
|
||||||
|
gatewayArgs = [
|
||||||
|
'-jar',
|
||||||
|
gatewayJarFile,
|
||||||
|
'--spring.profiles.active=test',
|
||||||
|
'-Xms128m',
|
||||||
|
'-Xmx256m'
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
console.log('🚪 使用Maven启动网关服务...');
|
||||||
|
console.log(' 提示: 运行 "mvn clean package -DskipTests" 构建JAR文件以获得更快的启动速度');
|
||||||
|
gatewayCommand = 'mvn';
|
||||||
|
gatewayArgs = ['spring-boot:run', '-Dspring-boot.run.profiles=test'];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(` 目录: ${gatewayDir}`);
|
||||||
|
console.log(` 命令: ${gatewayCommand} ${gatewayArgs.join(' ')}`);
|
||||||
|
|
||||||
|
gatewayProcess = spawn(gatewayCommand, gatewayArgs, {
|
||||||
|
cwd: gatewayDir,
|
||||||
|
stdio: 'pipe',
|
||||||
|
shell: true,
|
||||||
|
detached: false,
|
||||||
|
env: { ...process.env, SPRING_PROFILES_ACTIVE: 'test' }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (gatewayProcess.stdout) {
|
||||||
|
gatewayProcess.stdout.on('data', (data) => {
|
||||||
|
const output = data.toString();
|
||||||
|
if (output.includes('Started GatewayApplication') || output.includes('Netty started on port')) {
|
||||||
|
console.log('✅ 网关服务启动成功');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gatewayProcess.stderr) {
|
||||||
|
gatewayProcess.stderr.on('data', (data) => {
|
||||||
|
const output = data.toString();
|
||||||
|
if (output.includes('ERROR') || output.includes('Exception')) {
|
||||||
|
console.error('❌ 网关服务启动错误:', output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
gatewayProcess.on('error', (error) => {
|
||||||
|
console.error('❌ 网关服务启动失败:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
gatewayProcess.on('exit', (code, signal) => {
|
||||||
|
if (code !== 0 && code !== null) {
|
||||||
|
console.error(`❌ 网关服务异常退出,退出码: ${code}, 信号: ${signal}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('⏳ 等待网关服务就绪...');
|
||||||
|
await waitForGatewayReady();
|
||||||
|
|
||||||
const frontendDir = path.resolve(__dirname, '..');
|
const frontendDir = path.resolve(__dirname, '..');
|
||||||
console.log('🌐 启动前端服务...');
|
console.log('🌐 启动前端服务...');
|
||||||
console.log(` 目录: ${frontendDir}`);
|
console.log(` 目录: ${frontendDir}`);
|
||||||
@@ -195,6 +262,32 @@ async function waitForBackendReady(): Promise<void> {
|
|||||||
throw new Error('❌ 后端服务启动超时');
|
throw new Error('❌ 后端服务启动超时');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function waitForGatewayReady(): Promise<void> {
|
||||||
|
const maxRetries = 60;
|
||||||
|
const retryInterval = 1000;
|
||||||
|
|
||||||
|
for (let i = 0; i < maxRetries; i++) {
|
||||||
|
try {
|
||||||
|
const response = await fetch('http://localhost:8080/actuator/health');
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.status === 'UP') {
|
||||||
|
console.log(`✅ 网关服务健康检查通过 (尝试 ${i + 1}/${maxRetries})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 服务还未就绪,继续等待
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < maxRetries - 1) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, retryInterval));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('❌ 网关服务启动超时');
|
||||||
|
}
|
||||||
|
|
||||||
async function waitForFrontendReady(): Promise<void> {
|
async function waitForFrontendReady(): Promise<void> {
|
||||||
const maxRetries = 60;
|
const maxRetries = 60;
|
||||||
const retryInterval = 1000;
|
const retryInterval = 1000;
|
||||||
@@ -222,8 +315,8 @@ async function waitForFrontendReady(): Promise<void> {
|
|||||||
|
|
||||||
async function cleanupTestData(): Promise<void> {
|
async function cleanupTestData(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// 登录获取token
|
// 登录获取token(通过网关)
|
||||||
const loginResponse = await fetch('http://localhost:8084/api/auth/login', {
|
const loginResponse = await fetch('http://localhost:8080/api/auth/login', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -243,7 +336,7 @@ async function cleanupTestData(): Promise<void> {
|
|||||||
const token = loginData.token;
|
const token = loginData.token;
|
||||||
|
|
||||||
// 获取所有用户
|
// 获取所有用户
|
||||||
const usersResponse = await fetch('http://localhost:8084/api/users', {
|
const usersResponse = await fetch('http://localhost:8080/api/users', {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
}
|
}
|
||||||
@@ -256,7 +349,7 @@ async function cleanupTestData(): Promise<void> {
|
|||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
if (user.id > 10) {
|
if (user.id > 10) {
|
||||||
try {
|
try {
|
||||||
await fetch(`http://localhost:8084/api/users/${user.id}`, {
|
await fetch(`http://localhost:8080/api/users/${user.id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
@@ -271,7 +364,7 @@ async function cleanupTestData(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有角色
|
// 获取所有角色
|
||||||
const rolesResponse = await fetch('http://localhost:8084/api/roles', {
|
const rolesResponse = await fetch('http://localhost:8080/api/roles', {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
}
|
}
|
||||||
@@ -284,7 +377,7 @@ async function cleanupTestData(): Promise<void> {
|
|||||||
for (const role of roles) {
|
for (const role of roles) {
|
||||||
if (role.id > 4) {
|
if (role.id > 4) {
|
||||||
try {
|
try {
|
||||||
await fetch(`http://localhost:8084/api/roles/${role.id}`, {
|
await fetch(`http://localhost:8080/api/roles/${role.id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
@@ -334,6 +427,30 @@ async function globalTeardown() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gatewayProcess) {
|
||||||
|
console.log('🛑 停止网关服务...');
|
||||||
|
gatewayProcess.kill('SIGTERM');
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
if (gatewayProcess) {
|
||||||
|
gatewayProcess.on('exit', () => {
|
||||||
|
console.log('✅ 网关服务已停止');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (gatewayProcess) {
|
||||||
|
gatewayProcess.kill('SIGKILL');
|
||||||
|
console.log('⚠️ 强制停止网关服务');
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (frontendProcess) {
|
if (frontendProcess) {
|
||||||
console.log('🛑 停止前端服务...');
|
console.log('🛑 停止前端服务...');
|
||||||
frontendProcess.kill('SIGTERM');
|
frontendProcess.kill('SIGTERM');
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default defineConfig({
|
|||||||
strictPort: true,
|
strictPort: true,
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://localhost:8084',
|
target: process.env.VITE_API_TARGET || 'http://localhost:8080',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false
|
secure: false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user