const { Client } = require('ssh2'); const fs = require('fs'); const path = require('path'); const config = { host: 'hs.yifenbao.cn', port: 22, username: 'root', password: 'Torch1112' }; const conn = new Client(); const localH5Dir = path.join(__dirname, 'dist', 'build', 'h5'); const execCmd = (cmd) => { return new Promise((resolve, reject) => { conn.exec(cmd, (err, stream) => { if (err) { reject(err); return; } let output = ''; stream.stdout.on('data', (data) => { output += data.toString(); }); stream.stderr.on('data', (data) => { output += data.toString(); }); stream.on('close', (code) => { resolve({ code, output }); }); }); }); }; const sftpPut = (localPath, remotePath) => { return new Promise((resolve, reject) => { conn.sftp((err, sftp) => { if (err) { reject(err); return; } sftp.fastPut(localPath, remotePath, (err) => { if (err) { reject(err); } else { resolve(); } }); }); }); }; conn.on('ready', async () => { console.log('SSH连接成功'); try { console.log('1. 创建临时目录...'); await execCmd('rm -rf /tmp/huishou-h5 && mkdir -p /tmp/huishou-h5/assets'); console.log('2. 上传index.html...'); await sftpPut(`${localH5Dir}/index.html`, '/tmp/huishou-h5/index.html'); console.log(' ✓ index.html上传成功'); console.log('3. 上传assets文件...'); const assetFiles = fs.readdirSync(`${localH5Dir}/assets`); for (const file of assetFiles) { await sftpPut(`${localH5Dir}/assets/${file}`, `/tmp/huishou-h5/assets/${file}`); console.log(` ✓ ${file}`); } console.log('4. 上传static目录...'); const staticDir = `${localH5Dir}/static`; if (fs.existsSync(staticDir)) { const staticFiles = []; const collectStatic = (dir) => { const items = fs.readdirSync(dir, { withFileTypes: true }); for (const item of items) { const fullPath = path.join(dir, item.name); if (item.isDirectory()) { collectStatic(fullPath); } else { staticFiles.push(fullPath); } } }; collectStatic(staticDir); for (const file of staticFiles) { const relPath = path.relative(staticDir, file).replace(/\\/g, '/'); await execCmd(`mkdir -p /tmp/huishou-h5/static/${path.dirname(relPath)}`); await sftpPut(file, `/tmp/huishou-h5/static/${relPath}`); console.log(` ✓ static/${relPath}`); } } console.log('5. 复制到Docker容器...'); await execCmd('docker cp /tmp/huishou-h5/. huishou:/usr/share/nginx/html/h5/'); console.log(' ✓ 文件已复制到容器'); console.log('6. 验证部署...'); const verifyResult = await execCmd('docker exec huishou ls -la /usr/share/nginx/html/h5/assets/ | head -5'); console.log(' 容器内assets目录:'); console.log(' ', verifyResult.output.trim()); const weighJsResult = await execCmd('docker exec huishou ls /usr/share/nginx/html/h5/assets/ | grep pages-weigh'); console.log(' 称重页面JS文件:', weighJsResult.output.trim()); const manualCheck = await execCmd(`docker exec huishou grep -o "inputMode" /usr/share/nginx/html/h5/assets/${weighJsResult.output.trim()} | head -3`); console.log(' inputMode出现次数:', manualCheck.output.trim()); console.log('\n✅ 部署完成!'); } catch (err) { console.error('部署失败:', err.message); } finally { conn.end(); } }); conn.on('error', (err) => { console.error('SSH连接错误:', err.message); }); conn.connect(config);