# 微信登录、企业微信登录与Fake登录流程详细文档

## 文档概述

本文档详细描述了智柜宝系统中三种登录方式的完整流程、参数说明、返回信息及实现逻辑。

## 一、微信登录（普通微信公众号登录）

### 1.1 登录流程图

```
用户访问应用
    ↓
检查微信环境（micromessenger）
    ↓
跳转微信授权页面
    ↓
用户授权
    ↓
微信回调携带 code 和 state
    ↓
调用 getOpenIdApi 换取 openid
    ↓
调用 getBalanceApi 获取余额
    ↓
完成认证
```

### 1.2 核心实现

#### 前端回调处理（`src/main.ts` 或页面组件）

```typescript
onMounted(() => {
  const urlParams = new URLSearchParams(window.location.search);
  const code = urlParams.get('code');
  const state = urlParams.get('state');

  if (code) {
    wxStore.handleWxCallback({ code, state });
  }
});
```

#### Store 处理逻辑（`src/pinia/stores/wx.ts:81-147`）

```typescript
const handleWxCallback = async (params: { corpid?: string; code?: string; state?: string; }) => {
  isHandleWxCallbackComplete.value = false;

  if (params.code) {
    code.value = params.code;
    state.value = params.state || state.value;
    corpid.value = params.corpid || corpid.value;
    corpidLogin.value = !!corpid.value;

    try {
      // 微信公众号登录（无 corpid）
      if (!corpid.value) {
        const res = await getOpenIdApi({ code: params.code });
        if (res && res.code == 0) {
          openid.value = res.data;
        }

        // 获取余额信息
        if (openid.value) {
          corpid.value = "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw"; // 默认企业ID
          const balanceRes = await getBalanceApi(corpid.value, openid.value);
          if (balanceRes && balanceRes.code == 0) {
            balance.value = balanceRes.data.balance;
            useBalance.value = balanceRes.data.useBalance;
            balanceLimit.value = balanceRes.data.balanceLimit;
            userid.value = balanceRes.data.userid;
            if (!ab98User.value && balanceRes.data.ab98User) {
              setAb98User(balanceRes.data.ab98User);
            }
          }
        }
      }
    } catch (err) {
      console.error('获取 openid 失败:', err);
    } finally {
      isHandleWxCallbackComplete.value = true;
    }
  } else {
    isHandleWxCallbackComplete.value = true;
  }
};
```

### 1.3 API 接口详情

#### 获取 OpenID

**接口地址**: `GET /api/v1/payment/getOpenId`

**请求参数**:
```typescript
interface GetOpenIdRequestParams {
  code: string;  // 微信授权后返回的授权码
}
```

**返回数据**:
```typescript
interface ApiResponseData<T> {
  code: number;  // 状态码：0 表示成功
  msg: string;   // 消息
  data: string;  // openid 字符串
}
```

**示例响应**:
```json
{
  "code": 0,
  "msg": "success",
  "data": "oMRxw6Eum0DB1IjI_pEX_yrawBHw"
}
```

#### 获取余额

**接口地址**: `GET /api/v1/payment/getBalance`

**请求参数**:
```typescript
{
  corpid: string;   // 企业ID
  openid: string;   // 微信用户唯一标识
}
```

**返回数据**:
```typescript
interface GetBalanceResponse {
  userid: string;        // 系统用户ID
  corpid: string;        // 企业ID
  balance: number;       // 剩余借呗
  useBalance: number;    // 已用借呗
  balanceLimit: number;  // 借呗总额
  ab98User: ab98UserDTO; // 汇邦云用户信息
}
```

**示例响应**:
```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "userid": "woZ1ZrEgAAV9AEdRt1MGQxSg-KDJrDlA",
    "corpid": "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw",
    "balance": 5000,
    "useBalance": 2000,
    "balanceLimit": 7000,
    "ab98User": {
      "userid": "123456",
      "name": "张三",
      "tel": "13800138000",
      "sex": "男",
      "faceImg": "https://example.com/avatar.jpg",
      "registered": true,
      "ab98Balance": 10000
    }
  }
}
```

### 1.4 微信授权 URL 生成

