# 问题排查记录：权限平台默认值与开发服务 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`，不要完全依赖工具链自动推断。
