Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 依赖
node_modules/
package-lock.json
yarn.lock
pnpm-lock.yaml

# 构建输出
dist/*
!dist/
!dist/index.html
build/

# 环境变量
.env
.env.local
.env.*.local

# 编辑器
.vscode/
.idea/
*.swp
*.swo
*~

# 系统文件
.DS_Store
Thumbs.db

# 日志
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# 临时文件
*.tmp
.cache/
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Step3-VL-10B

## 开发

### 安装依赖

```bash
npm install
```

### 本地开发

```bash
npm run dev
```

开发服务器将在 `http://localhost:3000` 启动。

### 构建生产版本

```bash
npm run build
```

构建产物将输出到 `dist/` 目录。

### 预览构建结果

```bash
npm run preview
```

## 部署到阿里云 OSS

### 1. 配置环境变量

复制 `env.example` 为 `.env` 并填入你的阿里云 OSS 配置:

```bash
cp env.example .env
```

编辑 `.env` 文件:

```env
OSS_REGION=oss-cn-hangzhou
OSS_ACCESS_KEY_ID=your_access_key_id
OSS_ACCESS_KEY_SECRET=your_access_key_secret
OSS_BUCKET=your-bucket-name
OSS_PREFIX=step3-vl-10b/ # 可选,上传路径前缀
```

### 2. 部署

#### 方式一:构建并上传(推荐)

```bash
npm run deploy
```

这个命令会:

1. 执行构建(`npm run build`)
2. 自动上传到阿里云 OSS

#### 方式二:仅上传(已构建)

如果已经构建过,可以直接上传:

```bash
npm run upload
```
1 change: 1 addition & 0 deletions dist/index.html

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 阿里云 OSS 配置
# 请复制此文件为 .env 并填入实际配置

# OSS 区域,例如: oss-cn-hangzhou, oss-cn-beijing
OSS_REGION=oss-cn-hangzhou

# OSS AccessKey ID
OSS_ACCESS_KEY_ID=your_access_key_id

# OSS AccessKey Secret
OSS_ACCESS_KEY_SECRET=your_access_key_secret

# OSS Bucket 名称
OSS_BUCKET=your-bucket-name

# OSS 上传路径前缀(可选)
# 例如: step3-vl-10b/ 或 static/
# 如果留空,文件将上传到 bucket 根目录
OSS_PREFIX=
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ <h4>Style Controls</h4>
</div>
</div> -->

<script src="script.js"></script>
<script type="module" src="script.js"></script>
</body>

</html>
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "step3-vl-10b-gh-pages",
"version": "1.0.0",
"description": "Step3-VL-10B Model Showcase Website",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build && node scripts/copy-assets.js",
"preview": "vite preview",
"deploy": "npm run build && node scripts/upload-to-oss.js",
"upload": "node scripts/upload-to-oss.js"
},
"devDependencies": {
"vite": "^5.0.0",
"vite-plugin-html": "^3.2.2"
},
"dependencies": {
"ali-oss": "^6.20.0",
"dotenv": "^16.3.1"
}
}
46 changes: 46 additions & 0 deletions scripts/copy-assets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { copyFileSync, mkdirSync, readdirSync, statSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const projectRoot = join(__dirname, '..');
const distDir = join(projectRoot, 'dist');

// 需要复制的静态资源目录和文件
const assetsToCopy = [
{ src: 'images', dest: 'images' },
{ src: 'logo.png', dest: 'logo.png' },
{ src: 'ref_design/assest/llm_logos', dest: 'ref_design/assest/llm_logos' },
];

function copyRecursive(src, dest) {
const stat = statSync(src);

if (stat.isDirectory()) {
mkdirSync(dest, { recursive: true });
const files = readdirSync(src);
files.forEach(file => {
copyRecursive(join(src, file), join(dest, file));
});
} else {
mkdirSync(dirname(dest), { recursive: true });
copyFileSync(src, dest);
}
}

console.log('📦 复制静态资源到 dist 目录...');

assetsToCopy.forEach(({ src, dest }) => {
const srcPath = join(projectRoot, src);
const destPath = join(distDir, dest);

try {
copyRecursive(srcPath, destPath);
console.log(`✅ 已复制: ${src} -> ${dest}`);
} catch (error) {
console.warn(`⚠️ 跳过: ${src} (${error.message})`);
}
});

console.log('✨ 静态资源复制完成!');
173 changes: 173 additions & 0 deletions scripts/upload-to-oss.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import OSS from 'ali-oss';
import { readFileSync, readdirSync, statSync } from 'fs';
import { join, relative, resolve } from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import dotenv from 'dotenv';

// 加载环境变量
dotenv.config();

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const projectRoot = resolve(__dirname, '..');
const distDir = join(projectRoot, 'dist');

// 从环境变量读取配置
const ossConfig = {
region: process.env.OSS_REGION || '',
accessKeyId: process.env.OSS_ACCESS_KEY_ID || '',
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET || '',
bucket: process.env.OSS_BUCKET || '',
// 上传到 OSS 的路径前缀,例如 'step3-vl-10b/' 或 ''
prefix: process.env.OSS_PREFIX || '',
};

// 验证配置
const requiredFields = ['region', 'accessKeyId', 'accessKeySecret', 'bucket'];
const missingFields = requiredFields.filter(field => !ossConfig[field]);

if (missingFields.length > 0) {
console.error('❌ 缺少必需的 OSS 配置项:');
missingFields.forEach(field => {
console.error(` - ${field}`);
});
console.error('\n请检查 .env 文件或环境变量配置');
process.exit(1);
}

// 创建 OSS 客户端
const client = new OSS(ossConfig);

// 需要上传的文件扩展名
const allowedExtensions = [
'.html', '.css', '.js', '.json',
'.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico',
'.woff', '.woff2', '.ttf', '.eot',
'.pdf', '.zip', '.txt'
];

// 递归获取所有文件
function getAllFiles(dir, fileList = []) {
const files = readdirSync(dir);

files.forEach(file => {
const filePath = join(dir, file);
const stat = statSync(filePath);

if (stat.isDirectory()) {
// 跳过 node_modules 和 .git 目录
if (file !== 'node_modules' && file !== '.git') {
getAllFiles(filePath, fileList);
}
} else {
const ext = file.substring(file.lastIndexOf('.')).toLowerCase();
if (allowedExtensions.includes(ext) || !ext) {
fileList.push(filePath);
}
}
});

return fileList;
}

// 上传文件到 OSS
async function uploadFile(localPath) {
const relativePath = relative(distDir, localPath);
const ossPath = ossConfig.prefix
? `${ossConfig.prefix}${relativePath.replace(/\\/g, '/')}`
: relativePath.replace(/\\/g, '/');

try {
const content = readFileSync(localPath);
const result = await client.put(ossPath, content);
return { success: true, path: ossPath, url: result.url };
} catch (error) {
return { success: false, path: ossPath, error: error.message };
}
}

// 主函数
async function main() {
console.log('🚀 开始上传文件到阿里云 OSS...\n');
console.log(`📦 Bucket: ${ossConfig.bucket}`);
console.log(`📍 Region: ${ossConfig.region}`);
console.log(`📁 Prefix: ${ossConfig.prefix || '(无)'}`);
console.log(`📂 源目录: ${distDir}\n`);

// 检查 dist 目录是否存在
try {
statSync(distDir);
} catch (error) {
console.error('❌ dist 目录不存在,请先运行 npm run build');
process.exit(1);
}

// 获取所有文件
const files = getAllFiles(distDir);
console.log(`📋 找到 ${files.length} 个文件需要上传\n`);

// 上传文件
const results = [];
let successCount = 0;
let failCount = 0;

for (let i = 0; i < files.length; i++) {
const file = files[i];
const relativePath = relative(distDir, file);
process.stdout.write(`[${i + 1}/${files.length}] 上传: ${relativePath} ... `);

const result = await uploadFile(file);
results.push(result);

if (result.success) {
successCount++;
console.log('✅');
} else {
failCount++;
console.log(`❌ 失败: ${result.error}`);
}
}

// 输出结果统计
console.log('\n' + '='.repeat(60));
console.log('📊 上传结果统计:');
console.log(` ✅ 成功: ${successCount}`);
console.log(` ❌ 失败: ${failCount}`);
console.log(` 📁 总计: ${files.length}`);
console.log('='.repeat(60));

// 如果有失败的文件,列出详情
if (failCount > 0) {
console.log('\n❌ 失败的文件:');
results
.filter(r => !r.success)
.forEach(r => {
console.log(` - ${r.path}: ${r.error}`);
});
}

// 输出访问 URL(如果配置了自定义域名)
if (successCount > 0) {
console.log('\n✨ 上传完成!');
if (ossConfig.prefix) {
console.log(`\n🌐 访问地址示例:`);
console.log(` https://${ossConfig.bucket}.${ossConfig.region}.aliyuncs.com/${ossConfig.prefix}index.html`);
} else {
console.log(`\n🌐 访问地址示例:`);
console.log(` https://${ossConfig.bucket}.${ossConfig.region}.aliyuncs.com/index.html`);
}
}

// 如果有失败,退出码为 1
if (failCount > 0) {
process.exit(1);
}
}

// 运行主函数
main().catch(error => {
console.error('\n❌ 上传过程中发生错误:');
console.error(error);
process.exit(1);
});
Loading