diff --git a/.gitignore b/.gitignore index 8c7d99d..9c97b34 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ components.d.ts # 组件汇总文件,仅限开发本地浏览 component.md + +./deploy.js diff --git a/deploy.js b/deploy.js new file mode 100644 index 0000000..1fb734d --- /dev/null +++ b/deploy.js @@ -0,0 +1,75 @@ +import { Client } from 'ssh2'; +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const serverConfig = { + host: '222.20.126.217', + port: 22, + username: 'admini', + password: 'zlzxb@1888', + remotePath: '/home/admini/ossrpp/base/nginx/dist/SAP/' +}; + +async function uploadDirectory(sftp, localDir, remoteDir) { + const items = fs.readdirSync(localDir); + + // 确保远程目录存在 + try { + await new Promise((res) => sftp.mkdir(remoteDir, { mode: '0755' }, () => res())); + } catch (e) {} + + for (const item of items) { + const localPath = path.join(localDir, item); + const remotePath = path.join(remoteDir, item).replace(/\\/g, '/'); // 转换为Linux路径 + + if (fs.statSync(localPath).isDirectory()) { + await uploadDirectory(sftp, localPath, remotePath); + } else { + await new Promise((resolve, reject) => { + console.log(`🚀 上传中: ${item}`); + sftp.fastPut(localPath, remotePath, (err) => { + if (err) reject(err); + else resolve(); + }); + }); + } + } +} + +async function startDeploy() { + const conn = new Client(); + console.log('✨ 开始部署流程...'); + + conn.on('ready', () => { + console.log('✅ SSH 连接成功!'); + conn.sftp(async (err, sftp) => { + if (err) throw err; + + try { + const localDist = path.join(__dirname, 'SAP'); + await uploadDirectory(sftp, localDist, serverConfig.remotePath); + console.log('🎉 所有文件上传成功!'); + conn.end(); + } catch (uploadErr) { + console.error('❌ 上传失败:', uploadErr); + conn.end(); + } + }); + }).on('error', (err) => { + console.error('❌ 连接出错 (检查IP或密码):', err.message); + }).on('close', () => { + console.log('🔌 连接已关闭'); + process.exit(0); + }).connect({ + host: serverConfig.host, + port: serverConfig.port, + username: serverConfig.username, + password: serverConfig.password, + readyTimeout: 10000 // 10秒超时 + }); +} + +startDeploy(); diff --git a/package.json b/package.json index a4994dc..187f678 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "preview": "vite preview", "type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", - "format": "prettier --write src/" + "format": "prettier --write src/", + "deploy": "node deploy.js" }, "dependencies": { "@devui-design/icons": "^1.4.0", @@ -76,6 +77,7 @@ "prettier": "^2.8.8", "rollup-plugin-visualizer": "^5.9.2", "sass": "^1.63.6", + "ssh2": "^1.17.0", "tailwindcss": "^3.3.3", "terser": "^5.39.0", "typescript": "~5.0.4", diff --git a/src/views/Jyh/Community/StatsBar.vue b/src/views/Jyh/Community/StatsBar.vue index 18ea38b..1760fe1 100644 --- a/src/views/Jyh/Community/StatsBar.vue +++ b/src/views/Jyh/Community/StatsBar.vue @@ -6,18 +6,18 @@
- 30+ - 高校参与 + 12 + 武汉开源社区数量
- 120+ - 社区活动 + 70W+ + 武汉开源开发者数量
- 200+ - 开源项目 + 500+ + 武汉开源项目数量
diff --git a/yarn.lock b/yarn.lock index e099d8f..44dd8e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1871,6 +1871,13 @@ arraybuffer.prototype.slice@^1.0.3: is-array-buffer "^3.0.4" is-shared-array-buffer "^1.0.2" +asn1@^0.2.6: + version "0.2.6" + resolved "https://registry.npmmirror.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + async-validator@^4.0.0, async-validator@^4.0.7: version "4.2.5" resolved "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz" @@ -1938,6 +1945,13 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +bcrypt-pbkdf@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + binary-extensions@^2.0.0: version "2.3.0" resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" @@ -1985,6 +1999,11 @@ buffer-from@^1.0.0: resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buildcheck@~0.0.6: + version "0.0.7" + resolved "https://registry.npmmirror.com/buildcheck/-/buildcheck-0.0.7.tgz#07a5e76c10ead8fa67d9e4c587b68f49e8f29d61" + integrity sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA== + call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz" @@ -2159,6 +2178,14 @@ core-js@^3.15.1, core-js@^3.31.1: resolved "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz" integrity sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA== +cpu-features@~0.0.10: + version "0.0.10" + resolved "https://registry.npmmirror.com/cpu-features/-/cpu-features-0.0.10.tgz#9aae536db2710c7254d7ed67cb3cbc7d29ad79c5" + integrity sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA== + dependencies: + buildcheck "~0.0.6" + nan "^2.19.0" + crc-32@~1.2.0, crc-32@~1.2.1: version "1.2.2" resolved "https://mirrors.cloud.tencent.com/npm/crc-32/-/crc-32-1.2.2.tgz" @@ -3976,6 +4003,11 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" +nan@^2.19.0, nan@^2.23.0: + version "2.25.0" + resolved "https://registry.npmmirror.com/nan/-/nan-2.25.0.tgz#937ed345e63d9481362a7942d49c4860d27eeabd" + integrity sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g== + nanoid@^3.3.8: version "3.3.11" resolved "https://mirrors.cloud.tencent.com/npm/nanoid/-/nanoid-3.3.11.tgz" @@ -4447,7 +4479,7 @@ safe-regex-test@^1.0.3: es-errors "^1.3.0" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -4632,6 +4664,17 @@ ssf@~0.11.2: dependencies: frac "~1.1.2" +ssh2@^1.17.0: + version "1.17.0" + resolved "https://registry.npmmirror.com/ssh2/-/ssh2-1.17.0.tgz#dc686e8e3abdbd4ad95d46fa139615903c12258c" + integrity sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ== + dependencies: + asn1 "^0.2.6" + bcrypt-pbkdf "^1.0.2" + optionalDependencies: + cpu-features "~0.0.10" + nan "^2.23.0" + "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -4859,6 +4902,11 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tweetnacl@^0.14.3: + version "0.14.5" + resolved "https://registry.npmmirror.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + type-fest@^0.20.2: version "0.20.2" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"