```typescript
const generateWxAuthUrl = () => {
  const appId = import.meta.env.VITE_WX_APP_ID;
  const redirectUri = encodeURIComponent(window.location.origin + '/callback');
  const scope = 'snsapi_userinfo'; // 或 snsapi_base
  const state = Math.random().toString(36).substring(2, 15);

  return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
};
```

**参数说明**:
- `appid`: 微信公众号的 AppID
- `redirect_uri`: 授权后回调的网址（需 URL 编码）
- `scope`: 授权范围
  - `snsapi_base`: 静默授权，只能获取 openid
  - `snsapi_userinfo`: 需用户授权，可获取用户信息
- `state`: 自定义参数，用于防止 CSRF 攻击

---

## 二、企业微信登录

### 2.1 登录流程图

```
用户访问应用
    ↓
检测 URL 中的 corpid 参数
    ↓
跳转企业微信授权页面
    ↓
用户授权
    ↓
企业微信回调携带 corpid、code、state
    ↓
调用 qyLogin 验证并获取用户信息
    ↓
调用 getBalanceByQyUserid 获取余额
    ↓
关联 AB98 用户系统
    ↓
完成认证
```

### 2.2 核心实现

#### 路由守卫处理（`src/router/guard.ts:22-31`）

```typescript
// 企业微信登录参数检测
const urlParams = new URLSearchParams(window.location.search);
const corpid = urlParams.get('corpid') || undefined;
if (corpid) {
  return true;
}
const isAdmin = urlParams.get('isAdmin') || undefined;
if (isAdmin) {
  return true;
}
```

#### Store 处理逻辑（`src/pinia/stores/wx.ts:93-109`）

```typescript
if (!corpid.value) {
  // 微信公众号登录
  const res = await getOpenIdApi({ code: params.code });
  if (res && res.code == 0) {
    openid.value = res.data;
  }
} else {
  // 企业微信登录
  const res = await qyLogin({
    corpid: corpid.value,
    code: params.code,
    state: params.state
  });

  if (res && res.code == 0) {
    userid.value = res.data.userid;           // 系统用户ID
    openid.value = res.data.openid;           // 微信 openid
    isCabinetAdmin.value = res.data.isCabinetAdmin === 1; // 是否为柜子管理员
    name.value = res.data.name;               // 用户姓名
    qyUserId.value = res.data.qyUserId;       // 企业微信用户ID
    setAb98User(res.data.ab98User);           // 设置 AB98 用户信息
  }
}
```

#### 余额获取（`src/pinia/stores/wx.ts:66-79`）

```typescript
const refreshBalance = async () => {
  if (corpid.value && userid.value) {
    const res = await getBalanceByQyUserid(corpid.value, userid.value);
    if (res && res.code == 0) {
      balance.value = res.data.balance;
      useBalance.value = res.data.useBalance;
      balanceLimit.value = res.data.balanceLimit;

      if (res.data.ab98User) {
        setAb98User(res.data.ab98User);
      }
    }
  }
};
```

### 2.3 API 接口详情

#### 企业微信登录

**接口地址**: `GET /api/v1/payment/login/qy`

**请求参数**:
```typescript
interface QyLoginRequestParams {
  corpid: string;  // 企业ID
  code: string;    // 企业微信授权后返回的授权码
  state?: string;  // 状态参数（防CSRF）
}
```

**返回数据**:
```typescript
interface QyLoginDTO {
  userid: string;           // 系统用户ID
  openid: string;           // 微信 openid
  isCabinetAdmin: number;   // 是否为柜子管理员（1是 0否）
  qyUserId: number;         // 企业微信用户ID
  name: string;             // 用户姓名
  ab98User: ab98UserDTO;    // 汇邦云用户信息
}
```

**示例响应**:
```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "userid": "woZ1ZrEgAAV9AEdRt1MGQxSg-KDJrDlA",
    "openid": "oMRxw6Eum0DB1IjI_pEX_yrawBHw",
    "isCabinetAdmin": 1,
    "qyUserId": 10001,
    "name": "张三",
    "ab98User": {
      "userid": "123456",
      "name": "张三",
      "tel": "13800138000",
      "sex": "男",
      "faceImg": "https://example.com/avatar.jpg",
      "registered": true,
      "ab98Balance": 10000
    }
  }
}
```

