11
This commit is contained in:
parent
0ef962e5ba
commit
fc87ad0b3d
11
App.tsx
11
App.tsx
|
|
@ -1,4 +1,5 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { useEffect } from 'react';
|
||||||
import { NavigationContainer } from '@react-navigation/native';
|
import { NavigationContainer } from '@react-navigation/native';
|
||||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||||
import { View, StyleSheet, Image, Platform } from 'react-native';
|
import { View, StyleSheet, Image, Platform } from 'react-native';
|
||||||
|
|
@ -9,7 +10,7 @@ import { enableScreens } from 'react-native-screens';
|
||||||
import HomeStackNavigator from './src/views/HomeStackNavigator';
|
import HomeStackNavigator from './src/views/HomeStackNavigator';
|
||||||
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
|
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
|
||||||
import { rpx } from './src/utils/rpx';
|
import { rpx } from './src/utils/rpx';
|
||||||
|
import { AMapSdk, MapView, Marker, MapType } from 'react-native-amap3d';
|
||||||
enableScreens();
|
enableScreens();
|
||||||
|
|
||||||
type RootStackParamList = {
|
type RootStackParamList = {
|
||||||
|
|
@ -21,6 +22,14 @@ type RootStackParamList = {
|
||||||
const Tab = createBottomTabNavigator<RootStackParamList>();
|
const Tab = createBottomTabNavigator<RootStackParamList>();
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
useEffect(() => {
|
||||||
|
AMapSdk.init(
|
||||||
|
Platform.select({
|
||||||
|
android: "812efd3a950ba3675f928630302c6463",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const getTabBarVisibility = (route: any) => {
|
const getTabBarVisibility = (route: any) => {
|
||||||
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
|
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
|
||||||
const showOnScreens = ['Home']; // 只在 Home 页面显示底部导航栏
|
const showOnScreens = ['Home']; // 只在 Home 页面显示底部导航栏
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,9 @@ android {
|
||||||
compileSdk rootProject.ext.compileSdkVersion
|
compileSdk rootProject.ext.compileSdkVersion
|
||||||
|
|
||||||
namespace "com.bikeapp_demo"
|
namespace "com.bikeapp_demo"
|
||||||
|
configurations {
|
||||||
|
all*.exclude group: 'com.amap.api', module: 'location'
|
||||||
|
}
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
missingDimensionStrategy 'react-native-camera', 'general'
|
missingDimensionStrategy 'react-native-camera', 'general'
|
||||||
applicationId "com.bikeapp_demo"
|
applicationId "com.bikeapp_demo"
|
||||||
|
|
@ -111,6 +114,8 @@ dependencies {
|
||||||
implementation "com.google.android.gms:play-services-vision:20.1.3"
|
implementation "com.google.android.gms:play-services-vision:20.1.3"
|
||||||
implementation "com.google.android.gms:play-services-vision-common:19.1.3"
|
implementation "com.google.android.gms:play-services-vision-common:19.1.3"
|
||||||
implementation project(':react-native-camera')
|
implementation project(':react-native-camera')
|
||||||
|
implementation 'com.amap.api:3dmap:latest.integration'
|
||||||
|
implementation 'com.amap.api:location:latest.integration'
|
||||||
if (hermesEnabled.toBoolean()) {
|
if (hermesEnabled.toBoolean()) {
|
||||||
implementation("com.facebook.react:hermes-android")
|
implementation("com.facebook.react:hermes-android")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/google' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/public' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("com.android.tools.build:gradle")
|
classpath("com.android.tools.build:gradle")
|
||||||
|
|
@ -17,5 +20,16 @@ buildscript {
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
// 添加阿里云 maven 镜像
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/google' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/public' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
|
||||||
|
// 原有的仓库配置
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
apply plugin: "com.facebook.react.rootproject"
|
apply plugin: "com.facebook.react.rootproject"
|
||||||
|
|
|
||||||
41
package-lock.json
generated
41
package-lock.json
generated
|
|
@ -9,13 +9,14 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/geolocation": "^3.4.0",
|
"@react-native-community/geolocation": "^3.4.0",
|
||||||
|
"@react-native-community/slider": "^4.5.5",
|
||||||
|
"@react-native-picker/picker": "^2.9.0",
|
||||||
"@react-navigation/bottom-tabs": "^6.4.0",
|
"@react-navigation/bottom-tabs": "^6.4.0",
|
||||||
"@react-navigation/native": "^6.1.18",
|
"@react-navigation/native": "^6.1.18",
|
||||||
"@react-navigation/stack": "^6.3.8",
|
"@react-navigation/stack": "^6.3.8",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.74.5",
|
"react-native": "0.74.5",
|
||||||
"react-native-amap-geolocation": "^1.2.3",
|
|
||||||
"react-native-amap3d": "^3.0.7",
|
"react-native-amap3d": "^3.0.7",
|
||||||
"react-native-camera": "^4.2.1",
|
"react-native-camera": "^4.2.1",
|
||||||
"react-native-gesture-handler": "^2.20.2",
|
"react-native-gesture-handler": "^2.20.2",
|
||||||
|
|
@ -24,7 +25,8 @@
|
||||||
"react-native-qrcode-scanner": "^1.5.5",
|
"react-native-qrcode-scanner": "^1.5.5",
|
||||||
"react-native-reanimated": "^3.16.1",
|
"react-native-reanimated": "^3.16.1",
|
||||||
"react-native-safe-area-context": "^4.14.0",
|
"react-native-safe-area-context": "^4.14.0",
|
||||||
"react-native-screens": "^3.35.0"
|
"react-native-screens": "^3.35.0",
|
||||||
|
"react-native-wheel-picker-android": "^2.0.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
|
|
@ -2799,6 +2801,20 @@
|
||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native-community/slider": {
|
||||||
|
"version": "4.5.5",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@react-native-community/slider/-/slider-4.5.5.tgz",
|
||||||
|
"integrity": "sha512-x2N415pg4ZxIltArOKczPwn7JEYh+1OxQ4+hTnafomnMsqs65HZuEWcX+Ch8c5r8V83DiunuQUf5hWGWlw8hQQ=="
|
||||||
|
},
|
||||||
|
"node_modules/@react-native-picker/picker": {
|
||||||
|
"version": "2.9.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@react-native-picker/picker/-/picker-2.9.0.tgz",
|
||||||
|
"integrity": "sha512-khEhIW/uhfMqq/+tvg4rEAiPGT8GX+Y6QydlP2TSMSmRHoSJK+ShXvXZXSr4Sii4imkj4BwvLunGywwtQDODqg==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-native/assets-registry": {
|
"node_modules/@react-native/assets-registry": {
|
||||||
"version": "0.74.87",
|
"version": "0.74.87",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -8305,6 +8321,14 @@
|
||||||
"mkdirp": "bin/cmd.js"
|
"mkdirp": "bin/cmd.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.30.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
|
||||||
|
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
|
|
@ -9055,11 +9079,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-native-amap-geolocation": {
|
|
||||||
"version": "1.2.3",
|
|
||||||
"resolved": "https://registry.npmmirror.com/react-native-amap-geolocation/-/react-native-amap-geolocation-1.2.3.tgz",
|
|
||||||
"integrity": "sha512-NKQG1eKJGHFnSGAMtsXZYfoKzlDAyK23cuKaIcJaWfa0kNr23pVrxOss3TcNRZTu8Syr9AwRus7I0PLGEcAaNA=="
|
|
||||||
},
|
|
||||||
"node_modules/react-native-amap3d": {
|
"node_modules/react-native-amap3d": {
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -9179,6 +9198,14 @@
|
||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-native-wheel-picker-android": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-native-wheel-picker-android/-/react-native-wheel-picker-android-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-gwstWymEZUmSokWKDQufD3t/alSRkYDTSEe3YrtsDtpcKM55t9BeAPdKzYURTVRUGCYeoOy4nyxKBYkMnqbvlQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"moment": "^2.22.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-native/node_modules/@jest/types": {
|
"node_modules/react-native/node_modules/@jest/types": {
|
||||||
"version": "26.6.2",
|
"version": "26.6.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,14 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/geolocation": "^3.4.0",
|
"@react-native-community/geolocation": "^3.4.0",
|
||||||
|
"@react-native-community/slider": "^4.5.5",
|
||||||
|
"@react-native-picker/picker": "^2.9.0",
|
||||||
"@react-navigation/bottom-tabs": "^6.4.0",
|
"@react-navigation/bottom-tabs": "^6.4.0",
|
||||||
"@react-navigation/native": "^6.1.18",
|
"@react-navigation/native": "^6.1.18",
|
||||||
"@react-navigation/stack": "^6.3.8",
|
"@react-navigation/stack": "^6.3.8",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.74.5",
|
"react-native": "0.74.5",
|
||||||
"react-native-amap-geolocation": "^1.2.3",
|
|
||||||
"react-native-amap3d": "^3.0.7",
|
"react-native-amap3d": "^3.0.7",
|
||||||
"react-native-camera": "^4.2.1",
|
"react-native-camera": "^4.2.1",
|
||||||
"react-native-gesture-handler": "^2.20.2",
|
"react-native-gesture-handler": "^2.20.2",
|
||||||
|
|
@ -26,7 +27,8 @@
|
||||||
"react-native-qrcode-scanner": "^1.5.5",
|
"react-native-qrcode-scanner": "^1.5.5",
|
||||||
"react-native-reanimated": "^3.16.1",
|
"react-native-reanimated": "^3.16.1",
|
||||||
"react-native-safe-area-context": "^4.14.0",
|
"react-native-safe-area-context": "^4.14.0",
|
||||||
"react-native-screens": "^3.35.0"
|
"react-native-screens": "^3.35.0",
|
||||||
|
"react-native-wheel-picker-android": "^2.0.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
|
|
|
||||||
BIN
src/assets/Image/Bledis.png
Normal file
BIN
src/assets/Image/Bledis.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
40
src/utils/coordtransform.ts
Normal file
40
src/utils/coordtransform.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
// WGS-84 转 GCJ-02
|
||||||
|
export const transformFromWGSToGCJ = (lat: number, lng: number) => {
|
||||||
|
const PI = 3.14159265358979324;
|
||||||
|
const ee = 0.00669342162296594323;
|
||||||
|
const a = 6378245.0;
|
||||||
|
|
||||||
|
let dLat = transformLat(lng - 105.0, lat - 35.0);
|
||||||
|
let dLng = transformLng(lng - 105.0, lat - 35.0);
|
||||||
|
|
||||||
|
const radLat = lat / 180.0 * PI;
|
||||||
|
let magic = Math.sin(radLat);
|
||||||
|
magic = 1 - ee * magic * magic;
|
||||||
|
|
||||||
|
const sqrtMagic = Math.sqrt(magic);
|
||||||
|
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
|
||||||
|
dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);
|
||||||
|
|
||||||
|
return {
|
||||||
|
latitude: lat + dLat,
|
||||||
|
longitude: lng + dLng,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function transformLat(x: number, y: number) {
|
||||||
|
let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
|
||||||
|
ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
|
||||||
|
ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;
|
||||||
|
ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformLng(x: number, y: number) {
|
||||||
|
let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
|
||||||
|
ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
|
||||||
|
ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;
|
||||||
|
ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PI = 3.14159265358979324;
|
||||||
|
|
@ -17,13 +17,13 @@ type NavigationProp = StackNavigationProp<RootStackParamList>;
|
||||||
const MiniMap = () => {
|
const MiniMap = () => {
|
||||||
const navigation = useNavigation<NavigationProp>();
|
const navigation = useNavigation<NavigationProp>();
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
AMapSdk.init(
|
// AMapSdk.init(
|
||||||
Platform.select({
|
// Platform.select({
|
||||||
android: "812efd3a950ba3675f928630302c6463",
|
// android: "812efd3a950ba3675f928630302c6463",
|
||||||
})
|
// })
|
||||||
);
|
// );
|
||||||
}, []);
|
// }, []);
|
||||||
|
|
||||||
const handleMapPress = () => {
|
const handleMapPress = () => {
|
||||||
navigation.navigate('DeviceMap');
|
navigation.navigate('DeviceMap');
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const NoDevice: React.FC = () => {
|
||||||
|
|
||||||
const handlePress = () => {
|
const handlePress = () => {
|
||||||
|
|
||||||
navigation.navigate('BindIndex');
|
navigation.navigate('BindIndex' as never);
|
||||||
// console.log(navigation);
|
// console.log(navigation);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ type RootStackParamList = {
|
||||||
Home: undefined;
|
Home: undefined;
|
||||||
DeviceList: undefined;
|
DeviceList: undefined;
|
||||||
DeviceMap: undefined;
|
DeviceMap: undefined;
|
||||||
|
DeviceSet: undefined;
|
||||||
|
DeviceShare: undefined;
|
||||||
// 添加其他页面的路由参数类型
|
// 添加其他页面的路由参数类型
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -39,10 +41,16 @@ const NormaIndex: React.FC = () => {
|
||||||
const handlePress = () => {
|
const handlePress = () => {
|
||||||
navigation.navigate('DeviceList');
|
navigation.navigate('DeviceList');
|
||||||
};
|
};
|
||||||
|
const toSet = () => {
|
||||||
|
navigation.navigate('DeviceSet');
|
||||||
|
};
|
||||||
|
|
||||||
const toMap = () => {
|
const toMap = () => {
|
||||||
navigation.navigate('DeviceMap');
|
navigation.navigate('DeviceMap');
|
||||||
};
|
};
|
||||||
|
const toShare = () => {
|
||||||
|
navigation.navigate('DeviceShare');
|
||||||
|
};
|
||||||
|
|
||||||
const panResponder = useRef(
|
const panResponder = useRef(
|
||||||
PanResponder.create({
|
PanResponder.create({
|
||||||
|
|
@ -215,7 +223,7 @@ const NormaIndex: React.FC = () => {
|
||||||
|
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
|
|
||||||
<TouchableOpacity onPress={handlePress}>
|
<TouchableOpacity onPress={toSet}>
|
||||||
<Image
|
<Image
|
||||||
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/ucYQHQ2Ep4odL8JpbtfT' }}
|
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/ucYQHQ2Ep4odL8JpbtfT' }}
|
||||||
style={styles.carSet}
|
style={styles.carSet}
|
||||||
|
|
@ -223,10 +231,13 @@ const NormaIndex: React.FC = () => {
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
||||||
<View style={styles.otherSet}>
|
<View style={styles.otherSet}>
|
||||||
|
<TouchableOpacity onPress={toShare}>
|
||||||
<Image
|
<Image
|
||||||
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/ulDHhC4MrH3FO0AeTqVg' }}
|
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/ulDHhC4MrH3FO0AeTqVg' }}
|
||||||
style={styles.otherImg}
|
style={styles.otherImg}
|
||||||
/>
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
<Image
|
<Image
|
||||||
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/u849NsNxdtzxhUkUJnfW' }}
|
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/u849NsNxdtzxhUkUJnfW' }}
|
||||||
style={styles.otherImg}
|
style={styles.otherImg}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,11 @@ import BindIndex from './bind/bind_index';
|
||||||
import SnBind from './bind/sn_bind';
|
import SnBind from './bind/sn_bind';
|
||||||
import ConfirmBind from './bind/ConfirmBind';
|
import ConfirmBind from './bind/ConfirmBind';
|
||||||
import DeviceMap from './device/deviceMap';
|
import DeviceMap from './device/deviceMap';
|
||||||
|
import DeviceSet from './device/deviceSet';
|
||||||
|
import UnlockSetting from './device/UnlockSetting';
|
||||||
|
import BleDistance from './device/BleDistance';
|
||||||
|
import DeviceShare from './device/DeviceShare';
|
||||||
|
import AddShare from './device/AddShare';
|
||||||
// import BleBind from './bind/ble_bind';
|
// import BleBind from './bind/ble_bind';
|
||||||
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
|
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
|
||||||
|
|
||||||
|
|
@ -17,6 +22,11 @@ type RootStackParamList = {
|
||||||
SnBind: undefined;
|
SnBind: undefined;
|
||||||
ConfirmBind: undefined;
|
ConfirmBind: undefined;
|
||||||
DeviceMap: undefined;
|
DeviceMap: undefined;
|
||||||
|
DeviceSet: undefined;
|
||||||
|
BleDistance: undefined;
|
||||||
|
UnlockSetting: undefined;
|
||||||
|
DeviceShare: undefined;
|
||||||
|
AddShare: undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Stack = createStackNavigator<RootStackParamList>();
|
const Stack = createStackNavigator<RootStackParamList>();
|
||||||
|
|
@ -44,7 +54,7 @@ type Props = {
|
||||||
export default function HomeStackNavigator({ navigation, route }: Props) {
|
export default function HomeStackNavigator({ navigation, route }: Props) {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
|
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
|
||||||
const hideTabBarRoutes = ['DeviceList', 'BindIndex', 'SnBind', 'BleBind', 'ConfirmBind', 'DeviceMap']; // 添加新的路由名
|
const hideTabBarRoutes = ['DeviceList', 'BindIndex', 'SnBind', 'BleBind', 'ConfirmBind', 'DeviceMap', 'DeviceSet', 'UnlockSetting', 'BleDistance', 'DeviceShare']; // 添加新的路由名
|
||||||
const shouldHideTabBar = hideTabBarRoutes.includes(routeName);
|
const shouldHideTabBar = hideTabBarRoutes.includes(routeName);
|
||||||
|
|
||||||
navigation.getParent()?.setOptions({
|
navigation.getParent()?.setOptions({
|
||||||
|
|
@ -86,7 +96,32 @@ export default function HomeStackNavigator({ navigation, route }: Props) {
|
||||||
name="DeviceMap"
|
name="DeviceMap"
|
||||||
component={DeviceMap}
|
component={DeviceMap}
|
||||||
options={createScreenOptions('设备位置')}
|
options={createScreenOptions('设备位置')}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DeviceSet"
|
||||||
|
component={DeviceSet}
|
||||||
|
options={createScreenOptions('车辆设置')}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="UnlockSetting"
|
||||||
|
component={UnlockSetting}
|
||||||
|
options={createScreenOptions('无感解锁')}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="BleDistance"
|
||||||
|
component={BleDistance}
|
||||||
|
options={createScreenOptions('蓝牙距离')}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DeviceShare"
|
||||||
|
component={DeviceShare}
|
||||||
|
options={createScreenOptions('车辆共享')}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="AddShare"
|
||||||
|
component={AddShare}
|
||||||
|
options={createScreenOptions('添加共享人')}
|
||||||
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
354
src/views/device/AddShare.tsx
Normal file
354
src/views/device/AddShare.tsx
Normal file
|
|
@ -0,0 +1,354 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { View, Text, StyleSheet, Image, TextInput, TouchableWithoutFeedback, Keyboard, TouchableOpacity, Modal } from 'react-native';
|
||||||
|
import { rpx } from '../../utils/rpx';
|
||||||
|
|
||||||
|
const AddShare = () => {
|
||||||
|
const [phone, setPhone] = useState('');
|
||||||
|
const [name, setName] = useState('');
|
||||||
|
const [time, setTime] = useState('');
|
||||||
|
const [showTimeModal, setShowTimeModal] = useState(false);
|
||||||
|
const [showBleInfo, setShowBleInfo] = useState(false);
|
||||||
|
const timeOptions = ['1天', '7天', '30天', '永久'];
|
||||||
|
const [allowBleLocation, setAllowBleLocation] = useState(true);
|
||||||
|
const handlePress = () => {
|
||||||
|
setShowTimeModal(true);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.IptBox}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="共享人手机号"
|
||||||
|
value={phone}
|
||||||
|
onChangeText={setPhone}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uMSABuH69gxKXIP0zqtl' }}
|
||||||
|
style={styles.phoneImg}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.IptBox}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="共享人姓名"
|
||||||
|
value={name}
|
||||||
|
onChangeText={setName}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity onPress={handlePress} activeOpacity={1}>
|
||||||
|
<View style={styles.IptBox}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="共享钥匙有效期"
|
||||||
|
value={time}
|
||||||
|
onChangeText={setTime}
|
||||||
|
editable={false}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uGq4yJlU1ZZRkwiJ8Y74' }}
|
||||||
|
style={styles.phoneImg}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={styles.bleInfo} onPress={() => setShowBleInfo(true)}>
|
||||||
|
<Image source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uvjPwfAKsL9kHD1Tb9aW' }} style={styles.bleImg}></Image>
|
||||||
|
<View style={styles.bleInfoBox}>
|
||||||
|
<Text style={styles.tit}>上次蓝牙连接位置</Text>
|
||||||
|
<Text style={[
|
||||||
|
styles.txt,
|
||||||
|
{ color: allowBleLocation ? '#4297F3' : '#666' }
|
||||||
|
]}>
|
||||||
|
{allowBleLocation ? '允许' : '不允许'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Modal visible={showBleInfo} transparent={true} animationType="slide">
|
||||||
|
<View style={styles.modalContainers}>
|
||||||
|
<View style={styles.modalContents}>
|
||||||
|
<Image
|
||||||
|
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uwMP7N2hCLFdwwDPhHMm' }}
|
||||||
|
style={styles.bleLocationImg}
|
||||||
|
/>
|
||||||
|
<Text style={styles.bleModalTitle}>
|
||||||
|
是否允许租赁人查看{'\n'}上次蓝牙连接位置
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<View style={styles.radioGroup}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.radioItem}
|
||||||
|
onPress={() => setAllowBleLocation(true)}
|
||||||
|
>
|
||||||
|
<Text style={styles.radioText}>允许</Text>
|
||||||
|
<View style={styles.radioCircle}>
|
||||||
|
{allowBleLocation && <View style={styles.radioSelected} />}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</TouchableOpacity>
|
||||||
|
<View style={styles.line}></View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.radioItem}
|
||||||
|
onPress={() => setAllowBleLocation(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.radioText}>不允许</Text>
|
||||||
|
<View style={styles.radioCircle}>
|
||||||
|
{!allowBleLocation && <View style={styles.radioSelected} />}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.confirmButton}
|
||||||
|
onPress={() => setShowBleInfo(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.confirmButtonText}>确定</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
<Modal
|
||||||
|
visible={showTimeModal}
|
||||||
|
transparent={true}
|
||||||
|
animationType="slide"
|
||||||
|
>
|
||||||
|
<View style={styles.modalContainer}>
|
||||||
|
<View style={styles.modalContent}>
|
||||||
|
<View style={styles.modalHeader}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.headerButton}
|
||||||
|
onPress={() => setShowTimeModal(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.cancelText}>取消</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.modalTitle}>选择有效期</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.headerButton}
|
||||||
|
onPress={() => setShowTimeModal(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.confirmText}>确定</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.optionsContainer}>
|
||||||
|
{timeOptions.map((option, index) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={index}
|
||||||
|
style={[
|
||||||
|
styles.optionItem,
|
||||||
|
time === option && styles.selectedItemBg
|
||||||
|
]}
|
||||||
|
onPress={() => {
|
||||||
|
setTime(option);
|
||||||
|
setShowTimeModal(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={[
|
||||||
|
styles.optionText,
|
||||||
|
time === option && styles.selectedOption
|
||||||
|
]}>
|
||||||
|
{option}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
</View>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: '#F3FCFF',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
modalContainers: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
paddingHorizontal: rpx(30),
|
||||||
|
},
|
||||||
|
modalContents: {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderRadius: rpx(20),
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingVertical: rpx(40),
|
||||||
|
padding:rpx(28)
|
||||||
|
},
|
||||||
|
bleLocationImg: {
|
||||||
|
width: rpx(338),
|
||||||
|
height: rpx(338),
|
||||||
|
marginBottom: rpx(30),
|
||||||
|
},
|
||||||
|
bleModalTitle: {
|
||||||
|
fontSize: rpx(36),
|
||||||
|
color: '#333',
|
||||||
|
textAlign: 'center',
|
||||||
|
lineHeight: rpx(50),
|
||||||
|
marginBottom: rpx(40),
|
||||||
|
},
|
||||||
|
line: {
|
||||||
|
borderWidth: rpx(1),
|
||||||
|
borderColor: '#eee',
|
||||||
|
marginBottom: rpx(28)
|
||||||
|
},
|
||||||
|
radioGroup: {
|
||||||
|
width: '100%',
|
||||||
|
paddingHorizontal: rpx(60),
|
||||||
|
marginBottom: rpx(40),
|
||||||
|
borderWidth: rpx(2),
|
||||||
|
borderColor: '#eee',
|
||||||
|
borderRadius: rpx(30),
|
||||||
|
paddingTop: rpx(28)
|
||||||
|
},
|
||||||
|
radioItem: {
|
||||||
|
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: rpx(30),
|
||||||
|
},
|
||||||
|
radioCircle: {
|
||||||
|
width: rpx(44),
|
||||||
|
height: rpx(44),
|
||||||
|
borderRadius: rpx(22),
|
||||||
|
borderWidth: rpx(2),
|
||||||
|
borderColor: '#4297F3',
|
||||||
|
marginRight: rpx(20),
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
radioSelected: {
|
||||||
|
width: rpx(28),
|
||||||
|
height: rpx(28),
|
||||||
|
borderRadius: rpx(14),
|
||||||
|
backgroundColor: '#4297F3',
|
||||||
|
},
|
||||||
|
radioText: {
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
confirmButton: {
|
||||||
|
width: rpx(560),
|
||||||
|
height: rpx(88),
|
||||||
|
backgroundColor: '#4297F3',
|
||||||
|
borderRadius: rpx(44),
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
confirmButtonText: {
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#fff',
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
bleImg: {
|
||||||
|
width: rpx(88),
|
||||||
|
height: rpx(88),
|
||||||
|
},
|
||||||
|
tit: {
|
||||||
|
fontSize: rpx(36),
|
||||||
|
color: '#1E1D20',
|
||||||
|
},
|
||||||
|
txt: {
|
||||||
|
fontSize: rpx(36),
|
||||||
|
color: '#4297F3',
|
||||||
|
},
|
||||||
|
bleInfo: {
|
||||||
|
marginTop: rpx(30),
|
||||||
|
width: rpx(688),
|
||||||
|
height: rpx(174),
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
padding: rpx(44),
|
||||||
|
flexDirection: 'row',
|
||||||
|
// alignItems: 'center',
|
||||||
|
// justifyContent: 'center',
|
||||||
|
},
|
||||||
|
bleInfoBox: {
|
||||||
|
paddingLeft: rpx(20),
|
||||||
|
},
|
||||||
|
modalContainer: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
},
|
||||||
|
modalContent: {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderTopLeftRadius: rpx(20),
|
||||||
|
borderTopRightRadius: rpx(20),
|
||||||
|
paddingBottom: rpx(30),
|
||||||
|
},
|
||||||
|
modalHeader: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
height: rpx(100),
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: '#eee',
|
||||||
|
paddingHorizontal: rpx(30),
|
||||||
|
},
|
||||||
|
headerButton: {
|
||||||
|
padding: rpx(20),
|
||||||
|
},
|
||||||
|
modalTitle: {
|
||||||
|
fontSize: rpx(32),
|
||||||
|
fontWeight: '500',
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#666',
|
||||||
|
},
|
||||||
|
confirmText: {
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#4297F3',
|
||||||
|
},
|
||||||
|
optionsContainer: {
|
||||||
|
paddingHorizontal: rpx(30),
|
||||||
|
paddingTop: rpx(20),
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
optionItem: {
|
||||||
|
height: rpx(100),
|
||||||
|
width: rpx(300),
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
// paddingLeft: rpx(30),
|
||||||
|
borderRadius: rpx(16),
|
||||||
|
marginBottom: rpx(20),
|
||||||
|
},
|
||||||
|
optionText: {
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
selectedItemBg: {
|
||||||
|
backgroundColor: '#F0F7FF',
|
||||||
|
},
|
||||||
|
selectedOption: {
|
||||||
|
color: '#4297F3',
|
||||||
|
},
|
||||||
|
IptBox: {
|
||||||
|
marginTop: rpx(30),
|
||||||
|
paddingHorizontal: rpx(30),
|
||||||
|
width: rpx(688),
|
||||||
|
height: rpx(128),
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
borderRadius: rpx(30),
|
||||||
|
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
flex: 1,
|
||||||
|
fontSize: rpx(36),
|
||||||
|
},
|
||||||
|
phoneImg: {
|
||||||
|
width: rpx(54),
|
||||||
|
height: rpx(54),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export default AddShare;
|
||||||
79
src/views/device/BleDistance.tsx
Normal file
79
src/views/device/BleDistance.tsx
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { View, Text, StyleSheet, Image, TouchableOpacity, ScrollView } from 'react-native';
|
||||||
|
import { rpx } from '../../utils/rpx';
|
||||||
|
|
||||||
|
const BleDistance = () => {
|
||||||
|
const [isEnabled, setIsEnabled] = useState(false); // 添加状态控制按钮
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<ScrollView
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
|
contentContainerStyle={styles.scrollContent}
|
||||||
|
>
|
||||||
|
<Image source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/upCrcuiBaoZrd9ZRZayj' }} style={styles.icon} />
|
||||||
|
<Text style={styles.tit}>1.请走到空旷区</Text>
|
||||||
|
<Text style={styles.txt}>请在空旷区域进行标定,否则标定结果可能受环境(墙体、金属等)干扰影响</Text>
|
||||||
|
<Text style={styles.tit}>2.请减少周围的设备干扰</Text>
|
||||||
|
<Text style={styles.txt}>其他手机或设备的蓝牙信号及电磁可能会影响标定结果</Text>
|
||||||
|
<Text style={styles.tit}>3.请站在您期望的无感解锁位置</Text>
|
||||||
|
<Text style={styles.txt}>建议不要离车太远,否则可能导致您预期外的解锁 发生</Text>
|
||||||
|
<Text style={styles.tit}>4.点击标定按钮标</Text>
|
||||||
|
<Text style={styles.txt}>标定成功后车辆将基于当前位置设置无感解锁距离</Text>
|
||||||
|
<Text style={styles.tit}>提示</Text>
|
||||||
|
<Text style={styles.txt}>若您想要更改无感解锁距离,可以重新标定,受蓝牙信号强度波动影响,您的实际无感解锁位置可能与您的标定位置略有偏差</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.btn, { backgroundColor: isEnabled ? '#4297F3' : '#ccc' }]}
|
||||||
|
disabled={!isEnabled}
|
||||||
|
>
|
||||||
|
<Text style={styles.btnTxt}>开始标定</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: '#F3FCFF',
|
||||||
|
},
|
||||||
|
scrollContent: {
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingBottom: rpx(40), // 添加底部间距
|
||||||
|
},
|
||||||
|
btn: {
|
||||||
|
marginTop: rpx(50),
|
||||||
|
width: rpx(614),
|
||||||
|
height: rpx(92),
|
||||||
|
backgroundColor: '#4297F3',
|
||||||
|
borderRadius: rpx(16),
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
btnTxt: {
|
||||||
|
fontSize: rpx(40),
|
||||||
|
fontWeight: '500',
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
marginLeft: rpx(80),
|
||||||
|
marginTop: rpx(100),
|
||||||
|
width: rpx(540),
|
||||||
|
height: rpx(450),
|
||||||
|
},
|
||||||
|
txt: {
|
||||||
|
width: rpx(608),
|
||||||
|
marginTop: rpx(20),
|
||||||
|
fontSize: rpx(28),
|
||||||
|
color: '#808080',
|
||||||
|
},
|
||||||
|
tit: {
|
||||||
|
fontWeight: '500',
|
||||||
|
width: rpx(608),
|
||||||
|
marginTop: rpx(20),
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#3D3D3D',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BleDistance;
|
||||||
154
src/views/device/DeviceShare.tsx
Normal file
154
src/views/device/DeviceShare.tsx
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { View, Text, StyleSheet, Image, TouchableOpacity } from 'react-native';
|
||||||
|
import { rpx } from '../../utils/rpx';
|
||||||
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
const DeviceShare = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.shareBox}>
|
||||||
|
<Text style={styles.shareTitle}>共享钥匙(2/3)</Text>
|
||||||
|
<Text style={styles.shareTxt}>临时借用车辆,可以使用基础控车功能</Text>
|
||||||
|
<View style={styles.card}>
|
||||||
|
<View style={styles.cardTop}>
|
||||||
|
<Image source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uVnIDwcwQP7oo12PeYVJ' }} style={styles.cardTopImg}></Image>
|
||||||
|
<View style={styles.cardTopTxt}>
|
||||||
|
<Text style={styles.cardTopName}>张三</Text>
|
||||||
|
<Text style={styles.cardTopPhone}>13860332568</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.cardType}>待领取</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.cardBottom}>
|
||||||
|
<Text style={styles.lasttime}>剩余有效期:23小时27分</Text>
|
||||||
|
<Image source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uGq4yJlU1ZZRkwiJ8Y74' }} style={styles.lasttimeImg}></Image>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity onPress={() => {
|
||||||
|
navigation.navigate('AddShare' as never);
|
||||||
|
}}>
|
||||||
|
<View style={styles.addBtn}>
|
||||||
|
<Image source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uI4CdJFzS1GkY1AzfFyG' }} style={styles.addBtnImg}></Image>
|
||||||
|
<Text style={styles.addBtnTxt}>添加成员</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
<View style={styles.shareTip}>
|
||||||
|
<Text style={styles.shareBtnTxt}>查看已失效共享</Text>
|
||||||
|
<Image source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uGq4yJlU1ZZRkwiJ8Y74' }} style={styles.lasttimeImg}></Image>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: '#F3FCFF',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
addBtnImg: {
|
||||||
|
width: rpx(32),
|
||||||
|
height: rpx(32),
|
||||||
|
},
|
||||||
|
shareTip: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginTop: rpx(44),
|
||||||
|
},
|
||||||
|
shareBtnTxt: {
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#808080',
|
||||||
|
},
|
||||||
|
addBtn: {
|
||||||
|
width: rpx(592),
|
||||||
|
height: rpx(108),
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
borderRadius: rpx(16),
|
||||||
|
marginTop: rpx(30),
|
||||||
|
borderWidth: rpx(2),
|
||||||
|
borderColor: '#808080',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flexDirection: 'row',
|
||||||
|
},
|
||||||
|
addBtnTxt: {
|
||||||
|
marginLeft: rpx(12),
|
||||||
|
fontSize: rpx(36),
|
||||||
|
color: '#808080',
|
||||||
|
},
|
||||||
|
cardBottom: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'nowrap',
|
||||||
|
},
|
||||||
|
lasttime: {
|
||||||
|
marginLeft: rpx(124),
|
||||||
|
fontSize: rpx(24),
|
||||||
|
color: '#4297F3',
|
||||||
|
},
|
||||||
|
lasttimeImg: {
|
||||||
|
marginLeft: 'auto',
|
||||||
|
width: rpx(24),
|
||||||
|
height: rpx(24),
|
||||||
|
},
|
||||||
|
cardTop: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'nowrap',
|
||||||
|
},
|
||||||
|
cardType: {
|
||||||
|
marginLeft: 'auto',
|
||||||
|
alignSelf: 'flex-start',
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#4297F3',
|
||||||
|
},
|
||||||
|
cardTopTxt: {
|
||||||
|
marginLeft: rpx(28),
|
||||||
|
|
||||||
|
},
|
||||||
|
cardTopImg: {
|
||||||
|
width: rpx(96),
|
||||||
|
height: rpx(96),
|
||||||
|
borderRadius: rpx(48),
|
||||||
|
},
|
||||||
|
cardTopName: {
|
||||||
|
|
||||||
|
fontSize: rpx(44),
|
||||||
|
color: '#3D3D3D',
|
||||||
|
},
|
||||||
|
cardTopPhone: {
|
||||||
|
fontSize: rpx(36),
|
||||||
|
color: '#808080',
|
||||||
|
},
|
||||||
|
|
||||||
|
shareBox: {
|
||||||
|
width: rpx(688),
|
||||||
|
borderRadius: rpx(30),
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
padding: rpx(32),
|
||||||
|
},
|
||||||
|
shareTitle: {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
fontSize: rpx(44),
|
||||||
|
color: '#3D3D3D',
|
||||||
|
},
|
||||||
|
shareTxt: {
|
||||||
|
marginTop: rpx(14),
|
||||||
|
fontWeight: '500',
|
||||||
|
fontSize: rpx(28),
|
||||||
|
color: '#999',
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
width: rpx(592),
|
||||||
|
padding: rpx(32),
|
||||||
|
marginTop: rpx(32),
|
||||||
|
borderRadius: rpx(16),
|
||||||
|
borderWidth: rpx(2),
|
||||||
|
borderColor: '#808080 ',
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export default DeviceShare;
|
||||||
241
src/views/device/UnlockSetting.tsx
Normal file
241
src/views/device/UnlockSetting.tsx
Normal file
|
|
@ -0,0 +1,241 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { View, Text, TouchableOpacity, StyleSheet, Image, Switch } from 'react-native';
|
||||||
|
import Slider from '@react-native-community/slider'; // 修改这里的导入
|
||||||
|
import { rpx } from '../../utils/rpx';
|
||||||
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
const UnlockSetting = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [isAutoOff, setIsAutoOff] = useState(true);
|
||||||
|
const [sliderValue, setSliderValue] = useState(1); // 1表示标准
|
||||||
|
const [isCustomDistance, setIsCustomDistance] = useState(false); // 是否自定义距离
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uKcmg9OiTA72mIm59GRh' }} style={styles.img} />
|
||||||
|
<View style={styles.card}>
|
||||||
|
<View style={styles.cont_li}>
|
||||||
|
<View style={styles.cont_li_content}>
|
||||||
|
<View style={styles.cont_li_top}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/ue1qF3cHAVlV8Fn5CKV6' }} style={styles.icon_set} />
|
||||||
|
<Text style={styles.text_set}>无感解锁</Text>
|
||||||
|
<View style={styles.cont_li_right}>
|
||||||
|
<Switch
|
||||||
|
onValueChange={() => setIsAutoOff(!isAutoOff)}
|
||||||
|
value={isAutoOff}
|
||||||
|
trackColor={{ false: '#767577', true: '#4297F3' }}
|
||||||
|
thumbColor={'#fff'}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.tipTxt}>1.手机打开蓝牙并靠近车辆即可自动解锁,解锁时请尽 量减少手机与车辆之间的遮挡</Text>
|
||||||
|
<Text style={styles.tipTxt}>2.若解锁遇到问题,建议您尝试重新连接蓝牙,或尝试 调节无感解锁的感应距离</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{isAutoOff && (
|
||||||
|
<View style={styles.card}>
|
||||||
|
<View style={styles.cont_li}>
|
||||||
|
<View style={styles.cont_li_content}>
|
||||||
|
<View style={styles.cont_li_top}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uBAdXDKxFsApstvKlEWo' }} style={styles.icon_set} />
|
||||||
|
<Text style={styles.text_set}>解锁位置</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.distanceOptions}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.distanceOption, !isCustomDistance && styles.selectedOption]}
|
||||||
|
onPress={() => setIsCustomDistance(false)}
|
||||||
|
>
|
||||||
|
<View style={[styles.radioButton, !isCustomDistance && styles.selectedRadioButton]}>
|
||||||
|
<View style={[styles.radioInner, !isCustomDistance && styles.radioInnerSelected]} />
|
||||||
|
</View>
|
||||||
|
<Text style={[styles.distanceText, !isCustomDistance && styles.selectedText]}>设备距离</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
<View style={styles.sliderContainer}>
|
||||||
|
<Slider
|
||||||
|
style={styles.slider}
|
||||||
|
minimumValue={0}
|
||||||
|
maximumValue={2}
|
||||||
|
value={sliderValue}
|
||||||
|
onValueChange={setSliderValue}
|
||||||
|
minimumTrackTintColor="#4297F3"
|
||||||
|
maximumTrackTintColor="#EBEBEB"
|
||||||
|
/>
|
||||||
|
<View style={styles.sliderLabels}>
|
||||||
|
<Text style={styles.sliderLabel}>近</Text>
|
||||||
|
<Text style={styles.sliderLabel}>标准</Text>
|
||||||
|
<Text style={styles.sliderLabel}>远</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={styles.distanceOptions}>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.distanceOption, isCustomDistance && styles.selectedOption]}
|
||||||
|
onPress={() => setIsCustomDistance(true)}
|
||||||
|
>
|
||||||
|
<View style={[styles.radioButton, isCustomDistance && styles.selectedRadioButton]}>
|
||||||
|
<View style={[styles.radioInner, isCustomDistance && styles.radioInnerSelected]} />
|
||||||
|
</View>
|
||||||
|
<Text style={[styles.distanceText, isCustomDistance && styles.selectedText]}>自定义距离</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
{isCustomDistance && (
|
||||||
|
<TouchableOpacity style={styles.distanceBtn} onPress={() => navigation.navigate('BleDistance' as never)}>
|
||||||
|
<Text style={styles.distanceBtnTxt}>标定</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: '#F3FCFF',
|
||||||
|
},
|
||||||
|
distanceBtn: {
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: rpx(40),
|
||||||
|
width: rpx(154),
|
||||||
|
height: rpx(56),
|
||||||
|
backgroundColor: '#4297F3',
|
||||||
|
borderRadius: rpx(28),
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
distanceBtnTxt: {
|
||||||
|
fontWeight: '500',
|
||||||
|
fontSize: rpx(32),
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
|
selectedOption: {
|
||||||
|
backgroundColor: '#F5F5F5',
|
||||||
|
borderRadius: rpx(30),
|
||||||
|
},
|
||||||
|
selectedText: {
|
||||||
|
color: '#4297F3',
|
||||||
|
},
|
||||||
|
selectedRadioButton: {
|
||||||
|
borderColor: '#4297F3',
|
||||||
|
},
|
||||||
|
distanceOptions: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
marginTop: rpx(20),
|
||||||
|
marginLeft: rpx(62),
|
||||||
|
},
|
||||||
|
distanceOption: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginRight: rpx(40),
|
||||||
|
},
|
||||||
|
radioButton: {
|
||||||
|
width: rpx(40),
|
||||||
|
height: rpx(40),
|
||||||
|
borderRadius: rpx(20),
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor: '#CCCCCC',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginRight: rpx(10),
|
||||||
|
},
|
||||||
|
radioInner: {
|
||||||
|
width: rpx(24),
|
||||||
|
height: rpx(24),
|
||||||
|
borderRadius: rpx(12),
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
},
|
||||||
|
radioInnerSelected: {
|
||||||
|
backgroundColor: '#4297F3',
|
||||||
|
},
|
||||||
|
distanceText: {
|
||||||
|
fontSize: rpx(28),
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
sliderContainer: {
|
||||||
|
marginTop: rpx(30),
|
||||||
|
marginLeft: rpx(62),
|
||||||
|
width: '85%',
|
||||||
|
},
|
||||||
|
slider: {
|
||||||
|
width: '100%',
|
||||||
|
height: rpx(40),
|
||||||
|
},
|
||||||
|
sliderLabels: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
marginTop: rpx(10),
|
||||||
|
},
|
||||||
|
sliderLabel: {
|
||||||
|
fontSize: rpx(24),
|
||||||
|
color: '#999',
|
||||||
|
},
|
||||||
|
img: {
|
||||||
|
width: rpx(688),
|
||||||
|
height: rpx(600),
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
marginTop: rpx(20),
|
||||||
|
width: rpx(688),
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderRadius: rpx(30),
|
||||||
|
padding: rpx(30),
|
||||||
|
paddingTop: rpx(0),
|
||||||
|
},
|
||||||
|
icon_set: {
|
||||||
|
width: rpx(50),
|
||||||
|
height: rpx(50),
|
||||||
|
},
|
||||||
|
cont_li: {
|
||||||
|
paddingTop: rpx(32),
|
||||||
|
paddingBottom: rpx(32),
|
||||||
|
borderBottomWidth: rpx(1),
|
||||||
|
borderBottomColor: '#EBEBEB',
|
||||||
|
},
|
||||||
|
cont_li_right: {
|
||||||
|
marginLeft: 'auto',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
cont_li_content: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
},
|
||||||
|
cont_li_top: {
|
||||||
|
width: '100%',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: rpx(8),
|
||||||
|
},
|
||||||
|
text_set: {
|
||||||
|
fontWeight: '500',
|
||||||
|
fontSize: rpx(36),
|
||||||
|
color: '#333',
|
||||||
|
marginLeft: rpx(10),
|
||||||
|
},
|
||||||
|
rightTxt: {
|
||||||
|
fontWeight: '500',
|
||||||
|
fontSize: rpx(28),
|
||||||
|
color: '#4297F3',
|
||||||
|
marginRight: rpx(8),
|
||||||
|
},
|
||||||
|
icon_right: {
|
||||||
|
width: rpx(32),
|
||||||
|
height: rpx(32),
|
||||||
|
},
|
||||||
|
tipTxt: {
|
||||||
|
width: '85%',
|
||||||
|
marginLeft: rpx(62),
|
||||||
|
fontSize: rpx(28),
|
||||||
|
color: '#999',
|
||||||
|
marginTop: rpx(8),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default UnlockSetting;
|
||||||
|
|
@ -16,7 +16,7 @@ export default function DeviceList() {
|
||||||
const [selectedItem, setSelectedItem] = useState<number | null>(null);
|
const [selectedItem, setSelectedItem] = useState<number | null>(null);
|
||||||
const handlePress = () => {
|
const handlePress = () => {
|
||||||
|
|
||||||
navigation.navigate('BindIndex');
|
navigation.navigate('BindIndex' as never);
|
||||||
// console.log(navigation);
|
// console.log(navigation);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,128 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { View, Text, StyleSheet, TouchableOpacity, Image, StatusBar, Linking, Platform } from 'react-native';
|
import { View, Text, StyleSheet, TouchableOpacity, Image, StatusBar, Linking, Platform, PermissionsAndroid } from 'react-native';
|
||||||
import { AMapSdk, MapView, Marker, MapType } from 'react-native-amap3d';
|
import { MapView, Marker, MapType } from 'react-native-amap3d';
|
||||||
import { init, Geolocation } from 'react-native-amap-geolocation';
|
import Geolocation from '@react-native-community/geolocation';
|
||||||
import { rpx } from '../../utils/rpx';
|
import { rpx } from '../../utils/rpx';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
import { transformFromWGSToGCJ } from '../../utils/coordtransform';
|
||||||
|
|
||||||
const DeviceMap = () => {
|
const DeviceMap = () => {
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
const latitude = 26.95500669;
|
const [location, setLocation] = useState({
|
||||||
const longitude = 120.32736769;
|
latitude: 26.95500669,
|
||||||
const imageUrl = "https://lxnapi.ccttiot.com/bike/img/static/uRx1B8B8acbquF2TO7Ry";
|
longitude: 120.32736769,
|
||||||
|
|
||||||
const [userLocation, setUserLocation] = React.useState({
|
|
||||||
latitude: 0,
|
|
||||||
longitude: 0,
|
|
||||||
});
|
});
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
// 请求 Android 定位权限
|
||||||
// 初始化定位
|
const requestAndroidPermission = async () => {
|
||||||
async function initGeolocation() {
|
try {
|
||||||
await init({
|
const granted = await PermissionsAndroid.request(
|
||||||
ios: "812efd3a950ba3675f928630302c6463",
|
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
||||||
android: "812efd3a950ba3675f928630302c6463"
|
{
|
||||||
});
|
title: "位置信息权限",
|
||||||
|
message: "需要获取您的位置信息",
|
||||||
Geolocation.getCurrentPosition(
|
buttonNeutral: "稍后询问",
|
||||||
({ coords }) => {
|
buttonNegative: "取消",
|
||||||
// console.log('定位错误:', coords);
|
buttonPositive: "确定"
|
||||||
setUserLocation({
|
}
|
||||||
latitude: coords.latitude,
|
|
||||||
longitude: coords.longitude,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.log('定位错误:', error);
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// timeout: 15000,
|
|
||||||
// maximumAge: 10000,
|
|
||||||
// distanceFilter: 100,
|
|
||||||
// }
|
|
||||||
);
|
);
|
||||||
|
return granted === PermissionsAndroid.RESULTS.GRANTED;
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(err);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
initGeolocation();
|
const getCurrentLocation = async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
// ... 权限检查和配置代码保持不变
|
||||||
|
|
||||||
|
// 同时发起高精度和低精度定位请求
|
||||||
|
const highAccuracyPromise = new Promise((resolve, reject) => {
|
||||||
|
Geolocation.getCurrentPosition(
|
||||||
|
resolve,
|
||||||
|
reject,
|
||||||
|
{
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 5000,
|
||||||
|
maximumAge: 1000
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const lowAccuracyPromise = new Promise((resolve, reject) => {
|
||||||
|
Geolocation.getCurrentPosition(
|
||||||
|
resolve,
|
||||||
|
reject,
|
||||||
|
{
|
||||||
|
enableHighAccuracy: false,
|
||||||
|
timeout: 10000,
|
||||||
|
maximumAge: 5000
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.race([highAccuracyPromise, lowAccuracyPromise])
|
||||||
|
.then((position: any) => {
|
||||||
|
console.log('原始定位结果:', position);
|
||||||
|
// 转换坐标系
|
||||||
|
const gcjLocation = transformFromWGSToGCJ(
|
||||||
|
position.coords.latitude,
|
||||||
|
position.coords.longitude
|
||||||
|
);
|
||||||
|
console.log('转换后的坐标:', gcjLocation);
|
||||||
|
setLocation(gcjLocation);
|
||||||
|
setIsLoading(false);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('定位失败:', error);
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取位置信息失败:', error);
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 位置监听也需要转换坐标系
|
||||||
|
useEffect(() => {
|
||||||
|
getCurrentLocation();
|
||||||
|
|
||||||
|
const watchId = Geolocation.watchPosition(
|
||||||
|
(position) => {
|
||||||
|
const gcjLocation = transformFromWGSToGCJ(
|
||||||
|
position.coords.latitude,
|
||||||
|
position.coords.longitude
|
||||||
|
);
|
||||||
|
setLocation(gcjLocation);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error('位置监听错误:', error);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 5000,
|
||||||
|
maximumAge: 1000,
|
||||||
|
distanceFilter: 10
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 组件卸载时清理
|
|
||||||
return () => {
|
return () => {
|
||||||
Geolocation.stop();
|
Geolocation.clearWatch(watchId);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// 跳转到高德地图
|
// 跳转到高德地图
|
||||||
const openAMap = async () => {
|
const openAMap = async () => {
|
||||||
const url = Platform.select({
|
const url = Platform.select({
|
||||||
android: `androidamap://navi?sourceApplication=appname&lat=${latitude}&lon=${longitude}&dev=0&style=2`,
|
android: `androidamap://navi?sourceApplication=appname&lat=${location.latitude}&lon=${location.longitude}&dev=0&style=2`,
|
||||||
ios: `iosamap://navi?sourceApplication=appname&lat=${latitude}&lon=${longitude}&dev=0&style=2`,
|
ios: `iosamap://navi?sourceApplication=appname&lat=${location.latitude}&lon=${location.longitude}&dev=0&style=2`,
|
||||||
});
|
});
|
||||||
|
const imageUrl = "https://lxnapi.ccttiot.com/bike/img/static/uRx1B8B8acbquF2TO7Ry";
|
||||||
const fallbackUrl = `https://uri.amap.com/navigation?to=${longitude},${latitude},目的地&mode=car&coordinate=gaode`;
|
const fallbackUrl = `https://uri.amap.com/navigation?to=${location.longitude},${location.latitude},目的地&mode=car&coordinate=gaode`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 检查是否安装了高德地图
|
// 检查是否安装了高德地图
|
||||||
|
|
@ -79,11 +143,6 @@ const DeviceMap = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<StatusBar
|
|
||||||
backgroundColor="#FFFFFF"
|
|
||||||
barStyle="dark-content"
|
|
||||||
translucent={false}
|
|
||||||
/>
|
|
||||||
<MapView
|
<MapView
|
||||||
style={styles.map}
|
style={styles.map}
|
||||||
mapType={MapType.Standard}
|
mapType={MapType.Standard}
|
||||||
|
|
@ -92,42 +151,38 @@ const DeviceMap = () => {
|
||||||
zoomEnabled={true}
|
zoomEnabled={true}
|
||||||
initialCameraPosition={{
|
initialCameraPosition={{
|
||||||
target: {
|
target: {
|
||||||
latitude,
|
latitude: location.latitude,
|
||||||
longitude,
|
longitude: location.longitude,
|
||||||
},
|
},
|
||||||
zoom: 15,
|
zoom: 15,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* 设备位置标记 */}
|
|
||||||
<Marker
|
<Marker
|
||||||
position={{
|
position={{
|
||||||
latitude,
|
latitude: location.latitude,
|
||||||
longitude,
|
longitude: location.longitude,
|
||||||
}}
|
}}
|
||||||
icon={{ uri: imageUrl }}
|
icon={{ uri: 'imageUrl' }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 用户位置标记 */}
|
|
||||||
{userLocation.latitude !== 0 && (
|
|
||||||
<Marker
|
|
||||||
position={{
|
|
||||||
latitude: userLocation.latitude,
|
|
||||||
longitude: userLocation.longitude,
|
|
||||||
}}
|
|
||||||
icon={{ uri: 'imageUrl' }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</MapView>
|
</MapView>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uOCaLkinKXhZLxCkTFAQ' }} style={styles.locationIcon} />
|
||||||
<View style={styles.bottomCard}>
|
<View style={styles.bottomCard}>
|
||||||
<View style={styles.addressInfo}>
|
<View style={styles.addressInfo}>
|
||||||
<Text style={styles.addressText}>
|
<Text style={styles.addressText}>
|
||||||
福建省宁德市福鼎市海滨路200号靠近福鼎第四中学
|
福建省宁德市福鼎市海滨路200号靠近福鼎第四中学
|
||||||
</Text>
|
</Text>
|
||||||
<Image
|
<Image
|
||||||
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/voice' }}
|
source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/ucBlLZW1SpAaKxSQYkr6' }}
|
||||||
style={styles.voiceIcon}
|
style={styles.voiceIcon}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
<View style={styles.timeBlock}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uMnpK2e8az06pzJrKms5' }} style={styles.timeClock} />
|
||||||
|
<Text style={styles.timeText1}>
|
||||||
|
12:00
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styles.navigationButton}
|
style={styles.navigationButton}
|
||||||
onPress={openAMap}
|
onPress={openAMap}
|
||||||
|
|
@ -140,14 +195,46 @@ const DeviceMap = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: '#FFFFFF',
|
backgroundColor: '#FFFFFF',
|
||||||
},
|
},
|
||||||
|
locationIcon: {
|
||||||
|
position: 'absolute',
|
||||||
|
right: rpx(32),
|
||||||
|
bottom: rpx(400),
|
||||||
|
width: rpx(90),
|
||||||
|
height: rpx(90),
|
||||||
|
},
|
||||||
map: {
|
map: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
|
timeBlock: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row', // 确保内容水平排列
|
||||||
|
alignSelf: 'flex-start',
|
||||||
|
justifyContent:'center',
|
||||||
|
alignItems:'center',
|
||||||
|
padding: rpx(8) ,
|
||||||
|
paddingHorizontal:rpx(18),
|
||||||
|
backgroundColor: '#EFEFEF',
|
||||||
|
borderRadius: rpx(29),
|
||||||
|
flexWrap: 'nowrap', // 防止换行
|
||||||
|
marginBottom:rpx(40),
|
||||||
|
},
|
||||||
|
|
||||||
|
timeClock:{
|
||||||
|
marginRight:rpx(14),
|
||||||
|
width:rpx(26),
|
||||||
|
height:rpx(26),
|
||||||
|
},
|
||||||
|
timeText1:{
|
||||||
|
fontSize:rpx(24),
|
||||||
|
color:'#808080',
|
||||||
|
|
||||||
|
},
|
||||||
header: {
|
header: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: 0,
|
||||||
|
|
@ -196,7 +283,7 @@ const styles = StyleSheet.create({
|
||||||
backgroundColor: '#FFFFFF',
|
backgroundColor: '#FFFFFF',
|
||||||
borderTopLeftRadius: rpx(24),
|
borderTopLeftRadius: rpx(24),
|
||||||
borderTopRightRadius: rpx(24),
|
borderTopRightRadius: rpx(24),
|
||||||
padding: rpx(32),
|
padding: rpx(36),
|
||||||
},
|
},
|
||||||
addressInfo: {
|
addressInfo: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
|
@ -205,18 +292,18 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
addressText: {
|
addressText: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
fontSize: rpx(28),
|
fontSize: rpx(36),
|
||||||
color: '#333333',
|
color: '#333333',
|
||||||
marginRight: rpx(16),
|
marginRight: rpx(16),
|
||||||
},
|
},
|
||||||
voiceIcon: {
|
voiceIcon: {
|
||||||
width: rpx(44),
|
width: rpx(90),
|
||||||
height: rpx(44),
|
height: rpx(90),
|
||||||
},
|
},
|
||||||
navigationButton: {
|
navigationButton: {
|
||||||
height: rpx(96),
|
height: rpx(96),
|
||||||
backgroundColor: '#2089FF',
|
backgroundColor: '#2089FF',
|
||||||
borderRadius: rpx(48),
|
borderRadius: rpx(20),
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
364
src/views/device/deviceSet.tsx
Normal file
364
src/views/device/deviceSet.tsx
Normal file
|
|
@ -0,0 +1,364 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { View, Text, StyleSheet, Image, TouchableOpacity, Modal } from 'react-native';
|
||||||
|
import { rpx } from '../../utils/rpx';
|
||||||
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
|
||||||
|
const DeviceSet = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [showAutoOffModal, setShowAutoOffModal] = useState(false);
|
||||||
|
const [showAutoLockModal, setShowAutoLockModal] = useState(false);
|
||||||
|
const [selectedTime, setSelectedTime] = useState('3分钟');
|
||||||
|
const [selectedLockTime, setSelectedLockTime] = useState('15秒');
|
||||||
|
const [showSensitivityModal, setShowSensitivityModal] = useState(false);
|
||||||
|
const [selectedSensitivity, setSelectedSensitivity] = useState('3级');
|
||||||
|
|
||||||
|
// 自动关机选项
|
||||||
|
const autoOffOptions = ['1分钟', '3分钟', '5分钟', '10分钟'];
|
||||||
|
// 自动锁车选项
|
||||||
|
const autoLockOptions = ['15秒', '30秒', '1分钟', '3分钟'];
|
||||||
|
// 震动灵敏度选项
|
||||||
|
const sensitivityOptions = ['1级', '2级', '3级', '4级', '5级'];
|
||||||
|
// 处理无感解锁点击
|
||||||
|
const handleUnlockPress = () => {
|
||||||
|
navigation.navigate('UnlockSetting' as never); // 替换成实际的路由名
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.card}>
|
||||||
|
<TouchableOpacity style={styles.cont_li} onPress={handleUnlockPress}>
|
||||||
|
<View style={styles.cont_li_content}>
|
||||||
|
<View style={styles.cont_li_top}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/ue1qF3cHAVlV8Fn5CKV6' }} style={styles.icon_set} />
|
||||||
|
<Text style={styles.text_set}>无感解锁</Text>
|
||||||
|
<View style={styles.cont_li_right}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uPNzghLYVj0uTnfliS0q' }} style={styles.icon_right} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.cont_li} onPress={() => setShowAutoOffModal(true)}>
|
||||||
|
<View style={styles.cont_li_content}>
|
||||||
|
<View style={styles.cont_li_top}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uY9EQQuqFMzgRrD92ENX' }} style={styles.icon_set} />
|
||||||
|
<Text style={styles.text_set}>自动关机</Text>
|
||||||
|
<View style={styles.cont_li_right}>
|
||||||
|
<Text style={styles.rightTxt}>{selectedTime}</Text>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uPNzghLYVj0uTnfliS0q' }} style={styles.icon_right} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.tipTxt}>车辆停稳并在等待时间内未行驶则自动关机</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.cont_li} onPress={() => setShowAutoLockModal(true)}>
|
||||||
|
<View style={styles.cont_li_content}>
|
||||||
|
<View style={styles.cont_li_top}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uZ8H5kYVkMM9jVChkHQS' }} style={styles.icon_set} />
|
||||||
|
<Text style={styles.text_set}>自动锁车</Text>
|
||||||
|
<View style={styles.cont_li_right}>
|
||||||
|
<Text style={styles.rightTxt}>{selectedLockTime}</Text>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uPNzghLYVj0uTnfliS0q' }} style={styles.icon_right} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.tipTxt}>车辆停稳并在等待时间内未行驶则自动锁车</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.cont_li} onPress={() => setShowSensitivityModal(true)}>
|
||||||
|
<View style={[styles.cont_li_content, styles.noBotLine]}>
|
||||||
|
<View style={styles.cont_li_top}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/ue1qF3cHAVlV8Fn5CKV6' }} style={styles.icon_set} />
|
||||||
|
<Text style={styles.text_set}>震动报警灵敏度</Text>
|
||||||
|
<View style={styles.cont_li_right}>
|
||||||
|
<Image source={{ uri: 'https://api.ccttiot.com/smartmeter/img/static/uPNzghLYVj0uTnfliS0q' }} style={styles.icon_right} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
visible={showAutoOffModal}
|
||||||
|
transparent={true}
|
||||||
|
animationType="slide"
|
||||||
|
>
|
||||||
|
<View style={styles.modalContainer}>
|
||||||
|
<View style={styles.modalContent}>
|
||||||
|
<View style={styles.modalHeader}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.headerButton}
|
||||||
|
onPress={() => setShowAutoOffModal(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.cancelText}>取消</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.modalTitle}>自动关机</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.headerButton}
|
||||||
|
onPress={() => setShowAutoOffModal(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.confirmText}>确定</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<View style={styles.optionsContainer}>
|
||||||
|
{autoOffOptions.map((time, index) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={index}
|
||||||
|
style={[
|
||||||
|
styles.optionItem,
|
||||||
|
selectedTime === time && styles.selectedItemBg
|
||||||
|
]}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedTime(time);
|
||||||
|
setShowAutoOffModal(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={[
|
||||||
|
styles.optionText,
|
||||||
|
selectedTime === time && styles.selectedOption
|
||||||
|
]}>
|
||||||
|
{time}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
{/* 修改自动锁车弹窗 */}
|
||||||
|
<Modal
|
||||||
|
visible={showAutoLockModal}
|
||||||
|
transparent={true}
|
||||||
|
animationType="slide"
|
||||||
|
>
|
||||||
|
<View style={styles.modalContainer}>
|
||||||
|
<View style={styles.modalContent}>
|
||||||
|
<View style={styles.modalHeader}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.headerButton}
|
||||||
|
onPress={() => setShowAutoLockModal(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.cancelText}>取消</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.modalTitle}>自动锁车</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.headerButton}
|
||||||
|
onPress={() => setShowAutoLockModal(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.confirmText}>确定</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<View style={styles.optionsContainer}>
|
||||||
|
{autoLockOptions.map((time, index) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={index}
|
||||||
|
style={[
|
||||||
|
styles.optionItem,
|
||||||
|
selectedLockTime === time && styles.selectedItemBg
|
||||||
|
]}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedLockTime(time);
|
||||||
|
setShowAutoLockModal(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={[
|
||||||
|
styles.optionText,
|
||||||
|
selectedLockTime === time && styles.selectedOption
|
||||||
|
]}>
|
||||||
|
{time}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
{/* 在最后添加震动报警灵敏度选择弹窗 */}
|
||||||
|
<Modal
|
||||||
|
visible={showSensitivityModal}
|
||||||
|
transparent={true}
|
||||||
|
animationType="slide"
|
||||||
|
>
|
||||||
|
<View style={styles.modalContainer}>
|
||||||
|
<View style={styles.modalContent}>
|
||||||
|
<View style={styles.modalHeader}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.headerButton}
|
||||||
|
onPress={() => setShowSensitivityModal(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.cancelText}>取消</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.modalTitle}>报警灵敏度</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.headerButton}
|
||||||
|
onPress={() => setShowSensitivityModal(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.confirmText}>确定</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<View style={styles.optionsContainer}>
|
||||||
|
{sensitivityOptions.map((level, index) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={index}
|
||||||
|
style={[
|
||||||
|
styles.optionItem,
|
||||||
|
selectedSensitivity === level && styles.selectedItemBg
|
||||||
|
]}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedSensitivity(level);
|
||||||
|
setShowSensitivityModal(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={[
|
||||||
|
styles.optionText,
|
||||||
|
selectedSensitivity === level && styles.selectedOption
|
||||||
|
]}>
|
||||||
|
{level}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
headerButton: {
|
||||||
|
padding: rpx(8),
|
||||||
|
minWidth: rpx(80),
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
confirmText: {
|
||||||
|
fontSize: rpx(28),
|
||||||
|
color: '#4297F3',
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
optionsContainer: {
|
||||||
|
paddingVertical: rpx(20),
|
||||||
|
},
|
||||||
|
optionItem: {
|
||||||
|
padding: rpx(30),
|
||||||
|
alignItems: 'center',
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: '#EBEBEB',
|
||||||
|
},
|
||||||
|
selectedItemBg: {
|
||||||
|
backgroundColor: '#F5F5F5',
|
||||||
|
},
|
||||||
|
optionText: {
|
||||||
|
fontSize: rpx(30),
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
selectedOption: {
|
||||||
|
color: '#4297F3',
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
modalHeader: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: rpx(16),
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: '#EBEBEB',
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: '#F3FCFF',
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
marginTop: rpx(20),
|
||||||
|
width: rpx(688),
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderRadius: rpx(30),
|
||||||
|
padding: rpx(30),
|
||||||
|
paddingTop: rpx(0),
|
||||||
|
},
|
||||||
|
icon_set: {
|
||||||
|
width: rpx(50),
|
||||||
|
height: rpx(50),
|
||||||
|
},
|
||||||
|
cont_li_right: {
|
||||||
|
marginLeft: 'auto',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
rightTxt: {
|
||||||
|
fontWeight: '500',
|
||||||
|
fontSize: rpx(28),
|
||||||
|
color: '#4297F3',
|
||||||
|
marginRight: rpx(8),
|
||||||
|
},
|
||||||
|
noBotLine: {
|
||||||
|
borderBottomWidth: 0,
|
||||||
|
borderBottomColor: 'transparent',
|
||||||
|
},
|
||||||
|
tipTxt: {
|
||||||
|
width: '85%',
|
||||||
|
marginLeft: rpx(62),
|
||||||
|
fontSize: rpx(28),
|
||||||
|
color: '#999',
|
||||||
|
marginTop: rpx(8),
|
||||||
|
},
|
||||||
|
icon_right: {
|
||||||
|
width: rpx(32),
|
||||||
|
height: rpx(32),
|
||||||
|
},
|
||||||
|
cont_li_content: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
},
|
||||||
|
cont_li: {
|
||||||
|
paddingTop: rpx(32),
|
||||||
|
paddingBottom: rpx(32),
|
||||||
|
borderBottomWidth: rpx(1),
|
||||||
|
borderBottomColor: '#EBEBEB',
|
||||||
|
},
|
||||||
|
text_set: {
|
||||||
|
fontWeight: '500',
|
||||||
|
fontSize: rpx(36),
|
||||||
|
color: '#333',
|
||||||
|
marginLeft: rpx(10),
|
||||||
|
},
|
||||||
|
cont_li_top: {
|
||||||
|
width: '100%',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: rpx(8),
|
||||||
|
},
|
||||||
|
modalContainer: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
},
|
||||||
|
modalContent: {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderTopLeftRadius: rpx(20),
|
||||||
|
borderTopRightRadius: rpx(20),
|
||||||
|
paddingBottom: rpx(34),
|
||||||
|
},
|
||||||
|
|
||||||
|
modalTitle: {
|
||||||
|
fontSize: rpx(32),
|
||||||
|
fontWeight: '500',
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
|
||||||
|
cancelButton: {
|
||||||
|
marginTop: rpx(16),
|
||||||
|
padding: rpx(30),
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
fontSize: rpx(30),
|
||||||
|
color: '#666',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DeviceSet;
|
||||||
Loading…
Reference in New Issue
Block a user