Commit 48118b3e by 修福龙

刷脸开门系统信息提示以及收银台语音通话功能实现

parent 743ae110
import React, {Component} from 'react';
import {View, Text, Image, Dimensions} from 'react-native';
import {View, Text, Image, Dimensions, Modal} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import {connect} from 'react-redux';
import RtcEngine 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';
......@@ -11,6 +11,7 @@ import delay from '../utils/delay';
import Speech from '../utils/Speech';
import WxFacepay from '../utils/WxFacepay';
import phone from '../assets/Vertical/phone.png';
import {onTalkCall, leaveTalkCall} from '../utils/agora';
const {width} = Dimensions.get('screen');
......@@ -20,11 +21,13 @@ class FacePage extends Component {
verifyCodeModal: false, // 显示输入验证码弹窗
orderDetailsModal: false, // 显示订单详情弹窗
goodsArr: [],
talkCall: 2, // 0请求通话,1通话中,2,已挂断通话
talkCall: 2, // 0请求通话,1通话中,2,已挂断通话,待机状态
contact: '',
storeName: '',
customerPhone: '',
current: 1,
tip: '',
tipsModal: false,
};
async componentWillMount() {
......@@ -134,49 +137,11 @@ class FacePage extends Component {
try {
// 加入语音通话
clearInterval(this.noTalkCall);
clearInterval(this.callTimeout);
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);
// });
// this.engine.addListener('Error', data => {
// console.log('Error' + data);
// });
// this.engine.addListener('JoinChannelSuccess', 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.muteLocalAudioStream(true); //停止发送本地音频流
// 加入频道
await this.engine.joinChannel(data.token, data.channel, null, data.uid);
//判断当前是否扬声器
if (!(await this.engine.isSpeakerphoneEnabled())) {
await this.engine.setEnableSpeakerphone(true); //切换到外放
}
await onTalkCall(data);
this.setState({
talkCall: 1,
});
......@@ -188,9 +153,11 @@ class FacePage extends Component {
leaveC = async () => {
try {
clearInterval(this.noTalkCall);
if (this.engine) {
await this.engine.leaveChannel();
}
clearInterval(this.callTimeout);
await leaveTalkCall;
// if (this.engine) {
// await this.engine.leaveChannel();
// }
await this.props.dispatch({
type: 'agora/talkLeave',
});
......@@ -203,7 +170,7 @@ class FacePage extends Component {
};
// device 代表当前打开的门
handleScaleChange = ({count}) => {
handleScaleChange = async ({count}) => {
if (count === -1) {
// 重力感应开始识别
this.wechatFace();
......@@ -215,6 +182,7 @@ class FacePage extends Component {
phoneModal: false,
verifyCodeModal: false,
current: 1,
tipsModal: false,
});
}
};
......@@ -226,10 +194,13 @@ class FacePage extends Component {
let tipText = ret.msg;
Speech.speak(tipText);
this.userId = ret.userId;
this.setState({tip: tipText, tipsModal: true});
if (ret.code === 401) {
// 需要验证手机号
this.setState({phoneModal: true});
} else if (ret.orders) {
this.setState({
phoneModal: true,
});
} else if (ret.orders && ret.orders.length > 0) {
let goodsArr = [];
ret.orders.map(v1 => {
v1.goods.map(v2 => {
......@@ -246,6 +217,7 @@ class FacePage extends Component {
} else if (ret.msg) {
let tipText = ret.msg.replace(/扫码/g, '人脸识别');
Speech.speak(tipText);
this.setState({tip: tipText, tipsModal: true});
}
} else {
Speech.speak('正在重新识别,请靠中间站稳');
......@@ -268,6 +240,7 @@ class FacePage extends Component {
} // 出现订单弹窗,不做人脸识别
const tipText = '正在人脸识别,请看向屏幕,靠中间站稳';
Speech.speak(tipText);
this.setState({tip: tipText, tipsModal: true});
let auth = (await this.authinfo()) || {};
if (
auth.return_code === 'SUCCESS' ||
......@@ -306,6 +279,8 @@ class FacePage extends Component {
// 语音通话请求
onCall = async () => {
const {talkCall} = this.state;
if (talkCall === 2) {
Speech.speak('正在接通中请稍候');
this.talkCall();
clearInterval(this.noTalkCall);
......@@ -313,6 +288,14 @@ class FacePage extends Component {
this.setState({
talkCall: 0,
});
clearInterval(this.callTimeout);
this.callTimeout = setTimeout(() => {
clearInterval(this.noTalkCall);
this.setState({
talkCall: 2,
});
}, 30000);
}
};
talkCall = () => {
......@@ -350,6 +333,8 @@ class FacePage extends Component {
contact,
customerPhone,
current,
tip,
tipsModal,
} = this.state;
let {dispatch} = this.props;
return (
......@@ -404,15 +389,36 @@ class FacePage extends Component {
</View>
</View>
<View style={styles.face}>
<View style={styles.faceRecogn}>
<Touch
onPress={this.wechatFace}
style={styles.faceGif}
onPress={this.wechatFace}
feedback={false}>
<Image
source={require('../assets/Vertical/face.gif')}
style={{flex: 1, width}}
/>
</Touch>
{tipsModal && tip && (
<View style={styles.modal}>
<View style={styles.tips}>
<Text style={styles.tipText}>{tip}</Text>
</View>
<Touch
onPress={this.onCall}
feedback={false}
style={styles.callTouch}>
<View style={styles.callTips}>
<Text style={styles.callTipsText}>呼叫客服</Text>
<Image
source={require('../assets/up.png')}
style={styles.callTipsImg}
/>
</View>
</Touch>
</View>
)}
</View>
<Touch
onPress={this.wechatFace}
style={styles.btnCome}
......@@ -516,9 +522,14 @@ const styles = {
alignItems: 'center',
justifyContent: 'space-around',
},
faceGif: {
faceRecogn: {
flex: 0.7,
},
faceGif: {
// flex: 0.7,
position: 'relative',
zIndex: 2,
},
btnCome: {
flex: 0.15,
// backgroundColor: '#00CD66',
......@@ -590,6 +601,64 @@ const styles = {
color: '#fff',
marginLeft: -70,
},
modal: {
// flex: 0.2,
marginTop: '30%',
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
zIndex: 999,
},
tips: {
flexDirection: 'row',
backgroundColor: '#FC4000',
width: '70%',
// height: '18%',
height: 200,
justifyContent: 'center',
alignItems: 'center',
marginRight: 5,
},
tipText: {
fontSize: 40,
color: '#fff',
textAlign: 'center',
paddingTop: 40,
paddingBottom: 40,
paddingLeft: 5,
paddingRight: 5,
},
callTouch: {
width: '30%',
// height: '18%',
height: 200,
marginLeft: 5,
backgroundColor: '#FC4000',
},
callTips: {
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
// backgroundColor: '#FC4000',
// width: '30%',
// height: '18%',
// marginLeft: 5,
},
callTipsText: {
fontSize: 40,
color: '#fff',
textAlign: 'center',
paddingTop: 70,
// paddingBottom: 40,
paddingLeft: 10,
paddingRight: 10,
},
callTipsImg: {
width: 80,
height: 60,
},
};
export default connect(({store}) => ({store}))(FacePage);
......@@ -16,6 +16,9 @@ import {login} from '../utils/config';
import {colors} from '../utils/common';
import WxFacepay from '../utils/WxFacepay';
import {width} from '../utils/screen';
import Speech from '../utils/Speech';
import delay from '../utils/delay';
import {leaveTalkCall, onTalkCall} from '../utils/agora';
let pageSize = 8; // 分页大小
window.pageSize = pageSize;
......@@ -28,6 +31,7 @@ class VerticalPage extends Component {
contact: '',
maskVisible: true,
visibleActive: false,
talkCall: 2, // 0请求通话,1通话中,2,已挂断通话,待机状态
};
async componentWillMount() {
......@@ -41,6 +45,65 @@ class VerticalPage extends Component {
}
}
async componentDidMount() {
this.listen();
}
listen = async () => {
try {
while (!window.socket) {
await delay(1000);
}
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);
clearInterval(this.callTimeout);
const {data} = await this.props.dispatch({
type: 'agora/agora',
});
await onTalkCall(data);
clearInterval(this.onCallTimeout);
this.onCallTimeout = setTimeout(() => {
this.leaveC();
}, 5 * 60 * 1000);
this.setState({
talkCall: 1,
});
} catch (e) {
console.log(e);
}
};
leaveC = async () => {
try {
clearInterval(this.noTalkCall);
clearInterval(this.callTimeout);
await leaveTalkCall;
await this.props.dispatch({
type: 'agora/talkLeave',
});
this.setState({
talkCall: 2,
});
} catch (e) {
console.log(e);
}
};
authinfo = async () => {
const rawdata = await WxFacepay.rawdata();
const {data} = await this.props.dispatch({type: 'goods/faceinfo', rawdata});
......@@ -140,6 +203,32 @@ class VerticalPage extends Component {
}
};
onCall = async () => {
const {talkCall} = this.state;
if (talkCall === 2) {
Speech.speak('正在接通中请稍候');
this.talkCall();
clearInterval(this.noTalkCall);
this.noTalkCall = setInterval(() => this.talkCall(), 10000);
this.setState({
talkCall: 0,
});
clearInterval(this.callTimeout);
this.callTimeout = setTimeout(() => {
clearInterval(this.noTalkCall);
this.setState({
talkCall: 2,
});
}, 30000);
}
};
talkCall = () => {
this.props.dispatch({
type: 'agora/talkCall',
});
};
renderHeader = () => {
return (
<View style={{flex: 1, flexDirection: 'column'}}>
......@@ -179,10 +268,29 @@ class VerticalPage extends Component {
</View>
<View style={styles.TdStyle}>
{item.price ? (
<Text style={styles.TdText}>
{' '}
{NP.round(item.price, 2).toFixed(2)}/{item.unit}{' '}
// <Text style={styles.TdText}>
// {' '}
// ¥{NP.round(item.price, 2).toFixed(2)}/{item.unit}{' '}
// </Text>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
}}>
<Text
style={{
fontSize: 20,
textDecorationLine: 'line-through',
}}>
{NP.round(item.prePrice, 2).toFixed(2)}/
<Text style={{fontSize: 20}}>{item.unit}</Text>
</Text>
<Text style={{fontSize: 25, color: colors.textXSActive}}>
{NP.round(item.price, 2).toFixed(2)}/
<Text style={styles.TdText}>{item.unit}</Text>
</Text>
</View>
) : (
<Text style={styles.TdText}>
{' '}
......@@ -283,10 +391,12 @@ class VerticalPage extends Component {
<Image style={styles.counterText} source={counterText} />
<Image source={img24h} />
</View>
<Touch onPress={() => this.onCall()}>
<View style={styles.right}>
<Image style={styles.phone} source={phone} />
<Text style={styles.number}>{contact}</Text>
</View>
</Touch>
</View>
<View style={styles.container}>
<View style={{flexDirection: 'row', flex: 1}}>
......
import RtcEngine from 'react-native-agora';
export const onTalkCall = async data => {
try {
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);
// });
// this.engine.addListener('Error', data => {
// console.log('Error' + data);
// });
// this.engine.addListener('JoinChannelSuccess', 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.muteLocalAudioStream(true); //停止发送本地音频流
// 加入频道
await this.engine.joinChannel(data.token, data.channel, null, data.uid);
//判断当前是否扬声器
if (!(await this.engine.isSpeakerphoneEnabled())) {
await this.engine.setEnableSpeakerphone(true); //切换到外放
}
} catch (e) {
console.log(e);
}
};
export const leaveTalkCall = async () => {
if (this.engine) {
await this.engine.leaveChannel();
}
};
export default {onTalkCall, leaveTalkCall};
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