修改SSO

This commit is contained in:
ZhuJW
2026-07-10 21:10:17 +08:00
parent fce40c7d6c
commit 6ebd45d894
14 changed files with 66 additions and 76 deletions
+3 -1
View File
@@ -2,4 +2,6 @@
**.vscode **.vscode
**/node_modules **/node_modules
__pycache__/ __pycache__/
*.py[cod] *.py[cod]
logs
*.idea
+2 -1
View File
@@ -13,7 +13,7 @@ JWT_SECRET_KEY=dev_mb_project_2025_xyz123 # 开发环境可随意,生产环
SECRET_KEY=dev_mb_2025_abc789 SECRET_KEY=dev_mb_2025_abc789
# 数据库配置 # 数据库配置
DATABASE_URL=mysql+pymysql://root:Tsystems_2026@150.158.121.95:3306/incident?charset=utf8mb4 DATABASE_URL=mysql+pymysql://root:Tsystems_2026@150.158.121.95:3306/incid_db?charset=utf8mb4
# oauth2配置 # oauth2配置
CLIENT_ID=A17336FC-A8D7-4CEA-8777-384BFEABABC1 CLIENT_ID=A17336FC-A8D7-4CEA-8777-384BFEABABC1
@@ -24,6 +24,7 @@ SS0_HOST = https://ssoalpha.dvb.corpinter.net.cn/
REDIRECT_URL = http://localhost:5221/report REDIRECT_URL = http://localhost:5221/report
# 用户登录成功后,最终重定向到的前端页面地址 # 用户登录成功后,最终重定向到的前端页面地址
DOMAIN = http://localhost:3001 DOMAIN = http://localhost:3001
IMAGE_BASE_URL=http://localhost:5221
# 前端请求头的key # 前端请求头的key
HEADERS_SECRET_KEY=mbincid-server12 HEADERS_SECRET_KEY=mbincid-server12
+1 -1
View File
@@ -74,7 +74,7 @@ def create_app():
domain_prefix='accidentportal/api' domain_prefix='accidentportal/api'
app.register_blueprint(auth_bp, url_prefix=f"/{domain_prefix}/api/auth") app.register_blueprint(auth_bp, url_prefix=f"/{domain_prefix}/auth")
app.register_blueprint(login_bp, url_prefix=f"/{domain_prefix}/user") app.register_blueprint(login_bp, url_prefix=f"/{domain_prefix}/user")
app.register_blueprint(incident_gen5_bp, url_prefix=f"/{domain_prefix}/gen5") app.register_blueprint(incident_gen5_bp, url_prefix=f"/{domain_prefix}/gen5")
app.register_blueprint(incident_gen6_bp, url_prefix=f"/{domain_prefix}/gen6") app.register_blueprint(incident_gen6_bp, url_prefix=f"/{domain_prefix}/gen6")
+2 -2
View File
@@ -84,7 +84,7 @@ def authorized():
decoded_jwt = jwt.decode(access_token, options={"verify_signature": False}) decoded_jwt = jwt.decode(access_token, options={"verify_signature": False})
# 5. 验证和清理 state 参数 (防止开放重定向攻击) # 5. 验证和清理 state 参数 (防止开放重定向攻击)
safe_state = "/callback" safe_state = current_app.config["FRONTEND_CALLBACK_PATH"]
print(f"Redirecting to: {DOMAIN}{safe_state}") print(f"Redirecting to: {DOMAIN}{safe_state}")
# 6. 设置 Cookie # 6. 设置 Cookie
@@ -227,7 +227,7 @@ def authorized_test():
decoded_jwt = jwt.decode(access_token, options={"verify_signature": False}) decoded_jwt = jwt.decode(access_token, options={"verify_signature": False})
# 5. 验证和清理 state 参数 (防止开放重定向攻击) # 5. 验证和清理 state 参数 (防止开放重定向攻击)
safe_state = "/callback" safe_state = current_app.config["FRONTEND_CALLBACK_PATH"]
print(f"Redirecting to: {DOMAIN}{safe_state}") print(f"Redirecting to: {DOMAIN}{safe_state}")
# 6. 设置 Cookie # 6. 设置 Cookie
+6 -2
View File
@@ -51,6 +51,8 @@ class DevelopmentConfig(Config):
SS0_HOST = os.getenv("SS0_HOST","https://ssoalpha.dvb.corpinter.net.cn/") SS0_HOST = os.getenv("SS0_HOST","https://ssoalpha.dvb.corpinter.net.cn/")
REDIRECT_URL = os.getenv("REDIRECT_URL","http://localhost:5221/report") REDIRECT_URL = os.getenv("REDIRECT_URL","http://localhost:5221/report")
DOMAIN = os.getenv("DOMAIN","http://localhost:3001") DOMAIN = os.getenv("DOMAIN","http://localhost:3001")
# 前端回调路由(dev 根路径)
FRONTEND_CALLBACK_PATH = os.getenv("FRONTEND_CALLBACK_PATH", "/callback")
# 2. 开发模式开关 # 2. 开发模式开关
DEBUG = True DEBUG = True
TESTING = True TESTING = True
@@ -69,8 +71,10 @@ class ProductionConfig(Config):
CLIENT_ID = os.getenv("CLIENT_ID","A17336FC-A8D7-4CEA-8777-384BFEABABC1") CLIENT_ID = os.getenv("CLIENT_ID","A17336FC-A8D7-4CEA-8777-384BFEABABC1")
CLIENT_PASSWORD = os.getenv("CLIENT_PASSWORD","U7-C1BZQdL8V5c.z~qA_64SO2l9F3J0o") CLIENT_PASSWORD = os.getenv("CLIENT_PASSWORD","U7-C1BZQdL8V5c.z~qA_64SO2l9F3J0o")
SS0_HOST = os.getenv("SS0_HOST","https://ssoalpha.dvb.corpinter.net.cn/") SS0_HOST = os.getenv("SS0_HOST","https://ssoalpha.dvb.corpinter.net.cn/")
REDIRECT_URL = os.getenv("REDIRECT_URL","http://localhost:5221/report") REDIRECT_URL = os.getenv("REDIRECT_URL","https://cadb.dvb.corpinter.net.cn/accidentportal/api/incident/authorized")
DOMAIN = os.getenv("DOMAIN","http://localhost:3001") DOMAIN = os.getenv("DOMAIN","https://cadb.dvb.corpinter.net.cn")
# 前端回调路由(prod 带域名前缀)
FRONTEND_CALLBACK_PATH = os.getenv("FRONTEND_CALLBACK_PATH", "/accidentportal/callback")
DEBUG = False # 禁用调试(关键!避免生产环境暴露敏感信息) DEBUG = False # 禁用调试(关键!避免生产环境暴露敏感信息)
TESTING = False TESTING = False
+25 -17
View File
@@ -1,32 +1,40 @@
# 集群配置 # 运行环境(决定加载 ProductionConfig;容器必须以环境变量注入)
DATABRICKS_TOKEN=dapi188523cfb1cf34ad5a605fd75c5c0d31 FLASK_ENV=production
CLUSTER_ID=1203-054146-wkjf95i0 FLASK_APP=run:app
DATABRICKS_HOST=https://adb-3035612432650494.2.databricks.azure.cn
# gen5 spark表的配置 # Databricks(注意:entrypoint.sh 用的是 DATABRICKS_CLUSTER_IDconfig.py 用的是 CLUSTER_ID,两个都给)
DATABRICKS_TOKEN=dapi188523cfb1cf34ad5a605fd75c5c0d31
DATABRICKS_HOST=https://adb-3035612432650494.2.databricks.azure.cn
DATABRICKS_CLUSTER_ID=1203-054146-wkjf95i0
CLUSTER_ID=1203-054146-wkjf95i0
# gen5 spark 表
GEN5_TABLE_NAME=hive_metastore.taf_level_two_plus.accident_report_data GEN5_TABLE_NAME=hive_metastore.taf_level_two_plus.accident_report_data
# JWT配置 # 安全密钥(生产请换成强随机值)
JWT_SECRET_KEY=dev_mb_project_2025_xyz123 # 开发环境可随意,生产环境需复杂密钥 JWT_SECRET_KEY=dev_mb_project_2025_xyz123
SECRET_KEY=dev_mb_2025_abc789 SECRET_KEY=dev_mb_2025_abc789
# 数据库配置 # 数据库
DATABASE_URL=mysql+pymysql://root:V2OuCHPL%40changeit@10.200.10.193:3306/incid_db?charset=utf8mb4 DATABASE_URL=mysql+pymysql://root:V2OuCHPL%40changeit@10.200.10.193:3306/incid_db?charset=utf8mb4
# oauth2配置 # OAuth2 / SSO
CLIENT_ID=B7E86ADC-A8F7-4462-87FC-A04DFDF3C58F CLIENT_ID=B7E86ADC-A8F7-4462-87FC-A04DFDF3C58F
CLIENT_PASSWORD=AWd408ETS_V~j-yt.763P1D9ovC25fbe CLIENT_PASSWORD=AWd408ETS_V~j-yt.763P1D9ovC25fbe
SS0_HOST=https://ssoalpha.dvb.corpinter.net.cn/ SS0_HOST=https://ssoalpha.dvb.corpinter.net.cn/
# 授权成功后,SSO 服务器重定向回你的应用的地址 (必须与 SSO 服务器上配置的一致)
REDIRECT_URL=http://150.158.236.152:5221/incident/authorized
# 用户登录成功后,最终重定向到的前端页面地址
DOMAIN=http://150.158.236.152:5000
# 图片上传的配置 # SSO 回调地址(必须与 SSO 平台登记的完全一致;经 nginx 反代到后端 /incident/authorized
REDIRECT_URL=https://cadb.dvb.corpinter.net.cn/accidentportal/api/incident/authorized
# 登录成功后浏览器最终跳转的前端域名
DOMAIN=https://cadb.dvb.corpinter.net.cn
# 前端回调路由(带前缀)
FRONTEND_CALLBACK_PATH=/accidentportal/callback
# 图片上传
UPLOAD_FOLDER=/app/uploads UPLOAD_FOLDER=/app/uploads
MAX_CONTENT_LENGTH=5242880 MAX_CONTENT_LENGTH=5242880
IMAGE_BASE_URL=http://150.158.236.152:5221 IMAGE_BASE_URL=https://cadb.dvb.corpinter.net.cn/accidentportal
# 前端请求头key # 前端请求头 key
HEADERS_SECRET_KEY=mbincid-server12 HEADERS_SECRET_KEY=mbincid-server12
+8 -2
View File
@@ -1,6 +1,6 @@
server { server {
listen 80; listen 80;
server_name 150.158.236.152; server_name cadb.dvb.corpinter.net.cn;
client_max_body_size 100M; client_max_body_size 100M;
# root /usr/share/nginx/html; # root /usr/share/nginx/html;
include /etc/nginx/mime.types; include /etc/nginx/mime.types;
@@ -39,7 +39,7 @@ server {
proxy_busy_buffers_size 256k; proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 1024m; proxy_max_temp_file_size 1024m;
proxy_pass http://172.17.0.1:5221/accidentportal/api/; proxy_pass https://cadb.dvb.corpinter.net.cn/accidentportal/api/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -53,6 +53,12 @@ server {
# 关键:Cookie处理 # 关键:Cookie处理
proxy_cookie_path / "/; SameSite=Lax"; proxy_cookie_path / "/; SameSite=Lax";
} }
# 图片/上传(IMAGE_BASE_URL + file_path 拼成 /uploads/...
location /accidentportal/uploads/ {
proxy_pass https://cadb.dvb.corpinter.net.cn/accidentportal/uploads/;
proxy_set_header Host $host;
}
} }
+1 -1
View File
@@ -13,7 +13,7 @@ VITE_GLOB_APP_TITLE="RDCA_Incidents Data Portal"
VITE_ENV=test VITE_ENV=test
# 登录跳转 # 登录跳转
VITE_LOGIN_URL = http://localhost:5221/accidentportal/user/login VITE_LOGIN_URL = /api/user/login
# 请求头的密钥 # 请求头的密钥
VITE_APP_CHECK_KEY = 'mbincid-server12' VITE_APP_CHECK_KEY = 'mbincid-server12'
+9 -9
View File
@@ -1,14 +1,14 @@
# 接口前缀(相对路径,走 nginx 反代)
VITE_APP_BASE_API=/accidentportal/api VITE_APP_BASE_API=/accidentportal/api
VITE_APP_BASE_URL=http://150.158.236.152:5221 # 站点域名
# The title of your application (string) VITE_APP_BASE_URL=https://cadb.dvb.corpinter.net.cn
VITE_GLOB_APP_TITLE="RDCA_Incidents Data Portal" VITE_GLOB_APP_TITLE="RDCA_Incidents Data Portal"
# 登录跳转 # 登录入口:整页跳到后端 SSO 入口(经 nginx /accidentportal/api 反代)
# VITE_LOGIN_URL = http://150.158.236.152:5221/login VITE_LOGIN_URL=/accidentportal/api/user/login
VITE_LOGIN_URL = http://150.158.236.152:5221/accidentportal/api/user/login
# 请求头的密钥 VITE_APP_CHECK_KEY='mbincid-server12'
VITE_APP_CHECK_KEY = 'mbincid-server12'
# 前端配置域名加的前缀 # 前端路由/资源前缀
VITE_APP_DOMAIN_PREFIX = 'accidentportal' VITE_APP_DOMAIN_PREFIX='accidentportal'
+1 -1
View File
@@ -53,7 +53,7 @@ onMounted(async () => {
// console.log(`Redirecting to: ${redirectPath}`); // console.log(`Redirecting to: ${redirectPath}`);
// router.push({name:"report"}); // router.push({name:"report"});
// } // }
window.location.href = 'https://cadb.dvb.corpinter.net.cn/accidentportal/oauth/report' window.location.href = `${import.meta.env.BASE_URL}oauth/report`
} else { } else {
console.error("No authentication cookies found"); console.error("No authentication cookies found");
error.value = "Authentication failed: missing cookies"; error.value = "Authentication failed: missing cookies";
+1 -1
View File
@@ -37,7 +37,7 @@ const router = createRouter({
...staticRoutes, ...staticRoutes,
...routes ...routes
], ],
history: createWebHistory(import.meta.env.VITE_APP_DOMAIN_PREFIX), //accidentportal history: createWebHistory(import.meta.env.BASE_URL), // dev: '/' prod: '/accidentportal/'
// history: createWebHashHistory('/accidentportal/'), //accidentportal // history: createWebHashHistory('/accidentportal/'), //accidentportal
}) })
+1 -2
View File
@@ -28,9 +28,8 @@ async function requestHandler(config: InternalAxiosRequestConfig & RequestConfig
import.meta.env.DEV import.meta.env.DEV
&& import.meta.env.VITE_APP_BASE_API_DEV && import.meta.env.VITE_APP_BASE_API_DEV
&& import.meta.env.VITE_APP_BASE_URL_DEV && import.meta.env.VITE_APP_BASE_URL_DEV
&& config.customDev
) { ) {
// 替换url的请求前缀baseUrl // 开发环境统一使用 /api 前缀(由 vite 代理重写为后端真实前缀)
config.baseURL = import.meta.env.VITE_APP_BASE_API_DEV config.baseURL = import.meta.env.VITE_APP_BASE_API_DEV
} }
// console.log('Request URL:', config.baseURL) // console.log('Request URL:', config.baseURL)
-31
View File
@@ -11,32 +11,19 @@ declare module 'vue' {
AAlert: typeof import('ant-design-vue/es')['Alert'] AAlert: typeof import('ant-design-vue/es')['Alert']
AApp: typeof import('ant-design-vue/es')['App'] AApp: typeof import('ant-design-vue/es')['App']
AAvatar: typeof import('ant-design-vue/es')['Avatar'] AAvatar: typeof import('ant-design-vue/es')['Avatar']
AAvatarGroup: typeof import('ant-design-vue/es')['AvatarGroup']
ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb'] ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem'] ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem']
AButton: typeof import('ant-design-vue/es')['Button'] AButton: typeof import('ant-design-vue/es')['Button']
ACard: typeof import('ant-design-vue/es')['Card'] ACard: typeof import('ant-design-vue/es')['Card']
ACardGrid: typeof import('ant-design-vue/es')['CardGrid']
ACardMeta: typeof import('ant-design-vue/es')['CardMeta']
Access: typeof import('./../src/components/access/index.vue')['default'] Access: typeof import('./../src/components/access/index.vue')['default']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
ACol: typeof import('ant-design-vue/es')['Col'] ACol: typeof import('ant-design-vue/es')['Col']
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider'] AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
ADescriptions: typeof import('ant-design-vue/es')['Descriptions']
ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem']
ADivider: typeof import('ant-design-vue/es')['Divider'] ADivider: typeof import('ant-design-vue/es')['Divider']
ADrawer: typeof import('ant-design-vue/es')['Drawer'] ADrawer: typeof import('ant-design-vue/es')['Drawer']
ADropdown: typeof import('ant-design-vue/es')['Dropdown'] ADropdown: typeof import('ant-design-vue/es')['Dropdown']
AForm: typeof import('ant-design-vue/es')['Form'] AForm: typeof import('ant-design-vue/es')['Form']
AFormItem: typeof import('ant-design-vue/es')['FormItem'] AFormItem: typeof import('ant-design-vue/es')['FormItem']
AFormItemRest: typeof import('ant-design-vue/es')['FormItemRest']
AImage: typeof import('ant-design-vue/es')['Image']
AImagePreviewGroup: typeof import('ant-design-vue/es')['ImagePreviewGroup']
AInput: typeof import('ant-design-vue/es')['Input'] AInput: typeof import('ant-design-vue/es')['Input']
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
AInputSearch: typeof import('ant-design-vue/es')['InputSearch'] AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
ALayout: typeof import('ant-design-vue/es')['Layout'] ALayout: typeof import('ant-design-vue/es')['Layout']
ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent'] ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent']
@@ -49,36 +36,19 @@ declare module 'vue' {
AMenu: typeof import('ant-design-vue/es')['Menu'] AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider'] AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal']
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
AProgress: typeof import('ant-design-vue/es')['Progress']
ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker'] ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
AResult: typeof import('ant-design-vue/es')['Result']
ARow: typeof import('ant-design-vue/es')['Row'] ARow: typeof import('ant-design-vue/es')['Row']
ASelect: typeof import('ant-design-vue/es')['Select'] ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption'] ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASpace: typeof import('ant-design-vue/es')['Space'] ASpace: typeof import('ant-design-vue/es')['Space']
ASpin: typeof import('ant-design-vue/es')['Spin'] ASpin: typeof import('ant-design-vue/es')['Spin']
AStatistic: typeof import('ant-design-vue/es')['Statistic']
AStatisticCountdown: typeof import('ant-design-vue/es')['StatisticCountdown']
AStep: typeof import('ant-design-vue/es')['Step']
ASteps: typeof import('ant-design-vue/es')['Steps']
ASubMenu: typeof import('ant-design-vue/es')['SubMenu'] ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
ASwitch: typeof import('ant-design-vue/es')['Switch'] ASwitch: typeof import('ant-design-vue/es')['Switch']
ATable: typeof import('ant-design-vue/es')['Table'] ATable: typeof import('ant-design-vue/es')['Table']
ATabPane: typeof import('ant-design-vue/es')['TabPane'] ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs'] ATabs: typeof import('ant-design-vue/es')['Tabs']
ATag: typeof import('ant-design-vue/es')['Tag'] ATag: typeof import('ant-design-vue/es')['Tag']
ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
ATooltip: typeof import('ant-design-vue/es')['Tooltip'] ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect']
ATypographyParagraph: typeof import('ant-design-vue/es')['TypographyParagraph']
ATypographyText: typeof import('ant-design-vue/es')['TypographyText']
AUpload: typeof import('ant-design-vue/es')['Upload']
AWatermark: typeof import('ant-design-vue/es')['Watermark'] AWatermark: typeof import('ant-design-vue/es')['Watermark']
BaseLoading: typeof import('./../src/components/base-loading/index.vue')['default'] BaseLoading: typeof import('./../src/components/base-loading/index.vue')['default']
CarbonLanguage: typeof import('./../src/components/icons/carbon-language.vue')['default'] CarbonLanguage: typeof import('./../src/components/icons/carbon-language.vue')['default']
@@ -101,7 +71,6 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
SelectLang: typeof import('./../src/components/select-lang/index.vue')['default'] SelectLang: typeof import('./../src/components/select-lang/index.vue')['default']
TokenProvider: typeof import('./../src/components/token-provider/index.vue')['default'] TokenProvider: typeof import('./../src/components/token-provider/index.vue')['default']
Tooltip: typeof import('ant-design-vue/es')['Tooltip']
UserAvatar: typeof import('./../src/components/user-avatar/index.vue')['default'] UserAvatar: typeof import('./../src/components/user-avatar/index.vue')['default']
VirtualList: typeof import('./../src/components/virtual-list/index.vue')['default'] VirtualList: typeof import('./../src/components/virtual-list/index.vue')['default']
} }
+6 -5
View File
@@ -22,16 +22,17 @@ export default ({ mode }: ConfigEnv): UserConfig => {
// } // }
// } // }
if (mode === 'development' && env.VITE_APP_BASE_API && env.VITE_APP_BASE_URL) { if (mode === 'development' && env.VITE_APP_BASE_API_DEV && env.VITE_APP_BASE_URL_DEV) {
proxyObj[env.VITE_APP_BASE_API] = { proxyObj[env.VITE_APP_BASE_API_DEV] = {
target: env.VITE_APP_BASE_URL, target: env.VITE_APP_BASE_URL_DEV,
changeOrigin: true, changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${env.VITE_APP_BASE_API}`), ''), // 浏览器请求 /api/xxx,转发给后端时补上域名前缀 -> /accidentportal/api/xxx
rewrite: path => path.replace(new RegExp(`^${env.VITE_APP_BASE_API_DEV}`), '/accidentportal/api'),
} }
} }
return { return {
base: '/accidentportal/', base: mode === 'development' ? '/' : '/accidentportal/',
plugins: createVitePlugins(env), plugins: createVitePlugins(env),
resolve: { resolve: {
alias: [ alias: [