#### 根据企业微信用户ID获取余额

**接口地址**: `GET /api/v1/payment/getBalanceByQyUserid`

**请求参数**:
```typescript
{
  corpid: string;   // 企业ID
  userid: string;   // 系统用户ID
}
```

**返回数据**: 同 `GetBalanceResponse` 结构

### 2.4 企业微信授权 URL 生成

```typescript
const generateQyWxAuthUrl = () => {
  const corpid = import.meta.env.VITE_WX_CORP_ID;
  const redirectUri = encodeURIComponent(window.location.origin + '/callback');
  const scope = 'snsapi_base'; // 企业微信通常使用 base
  const state = Math.random().toString(36).substring(2, 15);

  return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${corpid}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
};
```

---

## 三、Fake登录（模拟企业微信登录）

### 3.1 应用场景

Fake登录用于开发测试环境，模拟企业微信登录流程，无需真实的企业微信授权，直接使用预设的测试账号信息。

### 3.2 登录流程图

```
触发 fake 登录
    ↓
设置 fake 登录状态
    ↓
设置默认企业ID
    ↓
设置默认用户ID
    ↓
调用 fakeQyLoginApi
    ↓
获取模拟用户信息
    ↓
完成认证
```

### 3.3 核心实现（`src/pinia/stores/wx.ts:149-163`）

```typescript
const fakeQyLogin = async () => {
  isFakeQyLogin.value = true;         // 标记为 fake 登录
  corpid.value = "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw"; // 默认企业ID
  corpidLogin.value = true;            // 标记为企业微信登录
  userid.value = "woZ1ZrEgAAV9AEdRt1MGQxSg-KDJrDlA"; // 默认用户ID

  // 调用 fake API
  const res = await fakeQyLoginApi({ corpid: corpid.value, userid: userid.value });

  if (res && res.code == 0) {
    userid.value = res.data.userid;
    openid.value = "oMRxw6Eum0DB1IjI_pEX_yrawBHw"; // 固定的测试 openid
    isCabinetAdmin.value = res.data.isCabinetAdmin === 1;
    name.value = res.data.name;
    qyUserId.value = res.data.qyUserId;
    setAb98User(res.data.ab98User);
  }
};
```

### 3.4 API 接口详情

**接口地址**: `GET /api/v1/payment/login/qy/fake`

**请求参数**:
```typescript
{
  corpid: string;   // 企业ID
  userid: string;   // 系统用户ID
}
```

**返回数据**: 与 `QyLoginDTO` 相同

**示例响应**:
```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "userid": "woZ1ZrEgAAV9AEdRt1MGQxSg-KDJrDlA",
    "openid": "oMRxw6Eum0DB1IjI_pEX_yrawBHw",
    "isCabinetAdmin": 1,
    "qyUserId": 10001,
    "name": "测试用户",
    "ab98User": {
      "userid": "123456",
      "name": "测试用户",
      "tel": "13800138000",
      "sex": "男",
      "faceImg": "https://example.com/test-avatar.jpg",
      "registered": true,
      "ab98Balance": 10000
    }
  }
}
```

### 3.5 调用方式

#### 在页面中调用

```typescript
import { useWxStore } from '@/pinia/stores/wx';

const wxStore = useWxStore();

// 触发 fake 登录
const handleFakeLogin = () => {
  wxStore.fakeQyLogin();
};
```

#### 在组件模板中调用

```vue
<template>
  <van-button @click="wxStore.fakeQyLogin">
    模拟登录
  </van-button>
</template>
```

---

## 四、状态管理（Pinia Store）

### 4.1 WxStore 状态定义（`src/pinia/stores/wx.ts:7-38`）

