ReactNative项目OpenHarmony三方库集成实战:react-native-permissions
权限管理是至关重要的一环。无论是访问相机、麦克风、位置信息还是读取联系人,都需要先获取用户的授权。是 React Native 生态中最流行的权限管理库,提供了统一的跨平台权限申请和检查 API。库名称版本信息4.1.3: 支持 RN 0.72 版本5.3.1: 支持 RN 0.77 版本官方仓库鸿蒙仓库主要功能🔍 检查权限状态📝 申请权限🔧 批量权限管理⚙️ 打开系统设置import {}
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

📋 前言
权限管理是至关重要的一环。无论是访问相机、麦克风、位置信息还是读取联系人,都需要先获取用户的授权。react-native-permissions 是 React Native 生态中最流行的权限管理库,提供了统一的跨平台权限申请和检查 API。
🎯 库简介
基本信息
- 库名称:
react-native-permissions - 版本信息:
4.1.3+@react-native-ohos/react-native-permissions: 支持 RN 0.72 版本5.3.1+@react-native-ohos/react-native-permissions: 支持 RN 0.77 版本
- 官方仓库: https://github.com/zoontek/react-native-permissions
- 鸿蒙仓库: https://github.com/react-native-oh-library/react-native-permissions
- 主要功能:
- 🔍 检查权限状态
- 📝 申请权限
- 🔧 批量权限管理
- ⚙️ 打开系统设置
为什么需要 react-native-permissions?
| 特性 | React Native 原生 Permissions | react-native-permissions |
|---|---|---|
| 统一 API | ❌ 平台差异大 | ✅ 跨平台一致 |
| 权限检查 | ⚠️ 需自行实现 | ✅ 内置支持 |
| 批量操作 | ❌ 不支持 | ✅ 支持多权限 |
| 类型安全 | ❌ 不支持 | ✅ TypeScript 支持 |
| HarmonyOS 支持 | ❌ 不支持 | ✅ 完全支持 |
支持的功能
| 功能 | 说明 | HarmonyOS 支持 |
|---|---|---|
| check | 检查单个权限 | ✅ |
| request | 申请单个权限 | ✅ |
| checkMultiple | 检查多个权限 | ✅ |
| requestMultiple | 申请多个权限 | ✅ |
| checkNotifications | 检查通知权限 | ✅ |
| requestNotifications | 申请通知权限 | ✅ |
| openSettings | 打开系统设置 | ✅ |
| openPhotoPicker | 打开图片选择器 | ✅ |
📦 安装步骤
1. 安装依赖
在项目根目录执行以下命令:
# RN 0.72 版本
npm install @react-native-ohos/react-native-permissions@4.1.3-rc.1
# RN 0.77 版本
npm install @react-native-ohos/react-native-permissions@5.3.1-rc.1
2. 验证安装
安装完成后,检查 package.json 中是否包含:
{
"dependencies": {
"@react-native-ohos/react-native-permissions": "^4.1.3-rc.1"
}
}
🔧 HarmonyOS 平台配置
权限声明
在 harmony/entry/src/main/module.json5 中声明需要的权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_permission_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:microphone_permission_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:location_permission_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.READ_CALENDAR",
"reason": "$string:read_calendar_reason",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.ACCESS_BLUETOOTH",
"reason": "$string:bluetooth_reason",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
}
]
}
}
在 harmony/entry/src/main/resources/zh_CN/element/string.json 中添加权限说明:
{
"string": [
{
"name": "camera_permission_reason",
"value": "用于拍照和录制视频"
},
{
"name": "microphone_permission_reason",
"value": "用于录音和语音识别"
},
{
"name": "location_permission_reason",
"value": "用于获取位置信息"
},
{
"name": "read_calendar_reason",
"value": "用于读取日历信息"
},
{
"name": "bluetooth_reason",
"value": "用于连接蓝牙设备"
}
]
}
权限等级说明
HarmonyOS 权限分为两个等级:
| 等级 | 说明 | 配置要求 |
|---|---|---|
normal |
普通权限,风险较低 | 正常签名即可 |
system_basic |
系统基础权限,风险较高 | 需要 ACL 签名配置 |
normal 权限列表:
ohos.permission.APPROXIMATELY_LOCATION- 模糊位置ohos.permission.LOCATION- 精确位置ohos.permission.CAMERA- 相机ohos.permission.MICROPHONE- 麦克风ohos.permission.READ_CALENDAR- 读取日历ohos.permission.WRITE_CALENDAR- 写入日历ohos.permission.READ_MEDIA- 读取媒体文件ohos.permission.ACCESS_BLUETOOTH- 蓝牙
system_basic 权限列表(需要 ACL 签名):
ohos.permission.READ_CONTACTS- 读取联系人ohos.permission.WRITE_CONTACTS- 写入联系人ohos.permission.READ_IMAGEVIDEO- 读取图片视频ohos.permission.WRITE_IMAGEVIDEO- 写入图片视频ohos.permission.READ_AUDIO- 读取音频ohos.permission.WRITE_AUDIO- 写入音频
system_basic 权限签名配置
对于 system_basic 级别权限,需要修改签名模板并重新签名。
步骤 1:修改 Debug 签名模板
找到 SDK 目录下的签名模板文件:
{SDK路径}/openharmony/toolchains/lib/UnsgnedDebugProfileTemplate.json
例如:d:\DevEco Studio\sdk\default\openharmony\toolchains\lib\UnsgnedDebugProfileTemplate.json
打开文件,修改以下内容:
1. 将 APL 等级从 normal 改为 system_basic:
"bundle-info": {
...
"apl": "system_basic",
...
}
2. 在 acls 中添加允许的权限:
"acls": {
"allowed-acls": [
"ohos.permission.READ_CONTACTS",
"ohos.permission.WRITE_CONTACTS",
"ohos.permission.READ_IMAGEVIDEO",
"ohos.permission.WRITE_IMAGEVIDEO"
]
}
修改后的完整示例:
{
"version-name": "2.0.0",
"version-code": 2,
"uuid": "fe686e37-****-****-****-************",
"validity": {
"not-before": 1594865258,
"not-after": 1689473258
},
"type": "debug",
"bundle-info": {
"developer-id": "OpenHarmony",
"development-certificate": "...",
"bundle-name": "com.OpenHarmony.app.test",
"apl": "system_basic",
"app-feature": "hos_normal_app"
},
"acls": {
"allowed-acls": [
"ohos.permission.READ_CONTACTS",
"ohos.permission.WRITE_CONTACTS",
"ohos.permission.READ_IMAGEVIDEO",
"ohos.permission.WRITE_IMAGEVIDEO"
]
},
"permissions": {
"restricted-permissions": []
},
"issuer": "pki_internal"
}
步骤 2:在 DevEco Studio 中重新签名
- 打开 DevEco Studio
- 点击 File > Project Structure > Project > Signing Configs
- 取消勾选 “Automatically generate signature”
- 重新勾选 “Automatically generate signature”
- 等待自动签名完成
- 点击 OK
步骤 3:重新运行应用
签名完成后,重新运行应用即可正常安装。
⚠️ 注意:修改签名模板后必须重新签名才能生效。如果仍然报错 9568289,请尝试清理项目后重新构建。
原生模块配置(RN 0.72)
1. 引入原生端代码
打开 harmony/entry/oh-package.json5,添加依赖:
"dependencies": {
"@rnoh/react-native-openharmony": "0.72.90",
"@react-native-ohos/react-native-permissions": "file:../../node_modules/@react-native-ohos/react-native-permissions/harmony/permissions.har"
}
点击右上角的 sync 按钮,或在终端执行:
cd harmony/entry
ohpm install
2. 配置 CMakeLists.txt
打开 harmony/entry/src/main/cpp/CMakeLists.txt,添加:
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
# RNOH_BEGIN: manual_package_linking_1
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-permissions/src/main/cpp" ./permissions)
# RNOH_END: manual_package_linking_1
# RNOH_BEGIN: manual_package_linking_2
+ target_link_libraries(rnoh_app PUBLIC rnoh_permissions)
# RNOH_END: manual_package_linking_2
3. 配置 PackageProvider.cpp
打开 harmony/entry/src/main/cpp/PackageProvider.cpp,添加:
+ #include "PermissionsPackage.h"
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
+ std::make_shared<PermissionsPackage>(ctx),
};
}
4. 配置 RNPackagesFactory.ts
打开 harmony/entry/src/main/ets/RNPackagesFactory.ts,添加:
+ import {PermissionsPackage} from '@react-native-ohos/react-native-permissions/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
+ new PermissionsPackage(ctx)
];
}
📖 API 详解
权限状态常量
| 状态 | 说明 | 值 |
|---|---|---|
| RESULTS.UNAVAILABLE | 设备不支持 | ‘unavailable’ |
| RESULTS.DENIED | 未授权 | ‘denied’ |
| RESULTS.GRANTED | 已授权 | ‘granted’ |
| RESULTS.BLOCKED | 被拒绝且不再询问 | ‘blocked’ |
基础 API
check(permission: string): Promise<PermissionStatus>
检查单个权限的状态。
import { check, RESULTS } from 'react-native-permissions';
const checkCameraPermission = async () => {
const result = await check('ohos.permission.CAMERA');
switch (result) {
case RESULTS.UNAVAILABLE:
console.log('设备不支持相机');
break;
case RESULTS.DENIED:
console.log('相机权限未授权');
break;
case RESULTS.GRANTED:
console.log('相机权限已授权');
break;
case RESULTS.BLOCKED:
console.log('相机权限被拒绝且不再询问');
break;
}
return result;
};
request(permission: string): Promise<PermissionStatus>
申请单个权限。
import { request, RESULTS } from 'react-native-permissions';
const requestCameraPermission = async () => {
const result = await request('ohos.permission.CAMERA');
if (result === RESULTS.GRANTED) {
console.log('相机权限申请成功');
// 执行需要相机权限的操作
} else {
console.log('相机权限申请失败');
}
return result;
};
checkMultiple(permissions: string[]): Promise<Record<string, PermissionStatus>>
批量检查多个权限。
import { checkMultiple } from 'react-native-permissions';
const checkMultiplePermissions = async () => {
const statuses = await checkMultiple([
'ohos.permission.CAMERA',
'ohos.permission.MICROPHONE',
'ohos.permission.LOCATION',
]);
console.log('相机权限:', statuses['ohos.permission.CAMERA']);
console.log('麦克风权限:', statuses['ohos.permission.MICROPHONE']);
console.log('位置权限:', statuses['ohos.permission.LOCATION']);
return statuses;
};
requestMultiple(permissions: string[]): Promise<Record<string, PermissionStatus>>
批量申请多个权限。
import { requestMultiple, RESULTS } from 'react-native-permissions';
const requestMultiplePermissions = async () => {
const statuses = await requestMultiple([
'ohos.permission.CAMERA',
'ohos.permission.MICROPHONE',
]);
// 检查是否所有权限都已授权
const allGranted = Object.values(statuses).every(
status => status === RESULTS.GRANTED
);
if (allGranted) {
console.log('所有权限申请成功');
} else {
console.log('部分权限申请失败');
}
return statuses;
};
其他 API
openSettings(): Promise<void>
打开系统设置页面,引导用户手动授权。
import { openSettings } from 'react-native-permissions';
const handleOpenSettings = async () => {
await openSettings();
// 用户可以在设置中手动开启权限
};
checkNotifications(): Promise<NotificationsResponse>
检查通知权限状态。
import { checkNotifications } from 'react-native-permissions';
const checkNotificationPermission = async () => {
const { status, settings } = await checkNotifications();
console.log('通知权限状态:', status);
return status;
};
requestNotifications(options: NotificationOption[]): Promise<NotificationsResponse>
申请通知权限。
import { requestNotifications } from 'react-native-permissions';
const requestNotificationPermission = async () => {
const { status } = await requestNotifications(['alert', 'sound', 'badge']);
console.log('通知权限申请结果:', status);
return status;
};
📱 完整示例

