This commit is contained in:
wucongxing8150 2025-08-11 11:41:22 +08:00
parent 3dc28bf225
commit e576fb8c4c
16 changed files with 802 additions and 11 deletions

3
.env.dev-server Normal file
View File

@ -0,0 +1,3 @@
NODE_ENV=development
VITE_APP_TITLE='SmartAdmin 开发服务器环境(Dev Server)'
VITE_APP_API_URL='http://dev-casedata.igandan.com:5480'

View File

@ -1,3 +1,3 @@
NODE_ENV=development
VITE_APP_TITLE='SmartAdmin 开发环境(Dev)'
VITE_APP_API_URL='http://127.0.0.1:5478'
VITE_APP_API_URL='http://127.0.0.1:5480'

View File

@ -1,3 +1,3 @@
NODE_ENV=development
VITE_APP_TITLE='SmartAdmin 本地环境(Local)'
VITE_APP_API_URL='http://127.0.0.1:5478'
VITE_APP_API_URL='http://127.0.0.1:5480'

View File

@ -1,3 +1,3 @@
NODE_ENV=production
VITE_APP_TITLE='SmartAdmin 测试环境(Test)'
VITE_APP_API_URL='http://127.0.0.1:5478'
VITE_APP_API_URL='http://127.0.0.1:5480'

135
ENV_CHANGES_SUMMARY.md Normal file
View File

@ -0,0 +1,135 @@
# 环境配置修改总结
## 修改概述
根据用户需求已成功实现自动环境检测功能系统能够自动判断当前环境并使用相应的API地址
- **本地环境**: 自动使用 `http://127.0.0.1:5480`
- **开发服务器环境**: 自动使用 `http://dev-casedata.igandan.com:5480`
- **其他环境**: 使用配置文件中的 `VITE_APP_API_URL`
## 具体修改内容
### 1. 新增文件
#### `src/utils/env-util.js`
- 创建环境检测工具
- 实现自动环境判断逻辑
- 提供 `detectEnvironment()``getCurrentApiUrl()` 函数
#### `src/utils/env-test.js`
- 创建环境检测测试文件
- 提供测试函数 `testEnvironmentDetection()`
- 在开发环境下自动加载,方便调试
#### `.env.dev-server`
- 新增开发服务器环境配置文件
- API地址: `http://dev-casedata.igandan.com:5480`
#### `ENV_README.md`
- 详细的环境配置使用说明文档
#### `ENV_CHANGES_SUMMARY.md`
- 本修改总结文档
### 2. 修改文件
#### `src/lib/axios.js`
- 引入环境检测工具
- 将 `baseURL` 从静态配置改为动态检测: `getCurrentApiUrl()`
#### `package.json`
- 新增 `build:dev-server` 构建命令
#### `src/main.js`
- 在开发环境下自动引入环境检测测试文件
#### 环境配置文件
- `.env.localhost`: 端口从5478改为5480
- `.env.development`: 端口从5478改为5480
- `.env.test`: 端口从5478改为5480
## 环境检测逻辑
### 本地环境检测
```javascript
// 检测以下主机名或IP地址
hostname === 'localhost' ||
hostname === '127.0.0.1' ||
hostname === '0.0.0.0' ||
hostname.includes('192.168.') ||
hostname.includes('10.') ||
hostname.includes('172.')
```
### 开发服务器环境检测
```javascript
// 检测特定域名
hostname === 'dev-casedata.igandan.com'
```
### 优先级
1. **环境检测** (最高优先级)
2. **配置文件** (中等优先级)
3. **默认值** (最低优先级)
## 使用方法
### 开发时
```bash
# 本地开发 - 自动使用 127.0.0.1:5480
npm run localhost
# 开发环境 - 自动使用 127.0.0.1:5480
npm run dev
```
### 部署时
```bash
# 部署到开发服务器 - 自动使用 dev-casedata.igandan.com:5480
npm run build:dev-server
# 其他环境
npm run build:test
npm run build:pre
npm run build:prod
```
## 测试验证
### 控制台测试
在开发环境下,打开浏览器控制台,运行:
```javascript
testEnv()
```
### 预期结果
- **本地环境**: API地址显示为 `http://127.0.0.1:5480`
- **开发服务器环境**: API地址显示为 `http://dev-casedata.igandan.com:5480`
## 技术特点
1. **零配置**: 无需手动修改任何代码,系统自动判断环境
2. **智能检测**: 基于主机名、IP地址、环境变量等多维度检测
3. **端口统一**: 所有环境都使用5480端口
4. **向后兼容**: 不影响现有的环境配置文件
5. **开发友好**: 提供测试工具和详细文档
## 注意事项
1. **端口配置**: 确保后端服务在5480端口运行
2. **域名配置**: 确保 `dev-casedata.igandan.com` 域名正确解析
3. **环境变量**: 开发环境下会自动加载测试文件
4. **构建命令**: 使用正确的构建命令来部署到不同环境
## 完成状态
**环境检测工具** - 已完成
**自动API地址配置** - 已完成
**端口统一为5480** - 已完成
**环境配置文件更新** - 已完成
**构建命令添加** - 已完成
**测试工具** - 已完成
**文档说明** - 已完成
所有修改已完成系统现在能够自动判断环境并使用相应的API地址

