aslan-admin/docs/问题排查记录-权限平台与开发服务地址.md
2026-04-20 18:08:00 +08:00

213 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 问题排查记录:权限平台默认值与开发服务 Network 地址
## 记录时间
- 2026-04
## 背景
本次排查涉及两个独立但连续出现的问题:
1. 页面初始化时,`this.permissionsSysOriginPlatforms[0]` 偶发拿不到,导致默认平台没有赋值,后续 `renderData(true)` 不执行。
2. 本地执行 `npm run dev` 后,控制台一直显示 `Network: unavailable`,但同机器的其他项目可以正常显示类似 `http://192.168.0.115:5173/` 的局域网访问地址。
---
## 一、权限平台默认值偶发为空
### 现象
页面中存在如下初始化逻辑:
```js
const querySystem = this.permissionsSysOriginPlatforms[0];
if (!querySystem) {
return;
}
that.listQuery.sysOrigins = [querySystem.value];
that.renderData(true);
```
`this.permissionsSysOriginPlatforms[0]` 为空时,页面会直接返回,默认查询条件与首屏数据都不会初始化。
### 结论
`permissionsSysOriginPlatforms` 不是接口直接返回的平台数组,而是:
1. 按钮权限接口先返回权限别名列表。
2. 前端再用本地写死的 `sysOriginPlatforms` 常量进行过滤。
3. 过滤结果再写入 Vuex页面最终通过 getter 读取。
也就是说:
- 平台候选项来源于前端常量。
- 当前用户能拿到哪些平台,取决于按钮权限接口返回的权限别名。
### 关键代码链路
- 页面读取位置:`src/views/user/user-table/index.vue`
- getter 映射位置:`src/store/getters.js`
- Vuex 组装位置:`src/store/modules/user.js`
- 平台常量定义:`src/constant/origin.js`
- 按钮权限接口:`src/api/ops-system.js`
### 根因
根因是时序问题,不是页面本地代码本身写错:
1. 路由守卫中会调用 `store.dispatch('user/buttonPermissions')`
2. 但原逻辑没有 `await` 这个异步请求。
3. 页面已经进入并执行 `created()` 时,权限数据可能还没回填到 Vuex。
4. 于是 `this.permissionsSysOriginPlatforms[0]` 偶发为空。
另外还有一个补充前提:
- 当前前端常量里只有 `ATYOU` 一个系统平台,并且依赖权限 `query:atyou`
- 如果接口没有返回这个权限,过滤后数组本身也会为空。
### 已做处理
已在 `src/permission.js` 中将:
```js
store.dispatch('user/buttonPermissions')
```
修改为:
```js
await store.dispatch('user/buttonPermissions')
```
### 处理结果
调整后,路由放行前会先等待按钮权限加载完成,页面 `created()` 再读取 `permissionsSysOriginPlatforms` 时,不会再因为异步竞争导致首项为空。
### 后续建议
- 若后续仍出现空数组,需要优先检查接口返回是否包含 `query:atyou`
- 如果页面还需要进一步增强健壮性,可以在页面侧增加 watcher 或兜底默认逻辑,但当前首先应保证路由阶段权限已完成回填。
---
## 二、开发服务 `Network: unavailable`
### 现象
执行 `npm run dev` 后输出类似:
```txt
App running at:
- Local: http://localhost:9528
- Network: unavailable
```
但同一台机器上的其他项目可以正常显示局域网访问地址。
### 初步排查结论
这不是项目无法启动,也不是没有局域网 IP而是 Vue CLI 选错了网卡。
通过系统网络信息确认:
- 当前机器存在可用私网地址:`192.168.0.115`
- 同时还存在一个虚拟网卡地址:`26.26.26.1`
### 根因
项目使用的是较老版本的 `@vue/cli-service 3.6.0`
该版本在生成 `Network` 地址时,会在内部调用 `address.ip()` 取一个 IPv4 地址,然后只接受以下私网地址范围:
- `10.x.x.x`
- `172.16.x.x``172.31.x.x`
- `192.168.x.x`
如果拿到的不是私网地址,就会直接将 `Network` 显示为 `unavailable`
本次机器环境中Vue CLI 优先拿到的是虚拟网卡 `26.26.26.1`,由于它不属于私网范围,因此被直接丢弃,最终控制台显示 `Network: unavailable`
### 关键代码位置
- 输出逻辑:`node_modules/@vue/cli-service/lib/commands/serve.js`
- 局域网地址选择逻辑:`node_modules/@vue/cli-service/lib/util/prepareURLs.js`
### 已尝试处理
#### 第一步
先在 `vue.config.js` 中增加:
```js
host: '0.0.0.0'
```
目的:
- 让 dev server 监听所有网卡,而不是只监听本机回环地址。
结果:
- 监听范围已放开。
-`Network` 仍然显示 `unavailable`
- 说明问题不在监听地址,而在 Vue CLI 的网卡识别逻辑。
#### 第二步
`vue.config.js` 中新增自定义 LAN IP 选择逻辑,替代 Vue CLI 默认的“随便取一个 IPv4”的方式。
处理思路:
1. 使用 `os.networkInterfaces()` 枚举网卡。
2. 只保留私网 IPv4。
3. 优先选择 `WLAN / Wi-Fi / Ethernet / 以太网` 这类常见真实网卡。
4. 排除 `TAP / VPN / Virtual / VMware / Hyper-V / Docker / vEthernet` 等虚拟网卡。
5. 将最终结果写入 `devServer.public`
### 当前配置结果
`vue.config.js` 已调整为:
- `host: '0.0.0.0'`
- `public: lanIp ? \`${lanIp}:${port}\` : undefined`
并增加了自动识别私网地址的辅助函数。
### 处理结果
此修改的目的不是单纯让服务“能访问”,而是:
1. 明确让服务监听所有网卡。
2. 明确告诉旧版 Vue CLI 应该向外公布哪个局域网地址。
3. 避免其误选虚拟网卡后把 Network 判成 unavailable。
### 备用方案
如果后续本机 IP 变化,或当前网络环境特殊,也可以临时手动指定:
```powershell
$env:DEV_SERVER_PUBLIC_IP='192.168.0.115'
npm run dev
```
或:
```powershell
npm run dev -- --public 192.168.0.115:9528
```
---
## 本次涉及的改动文件
- `src/permission.js`
- `vue.config.js`
- `docs/问题排查记录-权限平台与开发服务地址.md`
## 本次经验总结
1. 页面里出现“偶发空值”时,优先检查数据来源是不是异步回填,而不是只盯页面局部逻辑。
2. `permissionsSysOriginPlatforms` 这类字段要区分“候选项来源”和“最终权限结果来源”。
3. 老版本 Vue CLI 对网卡选择并不稳定,机器上存在 VPN、TAP、虚拟网卡时`Network: unavailable` 往往是地址识别问题,不代表 dev server 本身不可用。
4. 对局域网访问有明确需求的项目,最好显式配置 `devServer.host``devServer.public`,不要完全依赖工具链自动推断。