本节展示一个完整的权限管理应用,包含权限检查、申请、批量操作等功能。
import React, { useState, useEffect, useCallback } from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
ScrollView,
Alert,
SafeAreaView,
} from 'react-native';
import {
check,
request,
checkMultiple,
requestMultiple,
openSettings,
checkNotifications,
requestNotifications,
RESULTS,
} from 'react-native-permissions';
interface PermissionItem {
name: string;
permission: string;
status: string;
}
const PermissionsDemo = () => {
const [permissions, setPermissions] = useState<PermissionItem[]>([
{ name: '相机', permission: 'ohos.permission.CAMERA', status: 'checking' },
{ name: '麦克风', permission: 'ohos.permission.MICROPHONE', status: 'checking' },
{ name: '位置', permission: 'ohos.permission.APPROXIMATELY_LOCATION', status: 'checking' },
{ name: '日历', permission: 'ohos.permission.READ_CALENDAR', status: 'checking' },
{ name: '蓝牙', permission: 'ohos.permission.ACCESS_BLUETOOTH', status: 'checking' },
]);
const [notificationStatus, setNotificationStatus] = useState<string>('checking');
// 检查所有权限状态
const checkAllPermissions = useCallback(async () => {
const permissionNames = permissions.map(p => p.permission);
const statuses = await checkMultiple(permissionNames);
setPermissions(prev =>
prev.map(item => ({
...item,
status: statuses[item.permission],
}))
);
}, [permissions]);
// 检查通知权限
const checkNotification = useCallback(async () => {
const { status } = await checkNotifications();
setNotificationStatus(status);
}, []);
// 申请单个权限
const requestSinglePermission = async (permission: string, name: string) => {
const result = await request(permission);
if (result === RESULTS.GRANTED) {
Alert.alert('成功', `${name}权限申请成功`);
} else if (result === RESULTS.BLOCKED) {
Alert.alert(
'权限被拒绝',
`${name}权限被拒绝且不再询问,是否前往设置手动开启?`,
[
{ text: '取消', style: 'cancel' },
{ text: '前往设置', onPress: openSettings },
]
);
} else {
Alert.alert('失败', `${name}权限申请失败`);
}
// 刷新权限状态
checkAllPermissions();
};
// 申请所有权限
const requestAllPermissions = async () => {
const permissionNames = permissions.map(p => p.permission);
const statuses = await requestMultiple(permissionNames);
const grantedCount = Object.values(statuses).filter(
status => status === RESULTS.GRANTED
).length;
Alert.alert(
'权限申请完成',
`共申请 ${permissionNames.length} 个权限,成功 ${grantedCount} 个`
);
checkAllPermissions();
};
// 申请通知权限
const requestNotification = async () => {
const { status } = await requestNotifications(['alert', 'sound']);
setNotificationStatus(status);
if (status === RESULTS.GRANTED) {
Alert.alert('成功', '通知权限申请成功');
} else {
Alert.alert('失败', '通知权限申请失败');
}
};
// 获取状态颜色
const getStatusColor = (status: string) => {
switch (status) {
case RESULTS.GRANTED:
return '#4CAF50';
case RESULTS.DENIED:
return '#FF9800';
case RESULTS.BLOCKED:
return '#F44336';
case RESULTS.UNAVAILABLE:
return '#9E9E9E';
default:
return '#2196F3';
}
};
// 获取状态文本
const getStatusText = (status: string) => {
switch (status) {
case RESULTS.GRANTED:
return '已授权';
case RESULTS.DENIED:
return '未授权';
case RESULTS.BLOCKED:
return '已拒绝';
case RESULTS.UNAVAILABLE:
return '不支持';
default:
return '检查中';
}
};
useEffect(() => {
checkAllPermissions();
checkNotification();
}, []);
return (
<SafeAreaView style={styles.container}>
<Text style={styles.title}>权限管理</Text>
<ScrollView style={styles.scrollView}>
{/* 通知权限 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>通知权限</Text>
<View style={styles.permissionItem}>
<View style={styles.permissionInfo}>
<Text style={styles.permissionName}>推送通知</Text>
<View style={[styles.statusBadge, { backgroundColor: getStatusColor(notificationStatus) }]}>
<Text style={styles.statusText}>{getStatusText(notificationStatus)}</Text>
</View>
</View>
<TouchableOpacity
style={styles.button}
onPress={requestNotification}
>
<Text style={styles.buttonText}>申请</Text>
</TouchableOpacity>
</View>
</View>
{/* 普通权限列表 */}
<View style={styles.section}>
<View style={styles.sectionHeader}>
<Text style={styles.sectionTitle}>应用权限</Text>
<TouchableOpacity onPress={requestAllPermissions}>
<Text style={styles.linkText}>申请全部</Text>
</TouchableOpacity>
</View>
{permissions.map((item, index) => (
<View key={index} style={styles.permissionItem}>
<View style={styles.permissionInfo}>
<Text style={styles.permissionName}>{item.name}</Text>
<View style={[styles.statusBadge, { backgroundColor: getStatusColor(item.status) }]}>
<Text style={styles.statusText}>{getStatusText(item.status)}</Text>
</View>
</View>
<TouchableOpacity
style={[styles.button, item.status === RESULTS.GRANTED && styles.buttonDisabled]}
onPress={() => requestSinglePermission(item.permission, item.name)}
disabled={item.status === RESULTS.GRANTED}
>
<Text style={styles.buttonText}>
{item.status === RESULTS.GRANTED ? '已开启' : '申请'}
</Text>
</TouchableOpacity>
</View>
))}
</View>
{/* 刷新按钮 */}
<TouchableOpacity style={styles.refreshButton} onPress={checkAllPermissions}>
<Text style={styles.refreshButtonText}>刷新权限状态</Text>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
paddingVertical: 16,
backgroundColor: '#fff',
},
scrollView: {
flex: 1,
},
section: {
backgroundColor: '#fff',
marginTop: 8,
paddingHorizontal: 16,
paddingVertical: 12,
},
sectionHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 12,
},
sectionTitle: {
fontSize: 18,
fontWeight: '600',
color: '#333',
},
linkText: {
color: '#2196F3',
fontSize: 14,
},
permissionItem: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 12,
borderBottomWidth: 1,
borderBottomColor: '#f0f0f0',
},
permissionInfo: {
flexDirection: 'row',
alignItems: 'center',
flex: 1,
},
permissionName: {
fontSize: 16,
color: '#333',
flex: 1,
},
statusBadge: {
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 4,
marginRight: 12,
},
statusText: {
color: '#fff',
fontSize: 12,
fontWeight: '500',
},
button: {
backgroundColor: '#2196F3',
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 4,
minWidth: 60,
alignItems: 'center',
},
buttonDisabled: {
backgroundColor: '#ccc',
},
buttonText: {
color: '#fff',
fontSize: 14,
fontWeight: '500',
},
refreshButton: {
backgroundColor: '#4CAF50',
margin: 16,
paddingVertical: 14,
borderRadius: 8,
alignItems: 'center',
},
refreshButtonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
});
export default PermissionsDemo;
🔧 高级技巧
1. 封装权限工具类
// utils/permissions.ts
import {
check,
request,
checkMultiple,
requestMultiple,
openSettings,
RESULTS,
} from 'react-native-permissions';
export class PermissionUtil {
// 检查并申请权限
static async checkAndRequest(permission: string): Promise<boolean> {
const result = await check(permission);
if (result === RESULTS.GRANTED) {
return true;
}
if (result === RESULTS.BLOCKED) {
// 权限被永久拒绝,引导用户去设置
return false;
}
const requestResult = await request(permission);
return requestResult === RESULTS.GRANTED;
}
// 检查多个权限是否都授权
static async checkAllGranted(permissions: string[]): Promise<boolean> {
const statuses = await checkMultiple(permissions);
return Object.values(statuses).every(status => status === RESULTS.GRANTED);
}
// 获取未授权的权限列表
static async getDeniedPermissions(permissions: string[]): Promise<string[]> {
const statuses = await checkMultiple(permissions);
return permissions.filter(
permission => statuses[permission] !== RESULTS.GRANTED
);
}
}
2. 自定义 Hook
// hooks/usePermissions.ts
import { useState, useEffect, useCallback } from 'react';
import { checkMultiple, RESULTS } from 'react-native-permissions';
export const usePermissions = (permissions: string[]) => {
const [statuses, setStatuses] = useState<Record<string, string>>({});
const [loading, setLoading] = useState(true);
const checkPermissions = useCallback(async () => {
setLoading(true);
const result = await checkMultiple(permissions);
setStatuses(result);
setLoading(false);
}, [permissions]);
const allGranted = Object.values(statuses).every(
status => status === RESULTS.GRANTED
);
useEffect(() => {
checkPermissions();
}, [checkPermissions]);
return { statuses, loading, allGranted, refresh: checkPermissions };
};
3. 权限申请流程封装
// 拍照权限申请流程
export const requestCameraPermissionFlow = async () => {
const result = await request('ohos.permission.CAMERA');
if (result === RESULTS.GRANTED) {
// 可以拍照
return true;
}
if (result === RESULTS.BLOCKED) {
Alert.alert(
'需要相机权限',
'请在设置中开启相机权限以使用拍照功能',
[
{ text: '取消', style: 'cancel' },
{ text: '去设置', onPress: openSettings },
]
);
}
return false;
};
❓ 常见问题
1. 权限申请无响应
问题:调用 request() 后没有弹出权限申请对话框。
解决方案:
- 检查
module.json5中是否正确声明了权限 - 检查权限字符串是否正确(区分大小写)
- 确保权限不是
system_basic级别(需要特殊签名)
// 正确的权限字符串
'ohos.permission.CAMERA'
'ohos.permission.MICROPHONE'
'ohos.permission.APPROXIMATELY_LOCATION'
2. 权限状态始终返回 denied
问题:即使已经授权,check() 仍然返回 denied。
解决方案:
- 检查权限名称是否拼写正确
- 确认权限已在
module.json5中声明 - 尝试重新安装应用
3. system_basic 权限申请失败
问题:申请 system_basic 级别权限时失败。
解决方案:
- 修改签名模板的
apl为system_basic - 在
acls中添加需要的权限 - 重新签名并安装应用
4. TypeScript 类型错误
问题:使用 PERMISSIONS.HARMONY.XXX 时报类型错误。
解决方案:
// 直接使用权限字符串,不要使用 PERMISSIONS 对象
const result = await request('ohos.permission.CAMERA');
// 或者从 @react-native-ohos/react-native-permissions 导入
import { PERMISSIONS } from '@react-native-ohos/react-native-permissions';
📚 参考资料
✅ 总结
react-native-permissions 是一个功能强大的权限管理库,在 HarmonyOS 平台上也能良好运行。通过本文的介绍,你应该能够:
- ✅ 完成库的安装和配置
- ✅ 掌握权限检查和申请的基本操作
- ✅ 实现批量权限管理
- ✅ 处理权限被拒绝的情况
- ✅ 区分 normal 和 system_basic 权限
在实际开发中,建议根据应用功能需求合理申请权限,避免一次性申请过多权限导致用户体验下降。对于 system_basic 级别权限,需要特别注意签名配置。
更多推荐



所有评论(0)