```typescript
export const useWxStore = defineStore("wx", () => {
  // 授权信息
  const code = ref<string>("");           // 微信授权 code
  const state = ref<string>("");          // 防CSRF的state参数

  // 用户标识
  const openid = ref<string>("");         // 微信用户唯一标识
  const userid = ref<string>("");         // 系统用户ID
  const qyUserId = ref<number>(0);        // 企业微信用户ID

  // 企业信息
  const corpid = ref<string>("");         // 企业ID
  const corpidLogin = ref<boolean>(false);// 是否企业微信登录

  // 用户信息
  const isCabinetAdmin = ref<boolean>(false);  // 是否是柜子管理员
  const name = ref<string>("");               // 企业微信用户姓名
  const ab98User = ref<ab98UserDTO | null>(null); // 汇邦云用户信息

  // 余额信息
  const balance = ref<number>(0);        // 剩余借呗
  const useBalance = ref<number>(0);     // 已用借呗
  const balanceLimit = ref<number>(0);   // 借呗总额

  // 登录状态
  const isFakeQyLogin = ref<boolean>(false);  // 是否fake登录
  const isHandleWxCallbackComplete = ref<boolean>(false); // 回调处理是否完成
});
```

### 4.2 AB98用户Store（`src/pinia/stores/ab98-user.ts`）

```typescript
export const useAb98UserStore = defineStore("ab98User", () => {
  // 用户基本信息
  const face_img = ref<string>('');   // 用户头像
  const sex = ref<string>('');        // 性别
  const name = ref<string>('');       // 姓名
  const userid = ref<string>("");     // 用户ID
  const registered = ref<boolean>(false); // 是否已注册
  const tel = ref<string>("");        // 手机号
  const token = ref<string>("");      // 认证令牌

  // 登录状态
  const isLogin = ref<boolean>(false);
  const tokenLogin = ref<string>("");
  const loginCode = '1';              // 默认验证码
});
```

### 4.3 核心方法

#### 设置 AB98 用户信息

```typescript
const setAb98User = (user: ab98UserDTO) => {
  ab98User.value = user;
  const ab98UserStore = useAb98UserStore();
  ab98UserStore.setUserInfo({
    face_img: ab98User.value.faceImg || "",
    success: true,
    sex: ab98User.value.sex || "",
    name: ab98User.value.name || "",
    userid: ab98User.value.userid || "",
    registered: true,
    tel: ab98User.value.tel || "",
  });
};
```

#### 等待回调完成

```typescript
const waitForHandleWxCallbackComplete = async (timeout = 30000): Promise<boolean> => {
  const startTime = Date.now();
  while (!isHandleWxCallbackComplete.value) {
    if (Date.now() - startTime > timeout) {
      console.warn('等待 handleWxCallback 完成超时');
      return false;
    }
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  return true;
};
```

---

## 五、数据类型定义

### 5.1 ab98UserDTO

```typescript
interface ab98UserDTO {
  /** 主键ID */
  ab98UserId?: number;
  /** openid */
  openid?: string;
  /** 汇邦云用户唯一ID */
  userid?: string;
  /** 真实姓名 */
  name?: string;
  /** 手机号码 */
  tel?: string;
  /** 身份证号码 */
  idnum?: string;
  /** 性别（男 女） */
  sex?: string;
  /** 人脸照片地址 */
  faceImg?: string;
  /** 身份证正面地址 */
  idcardFront?: string;
  /** 身份证背面地址 */
  idcardBack?: string;
  /** 身份证登记地址 */
  address?: string;
  /** 是否已注册（0未注册 1已注册） */
  registered?: boolean;
  /** 借呗余额 单位分 */
  ab98Balance?: number;
}
```

### 5.2 通用响应类型

```typescript
interface ApiResponseData<T> {
  code: number;    // 状态码：0表示成功，其他值表示失败
  msg: string;     // 消息
  data: T;         // 数据
}

interface ApiResponseMsgData<T> {
  code: number;    // 状态码
  msg: string;     // 消息
  data: T;         // 数据
}
```

---

## 六、环境配置

### 6.1 环境变量

#### 开发环境（`.env.development`）

```env
# 微信公众号配置
VITE_WX_APP_ID=your_dev_app_id
VITE_WX_CORP_ID=your_dev_corp_id

# API 基础地址
VITE_BASE_URL=https://apifoxmock.com/m1/2930465-2145633-default
```

#### 生产环境（`.env.production`）

```env
# 微信公众号配置
VITE_WX_APP_ID=your_prod_app_id
VITE_WX_CORP_ID=your_prod_corp_id

# API 基础地址
VITE_BASE_URL=https://api.example.com
```

### 6.2 微信环境检测（`src/common/utils/wx.ts`）

```typescript
function checkInWeChat(targetUrl: string) {
  const ua = navigator.userAgent.toLowerCase();
  if (!ua.includes('micromessenger')) {
    // 不在微信内，提示用户在微信中打开
    const weChatUrl = `weixin://dl/business/?t=${encodeURIComponent(targetUrl)}`;
    window.location.href = weChatUrl;

    setTimeout(() => {
      if (document.hidden) return;
      alert("未检测到微信，请手动打开微信并访问链接。");
    }, 2000);
  } else {
    console.log("已在微信内，无需跳转");
  }
}
```

---

## 七、路由守卫与权限控制

### 7.1 登录检查（`src/router/guard.ts`）

```typescript
router.beforeEach((to, _from) => {
  // 检测企业微信登录参数
  const urlParams = new URLSearchParams(window.location.search);
  const corpid = urlParams.get('corpid') || undefined;
  if (corpid) return true;

  const isAdmin = urlParams.get('isAdmin') || undefined;
  if (isAdmin) return true;

  // 检查 AB98 用户登录状态
  const ab98UserStore = useAb98UserStore();
  if (!ab98UserStore.isLogin) {
    if (isWhiteList(to)) return true;  // 白名单页面直接访问
    return "/ab98";                    // 重定向到登录页
  }

  return true;
});
```

### 7.2 等待认证完成

在页面组件中使用：

```vue
<script setup lang="ts">
import { useWxStore } from '@/pinia/stores/wx';

const wxStore = useWxStore();

onMounted(async () => {
  const success = await wxStore.waitForHandleWxCallbackComplete();
  if (!success) {
    console.error('微信认证超时');
  }
});
</script>

<template>
  <div v-if="!wxStore.isHandleWxCallbackComplete">
    <van-loading>微信认证中...</van-loading>
  </div>
  <div v-else>
    <!-- 页面内容 -->
  </div>
