# MX 原生桥接 API 使用指南

## 概述

`core/mxApi` 是敏行混合应用的原生桥接模块，提供与原生 Android/iOS 应用通信的能力。

## 功能列表

### UI 控制

```typescript
import { hideWebViewTitle, showOptionMenu, setCustomHeaderMenu } from '@/core/mxApi'

// 隐藏原生标题栏
hideWebViewTitle()

// 显示右上角菜单
showOptionMenu()

// 设置自定义菜单
setCustomHeaderMenu({
  menus: [
    { id: '1', title: '设置' },
    { id: '2', title: '关于' }
  ]
})
```

### 获取用户信息

```typescript
import { getCurrentUser } from '@/core/mxApi'

const user = await getCurrentUser()
console.log(user.id, user.name, user.token)
```

### 选人组件

```typescript
import { MXSelectUsers } from '@/core/mxApi'

const users = await MXSelectUsers({
  enableSelectDept: false,  // 是否允许选择部门
  canSelectSelf: true       // 是否可选自己
})

console.log('选中的用户:', users)
```

### 原生 HTTP 请求（绕过跨域）

```typescript
import { ajaxGet, ajaxPost, ajaxPut, ajaxDelete } from '@/core/mxApi'

// GET 请求
const { data } = await ajaxGet('/api/users', { page: 1, limit: 10 })

// POST 请求
const { data } = await ajaxPost('/api/users', { name: '张三' })

// PUT 请求
await ajaxPut('/api/users/123', { name: '李四' })

// DELETE 请求
await ajaxDelete('/api/users', '123')
```

### 环境检测

```typescript
import { isNativeApp } from '@/core/mxApi'

if (isNativeApp()) {
  // 在原生环境中，可使用所有原生 API
  const user = await getCurrentUser()
} else {
  // 在浏览器中，使用 axios 或降级方案
  import('@/utils/request').then(({ request }) => {
    // 使用 axios 发起请求
  })
}
```

## 与 axios 的区别

| 特性 | axios | MX ajax |
|------|-------|---------|
| 跨域限制 | 受同源策略限制 | 无限制 |
| 认证信息 | 需手动添加 Token | 可复用原生层认证 |
| 网络代理 | 无 | 使用原生层代理配置 |
| SSL 证书 | 浏览器验证 | 可使用企业证书 |
| 适用环境 | 浏览器、WebView | 仅混合应用原生环境 |

## 项目中的两种 HTTP 方案

### 方案 1：axios（默认）

```typescript
// src/utils/request.ts
import axios from 'axios'
import { apiConfig } from '@/config/env'

const service = axios.create({
  baseURL: apiConfig.baseURL,
  timeout: apiConfig.timeout,
})

export default service
```

**适用场景**：
- 浏览器开发调试
- 不需要绕过跨域限制
- 使用标准 RESTful API

### 方案 2：原生 AJAX

```typescript
// src/core/mxApi/index.ts
import { ajaxGet, ajaxPost } from '@/core/mxApi'

// 使用原生 HTTP 客户端
const { data } = await ajaxGet('/api/users')
```

**适用场景**：
- 需要绕过浏览器跨域限制
- 使用原生层认证信息
- 需要企业证书支持
- 在敏行 App 中运行

## 智能切换示例

```typescript
import { isNativeApp, ajaxGet as nativeGet } from '@/core/mxApi'
import { request } from '@/utils/request'

export async function fetchUsers(page: number) {
  if (isNativeApp()) {
    // 使用原生 AJAX
    const { data } = await nativeGet('/api/users', { page })
    return data
  } else {
    // 使用 axios
    const res = await request({
      url: '/api/users',
      params: { page }
    })
    return res.data
  }
}
```

## 注意事项

### 1. 设备就绪机制

mxApi 内置任务队列，在设备未就绪时会自动缓存调用请求。无需手动处理 `deviceready` 事件。

### 2. 环境变量

原生 AJAX 使用 `VITE_API_BASE_URL` 作为基础 URL，与 axios 配置保持一致。

### 3. 错误处理

当原生接口不存在时，会抛出错误。建议在调用前检测环境：

```typescript
import { isNativeApp } from '@/core/mxApi'

if (!isNativeApp()) {
  showToast('请在敏行 App 中使用此功能')
  return
}
```

### 4. TypeScript 类型支持

所有 API 都有完整的类型定义，包括：
- `MXUser` - 用户信息
- `MXSelectUsersOptions` - 选人配置
- `MXAjaxResponse<T>` - AJAX 响应

## 开发调试

在浏览器中开发时，原生接口不可用。建议：

1. **使用条件判断**：根据环境选择不同的请求方式
2. **使用 Vant 组件**：如 `showToast` 显示提示
3. **日志输出**：mxApi 会自动输出调用日志

```typescript
// 开发环境提示
if (!isNativeApp()) {
  console.warn('当前为浏览器环境，原生 API 不可用')
}
```

## 完整示例

```vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { showToast } from 'vant'
import { isNativeApp, getCurrentUser, MXSelectUsers } from '@/core/mxApi'
import type { MXUser } from '@/core/mxApi'

const user = ref<MXUser | null>(null)
const selectedUsers = ref<MXUser[]>([])

onMounted(async () => {
  if (isNativeApp()) {
    try {
      user.value = await getCurrentUser()
      showToast(`欢迎, ${user.value.name}`)
    } catch (err) {
      console.error('获取用户失败:', err)
    }
  }
})

const handleSelectUsers = async () => {
  if (!isNativeApp()) {
    showToast('请在敏行 App 中使用')
    return
  }

  try {
    selectedUsers.value = await MXSelectUsers()
    showToast(`已选择 ${selectedUsers.value.length} 人`)
  } catch (err) {
    console.error('选人失败:', err)
  }
}
</script>

<template>
  <div>
    <van-cell title="当前用户" :value="user?.name || '未登录'" />
    <van-button @click="handleSelectUsers">选择联系人</van-button>
  </div>
</template>
```
