Commit dc08e48f by Denglingling

新增 APP 根据服务器版本号,自动更新下载(安卓可下载,IOS跳转到应用商店)

parent c1bff884
......@@ -33,33 +33,7 @@ class HomePage extends Component {
constructor(props) {
super(props)
this.state = {
showList: [
// {
// icon: require('../../images/quick_order.png'),
// title: '借货订单', // 原快速下单、手术报台
// page: 'QuickOrderPage',
// },
// {
// icon: require('../../images/self_order.png'),
// title: '自助下单',
// page: 'SelfOrderPage',
// },
// {
// icon: require('../../images/trans_order.png'),
// title: '转单申请', // 原转单
// page: 'TransOrderPage',
// },
// {
// icon: require('../../images/equip_consu.png'),
// title: '消耗确认', // 原器械消耗
// page: 'EquipConsuPage',
// },
// {
// icon: require('../../images/return_login.png'),
// title: '返回登录页',
// page: 'LoginPage',
// }
],
showList: [],
backLoginInfo: { // 不需要了
icon: require('../../images/return_login.png'),
title: '返回登录页',
......@@ -132,7 +106,7 @@ class HomePage extends Component {
hisDefauIcon, hisSeleIcon,
borrowInfo, consumpInfo,
transInfo, deviceInfo,
selfOrderInfo,backLoginInfo } = this.state
selfOrderInfo } = this.state
functions = referenceArrSort(functions, 'child_list', 'function_order')
let tempTabNames = []
let tempTabCodes = []
......@@ -166,7 +140,6 @@ class HomePage extends Component {
}
})
}
// tempModuleList.push(backLoginInfo) // 不用了
} else if(item.function_code == 'MOBILE_HISTORICAL_ORDER') {
tempTabIconNames.push(hisDefauIcon)
......@@ -225,7 +198,6 @@ class HomePage extends Component {
/>
<SafeAreaView style={safe_view}>
<HeadBackItem title={'骨科智慧仓'} navigation={navigation} isRightExit={isRightExit} />
<ScrollableTabView
style={styles.bom_tab_box}
initialPage={initialPage}
......@@ -317,7 +289,7 @@ const styles = StyleSheet.create({
fontFamily: font_family_regular
},
bom_tab_box: {
flex: 1
},
})
......
......@@ -27,13 +27,14 @@ import {
safe_view,
font_family_medium
} from '../../base/BaseStyle';
import { requestLogin, autoLogin, setDomainConfigurate } from '../../action/LoginAction';
import { requestLogin, autoLogin, setDomainConfigurate, setVersionApk } from '../../action/LoginAction';
import { show, isEmpty } from '../../utils/Utils';
import { LOGIN_DOING, LOGIN_SUCCESS, LOGIN_FAILURE, LOGIN_NO } from '../../base/ActionTypes';
import StatusBarView from '../common/StatusBarView';
import LodingModel from '../common/LodingModel';
import FillDomainModel from './module/FillDomainModel';
import SplashScreen from 'react-native-splash-screen';
import UpgradeView from './module/UpgradeView';
class LoginPage extends Component{
constructor(props) {
......@@ -45,7 +46,8 @@ class LoginPage extends Component{
subTitList: ['登录', '登录中...'],
isSubLoding: false,
isShowDomain: false, // 域名填写
version_apk: 'V1.2.2'
version_apk: '',
isEnterHomeFlag: false
}
}
......@@ -53,6 +55,7 @@ class LoginPage extends Component{
SplashScreen.hide() //关闭启动屏幕
this.timer = setTimeout(() => {
this.getLocalUserName()
this.setVersion()
}, 300)
}
......@@ -100,7 +103,12 @@ class LoginPage extends Component{
// 设置版本号
setVersion() {
// NativeModules
NativeModules.RNToolsManager.getAppVersion((event)=>{
this.props.setVersionApk(event)
this.setState({
version_apk: event
})
})
}
// 判断是否打开域名弹窗
......@@ -197,6 +205,9 @@ class LoginPage extends Component{
// 进入首页
enterHomePage() {
this.setState({
isEnterHomeFlag: true
})
this.props.navigation.navigate('HomePage')
}
......@@ -222,7 +233,7 @@ class LoginPage extends Component{
}
render() {
let {username, password, isSubLoding, subTit, isShowDomain, version_apk} = this.state
let {username, password, isSubLoding, subTit, isShowDomain, version_apk, isEnterHomeFlag} = this.state
let {global_domain_config} = this.props
let tempInd = global_domain_config.indexOf('/') + 2
let tempGlobalDomain = global_domain_config.slice(tempInd)
......@@ -300,6 +311,7 @@ class LoginPage extends Component{
callback={(domainVal) => this.fillDomainCallBack(domainVal)}
domainValue={tempGlobalDomain}
/>
{ isEnterHomeFlag ? <UpgradeView version_apk={version_apk}/> : null}
</View>
</ImageBackground>
</SafeAreaView>
......@@ -462,7 +474,10 @@ const mapDispatchToProps = (dispatch) => ({
},
setDomainConfigurate: (domainVal) => {
dispatch(setDomainConfigurate(domainVal))
}
},
setVersionApk: (versionApk) => {
dispatch(setVersionApk(versionApk))
},
})
export default connect(mapStateToProps, mapDispatchToProps)(LoginPage)
import React, {Component} from 'react'
import {Dimensions, Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View,NativeModules, PermissionsAndroid, Platform, Linking} from 'react-native'
import {connect} from 'react-redux'
import {requestLatestVersion, requestIOSLatestVersion} from '../../../action/LoginAction';
import {formatStrForDate, show} from '../../../utils/Utils';
// import {downFile} from '../../../utils/DownFileUtil';
import {openInstallActivity,changeDateFormat} from '../../../utils/Utils';
import {foundation_color, promary_text_color, btn_sub_color, title_text_color, second_text_size, font_family_medium, font_family_semibold, second_text_color, first_text_color, pxSize, Width, Height} from "../../../base/BaseStyle";
import {ACCESS_TOKEN} from '../../../base/BaseConstants';
import RNFetchBlob from 'rn-fetch-blob';
import moment from 'moment';
class UpgradeView extends Component {
constructor(props) {
super();
this.state = {
isShowModal: false,
updateInfo:{}
}
}
componentDidMount() {
if(Platform.OS === 'android'){
this.androidGetAppVersion()
}else if(Platform.OS === 'ios'){
this.iosGetAppVersion()
}
}
componentWillUnmount() {
clearTimeout(this.timer)
}
// IOS 获取最新版本
iosGetAppVersion() {
NativeModules.RNToolsManager.getAppVersion((versionName) => {
this.timer = setTimeout(() => {
requestIOSLatestVersion().then(res => {
console.log('版本==res:', res)
if(res.results && res.results.length > 0){
const curVersion = parseInt(versionName.split(".").join(""));
const ios_version = parseInt(res.results[0].version.split(".").join(""));
const updateInfo = {
version: res.results[0].version,
description: res.results[0].releaseNotes,
updateTime: res.results[0].currentVersionReleaseDate,
downLoadUrl: res.results[0].trackViewUrl
}
let cur_date = new Date()
let update_date = moment(res.results[0].currentVersionReleaseDate)._d
if(curVersion > ios_version && cur_date > update_date){
this.setState({isShowModal : true,updateInfo:updateInfo})
}
}
}).catch((error) => {
console.error(error);
})
},500)
})
}
// 安卓 获取最新版本
androidGetAppVersion() {
NativeModules.RNToolsManager.getAppVersion((versionName) => {
this.timer = setTimeout(() => {
let {global_domain_config} = this.props
let params = {
access_token: this.props.token || ACCESS_TOKEN,
app_code: 'MOBILE'
}
requestLatestVersion(global_domain_config, params).then(res => {
console.log('版本==res:', res)
let cur_date = new Date()
let update_date = moment(res.data.updateTime)._d
if(res.error_code === 0 && res.data.appCode === 'MOBILE' && cur_date > update_date){
const curVersion = parseInt(versionName.split(".").join(""));
const version = parseInt(res.data.version.split(".").join(""));
if(curVersion < version){
this.setState({isShowModal : true,updateInfo:res.data})
}
}
}).catch((error) => {
console.error(error);
})
},500)
})
}
closeModal() {
this.setState({
isShowModal: false
})
}
// 更新
subUpdateModal(){
this.closeModal()
this.downLoadApp()
}
render() {
return (
<View style={styles.dia_container}>
<Modal
animationType = {"fade"}
transparent = {true}
visible={this.state.isShowModal}
onRequestClose={() => this.closeModal()}>
{this.state.isShowModal ? this._renderModal(): <View/> }
</Modal>
</View>
)
}
_renderModal () {
const {updateInfo} = this.state;
return (
<TouchableOpacity
style={styles.modal_container}
activeOpacity={1}
onPress={() => this.closeModal()}>
<View style={styles.modal_view}>
<Text allowFontScaling={false} style={styles.modal_title}>是否升级到 {updateInfo.version} 新版本?</Text>
<Text allowFontScaling={false} style={styles.modal_timer}>更新时间:{changeDateFormat(updateInfo.updateTime,'yyyy-MM-dd')}</Text>
<View style={styles.modal_desc_view}>
<Text allowFontScaling={false} style={styles.modal_desc_text}>版本描述:</Text>
<Text allowFontScaling={false} style={styles.modal_desc_text}>{updateInfo.description}</Text>
</View>
<View style={styles.modal_button_container}>
<TouchableOpacity
activeOpacity = {0.8}
style={styles.modal_button_view}
onPress={()=>this.subUpdateModal()}>
<Text allowFontScaling={false} style={styles.modal_button_text}>更新</Text>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
)
}
// 更新 APP
downLoadApp() {
const {updateInfo} = this.state;
const {global_domain_config} = this.props
// console.log('updateInfo.downLoadUrl---', updateInfo.downLoadUrl)
const iosDownLoadUrl = 'https://apps.apple.com/cn/app/id1514343145'
const androidDownLoadUrl = global_domain_config + '/iwms/upload/app/bonehouse.apk'
const downLoadUrl = global_domain_config + '/download'
if(Platform.OS === 'android'){
this.requestReadPermission()
// Linking.openURL(downLoadUrl).catch(err => {
// show('跳转失败!')
// console.error('跳转失败!', err)
// });
}else if(Platform.OS === 'ios'){
Linking.openURL(iosDownLoadUrl).catch(err => {
// show('跳转失败!')
console.error('跳转失败!', err)
});
}
}
// 弹出提示框向用户请求某项权限
async requestReadPermission() {
let {global_domain_config} = this.props
try {
// 返回string类型
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
// {
// 'title': '请求存储空间',
// 'message': '如果没有权限不能更新安装APP,请点击同意'
// }
)
if(granted === PermissionsAndroid.RESULTS.GRANTED) {
Update = () => {
const android = RNFetchBlob.android;
show('更新下载中')
//配置手机系统通知栏下载文件通知,下载成功后点击通知可运行apk文件
RNFetchBlob.config({
addAndroidDownloads: {
useDownloadManager: true,
title: '更新',
description: '骨科智慧仓下载中...',
mime: 'application/vnd.android.package-archive',
path: `${RNFetchBlob.fs.dirs.DownloadDir}/bonehouse.apk`,
mediaScannable: true,
notification: true
}
}).fetch(
'GET',
global_domain_config + '/iwms/upload/app/bonehouse.apk', //apk下载地址
).then(res => {
//下载成功后自动打开安装已下载apk文件
android.actionViewIntent(
res.path(),
'application/vnd.android.package-archive'
);
});
}
Update()
// const android = RNFetchBlob.android;
// downFile(global_domain_config + '/iwms/upload/app/bonehouse.apk','bonehouse.apk')
// .then((result)=> {
// show(`本地下载地址:${result.path}`)
// if (result != null && result.result == true && result.path != null) {
// // openInstallActivity(result.path)
// //下载成功后自动打开安装已下载apk文件
// android.actionViewIntent(
// result.path,
// 'application/vnd.android.package-archive'
// );
// }
// }).catch((error)=>{
// show('下载失败')
// console.log('下载失败---', error)
// })
}else {
show("获取存储空间失败,无法更新APP")
}
}catch (err) {
show(err.toString())
}
}
}
const styles = StyleSheet.create({
dia_container: {
flex: 1
},
modal_container: {
width: Width(),
height: Height(),
backgroundColor: 'rgba(0, 0, 0, 0.5)',
alignItems: 'center',
justifyContent: 'center',
},
modal_view: {
width: Width() - 60,
backgroundColor: foundation_color,
borderRadius: 10,
padding: 20,
},
modal_title: {
color: promary_text_color,
fontSize: second_text_size,
fontFamily: font_family_semibold,
alignSelf: 'center',
marginVertical: 10
},
modal_version: {
fontSize: 16,
color: promary_text_color,
marginTop: 10,
},
modal_timer: {
fontSize: 14,
color: first_text_color,
marginTop: 10,
},
modal_desc_view: {
minHeight: pxSize(132),
marginTop: 10,
marginBottom: 10,
maxHeight: pxSize(152),
},
modal_desc_text: {
fontSize: 14,
color: first_text_color,
lineHeight: 28,
},
modal_button_container: {
height: 46,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
marginBottom: 10
},
modal_button_view: {
flex: 1,
height: 38,
backgroundColor: btn_sub_color,
borderRadius: 20,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
shadowColor: btn_sub_color,
shadowOffset: {
width: 1,
height: 2
},
shadowOpacity: 1,
elevation: 2,
borderWidth: 0
},
modal_button_text: {
color: title_text_color,
fontSize: second_text_size,
fontFamily: font_family_medium
},
})
const mapStateToProps = (state) => ({
token:state.login.token,
global_domain_config:state.login.global_domain_config
})
const mapDispatchToProps = (dispatch) => ({
})
export default connect(mapStateToProps, mapDispatchToProps)(UpgradeView)
\ No newline at end of file
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 sign in to comment