Commit 8051c6a8 by 修福龙

刷脸开门系统语音通话

parent 8da6d24e
......@@ -279,43 +279,36 @@ class OrderDetailsModal extends Component {
</View>
</View>
)}
<View style={styles.onCall}>
<Image
source={require('../assets/call.gif')}
style={styles.callGif}
/>
<Text style={styles.callText}>呼叫客服</Text>
</View>
{/*{talkCall === 1 ? (*/}
{/* <View style={styles.onCall}>*/}
{/* <Image*/}
{/* source={require('../assets/call.gif')}*/}
{/* style={styles.callGif}*/}
{/* />*/}
{/* <Text style={styles.onCallText}>正在语音通话中</Text>*/}
{/* </View>*/}
{/*) : talkCall === 0 ? (*/}
{/* <View style={styles.onCall}>*/}
{/* <Image*/}
{/* source={require('../assets/call.gif')}*/}
{/* style={styles.callGif}*/}
{/* />*/}
{/* <Text style={styles.onCallText}>正在接通中请稍候...</Text>*/}
{/* </View>*/}
{/*) : (*/}
{/* <Touch*/}
{/* onPress={() => onCall()}*/}
{/* style={styles.footer}*/}
{/* feedback={false}>*/}
{/* <View style={styles.call}>*/}
{/* <Image*/}
{/* source={require('../assets/call.gif')}*/}
{/* style={styles.callGif}*/}
{/* />*/}
{/* <Text style={styles.callText}>呼叫客服</Text>*/}
{/* </View>*/}
{/* </Touch>*/}
{/*)}*/}
{talkCall === 1 ? (
<View style={styles.onCall}>
<Image
source={require('../assets/call.gif')}
style={styles.callGif}
/>
<Text style={styles.onCallText}>正在语音通话中</Text>
</View>
) : talkCall === 0 ? (
<View style={styles.onCall}>
<Image
source={require('../assets/call.gif')}
style={styles.callGif}
/>
<Text style={styles.onCallText}>正在接通中请稍候...</Text>
</View>
) : (
<Touch
onPress={() => onCall()}
style={styles.footer}
feedback={false}>
<View style={styles.call}>
<Image
source={require('../assets/call.gif')}
style={styles.callGif}
/>
<Text style={styles.callText}>呼叫客服</Text>
</View>
</Touch>
)}
</View>
</Modal>
);
......
import * as api from '../services/agora';
export default {
namespace: 'agora',
state: {},
reducers: {},
effects: {
*agora(action, {call}) {
const {data} = yield call(api.agora);
return data;
},
*talkCall(action, {call}) {
const {data} = yield call(api.talkCall);
return data;
},
*talkLeave(action, {call}) {
const {data} = yield call(api.talkLeave);
return data;
},
},
};
......@@ -8,6 +8,7 @@ import order from './order';
import hkvs from './hkvs';
import user from './user';
import store from './store';
import agora from './agora';
const {width: _width, height: _height} = Dimensions.get('window');
......@@ -63,4 +64,15 @@ const app = {
},
};
export default [app, admin, goods, alipay, wxpay, order, hkvs, user, store];
export default [
app,
admin,
goods,
alipay,
wxpay,
order,
hkvs,
user,
store,
agora,
];
......@@ -140,14 +140,6 @@ export default {
const {data} = yield call(api.verifysms, action);
return data;
},
*agora(action, {call}) {
const {data} = yield call(api.agora);
return data;
},
*talkCall(action, {call}) {
const {data} = yield call(api.talkCall);
return data;
},
},
};
......
......@@ -2,9 +2,7 @@ import React, {Component} from 'react';
import {View, Text, Image, Dimensions} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import {connect} from 'react-redux';
// import {RtcEngineEvents} from 'react-native-agora/lib/RtcEvents';
// import RtcEngine from 'react-native-agora';
// import {RtcChannel} from 'react-native-agora';
import RtcEngine from 'react-native-agora';
import Touch from '../components/Touch';
import PhoneModal from '../components/PhoneModal';
import VerifyCodeModal from '../components/VerifyCodeModal';
......@@ -13,7 +11,6 @@ import delay from '../utils/delay';
import Speech from '../utils/Speech';
import WxFacepay from '../utils/WxFacepay';
import phone from '../assets/Vertical/phone.png';
// import log from './engine.log';
const {width} = Dimensions.get('screen');
......@@ -45,7 +42,6 @@ class FacePage extends Component {
async componentDidMount() {
this.listen();
// this.setAgoreEventListener();
}
onSubmit = async phone => {
......@@ -103,10 +99,8 @@ class FacePage extends Component {
};
handleOrderClose = () => {
// clearInterval(this.noTalkCall);
this.setState({
orderDetailsModal: false,
// talkCall: 2,
});
};
......@@ -123,49 +117,41 @@ class FacePage extends Component {
// 重力感应变化
window.socket.on('scale', this.handleScaleChange);
}
// if (!window.socket.hasListeners('talkCall')) {
// // 语音通话中
// window.socket.on('talkCall', this.handleTalkCall);
// // window.socket.on('talkCall', ({code, id, number, channel, device}) => {
// // console.log(code, id, number, channel, device);
// // if (code === 1) {
// // this.setState({
// // talkCall: 0,
// // });
// // } else if (code === 2) {
// // this.setState({
// // talkCall: 1,
// // });
// // }
// // console.warn(code, id, number, channel, device);
// // });
// }
// const {data} = await this.props.dispatch({
// type: 'store/agora',
// });
// console.warn(data);
// config.appid = data.appid;
// if (!this.engine) {
// this.engine = await RtcEngine.create(config);
// }
// console.log(data);
// if (!this.engine) {
// this.engine = await RtcEngine.create(data.appid);
// }
// // await this.engine.setLogFile('/engine.log'); //设置日志文件
// // await this.engine.setLogFileSize(1024); //指定 SDK 输出日志文件的内存大小,单位为 KB
// await this.engine.disableVideo(true); // 关闭视频模块
// await this.engine.enableLocalAudio(false); //调用 enableLocalAudio(false) 关闭本地采集后,系统会走媒体音量
// await this.engine.muteAllRemoteAudioStreams(false); //停止/恢复接收所有音频流。
// await this.engine.setDefaultMuteAllRemoteAudioStreams(false); // 设置是否默认接收音频流
// await this.engine.setDefaultMuteAllRemoteVideoStreams(true); // 设置是否默认接收视频流
// await this.engine.disableVideo(); //关闭视频模块
// await this.engine.setAudioProfile(4, 3); //设置音频编码配置
// await this.engine.adjustPlaybackSignalVolume(400); //调节本地播放的所有远端用户音量
// await this.engine.adjustAudioMixingPlayoutVolume(100); //调节音乐文件的本地播放音量
// await this.engine.setDefaultAudioRoutetoSpeakerphone(true); //默认从外放(扬声器)出声
if (!window.socket.hasListeners('talkCall')) {
// 语音通话中
window.socket.on('talkCall', this.handleTalkCall);
}
if (!window.socket.hasListeners('talkLeave')) {
// 语音通话中
window.socket.on('talkLeave', this.leaveC);
}
} catch (e) {
console.log(e);
}
};
handleTalkCall = async () => {
try {
// 加入语音通话
clearInterval(this.noTalkCall);
const {data} = await this.props.dispatch({
type: 'agora/agora',
});
if (!this.engine) {
//创建 RtcEngine 实例
this.engine = await RtcEngine.create(data.appid);
}
await this.engine.disableVideo(true); // 关闭视频模块
await this.engine.enableLocalAudio(false); //调用 enableLocalAudio(false) 关闭本地采集后,系统会走媒体音量
await this.engine.muteAllRemoteAudioStreams(false); //停止/恢复接收所有音频流。
await this.engine.setDefaultMuteAllRemoteAudioStreams(false); // 设置是否默认接收音频流
await this.engine.setDefaultMuteAllRemoteVideoStreams(true); // 设置是否默认接收视频流
await this.engine.disableVideo(); //关闭视频模块
await this.engine.setAudioProfile(4, 3); //设置音频编码配置
await this.engine.adjustPlaybackSignalVolume(400); //调节本地播放的所有远端用户音量
await this.engine.adjustAudioMixingPlayoutVolume(100); //调节音乐文件的本地播放音量
await this.engine.setDefaultAudioRoutetoSpeakerphone(true); //默认从外放(扬声器)出声
//监听
// this.engine.addListener('Warning', data => {
// console.log('Warning' + data);
// });
......@@ -173,119 +159,47 @@ class FacePage extends Component {
// console.log('Error' + data);
// });
// this.engine.addListener('JoinChannelSuccess', data => {
// console.warn('JoinChannelSuccess');
// console.warn(data);
// console.warn('JoinChannelSuccess' + data);
// });
// this.engine.addListener('LeaveChannel', data => {
// console.warn('LeaveChannel' + data);
// });
// this.engine.addListener('UserOffline', data => {
// console.warn('UserOffline' + data);
// });
await this.engine.enableWebSdkInteroperability(true); //打开与webSDK的互通
await this.engine.setChannelProfile(0); //设置频道场景
await this.engine.setClientRole(1); //设置为主播角色
// 加入频道
await this.engine.joinChannel(data.token, data.channel, null, data.uid);
//判断当前是否扬声器
if (!(await this.engine.isSpeakerphoneEnabled())) {
await this.engine.setEnableSpeakerphone(true); //切换到外放
}
await this.setState({
talkCall: 1,
});
} catch (e) {
console.log(e);
}
};
// handleTalkCall = async () => {
// try {
// // const {talkCall} = this.state;
// // 加入语音通话
// clearInterval(this.noTalkCall);
// const {data} = await this.props.dispatch({
// type: 'store/agora',
// });
// console.log(data);
// if (!this.engine) {
// this.engine = await RtcEngine.create(data.appid);
// // await this.engine.setLogFile('./engine.log'); //设置日志文件
// // await this.engine.setLogFileSize(1024); //指定 SDK 输出日志文件的内存大小,单位为 KB
// }
// this.engine.createRtcChannel(data.channel);
// this.engine.addListener('Warning', data => {
// console.log('Warning' + data);
// });
// this.engine.addListener('Error', data => {
// console.log('Error' + data);
// });
// this.engine.addListener('JoinChannelSuccess', data => {
// console.warn('JoinChannelSuccess');
// console.warn(data);
// });
// RtcChannel.joinChannel(data.token, null, 99, {
// autoSubscribeAudio: true,
// autoSubscribeVideo: false,
// }); //Join Channel
// RtcChannel.enableAudio();
// // await this.engine.disableVideo(true); // 关闭视频模块
// // await this.engine.enableLocalAudio(false); //调用 enableLocalAudio(false) 关闭本地采集后,系统会走媒体音量
// // await this.engine.muteAllRemoteAudioStreams(false); //停止/恢复接收所有音频流。
// // await this.engine.setDefaultMuteAllRemoteAudioStreams(false); // 设置是否默认接收音频流
// // await this.engine.setDefaultMuteAllRemoteVideoStreams(true); // 设置是否默认接收视频流
// // await this.engine.disableVideo(); //关闭视频模块
// // await this.engine.setAudioProfile(4, 3); //设置音频编码配置
// // await this.engine.adjustPlaybackSignalVolume(400); //调节本地播放的所有远端用户音量
// // await this.engine.adjustAudioMixingPlayoutVolume(100); //调节音乐文件的本地播放音量
// // await this.engine.setDefaultAudioRoutetoSpeakerphone(true); //默认从外放(扬声器)出声
// //
// // // await this.engine.addHandler(); //添加主回调事件
// // await this.engine.enableWebSdkInteroperability(true); //打开与webSDK的互通
// // await this.engine.setChannelProfile(0);
// // await this.engine.setClientRole(1); //设置为主播角色
// // // await this.engine.enableAudio();
// // await this.engine.joinChannel(data.token, data.channel, null, 99);
// // // await this.engine.setEnableSpeakerphone(true); //切换到外放
// // if (!(await this.engine.isSpeakerphoneEnabled())) {
// // console.warn(await this.engine.setEnableSpeakerphone(true));
// // await this.engine.setEnableSpeakerphone(true); //切换到外放
// // }
// // console.warn(await this.engine.getCallId());
// this.setState({
// talkCall: 1,
// });
// } catch (e) {
// console.log(e);
// }
// };
//设置事件监听
// setAgoreEventListener = () => {
// RtcEngine.Warning();
// RtcEngine.Error();
// RtcEngine.ApiCallExecuted();
// RtcEngine.JoinChannelSuccess();
// RtcEngine.LeaveChannel();
// // this.engine.addListener('Error');
// // this.engine.addListener('JoinChannelSuccess', res => {
// // console.warn('JoinChannelSuccess' + res);
// // });
// //成功加入房间
// // this.engine.onJoinChannelSuccess = (channel, uid, elapsed) => {
// // console.warn(`成功加入房间,频道号:${channel}+uid+${uid}`);
// // };
// //
// // //监听是否有新用户加入
// // this.engine.onUserJoined = (uid, elapsed) => {
// // console.warn(`新用户所加入的id为:${uid}`);
// // };
// //
// // //监听用户是否离开这个房间
// // this.engine.onUserOffline = (uid, reason) => {
// // console.warn(`用户离开的id为:${uid}`);
// // };
// //
// // //监听用户是否离开这个频道
// // this.engine.onLeaveChannel = () => {
// // console.warn('用户离开');
// // };
// };
// leaveC = async () => {
// const {data} = await this.props.dispatch({
// type: 'store/agora',
// });
// if (!this.engine) {
// this.engine = await RtcEngine.create(data.appid);
// }
// // if (this.engine) {
// console.warn('121212');
// await this.engine.leaveChannel();
// // }
// };
leaveC = async () => {
try {
clearInterval(this.noTalkCall);
if (this.engine) {
await this.engine.leaveChannel();
}
await this.props.dispatch({
type: 'agora/talkLeave',
});
this.setState({
talkCall: 2,
});
} catch (e) {
console.log(e);
}
};
// device 代表当前打开的门
handleScaleChange = ({count}) => {
......@@ -294,10 +208,7 @@ class FacePage extends Component {
this.wechatFace();
} else if (count === 0) {
// 重力感应归零
// clearInterval(this.noTalkCall);
// if (!this.engine) {
// this.engine.leaveChannel();
// }
this.leaveC();
this.setState({
orderDetailsModal: false,
phoneModal: false,
......@@ -394,16 +305,6 @@ class FacePage extends Component {
// 语音通话请求
onCall = async () => {
// const {data} = await this.props.dispatch({
// type: 'store/agora',
// });
// const engine = await RtcEngine.create(data.appid);
// await engine.joinChannel(data.token, data.channel, null, 0);
// this.noTalkCall = setInterval(async () => {
// await this.props.dispatch({
// type: 'store/talkCall',
// });
// }, 10000);
Speech.speak('正在接通中请稍候');
this.talkCall();
clearInterval(this.noTalkCall);
......@@ -415,7 +316,7 @@ class FacePage extends Component {
talkCall = () => {
this.props.dispatch({
type: 'store/talkCall',
type: 'agora/talkCall',
});
};
......@@ -526,42 +427,33 @@ class FacePage extends Component {
</View>
</Touch>
</View>
<View style={styles.onCall}>
<Image
source={require('../assets/call.gif')}
style={styles.callGif}
/>
<Text style={styles.callText}>呼叫客服</Text>
</View>
{/*{talkCall === 1 ? (*/}
{/* <Touch onPress={this.leaveC} style={styles.footer} feedback={false}>*/}
{/* <View style={styles.call}>*/}
{/* <Image*/}
{/* source={require('../assets/call.gif')}*/}
{/* style={styles.callGif}*/}
{/* />*/}
{/* <Text style={styles.onCallText}>正在语音通话中</Text>*/}
{/* </View>*/}
{/* </Touch>*/}
{/*) : talkCall === 0 ? (*/}
{/* <View style={styles.onCall}>*/}
{/* <Image*/}
{/* source={require('../assets/call.gif')}*/}
{/* style={styles.callGif}*/}
{/* />*/}
{/* <Text style={styles.onCallText}>正在接通中请稍候...</Text>*/}
{/* </View>*/}
{/*) : (*/}
{/* <Touch onPress={this.onCall} style={styles.footer} feedback={false}>*/}
{/* <View style={styles.call}>*/}
{/* <Image*/}
{/* source={require('../assets/call.gif')}*/}
{/* style={styles.callGif}*/}
{/* />*/}
{/* <Text style={styles.callText}>呼叫客服</Text>*/}
{/* </View>*/}
{/* </Touch>*/}
{/*)}*/}
{talkCall === 1 ? (
<View style={styles.onCall}>
<Image
source={require('../assets/call.gif')}
style={styles.callGif}
/>
<Text style={styles.onCallText}>正在语音通话中</Text>
</View>
) : talkCall === 0 ? (
<View style={styles.onCall}>
<Image
source={require('../assets/call.gif')}
style={styles.callGif}
/>
<Text style={styles.onCallText}>正在接通中请稍候...</Text>
</View>
) : (
<Touch onPress={this.onCall} style={styles.footer} feedback={false}>
<View style={styles.call}>
<Image
source={require('../assets/call.gif')}
style={styles.callGif}
/>
<Text style={styles.callText}>呼叫客服</Text>
</View>
</Touch>
)}
</View>
);
}
......
import React, {Component} from 'react';
import {View, Text, Image, Dimensions, Animated, Easing} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
// import QRCode from 'react-native-qrcode-svg';
import {connect} from 'react-redux';
import RtcEngine from 'react-native-agora';
import Touch from '../components/Touch';
import PhoneModal from '../components/PhoneModal';
import VerifyCodeModal from '../components/VerifyCodeModal';
import OrderDetailsModal from '../components/OrderDetailsModal';
import NP from '../utils/np';
import delay from '../utils/delay';
import config from '../utils/config';
import Speech from '../utils/Speech';
import WxFacepay from '../utils/WxFacepay';
const {width, height} = Dimensions.get('screen');
const graph = {
temperature: [1, 1, 1, 1, 1, 1, 1, 1],
humidity: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
shock: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
trigger: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
offset: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
};
const graphItemWidth = (width - 60) * 0.12;
const graphItemHeight = height * 0.0135;
const graphSpaceHeight = height * 0.006;
let qrHost = config.qrHost;
class OldFacePage extends Component {
state = {
tip: '',
tipBg: '#FC4000',
temperatureValue: new Animated.Value(0),
humidityValue: new Animated.Value(0),
shockValue: new Animated.Value(0),
triggerValue: new Animated.Value(0),
offsetValue: new Animated.Value(0),
phoneModal: false, // 显示输入电话号码弹窗
verifyCodeModal: false, // 显示输入验证码弹窗
orderDetailsModal: false, // 显示订单详情弹窗
goodsArr: [],
talkCall: 2, // 0请求通话,1通话中,2,已挂断通话
};
async componentWillMount() {
this.storeKey = await AsyncStorage.getItem('KEY');
if (!this.init) {
this.init = await WxFacepay.init();
}
}
async componentDidMount() {
this.listen();
clearInterval(this.noPersonInter);
this.noPersonInter = setInterval(async () => {
if (
(this.state.qrcode || this.state.scaleBusy) &&
(await this.noPerson())
) {
this.initScale();
this.setState({qrcode: null, tip: ''});
}
}, 5000);
}
onSubmit = async phone => {
const res = await this.props.dispatch({
type: 'store/sendsms',
phone,
});
if (res.code === 1) {
if (/^\d+$/.test(res.msg)) {
Speech.speak(res.msg.split('').join(' '));
} else {
Speech.speak('请输入验证码');
}
this.phone = phone;
this.setState({
phoneModal: false,
verifyCodeModal: true,
});
} else {
Speech.speak(res.msg);
}
};
onCodeSubmit = async code => {
const res = await this.props.dispatch({
type: 'store/verifysms',
code,
phone: this.phone,
userId: this.userId,
});
if (res.code === 1) {
this.setState({
verifyCodeModal: false,
});
const ret = await this.props.dispatch({
type: 'store/wxdoor',
userId: res.data,
});
this.handleDoorLogin(ret);
} else {
Speech.speak(res.msg);
}
};
handleClose = () => {
this.setState({
phoneModal: false,
});
};
handleCodeClose = () => {
this.setState({
verifyCodeModal: false,
});
};
handleOrderClose = () => {
clearInterval(this.noTalkCall);
this.setState({
orderDetailsModal: false,
talkCall: 2,
});
};
listen = async () => {
while (!window.socket) {
await delay(1000);
}
if (!window.socket.hasListeners('doorLogin')) {
// 扫码验证成功
window.socket.on('doorLogin', this.handleDoorLogin);
}
if (!window.socket.hasListeners('scale')) {
// 重力感应变化
window.socket.on('scale', this.handleScaleChange);
}
if (!window.socket.hasListeners('talkCall')) {
// 语音通话中
window.socket.on('talkCall', this.handleTalkCall);
// window.socket.on('talkCall', ({code, id, number, channel, device}) => {
// console.log(code, id, number, channel, device);
// if (code === 1) {
// this.setState({
// talkCall: 0,
// });
// } else if (code === 2) {
// this.setState({
// talkCall: 1,
// });
// }
// console.warn(code, id, number, channel, device);
// });
}
};
handleTalkCall = async () => {
// const {talkCall} = this.state;
// 加入语音通话
clearInterval(this.noTalkCall);
const {data} = await this.props.dispatch({
type: 'store/agora',
});
const engine = await RtcEngine.create(data.appid);
await engine.joinChannel(data.token, data.channel, null, 0);
this.setState({
talkCall: 1,
});
};
// 判断传感器上没人
noPerson = async () => {
const data = await this.props.dispatch({
type: 'store/scaleData',
});
return data && data.stableWeight === 0;
};
// device 代表当前打开的门
handleScaleChange = ({count}) => {
if (count === -1) {
// 重力感应开始识别
this.wechatFace();
this.startScale();
} else if (count === 0) {
// 重力感应归零
this.initScale();
this.setState({qrcode: null, tip: ''});
}
};
handleDoorLogin = async ret => {
console.warn(ret);
if (ret) {
const key = this.storeKey;
const prefix = `${qrHost}/#/store-${ret.action}-`;
if (ret.code < 0 || ret.code === 401) {
// 未授权,提示用户扫码验证
let tipText = ret.msg;
Speech.speak(tipText);
let qrcode = `${prefix}j${key}`;
if (ret.userId) {
qrcode += `-${ret.userId}`;
}
this.userId = ret.userId;
this.setState({qrcode, tip: tipText});
if (ret.code === 401) {
// 需要验证手机号
this.setState({phoneModal: true});
} else {
let goodsArr = [];
ret.orders.map(v1 => {
v1.goods.map(v2 => {
goodsArr.push(v2);
});
});
this.setState({orderDetailsModal: true, goodsArr});
}
} else if (ret.msg) {
let tipText = ret.msg.replace(/扫码/g, '人脸识别');
if (ret.code === 1) {
this.setState({qrcode: null});
} else if (ret.qrcode) {
this.setState({qrcode: `${prefix}j${key}`});
}
Speech.speak(tipText);
this.setState({tip: tipText});
}
} else {
Speech.speak('正在重新识别,请靠中间站稳');
}
};
startAnimation = () => {
let {ai} = this.props.store;
let duration = 1000;
let temperature =
(ai.temperature + 20) * 10 > 600 ? 600 : (ai.temperature + 20) * 10;
let humidity = ai.humidity > 100 ? 100 : ai.humidity;
let shock = ai.shock > 150 ? 150 : ai.shock;
let trigger = ai.trigger.data > 96 ? 96 : ai.trigger.data;
let offset = ai.offset > 50 ? 50 : ai.offset;
Animated.parallel([
Animated.spring(this.state.temperatureValue, {
toValue: temperature,
duration,
easing: Easing.linear,
}),
Animated.spring(this.state.humidityValue, {
toValue: humidity,
duration,
easing: Easing.linear,
}),
Animated.spring(this.state.shockValue, {
toValue: shock,
duration,
easing: Easing.linear,
}),
Animated.spring(this.state.triggerValue, {
toValue: trigger,
duration,
easing: Easing.linear,
}),
Animated.spring(this.state.offsetValue, {
toValue: offset,
duration,
easing: Easing.linear,
}),
]).start(() => {
this.state.temperatureValue.setValue(temperature);
this.state.humidityValue.setValue(humidity);
this.state.shockValue.setValue(shock);
this.state.triggerValue.setValue(trigger);
this.state.offsetValue.setValue(offset);
});
};
// 初始化重力感应
initScale = async () => {
this.setState({scaleBusy: false});
clearInterval(this.scaleInter);
await this.props.dispatch({
type: 'store/initScaleData',
});
this.startAnimation();
};
// 重力感应变化
startScale = () => {
this.setState({scaleBusy: true});
clearInterval(this.scaleInter);
this.scaleInter = setInterval(async () => {
await this.props.dispatch({
type: 'store/scaleData',
});
this.startAnimation();
}, 1000);
};
authinfo = async () => {
const rawdata = await WxFacepay.rawdata();
const {data} = await this.props.dispatch({
type: 'goods/wxauthinfo',
rawdata,
});
return data;
};
// 微信人脸身份识别
wechatFace = async () => {
if (this.state.qrcode) {
return;
} // 出现二维码,不做人脸识别
const tipText = '正在人脸识别,请看向屏幕,靠中间站稳';
Speech.speak(tipText);
this.setState({tip: tipText});
const auth = (await this.authinfo()) || {};
if (auth.return_code === 'SUCCESS') {
const params = {
appid: auth.appid,
mch_id: auth.mch_id,
store_id: this.storeKey,
authinfo: auth.authinfo,
face_authtype: 'FACEID-ONCE',
ask_unionid: 1,
};
let res = {};
while (
!res.openid &&
!(await this.noPerson()) // 没识别到人脸,重新识别
) {
res = await WxFacepay.faceinfo(params);
}
if (window.socket) {
window.socket.connect();
} // 返回结果,立即重新连接socket
if (!res.openid) {
return;
} // 没识别到人脸不开门
const ret = await this.props.dispatch({
type: 'store/wxdoor',
openid: res.openid,
wxtoken: res.token,
nickname: res.nickname,
});
this.handleDoorLogin(ret);
}
};
pressQrcode = async () => {
await this.setState({qrcode: null});
this.wechatFace();
};
// 语音通话请求
onCall = async () => {
// const {data} = await this.props.dispatch({
// type: 'store/agora',
// });
// const engine = await RtcEngine.create(data.appid);
// await engine.joinChannel(data.token, data.channel, null, 0);
this.talkCall();
clearInterval(this.noTalkCall);
// this.noTalkCall = setInterval(async () => {
// await this.props.dispatch({
// type: 'store/talkCall',
// });
// }, 10000);
this.noTalkCall = setInterval(() => this.talkCall(), 10000);
this.setState({
talkCall: 0,
});
};
talkCall = () => {
this.props.dispatch({
type: 'store/talkCall',
});
};
render() {
const {
scaleBusy,
tip,
tipBg,
verifyCodeModal,
temperatureValue,
humidityValue,
wakeup,
shockValue,
triggerValue,
offsetValue,
phoneModal,
orderDetailsModal,
goodsArr,
talkCall,
} = this.state;
let {store, dispatch} = this.props;
return (
<View style={{flex: 1, alignItems: 'center', backgroundColor: '#333'}}>
<PhoneModal
visible={phoneModal}
transparent
maskClosable
onClose={this.handleClose}
onRequestClose={this.handleClose}
onSubmit={this.onSubmit}
/>
<VerifyCodeModal
visible={verifyCodeModal}
transparent
maskClosable
onClose={this.handleCodeClose}
onRequestClose={this.handleCodeClose}
onSubmit={this.onCodeSubmit}
/>
<OrderDetailsModal
visible={orderDetailsModal}
transparent
maskClosable
onClose={this.handleOrderClose}
onRequestClose={this.handleOrderClose}
onCall={this.onCall}
goodsArr={goodsArr}
dispatch={dispatch}
talkCall={talkCall}
/>
<View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
<Touch onPress={this.pressQrcode} style={{flex: 1}}>
<Image
source={require('../assets/ai/face.gif')}
style={{flex: 1, width}}
/>
</Touch>
<Touch onPress={this.wechatFace}>
<View style={{...styles.tip, backgroundColor: tipBg}}>
<Text style={styles.tipText}>{tip}</Text>
</View>
</Touch>
</View>
<View
style={{
flex: 1,
backgroundColor: scaleBusy || wakeup ? '#ffffff' : '#030303',
flexDirection: 'row',
}}>
<View style={{width: 30}} />
<View style={styles.aiItem}>
<View style={styles.graph}>
<View style={styles.graphView}>
<Text
style={[
styles.graphText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
{store.ai.temperature >= 0
? `+${store.ai.temperature}`
: store.ai.temperature}
</Text>
</View>
<View style={styles.graphMain}>
<View
style={{
zIndex: 999,
}}>
{graph.temperature.map((v, k) => {
return (
<View key={k}>
<View
style={[
styles.graphSpace,
{
backgroundColor:
scaleBusy || wakeup ? '#ffffff' : '#000000',
},
]}
/>
<View style={styles.graphItem} />
</View>
);
})}
</View>
<Animated.View
style={[
styles.graphData,
{
height: temperatureValue.interpolate({
inputRange: [0, 600],
outputRange: [
0,
(graphItemHeight + graphSpaceHeight) *
graph.temperature.length,
],
}),
backgroundColor: '#fff100',
},
]}
/>
<View
style={[
styles.graphBg,
{
height:
(graphItemHeight + graphSpaceHeight) *
graph.temperature.length,
},
]}
/>
</View>
</View>
<Image
style={styles.aiIcon}
source={require('../assets/ai/temperature.png')}
/>
<Text
style={[
styles.aiText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
温度
</Text>
</View>
<View style={styles.aiItem}>
<View style={styles.graph}>
<View style={styles.graphView}>
<Text
style={[
styles.graphText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
{store.ai.humidity}%RH
</Text>
</View>
<View style={styles.graphMain}>
<View
style={{
zIndex: 999,
}}>
{graph.humidity.map((v, k) => {
return (
<View key={k}>
<View
style={[
styles.graphSpace,
{
backgroundColor:
scaleBusy || wakeup ? '#ffffff' : '#000000',
},
]}
/>
<View style={styles.graphItem} />
</View>
);
})}
</View>
<Animated.View
style={[
styles.graphData,
{
height: humidityValue.interpolate({
inputRange: [0, 100],
outputRange: [
0,
(graphItemHeight + graphSpaceHeight) *
graph.humidity.length,
],
}),
backgroundColor: '#7d4d76',
},
]}
/>
<View
style={[
styles.graphBg,
{
height:
(graphItemHeight + graphSpaceHeight) *
graph.humidity.length,
},
]}
/>
</View>
</View>
<Image
style={styles.aiIcon}
source={require('../assets/ai/humidity.png')}
/>
<Text
style={[
styles.aiText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
湿度
</Text>
</View>
<View style={styles.aiItem}>
<View style={styles.graph}>
<View style={styles.graphView}>
<Text
style={[
styles.graphText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
{NP.round(store.ai.shock, 0).toFixed(0)}mm/s
</Text>
</View>
<View style={styles.graphMain}>
<View
style={{
zIndex: 999,
}}>
{graph.shock.map((v, k) => {
return (
<View key={k}>
<View
style={[
styles.graphSpace,
{
backgroundColor:
scaleBusy || wakeup ? '#ffffff' : '#000000',
},
]}
/>
<View style={styles.graphItem} />
</View>
);
})}
</View>
<Animated.View
style={[
styles.graphData,
{
height: shockValue.interpolate({
inputRange: [0, 150],
outputRange: [
0,
(graphItemHeight + graphSpaceHeight) *
graph.shock.length,
],
}),
backgroundColor: '#fc615e',
},
]}
/>
<View
style={[
styles.graphBg,
{
height:
(graphItemHeight + graphSpaceHeight) *
graph.shock.length,
},
]}
/>
</View>
</View>
<Image
style={styles.aiIcon}
source={require('../assets/ai/shock.png')}
/>
<Text
style={[
styles.aiText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
震动
</Text>
</View>
<View style={styles.aiItem}>
<View style={styles.graph}>
<View style={styles.graphView}>
<Text
style={[
styles.graphText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
{store.ai.trigger.text}G
</Text>
</View>
<View style={styles.graphMain}>
<View
style={{
zIndex: 999,
}}>
{graph.trigger.map((v, k) => {
return (
<View key={k}>
<View
style={[
styles.graphSpace,
{
backgroundColor:
scaleBusy || wakeup ? '#ffffff' : '#000000',
},
]}
/>
<View style={styles.graphItem} />
</View>
);
})}
</View>
<Animated.View
style={[
styles.graphData,
{
height: triggerValue.interpolate({
inputRange: [0, 96],
outputRange: [
0,
(graphItemHeight + graphSpaceHeight) *
graph.trigger.length,
],
}),
backgroundColor: '#8e8a7d',
},
]}
/>
<View
style={[
styles.graphBg,
{
height:
(graphItemHeight + graphSpaceHeight) *
graph.trigger.length,
},
]}
/>
</View>
</View>
<Image
style={styles.aiIcon}
source={require('../assets/ai/trigger.png')}
/>
<Text
style={[
styles.aiText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
触点
</Text>
</View>
<View style={styles.aiItem}>
<View style={styles.graph}>
<View style={styles.graphView}>
<Text
style={[
styles.graphText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
±{NP.round(store.ai.offset, 0).toFixed(0)}G
</Text>
</View>
<View style={styles.graphMain}>
<View
style={{
zIndex: 999,
}}>
{graph.offset.map((v, k) => {
return (
<View key={k}>
<View
style={[
styles.graphSpace,
{
backgroundColor:
scaleBusy || wakeup ? '#ffffff' : '#000000',
},
]}
/>
<View style={styles.graphItem} />
</View>
);
})}
</View>
<Animated.View
style={[
styles.graphData,
{
height: offsetValue.interpolate({
inputRange: [0, 50],
outputRange: [
0,
(graphItemHeight + graphSpaceHeight) *
graph.offset.length,
],
}),
backgroundColor: '#69d6c5',
},
]}
/>
<View
style={[
styles.graphBg,
{
height:
(graphItemHeight + graphSpaceHeight) *
graph.offset.length,
},
]}
/>
</View>
</View>
<Image
style={styles.aiIcon}
source={require('../assets/ai/offset.png')}
/>
<Text
style={[
styles.aiText,
{color: scaleBusy || wakeup ? '#000000' : '#ffffff'},
]}>
误差
</Text>
</View>
<View style={{width: 30}} />
</View>
</View>
);
}
}
const styles = {
tip: {
width,
height: 60,
justifyContent: 'center',
alignItems: 'center',
},
tipText: {
color: 'white',
fontSize: 25,
},
aiIcon: {
width: width * 0.08,
height: width * 0.08,
},
aiText: {
fontSize: 14,
color: '#000000',
fontWeight: 'bold',
marginVertical: 12,
},
aiTriangle: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: 18,
marginBottom: 26,
},
atLeft: {
width: 0,
height: 0,
marginTop: 1,
borderStyle: 'solid',
borderTopWidth: 13,
borderBottomWidth: 13,
borderRightWidth: (width - 60) * 0.1,
borderTopColor: '#fff',
borderLeftColor: '#fff',
borderBottomColor: '#fff',
},
atRight: {
width: 0,
height: 0,
marginTop: 1,
borderStyle: 'solid',
borderTopWidth: 13,
borderBottomWidth: 13,
borderLeftWidth: (width - 60) * 0.1,
borderTopColor: '#fff',
borderBottomColor: '#fff',
borderRightColor: '#fff',
},
aiItem: {
flex: 1,
alignItems: 'center',
},
graph: {
width: graphItemWidth,
flex: 1,
},
graphMain: {
position: 'relative',
marginBottom: 12,
},
graphItem: {
width: graphItemWidth,
height: graphItemHeight,
backgroundColor: 'transparent',
},
graphSpace: {
width: graphItemWidth,
backgroundColor: '#ffffff',
height: graphSpaceHeight,
},
graphBg: {
width: graphItemWidth,
position: 'absolute',
top: 0,
left: 0,
backgroundColor: '#d7d2bb',
},
graphData: {
width: graphItemWidth,
position: 'absolute',
bottom: -1,
left: 0,
zIndex: 9,
},
graphView: {
flex: 1,
alignItems: 'center',
justifyContent: 'flex-end',
},
graphText: {
marginBottom: 5,
fontSize: 12,
color: '#000000',
},
};
export default connect(({store}) => ({store}))(OldFacePage);
import axios from 'axios';
export function agora() {
return axios.post('/store/agora/token');
}
export function talkCall() {
return axios.post('/store/agora/call');
}
export function talkLeave() {
return axios.post('/store/agora/leave');
}
......@@ -53,11 +53,3 @@ export function sendsms({phone}) {
export function verifysms({phone, code, userId}) {
return axios.post('/store/verifysms', qs.stringify({phone, code, userId}));
}
export function agora() {
return axios.post('/store/agora/token');
}
export function talkCall() {
return axios.post('/store/agora/call');
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment