You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
3.8 KiB
145 lines
3.8 KiB
#!/usr/bin/env node
|
|
|
|
/**
|
|
* 开发环境启动脚本
|
|
* 同时启动前端和链下服务
|
|
*/
|
|
|
|
const { spawn } = require('child_process')
|
|
const path = require('path')
|
|
const fs = require('fs')
|
|
|
|
// 颜色输出
|
|
const colors = {
|
|
reset: '\x1b[0m',
|
|
bright: '\x1b[1m',
|
|
green: '\x1b[32m',
|
|
yellow: '\x1b[33m',
|
|
red: '\x1b[31m',
|
|
blue: '\x1b[34m',
|
|
cyan: '\x1b[36m'
|
|
}
|
|
|
|
function log(message, color = 'reset') {
|
|
console.log(`${colors[color]}${message}${colors.reset}`)
|
|
}
|
|
|
|
// 检查链下服务配置
|
|
function checkServicesConfig() {
|
|
const servicesEnvPath = path.join(__dirname, 'services', '.env')
|
|
const servicesEnvExamplePath = path.join(__dirname, 'services', '.env.example')
|
|
|
|
if (!fs.existsSync(servicesEnvPath)) {
|
|
log('⚠️ 未找到 services/.env 文件', 'yellow')
|
|
if (fs.existsSync(servicesEnvExamplePath)) {
|
|
log(' 请复制 services/.env.example 为 services/.env 并配置', 'yellow')
|
|
} else {
|
|
log(' 请创建 services/.env 文件,配置以下内容:', 'yellow')
|
|
log(' - RPC_URL: 区块链RPC地址', 'yellow')
|
|
log(' - PRIVATE_KEY: 管理员私钥', 'yellow')
|
|
log(' - CONTRACT_ADDRESS: CampusRatingV2合约地址', 'yellow')
|
|
log(' - MAIN_CONTRACT_ADDRESS: CampusRating主合约地址', 'yellow')
|
|
}
|
|
log(' 链下服务将不会启动,但前端仍可正常运行', 'yellow')
|
|
return false
|
|
}
|
|
|
|
// 检查必要的环境变量
|
|
const envContent = fs.readFileSync(servicesEnvPath, 'utf-8')
|
|
if (!envContent.includes('PRIVATE_KEY=') || envContent.match(/PRIVATE_KEY=\s*$/)) {
|
|
log('⚠️ services/.env 中未配置 PRIVATE_KEY', 'yellow')
|
|
log(' 链下服务将不会启动,但前端仍可正常运行', 'yellow')
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// 启动前端
|
|
function startFrontend() {
|
|
log('\n🚀 启动前端应用...', 'cyan')
|
|
const frontend = spawn('npm', ['run', 'dev'], {
|
|
cwd: path.join(__dirname, 'app'),
|
|
stdio: 'inherit',
|
|
shell: true
|
|
})
|
|
|
|
frontend.on('error', (error) => {
|
|
log(`❌ 前端启动失败: ${error.message}`, 'red')
|
|
})
|
|
|
|
return frontend
|
|
}
|
|
|
|
// 启动链下服务
|
|
function startServices() {
|
|
log('\n🔧 启动链下服务...', 'cyan')
|
|
const services = spawn('npm', ['run', 'dev:all'], {
|
|
cwd: path.join(__dirname, 'services'),
|
|
stdio: 'inherit',
|
|
shell: true
|
|
})
|
|
|
|
services.on('error', (error) => {
|
|
log(`⚠️ 链下服务启动失败: ${error.message}`, 'yellow')
|
|
log(' 前端仍可正常运行', 'yellow')
|
|
})
|
|
|
|
return services
|
|
}
|
|
|
|
// 主函数
|
|
function main() {
|
|
log('\n' + '='.repeat(50), 'bright')
|
|
log(' 校园评分系统 - 开发环境启动', 'bright')
|
|
log('='.repeat(50) + '\n', 'bright')
|
|
|
|
// 检查链下服务配置
|
|
const hasServicesConfig = checkServicesConfig()
|
|
|
|
// 启动前端(必须)
|
|
const frontend = startFrontend()
|
|
|
|
// 启动链下服务(可选)
|
|
let services = null
|
|
if (hasServicesConfig) {
|
|
services = startServices()
|
|
}
|
|
|
|
// 处理退出信号
|
|
process.on('SIGINT', () => {
|
|
log('\n\n🛑 正在关闭服务...', 'yellow')
|
|
if (frontend) frontend.kill()
|
|
if (services) services.kill()
|
|
process.exit(0)
|
|
})
|
|
|
|
process.on('SIGTERM', () => {
|
|
log('\n\n🛑 正在关闭服务...', 'yellow')
|
|
if (frontend) frontend.kill()
|
|
if (services) services.kill()
|
|
process.exit(0)
|
|
})
|
|
|
|
// 监听进程退出
|
|
frontend.on('exit', (code) => {
|
|
if (code !== 0 && code !== null) {
|
|
log(`\n❌ 前端进程异常退出,代码: ${code}`, 'red')
|
|
}
|
|
if (services) services.kill()
|
|
process.exit(code || 0)
|
|
})
|
|
|
|
if (services) {
|
|
services.on('exit', (code) => {
|
|
if (code !== 0 && code !== null) {
|
|
log(`\n⚠️ 链下服务进程异常退出,代码: ${code}`, 'yellow')
|
|
log(' 前端仍可正常运行', 'yellow')
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
main()
|
|
|