</template>
```

---

## 八、错误处理与调试

### 8.1 常见错误

#### 1. 微信认证失败

**可能原因**:
- 回调域名未在微信公众平台配置
- AppID 或 Secret 错误
- 网络问题导致 API 调用失败

**解决方案**:
```typescript
const retryWxAuth = async (maxRetries = 3) => {
  for (let i = 0; i < maxRetries; i++) {
    try {
      await wxStore.handleWxCallback(params);
      if (wxStore.isHandleWxCallbackComplete) break;
    } catch (error) {
      console.error(`微信认证重试 ${i + 1} 失败:`, error);
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }
};
```

#### 2. OpenID 获取失败

**调试方法**:
```typescript
const debugWxAuth = async () => {
  console.log('当前 URL 参数:', window.location.search);

  const urlParams = new URLSearchParams(window.location.search);
  const code = urlParams.get('code');

  if (!code) {
    console.error('未获取到微信 code');
    return;
  }

  console.log('获取到 code:', code);

  try {
    const response = await getOpenIdApi({ code });
    console.log('OpenID 响应:', response);
  } catch (error) {
    console.error('获取 OpenID 失败:', error);
  }
};
```

### 8.2 日志输出

在关键位置添加日志：

```typescript
const handleWxCallback = async (params: any) => {
  console.log('=== 微信回调开始 ===');
  console.log('参数:', params);
  console.log('corpid:', corpid.value);
  console.log('corpidLogin:', corpidLogin.value);

  // ... 处理逻辑

  console.log('=== 微信回调完成 ===');
};
```

---

## 九、最佳实践

### 9.1 安全性

1. **CSRF 防护**
   - 使用 `state` 参数防止 CSRF 攻击
   - 生成随机字符串作为 `state` 值

2. **Token 加密**
   ```typescript
   const encryptToken = (token: string) => {
     return btoa(encodeURIComponent(token));
   };
   ```

3. **敏感信息存储**
   - 避免在 localStorage 中存储敏感信息
   - 使用加密后存储

### 9.2 性能优化

1. **减少 API 调用**
   ```typescript
   const cachedUserInfo = ref<ab98UserDTO | null>(null);

   const getUserInfo = async (forceRefresh = false) => {
     if (cachedUserInfo.value && !forceRefresh) {
       return cachedUserInfo.value;
     }
     const userInfo = await fetchUserInfo();
     cachedUserInfo.value = userInfo;
     return userInfo;
   };
   ```

2. **并行请求**
   ```typescript
   const loadUserData = async () => {
     const [userInfo, balanceInfo] = await Promise.all([
       getUserInfo(),
       getBalanceInfo()
     ]);
     return { userInfo, balanceInfo };
   };
   ```

### 9.3 用户体验

1. **加载状态提示**
   ```vue
   <template>
     <van-loading v-if="loading">认证中...</van-loading>
     <div v-else>页面内容</div>
   </template>
   ```

2. **错误提示**
   ```typescript
   const handleError = (error: any) => {
     Toast.fail(error.message || '操作失败');
   };
   ```

---

## 十、测试

### 10.1 单元测试

```typescript
// tests/stores/wx.test.ts
import { describe, it, expect } from "vitest";
import { setActivePinia, createPinia } from "pinia";
import { useWxStore } from "@/pinia/stores/wx";

describe("Wx Store", () => {
  beforeEach(() => {
    setActivePinia(createPinia());
  });

  it("应该处理微信回调", async () => {
    const wxStore = useWxStore();
    await wxStore.handleWxCallback({
      code: "test_code",
      state: "test_state"
    });
    expect(wxStore.code).toBe("test_code");
    expect(wxStore.state).toBe("test_state");
  });

  it("应该进行 fake 登录", async () => {
    const wxStore = useWxStore();
    await wxStore.fakeQyLogin();
    expect(wxStore.isFakeQyLogin).toBe(true);
  });
});
```

### 10.2 集成测试

```typescript
// tests/integration/login.test.ts
describe("登录流程集成测试", () => {
  it("应该完成完整的微信认证流程", async () => {
    // 1. 模拟微信回调
    const params = { code: "test_code", state: "test_state" };

    // 2. 处理回调
    await wxStore.handleWxCallback(params);

    // 3. 验证状态更新
    expect(wxStore.isHandleWxCallbackComplete).toBe(true);

    // 4. 检查用户信息
    expect(wxStore.openid).toBeTruthy();
  });
});
```

---

## 十一、总结

### 11.1 三种登录方式对比

| 特性 | 微信登录 | 企业微信登录 | Fake登录 |
|------|----------|--------------|----------|
| 触发方式 | 微信授权回调 | 企业微信授权回调 | 手动调用 |
| 依赖 | 微信公众号 | 企业微信 | 无 |
| 适用环境 | 生产/测试 | 生产/测试 | 仅测试 |
| 获取openid | ✓ | ✓ | ✓（模拟） |
| 获取用户信息 | ✓ | ✓ | ✓（模拟） |
| 获取余额 | ✓ | ✓ | ✓（模拟） |
| 管理员权限 | 根据后端返回 | 根据后端返回 | 根据后端返回 |

### 11.2 关键要点

1. **微信登录**：使用 `snsapi_userinfo` 或 `snsapi_base` 授权，通过 `code` 获取 `openid`
2. **企业微信登录**：需要 `corpid` 参数，通过 `code` 获取企业微信用户信息
3. **Fake登录**：仅用于测试环境，直接使用预设的测试账号
4. **状态管理**：使用 Pinia 管理登录状态和用户信息
5. **余额系统**：通过 `balance`、`useBalance`、`balanceLimit` 管理借呗额度
6. **AB98集成**：三种登录方式最终都会关联到汇邦云用户系统

### 11.3 开发注意事项

1. 确保在微信/企业微信环境下测试
2. 正确配置回调域名
3. 使用 `state` 参数防止 CSRF 攻击
4. 合理处理 API 调用错误
5. 在测试环境使用 Fake 登录提高效率
6. 遵循状态管理最佳实践

---

**文档版本**: v1.0
**最后更新**: 2025-11-07
**维护者**: 智柜宝开发团队