82
ENV_README.md Normal file
View File

@ -0,0 +1,82 @@
# 环境配置说明
## 环境配置文件
项目包含以下环境配置文件:
### 1. `.env.localhost` - 本地开发环境
- **用途**: 本地开发时使用
- **API地址**: `http://127.0.0.1:5480`
- **启动命令**: `npm run dev:localhost`
### 2. `.env.development` - 开发环境
- **用途**: 开发环境使用
- **API地址**: `http://127.0.0.1:5480`
- **启动命令**: `npm run dev`
### 3. `.env.dev-server` - 开发服务器环境
- **用途**: 部署到开发服务器时使用
- **API地址**: `http://dev-casedata.igandan.com:5480`
- **启动命令**: `npm run build:dev-server`
### 4. `.env.test` - 测试环境
- **用途**: 测试环境使用
- **API地址**: `http://127.0.0.1:5480`
- **启动命令**: `npm run build:test`
### 5. `.env.pre` - 预发布环境
- **用途**: 预发布环境使用
- **API地址**: `https://preview.smartadmin.vip/smart-admin-api`
- **启动命令**: `npm run build:pre`
### 6. `.env.production` - 生产环境
- **用途**: 生产环境使用
- **API地址**: `https://preview.smartadmin.vip/smart-admin-api`
- **启动命令**: `npm run build`
## 自动环境检测
项目已实现自动环境检测功能,无需手动配置:
### 检测逻辑
1. **本地环境**: 自动检测 `localhost``127.0.0.1``192.168.x.x` 等IP地址
2. **开发服务器**: 自动检测 `dev-casedata.igandan.com` 域名
3. **其他环境**: 使用配置文件中的 `VITE_APP_API_URL`
### 端口配置
- **本地环境**: 5480
- **开发服务器**: 5480
- **其他环境**: 根据配置文件
## 使用方法
### 开发时
```bash
# 本地开发
npm run dev:localhost
# 开发环境
npm run dev
```
### 部署时
```bash
# 部署到开发服务器
npm run build:dev-server
# 部署到测试环境
npm run build:test
# 部署到预发布环境
npm run build:pre
# 部署到生产环境
npm run build
```
## 注意事项
1. **端口统一**: 所有环境都使用5480端口
2. **自动检测**: 无需手动修改代码,系统会自动判断环境
3. **配置优先级**: 环境检测 > 配置文件 > 默认值
4. **开发便利**: 本地开发时自动使用127.0.0.1:5480部署时自动使用dev-casedata.igandan.com:5480

190
JS_PATH_FIX_README.md Normal file
View File

