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"