@ -0,0 +1,190 @@
# JS文件路径问题修复说明
## 🚨 问题描述
在部署到开发服务器 `dev-casedata.igandan.com`JS文件路径不正确导致404错误
```
/admin/js/vue-types-DoCPvpw_.js HTTP/1.1" 405 552
```
## 🔍 问题分析
### 1. 路径配置不一致
- **vite.config.js**: `base: '/'` (开发环境)
- **package.json构建命令**: `--base=/admin/` (生产环境)
- **实际部署路径**: `/admin/`
### 2. 构建输出路径问题
- JS文件被放在 `js/` 目录下
- 但base路径配置为 `/admin/`
- 导致最终路径变成 `/admin/js/` 而不是 `/admin/assets/js/`
## ✅ 解决方案
### 1. 统一base路径配置
#### 修改 `vite.config.js`
```javascript
export default {
base: process.env.NODE_ENV === 'production' ? '/admin/' : '/',
// ... 其他配置
}
```
#### 修改 `package.json` 构建命令
```json
{
"scripts": {
"build:dev-server": "vite build --config vite.config.dev-server.js --mode dev-server",
"build:test": "vite build --base=/admin/ --mode test",
"build:pre": "vite build --base=/admin/ --mode pre",
"build:prod": "vite build --base=/admin/ --mode production"
}
}
```
### 2. 创建专门的开发服务器配置
#### 新增 `vite.config.dev-server.js`
```javascript
export default {
base: '/admin/',
// ... 其他配置
build: {
rollupOptions: {
output: {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
}
}
}
}
```
### 3. 修复构建输出路径
#### 修改 `vite.config.js` 中的构建配置
```javascript
build: {
rollupOptions: {
output: {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
}
}
}
```
## 🚀 使用方法
### 1. 构建开发服务器版本
```bash
# 使用专门的配置文件构建
npm run build:dev-server
# 或者使用构建脚本
./build-dev-server.sh
```
### 2. 验证构建结果
构建完成后,检查以下文件路径是否正确:
```
dist/
├── index.html
├── assets/
│ ├── js/
│ │ ├── index-[hash].js
│ │ └── vendor-[hash].js
│ ├── css/
│ │ └── index-[hash].css
│ └── [其他资源文件]
```
### 3. 检查index.html中的路径
确保 `dist/index.html` 中的资源路径以 `/admin/assets/` 开头:
```html
<script type="module" crossorigin src="/admin/assets/js/index-[hash].js"></script>
<link rel="stylesheet" crossorigin href="/admin/assets/css/index-[hash].css">
```
## 🔧 部署配置
### Nginx配置示例
```nginx
server {
listen 80;
server_name dev-casedata.igandan.com;
location /admin/ {
alias /path/to/your/dist/;
try_files $uri $uri/ /admin/index.html;
# 处理静态资源
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
}
```
### Docker部署
确保构建后的文件正确复制到容器中:
```dockerfile
# 复制构建后的前端资源
COPY dist/ /usr/share/nginx/html/
```
## 📋 检查清单
- [ ] 修改 `vite.config.js` 中的base路径
- [ ] 创建 `vite.config.dev-server.js` 专用配置
- [ ] 更新 `package.json` 中的构建命令
- [ ] 修复构建输出路径配置
- [ ] 测试构建结果
- [ ] 验证部署后的资源访问
## 🎯 预期结果
修复后JS文件应该能够正确访问
- ✅ 正确路径: `/admin/assets/js/[filename]-[hash].js`
- ❌ 错误路径: `/admin/js/[filename]-[hash].js`
## 🆘 故障排除
### 如果问题仍然存在:
1. **清理构建缓存**
```bash
rm -rf dist node_modules/.vite
npm run build:dev-server
```
2. **检查环境变量**
```bash
cat .env.dev-server
```
3. **验证构建配置**
```bash
npm run build:dev-server -- --debug
```
4. **检查网络请求**
使用浏览器开发者工具查看Network标签页中的资源请求路径
## 📞 技术支持
如果按照以上步骤仍然无法解决问题,请检查:
1. 构建日志输出
2. 浏览器控制台错误信息
3. 服务器访问日志
4. 网络请求状态码

57
build-dev-server.sh Executable file
View File

@ -0,0 +1,57 @@
#!/bin/bash
# 开发服务器构建脚本
# 用于构建部署到 dev-casedata.igandan.com 的前端资源
echo "🚀 开始构建开发服务器版本..."
# 清理之前的构建
echo "🧹 清理之前的构建文件..."
rm -rf dist
# 安装依赖(如果需要)
if [ ! -d "node_modules" ]; then
echo "📦 安装依赖..."
npm install
fi
# 构建项目
echo "🔨 构建项目..."
npm run build:dev-server
# 检查构建结果
if [ $? -eq 0 ]; then
echo "✅ 构建成功!"
echo "📁 构建输出目录: dist/"
echo "🌐 访问路径: https://dev-casedata.igandan.com/admin/"
# 显示构建后的文件结构
echo "📋 构建文件列表:"
find dist -type f | head -20
# 检查关键文件
echo "🔍 检查关键文件:"
if [ -f "dist/index.html" ]; then
echo " ✅ index.html 存在"
# 检查JS文件路径
js_files=$(grep -o 'src="[^"]*\.js"' dist/index.html | head -5)
echo " 📜 JS文件路径示例:"
echo "$js_files"
else
echo " ❌ index.html 不存在"
fi
if [ -d "dist/assets" ]; then
echo " ✅ assets 目录存在"
echo " 📁 assets 目录内容:"
ls -la dist/assets/
else
echo " ❌ assets 目录不存在"
fi
else
echo "❌ 构建失败!"
exit 1
fi
echo "🎉 构建完成!"

View File

@ -11,9 +11,10 @@
"scripts": {
"localhost": "vite --mode localhost",
"dev": "vite",
"build:dev-server": "vite build --config vite.config.dev-server.js --mode dev-server",
"build:test": "vite build --base=/admin/ --mode test",
"build:pre": "vite build --mode pre",
"build:prod": "vite build --mode production"
"build:pre": "vite build --base=/admin/ --mode pre",
"build:prod": "vite build --base=/admin/ --mode production"
},
"type": "module",
"dependencies": {

View File

@ -15,13 +15,14 @@ import { decryptData, encryptData } from './encrypt';
import { DATA_TYPE_ENUM } from '../constants/common-const';
import _ from 'lodash';
import LocalStorageKeyConst from '/@/constants/local-storage-key-const.js';
import { getCurrentApiUrl } from '/@/utils/env-util';
// token的消息头
const TOKEN_HEADER = 'Authorization';
// 创建axios对象
const smartAxios = axios.create({
baseURL: import.meta.env.VITE_APP_API_URL,
baseURL: getCurrentApiUrl(),
});
// 退出系统

View File

@ -36,6 +36,11 @@ import '/@/utils/ployfill';
import { useDictStore } from '/@/store/modules/system/dict.js';
import { dictApi } from '/@/api/support/dict-api.js';
// 开发环境下引入环境检测测试
if (import.meta.env.DEV) {
import('/@/utils/env-test.js');
}
/*
* -------------------- 着重 解释说明下main.js的初始化逻辑 begin --------------------
*

66
src/utils/env-test.js Normal file
View File

@ -0,0 +1,66 @@
/*
* 环境检测测试文件
* 用于验证环境检测功能是否正常工作
*
* @Author: xing
* @Date: 2025-01-27
* @Copyright gdxz
*/
import { detectEnvironment, getCurrentApiUrl } from './env-util';
/**
* 测试环境检测功能
*/
export function testEnvironmentDetection() {
console.log('=== 环境检测测试 ===');
const env = detectEnvironment();
console.log('环境检测结果:');
console.log('- isLocal:', env.isLocal);
console.log('- isDevServer:', env.isDevServer);
console.log('- 当前主机名:', typeof window !== 'undefined' ? window.location.hostname : 'Node.js环境');
console.log('- 当前API地址:', getCurrentApiUrl());
console.log('- 环境变量NODE_ENV:', import.meta.env.NODE_ENV);
console.log('- 环境变量VITE_APP_API_URL:', import.meta.env.VITE_APP_API_URL);
// 测试不同环境下的API地址
console.log('\n=== 不同环境下的API地址测试 ===');
// 模拟本地环境
if (typeof window !== 'undefined') {
const originalHostname = window.location.hostname;
// 测试本地环境
Object.defineProperty(window.location, 'hostname', {
value: 'localhost',
writable: true
});
console.log('模拟localhost环境:', getCurrentApiUrl());
// 测试开发服务器环境
Object.defineProperty(window.location, 'hostname', {
value: 'dev-casedata.igandan.com',
writable: true
});
console.log('模拟dev-casedata.igandan.com环境:', getCurrentApiUrl());
// 恢复原始值
Object.defineProperty(window.location, 'hostname', {
value: originalHostname,
writable: true
});
}
console.log('\n=== 测试完成 ===');
}
/**
* 在浏览器控制台中运行测试
*/
if (typeof window !== 'undefined') {
// 将测试函数挂载到全局,方便在控制台调用
window.testEnv = testEnvironmentDetection;
console.log('环境检测测试已准备就绪,请在控制台运行: testEnv()');
}

73
src/utils/env-util.js Normal file
View File

@ -0,0 +1,73 @@
/*
* 环境检测工具
*
* @Author: xing
* @Date: 2025-01-27
* @Copyright gdxz
*/
/**
* 检测当前环境
* @returns {Object} 包含环境信息的对象
*/
export function detectEnvironment() {
// 检测是否为本地环境
const isLocal = () => {
// 检查主机名
if (typeof window !== 'undefined') {
const hostname = window.location.hostname;
return hostname === 'localhost' ||
hostname === '127.0.0.1' ||
hostname === '0.0.0.0' ||
hostname.includes('192.168.') ||
hostname.includes('10.') ||
hostname.includes('172.');
}
// 检查环境变量
if (import.meta.env.DEV) {
return true;
}
return false;
};
// 检测是否为开发服务器环境
const isDevServer = () => {
if (typeof window !== 'undefined') {
const hostname = window.location.hostname;
return hostname === 'dev-casedata.igandan.com';
}
return false;
};
const local = isLocal();
const devServer = isDevServer();
return {
isLocal,
isDevServer,
isLocal: local,
isDevServer: devServer,
// 根据环境返回对应的API地址
getApiUrl: () => {
if (local) {
return 'http://127.0.0.1:5480';
} else if (devServer) {
return 'http://dev-casedata.igandan.com:5480';
} else {
// 其他环境使用默认配置
return import.meta.env.VITE_APP_API_URL;
}
}
};
}
/**
* 获取当前环境的API基础URL
* @returns {string} API基础URL
*/
export function getCurrentApiUrl() {
const env = detectEnvironment();
return env.getApiUrl();
}

94
test-build.js Normal file
View File

@ -0,0 +1,94 @@
#!/usr/bin/env node
/*
* 构建测试脚本
* 用于验证vite配置是否正确
*/
import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
console.log('🧪 开始测试构建配置...\n');
// 检查配置文件
const configFiles = [
'vite.config.js',
'vite.config.dev-server.js',
'package.json',
'.env.dev-server'
];
console.log('📋 检查配置文件:');
configFiles.forEach(file => {
if (fs.existsSync(file)) {
console.log(`${file} 存在`);
} else {
console.log(`${file} 不存在`);
}
});
// 检查package.json中的脚本
console.log('\n📜 检查构建脚本:');
try {
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const scripts = packageJson.scripts;
if (scripts['build:dev-server']) {
console.log(` ✅ build:dev-server: ${scripts['build:dev-server']}`);
} else {
console.log(` ❌ build:dev-server 脚本不存在`);
}
if (scripts['build:test']) {
console.log(` ✅ build:test: ${scripts['build:test']}`);
} else {
console.log(` ❌ build:test 脚本不存在`);
}
} catch (error) {
console.log(` ❌ 无法读取package.json: ${error.message}`);
}
// 检查环境变量
console.log('\n🌍 检查环境变量:');
try {
const envContent = fs.readFileSync('.env.dev-server', 'utf8');
const lines = envContent.split('\n');
lines.forEach(line => {
if (line.trim() && !line.startsWith('#')) {
const [key, value] = line.split('=');
if (key && value) {
console.log(` ${key.trim()}: ${value.trim()}`);
}
}
});
} catch (error) {
console.log(` ❌ 无法读取.env.dev-server: ${error.message}`);
}
// 检查vite配置
console.log('\n⚙ 检查vite配置:');
try {
const viteConfig = fs.readFileSync('vite.config.js', 'utf8');
if (viteConfig.includes("base: process.env.NODE_ENV === 'production' ? '/admin/' : '/'")) {
console.log(' ✅ base路径配置正确');
} else {
console.log(' ❌ base路径配置不正确');
}
if (viteConfig.includes('assets/js/[name]-[hash].js')) {
console.log(' ✅ JS文件路径配置正确');
} else {
console.log(' ❌ JS文件路径配置不正确');
}
} catch (error) {
console.log(` ❌ 无法读取vite.config.js: ${error.message}`);
}
console.log('\n🎯 配置检查完成!');
console.log('💡 如果所有检查都通过,可以运行以下命令进行构建测试:');
console.log(' npm run build:dev-server');
console.log(' 或者');
console.log(' ./build-dev-server.sh');

84
vite.config.dev-server.js Normal file
View File

@ -0,0 +1,84 @@
/*
* vite配置 - 开发服务器环境专用
*
* @Author: xing
* @Date: 2025-01-27
* @Copyright gdxz
*/
import { resolve } from 'path';
import vue from '@vitejs/plugin-vue';
import customVariables from '/@/theme/custom-variables.js';
const pathResolve = (dir) => {
return resolve(__dirname, '.', dir);
};
export default {
base: '/admin/',
root: process.cwd(),
resolve: {
alias: [
// 国际化替换
{
find: 'vue-i18n',
replacement: 'vue-i18n/dist/vue-i18n.cjs.js',
},
// 绝对路径重命名:/@/xxxx => src/xxxx
{
find: /\/@\//,
replacement: pathResolve('src') + '/',
},
{
find: /^~/,
replacement: '',
},
],
},
plugins: [vue()],
optimizeDeps: {
include: ['ant-design-vue/es/locale/zh_CN', 'dayjs/locale/zh-cn', 'ant-design-vue/es/locale/en_US'],
exclude: ['vue-demi'],
},
build: {
// 清除console和debugger
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
rollupOptions: {
output: {
// 配置这个是让不同类型文件放在不同文件夹,不会显得太乱
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
manualChunks(id) {
// 静态资源分拆打包
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
},
},
},
target: 'esnext',
outDir: 'dist', // 指定输出路径
assetsDir: 'assets', // 指定生成静态文件目录
assetsInlineLimit: '4096', // 小于此阈值的导入或引用资源将内联为 base64 编码
chunkSizeWarningLimit: 500, // chunk 大小警告的限制
minify: 'terser', // 混淆器terser构建后文件体积更小
emptyOutDir: true, // 打包前先清空原有打包文件
},
css: {
preprocessorOptions: {
less: {
modifyVars: customVariables,
javascriptEnabled: true,
},
},
},
define: {
__INTLIFY_PROD_DEVTOOLS__: false,
'process.env': process.env,
},
};

View File

@ -15,7 +15,7 @@ const pathResolve = (dir) => {
return resolve(__dirname, '.', dir);
};
export default {
base: process.env.NODE_ENV === 'production' ? '/' : '/',
base: process.env.NODE_ENV === 'production' ? '/admin/' : '/',
root: process.cwd(),
resolve: {
alias: [
@ -65,9 +65,9 @@ export default {
rollupOptions: {
output: {
//配置这个是让不同类型文件放在不同文件夹,不会显得太乱
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: '[ext]/[name]-[hash].[ext]',
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
manualChunks(id) {
//静态资源分拆打包
if (id.includes('node_modules')) {