Commit bff71fd8 by 杨周龙

更改为tsx

1 parent f91781a1
Showing with 555 additions and 865 deletions
...@@ -6,42 +6,45 @@ ...@@ -6,42 +6,45 @@
* @flow strict-local * @flow strict-local
*/ */
import React, { useLayoutEffect } from 'react' import React, { useLayoutEffect, useEffect } from 'react'
import { StatusBar, Platform, Text, TextInput } from 'react-native' import { StatusBar, Platform, Text, TextInput } from 'react-native'
import { SafeAreaProvider } from 'react-native-safe-area-context' import { SafeAreaProvider } from 'react-native-safe-area-context'
import { RouterView } from './src/router' import { RouterView } from './src/router'
import { Provider } from 'react-redux' import { Provider } from 'react-redux'
import { ThemeProvider } from 'rn-ui' import { PrivacyAlert } from './src/components'
import { defaultTheme } from './src/commo/theme' import { PortalHot, Update } from 'react-native-mb-ui'
import { PrivacyAlert, Update } from './src/components' import { getVersionCode } from './src/libs/utils'
import store from './src/store' import { APP } from './src/config'
import SplashScreen from 'react-native-splash-screen' import SplashScreen from 'react-native-splash-screen'
import store from './src/store'
//阻止系统缩放 //阻止系统缩放
TextInput.defaultProps = Object.assign({}, TextInput.defaultProps, { allowFontScaling: false }) TextInput.defaultProps = Object.assign({}, TextInput.defaultProps, { allowFontScaling: false })
Text.defaultProps = Object.assign({}, Text.defaultProps, { allowFontScaling: false }) Text.defaultProps = Object.assign({}, Text.defaultProps, { allowFontScaling: false })
const App = () => { const Page = () => {
useLayoutEffect(() => { useLayoutEffect(() => {
store.dispatch.site.init()
SplashScreen.hide() SplashScreen.hide()
}, []) }, [])
useEffect(() => {
(async () => Update(`${APP.appAdminUrl}/api/app/version/${APP.APP_CODE}`, await getVersionCode()))()
}, [])
return ( return (
<>
<PrivacyAlert /> <Provider store={store}>
{Platform.OS === 'android' && <Update />}
{Platform.OS === 'ios' && <StatusBar translucent={true} backgroundColor="rgba(255,255,255,0)" barStyle="dark-content" />} {Platform.OS === 'ios' && <StatusBar translucent={true} backgroundColor="rgba(255,255,255,0)" barStyle="dark-content" />}
<Provider store={store}> <PortalHot>
<SafeAreaProvider> <SafeAreaProvider>
<ThemeProvider theme={defaultTheme}>
<RouterView /> <RouterView />
</ThemeProvider> <PrivacyAlert />
</SafeAreaProvider> </SafeAreaProvider>
</Provider> </PortalHot>
</> </Provider>
) )
} }
export default App export default Page
This diff could not be displayed because it is too large.
...@@ -23,18 +23,19 @@ ...@@ -23,18 +23,19 @@
"react-native": "0.62.2", "react-native": "0.62.2",
"react-native-device-info": "^5.5.8", "react-native-device-info": "^5.5.8",
"react-native-gesture-handler": "^1.6.1", "react-native-gesture-handler": "^1.6.1",
"react-native-mb-ui": "^1.6.16",
"react-native-reanimated": "^1.8.0", "react-native-reanimated": "^1.8.0",
"react-native-safe-area-context": "^1.0.0", "react-native-safe-area-context": "^1.0.0",
"react-native-screens": "^2.7.0", "react-native-screens": "^2.7.0",
"react-native-splash-screen": "^3.2.0", "react-native-splash-screen": "^3.2.0",
"react-native-vector-icons": "^6.6.0", "react-native-vector-icons": "^6.6.0",
"react-redux": "^7.2.0", "react-redux": "^7.2.0"
"rn-ui": "^0.3.17"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.6.2", "@babel/core": "^7.6.2",
"@babel/runtime": "^7.6.2", "@babel/runtime": "^7.6.2",
"@react-native-community/eslint-config": "^0.0.5", "@react-native-community/eslint-config": "^0.0.5",
"@types/node": "^14.14.10",
"babel-jest": "^24.9.0", "babel-jest": "^24.9.0",
"eslint": "^6.5.1", "eslint": "^6.5.1",
"jest": "^24.9.0", "jest": "^24.9.0",
......
import { FETCH } from '../libs/fetch'
export const findAddr = async () => {
return FETCH.request({
url: '/tms/open/addr/findAddr',
method: 'get'
})
}
export const findAddrVersion = async () => {
return FETCH.request({
url: '/tms/open/addr/findVersion',
method: 'get'
})
}
export const findStreet = async params => {
return FETCH.request({
url: '/tms/addr',
method: 'get',
params
})
}
\ No newline at end of file
import { FETCH } from '../libs/fetch'
import { APP } from '../config/app'
export const getTopVersion = (app_code, successCall, errorCall) => {
return FETCH.sourceRequest({
url: `${APP.updateApi}${app_code}`,
}, successCall, errorCall)
}
/**获取版本更新列表 */
export const getVersionList = (successCall, errorCall) => {
return FETCH.sourceRequest({
url: `${APP.appAdminUrl}/api/app_version/${APP.APP_CODE}`
}, successCall, errorCall)
}
\ No newline at end of file
No preview for this file type
No preview for this file type
No preview for this file type
This diff could not be displayed because it is too large.
import { setUnit } from '../libs/utils'
const Colors = {
primary: '#F77116',
secondary: '#1890FF',
screen: '#f5f6f7',
success: '#38C897',
placeholder: '#C0C5CC',
primaryText: '#333'
}
const TouchStyle = {
/**touchableOpacity 按下时的透明度 */
activeOpacity: 0.8
}
/**@description ui库全局配置 */
const defaultTheme = {
colors: {
primary: Colors.primary
},
XbdButton: {
long: true,
style: {
height: setUnit(99),
marginHorizontal: setUnit(33),
marginVertical: setUnit(42)
},
textStyle: {
fontSize: setUnit(33)
}
},
XbdCell: {
arrowSize: setUnit(33),
style: {
paddingHorizontal: setUnit(33),
paddingVertical: setUnit(33)
},
titleTextStyle: {
color: '#444',
fontSize: setUnit(33)
},
extraTextStyle: {
color: '#676869',
fontSize: setUnit(29)
}
}
}
export { Colors, TouchStyle, defaultTheme }
\ No newline at end of file
import { PrivacyAlert } from './privacy-alert'
import Update from './update'
export {
PrivacyAlert,
Update
}
\ No newline at end of file
import PrivacyAlert from './privacy-alert'
export {
PrivacyAlert
}
import PrivacyAlert from './view' import PrivacyAlert from './view'
export { PrivacyAlert } export default PrivacyAlert
\ No newline at end of file
...@@ -2,14 +2,14 @@ import { StyleSheet } from 'react-native' ...@@ -2,14 +2,14 @@ import { StyleSheet } from 'react-native'
import { setUnit } from '../../libs/utils' import { setUnit } from '../../libs/utils'
const styles = StyleSheet.create({ const styles = StyleSheet.create({
content: { content: {
color: '#333', color: '#333',
fontSize: setUnit(30) fontSize: setUnit(30)
}, },
privacy: { privacy: {
color: '#1892FF', color: '#1892FF',
fontSize: setUnit(30) fontSize: setUnit(30)
} }
}) })
export { styles } export { styles }
\ No newline at end of file
...@@ -5,51 +5,48 @@ ...@@ -5,51 +5,48 @@
*/ */
import React, { useCallback, useEffect, useState } from 'react' import React, { useCallback, useEffect, useState } from 'react'
import { Text, Linking } from 'react-native' import { Text, Linking } from 'react-native'
import { XbdAlertDialog } from 'rn-ui' import { Modal, Storage } from 'react-native-mb-ui'
import { APP } from '../../config' import { APP } from '../../config'
import { getStorage, setStorage, setUnit } from '../../libs/utils' import { setUnit } from '../../libs/utils'
import { styles } from './style' import { styles } from './style'
const Component = () => { const PrivacyAlert = () => {
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
useEffect(() => { useEffect(() => {
showPrivacy() showPrivacy()
}, []) }, [])
const goPrivacy = useCallback(() => Linking.openURL(APP.privacyLink), []) const goPrivacy = useCallback(() => Linking.openURL(APP.privacyLink), [])
const showPrivacy = async () => { const showPrivacy = async () => {
const notFirst = await getStorage(APP.notFirstInstall) const notFirst = await Storage.getItem(APP.notFirstInstall)
if (notFirst === null) if (notFirst === null)
setVisible(true) setVisible(true)
} }
const onOk = useCallback(() => { const onOk = useCallback(() => {
setVisible(false) setVisible(false)
setStorage(APP.notFirstInstall, true) Storage.setItem(APP.notFirstInstall, true)
}) })
return ( return (
<XbdAlertDialog <Modal
visible={visible} visible={visible}
title='温馨提示' title='温馨提示'
closable={false} onClose={onOk}
okText={'我知道了'} button={[{ text: '我知道了' }]}
maskClosable={false} style={{ width: setUnit(560) }}
onOk={onOk} content={
style={{ width: setUnit(560) }} <Text style={styles.content}>{`欢迎来到信巴迪商品交易所, 感谢您对信巴迪的信任和支持!\n`}
onVisibleChange={visible => setVisible(visible)}
center={
<Text style={styles.content}>{`欢迎来到欢迎来到信巴迪商品交易所, 感谢您对信巴迪的信任和支持!\n`}
为了提供给您更加优质和个性化的服务, 我们会收集或使用您的搜索、浏览与购买等信息。具体内容请您详阅 为了提供给您更加优质和个性化的服务, 我们会收集或使用您的搜索、浏览与购买等信息。具体内容请您详阅
<Text style={styles.privacy} onPress={goPrivacy}>《商城平台隐私权政策》</Text> <Text style={styles.privacy} onPress={goPrivacy}>《商城平台隐私权政策》</Text>
全文, 我们已采用业内先进的信息保护措施, 并会持续优化信息保护技术和安全管理流程, 来保护您的个人信息安全。 全文, 我们已采用业内先进的信息保护措施, 并会持续优化信息保护技术和安全管理流程, 来保护您的个人信息安全。
</Text> </Text>
} }
/> />
) )
} }
export default Component export default PrivacyAlert
\ No newline at end of file
import { StyleSheet } from 'react-native'
import { setUnit } from '../../libs/utils'
export const styles = StyleSheet.create({
body: {
backgroundColor: 'rgba(0,0,0,0.2)',
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
modal: {
width: setUnit(583),
backgroundColor: '#ffffff',
borderRadius: setUnit(17),
elevation: 1,
shadowOffset: {
width: setUnit(2),
height: setUnit(2)
},
shadowOpacity: 0.3,
shadowColor: '#eeeeee'
},
title: {
paddingTop: setUnit(48),
width: '100%',
textAlign: 'center',
fontSize: setUnit(38),
fontWeight: '500',
color: '#333333'
},
content: {
width: '100%',
paddingLeft: setUnit(25),
paddingRight: setUnit(25),
fontSize: setUnit(31),
color: '#333333',
fontWeight: '300',
paddingTop: setUnit(33)
},
button: {
width: '100%',
height: setUnit(100),
borderTopColor: '#e5e5e5',
borderTopWidth: setUnit(2),
justifyContent: 'center',
alignItems: 'center',
marginTop: setUnit(50)
},
buttonTitle: {
fontSize: setUnit(38),
fontWeight: '500',
color: '#434343'
}
})
import React, { useEffect, useState, useRef, useCallback } from 'react'
import { Alert, Linking, Modal, View, TouchableNativeFeedback, Text } from 'react-native'
import { getVersionCode, setStorage, getStorage } from '../../libs/utils'
import { getTopVersion } from '../../api/version'
import { XbdToast } from 'rn-ui'
import { styles } from './styles'
import { APP } from '../../config'
let http
const Component = () => {
const [show, setShow] = useState(false)
const [version, setVersion] = useState('')
const downUrl = useRef('')
/** 打开下载链接 */
const openDown = () => {
Linking.openURL(downUrl.current)
.catch(() => {
XbdToast.show('打开下载地址失败,请重试')
})
}
/**insterLog */
const insterLog = useCallback(() => setStorage('checkUpdateTime', new Date().getTime() + 86400000), [])
const getUpdate = async () => {
const notFirst = await getStorage(APP.notFirstInstall)
if (new Date().getTime() < (await getStorage('checkUpdateTime') || 0) && notFirst === null) return
const versionCode = await getVersionCode()
http = getTopVersion(APP.APP_CODE, res => {
if (res === null) return
const { version_code, down, version, is_update } = res
downUrl.current = down
if (version_code > versionCode && is_update) {
setShow(true)
setVersion(version)
}
else if (version_code > versionCode)
// 保存查询时间
Alert.alert('重要提示', `发现新版本${version}需要更新,是否更新`, [
{ text: '一天后提醒', onPress: insterLog },
{ text: '取消' },
{ text: '立即更新', onPress: openDown }
])
})
}
useEffect(() => {
setTimeout(() => getUpdate(), 3000)
return () => http && http.cancel()
}, [])
return (
<Modal visible={show} transparent={true} style={styles.body}>
<View style={styles.body}>
<View style={styles.modal}>
<Text style={styles.title}>重要提示</Text>
<Text style={styles.content}>发现新版本{version},需要更新才能继续使用。请更新后重新进入APP</Text>
<TouchableNativeFeedback onPress={openDown}>
<View style={styles.button}>
<Text style={styles.buttonTitle}>立即更新</Text>
</View>
</TouchableNativeFeedback>
</View>
</View>
</Modal>
)
}
export default Component
\ No newline at end of file
...@@ -43,7 +43,7 @@ const APP = { ...@@ -43,7 +43,7 @@ const APP = {
/** @description 适用平台:0=业务平台 1=运管平台 */ /** @description 适用平台:0=业务平台 1=运管平台 */
applyPlatform: [0], applyPlatform: [0],
/** @description 适用前端 0=web 1=app 3=小程序 */ /** @description 适用前端 0=web 1=app 3=小程序 */
applyCarrier: [1], applyCarrier: [1],
...@@ -58,7 +58,7 @@ const APP = { ...@@ -58,7 +58,7 @@ const APP = {
/**@description 查询版本更新的API地址 */ /**@description 查询版本更新的API地址 */
updateApi: isBuildDebug ? 'http://app-admin-dev.b2bwings.com/api/app/version/' : 'http://app-admin.b2bwings.com/api/app/version/', updateApi: isBuildDebug ? 'http://app-admin-dev.b2bwings.com/api/app/version/' : 'http://app-admin.b2bwings.com/api/app/version/',
/**@description app版本管理url */ /**@description app版本管理url */
appAdminUrl: isBuildDebug ? 'http://app-admin-dev.b2bwings.com' : 'http://app-admin.b2bwings.com', appAdminUrl: isBuildDebug ? 'http://app-admin-dev.b2bwings.com' : 'http://app-admin.b2bwings.com',
......
...@@ -5,23 +5,23 @@ ...@@ -5,23 +5,23 @@
*/ */
class CheckUtil { class CheckUtil {
/**校验邮箱格式 */ /**校验邮箱格式 */
static isEmail(str) { static isEmail(str) {
let reg = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ let reg = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
return reg.test(str) return reg.test(str)
} }
/**校验手机号 */ /**校验手机号 */
static isMobile(str) { static isMobile(str) {
let reg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/ let reg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
return reg.test(str) return reg.test(str)
} }
/**校验用户账号 */ /**校验用户账号 */
static checkAccount(str) { static checkAccount(str) {
let reg = /^\d{9}$/ let reg = /^\d{9}$/
return reg.test(str) return reg.test(str)
} }
} }
export default CheckUtil export default CheckUtil
\ No newline at end of file
...@@ -2,4 +2,4 @@ import http from './http-request' ...@@ -2,4 +2,4 @@ import http from './http-request'
import { APP } from '../config' import { APP } from '../config'
const FETCH = new http(APP.baseUrl) const FETCH = new http(APP.baseUrl)
export { FETCH } export { FETCH }
\ No newline at end of file
...@@ -10,7 +10,7 @@ export function formatPhoneNo(num) { ...@@ -10,7 +10,7 @@ export function formatPhoneNo(num) {
/** /**
* 格式化Email为 h****@b2bwings.com 的格式 * 格式化Email为 h****@b2bwings.com 的格式
* @param {*} str * @param {*} str
*/ */
export function formatEmail(str) { export function formatEmail(str) {
if (!str) { if (!str) {
...@@ -27,17 +27,17 @@ export function formatEmail(str) { ...@@ -27,17 +27,17 @@ export function formatEmail(str) {
/** /**
* @description 数字千分位 * @description 数字千分位
* @param {number|string} num * @param {number|string} num
* @author sheng * @author sheng
* @date 2020/04/26 * @date 2020/04/26
*/ */
export function thousandBitSeparator(num) { export function thousandBitSeparator(num) {
return num && (num.toString().indexOf('.') != -1 return num && (num.toString().indexOf('.') != -1
? num.toString().replace(/(\d)(?=(\d{3})+\.)/g, function ($0, $1) { ? num.toString().replace(/(\d)(?=(\d{3})+\.)/g, function ($0, $1) {
return $1 + ","; return $1 + ","
}) : num.toString().replace(/(\d)(?=(\d{3})+$)/g, function ($0, $1) { }) : num.toString().replace(/(\d)(?=(\d{3})+$)/g, function ($0, $1) {
return $1 + ","; return $1 + ","
})); }))
} }
/** /**
...@@ -64,8 +64,8 @@ export function getDateEndTime(stmp) { ...@@ -64,8 +64,8 @@ export function getDateEndTime(stmp) {
/** /**
* 日期格式化 * 日期格式化
* @param {*} fmt * @param {*} fmt
* @param {*} time 毫秒时间戳 * @param {*} time 毫秒时间戳
*/ */
export function dateFormat(fmt, time) { export function dateFormat(fmt, time) {
let ret let ret
...@@ -78,7 +78,7 @@ export function dateFormat(fmt, time) { ...@@ -78,7 +78,7 @@ export function dateFormat(fmt, time) {
"h+": newDate.getHours().toString(), // 时 "h+": newDate.getHours().toString(), // 时
"m+": newDate.getMinutes().toString(), // 分 "m+": newDate.getMinutes().toString(), // 分
"s+": newDate.getSeconds().toString() // 秒 "s+": newDate.getSeconds().toString() // 秒
}; }
for (let k in opt) { for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt) ret = new RegExp("(" + k + ")").exec(fmt)
if (ret) { if (ret) {
...@@ -90,16 +90,8 @@ export function dateFormat(fmt, time) { ...@@ -90,16 +90,8 @@ export function dateFormat(fmt, time) {
} }
/** /**
* 分钱转换为元
* @param {*} num
*/
export function fenToYuan(num) {
return (Number(num) / 100).toFixed(2)
}
/**
* 请求参数格式化为字符串 * 请求参数格式化为字符串
* @param {Object} query * @param {Object} query
* @author sheng * @author sheng
* @date 2020/06/23 * @date 2020/06/23
*/ */
...@@ -126,4 +118,4 @@ export function getRemainTime(minutes) { ...@@ -126,4 +118,4 @@ export function getRemainTime(minutes) {
/**剩余分钟 */ /**剩余分钟 */
let min = Math.round(minutes % 60) let min = Math.round(minutes % 60)
return hour <= 0 ? `${min}分钟` : `${hour}小时${min}分钟` return hour <= 0 ? `${min}分钟` : `${hour}小时${min}分钟`
} }
\ No newline at end of file
import axios, { CancelToken } from 'axios' import axios from 'axios'
import { APP } from '../config' import { APP } from '../config'
import { getStore } from '../store/context'
import { navigate } from '../router/ref'
import { ModalManager } from 'react-native-mb-ui'
class HttpRequest { class HttpRequest {
constructor (baseUrl, loginUrl = APP.loginPath) { public instance = null
this.baseUrl = baseUrl public header = null
this.loginUrl = loginUrl constructor(private baseUrl) {
this.header = { ...APP.header } this.header = { ...APP.header }
this.instance = null this.init()
this.init() }
} /**初始化 */
/**初始化 */ init() {
init() { let instance = axios.create({ baseURL: this.baseUrl, headers: this.header })
let instance = axios.create({ baseURL: this.baseUrl, headers: this.header }) this.interceptors(instance)
this.interceptors(instance) this.instance = instance
this.instance = instance }
}
/**绑定请求拦截器 */
interceptors(instance) {
// 请求
instance.interceptors.request.use(config => {
return config
}, error => {
// if (process.env.NODE_ENV === 'development') console.warn(error)
return Promise.reject(error)
})
/**绑定请求拦截器 */ // 响应
interceptors (instance) { instance.interceptors.response.use(res => {
// 请求
instance.interceptors.request.use(config => {
return config
}, error => {
return Promise.reject(error)
})
// 响应 return this.handleRespone(res)
instance.interceptors.response.use(res => {
return this.handleRespone(res) }, error => {
if (process.env.NODE_ENV === 'development') console.warn(error)
return Promise.reject(error.response ? `发生错误,错误代码:${error.response.status};详情:${error.response.message || ''}` : error.message + "")
})
}, error => { }
if (process.env.NODE_ENV === 'development') console.warn(error)
return Promise.reject(error.response ? `发生错误,错误代码:${error.response.status};详情:${error.response.message || ''}` : error.message + "")
})
} /**请求 */
async request(options) {
/**请求 */ return this.instance(options)
async request (options) { }
return this.instance(options)
}
/** /**
* 可取消的请求,返回一个source对象对象。可通过 source.cancel(msg) 取消此请求 * 可取消的请求,返回一个source对象对象。可通过 source.cancel(msg) 取消此请求
* @param {*} options * @param {*} options
* @param {function} successCallback * @param {function} successCallback
* @param {function} errorCallback * @param {function} errorCallback
*/ */
sourceRequest(options, successCallback, errorCallback) { sourceRequest(options, successCallback, errorCallback) {
const source = CancelToken.source() const source = axios.CancelToken.source()
options = Object.assign(options, { cancelToken: source.token }) options = Object.assign(options, { cancelToken: source.token })
this.instance(options) this.instance(options)
.then(successCallback) .then(successCallback)
.catch(errorCallback) .catch(errorCallback)
return source return source
} }
/** /**
* 设置请求头 * 设置请求头
* @param {string} key * @param {string} key
* @param {any} value * @param {any} value
*/ */
setHeader(key, value) { setHeader(key, value) {
this.instance.defaults.headers.common[key] = value this.instance.defaults.headers.common[key] = value
} }
/** /**
* 设置URL * 设置URL
* @param {string} url * @param {string} url
*/ */
setBaseUrl(url) { setBaseUrl(url) {
this.instance.defaults.baseURL = url this.instance.defaults.baseURL = url
} }
/**
* 处理响用体
* @param {response} res
*/
handleRespone(res) {
const { code, message, data } = res.data
switch (code) {
case 200: 1590
return data
case 401:
ModalManager.alert({ title: '提示', content: '登陆状态失效,请重新登陆' })
this.resetState()
return Promise.reject(`未登录或登录状态已过期 错误代码: ${code}`)
case 403:
return Promise.reject(`无权限使用此功能 错误代码: ${code};`)
default:
if (process.env.NODE_ENV === 'development') console.warn(JSON.stringify(res.config))
return Promise.reject(`${message || '未知原因'} 错误代码: ${code}`)
}
}
/** resetState() {
* 处理响用体 getStore().dispatch.user.reset()
* @param {response} res getStore().dispatch.me.reset()
*/ navigate('Login')
handleRespone(res) {
const { code, message, data } = res.data
switch(code) {
case 200:
return data
case 401:
return Promise.reject(`错误: ${code};详情:未登录或登录状态已过期`)
case 403:
return Promise.reject(`错误: ${code};详情:无权限使用此功能`)
default:
if (process.env.NODE_ENV === 'development') console.warn(JSON.stringify(res.config))
return Promise.reject(`错误: ${code};详情:${message || '未知原因'}`)
} }
}
} }
export default HttpRequest export default HttpRequest
...@@ -2,7 +2,6 @@ import { Dimensions } from 'react-native' ...@@ -2,7 +2,6 @@ import { Dimensions } from 'react-native'
import { UI_WIDTH } from '../config' import { UI_WIDTH } from '../config'
import DeviceInfo from 'react-native-device-info' import DeviceInfo from 'react-native-device-info'
import { CommonActions } from '@react-navigation/native' import { CommonActions } from '@react-navigation/native'
import AsyncStorage from '@react-native-community/async-storage'
import CheckUtil from './check' import CheckUtil from './check'
import { APP } from '../config' import { APP } from '../config'
import { FETCH } from './fetch' import { FETCH } from './fetch'
...@@ -15,10 +14,10 @@ const UI_SACEL = WINDOWS.width / UI_WIDTH ...@@ -15,10 +14,10 @@ const UI_SACEL = WINDOWS.width / UI_WIDTH
/** /**
* 设置px单位 * 设置px单位
* @param {*} num * @param {*} num
*/ */
export const setUnit = num => { export const setUnit = num => {
return num * UI_SACEL return num * UI_SACEL
} }
/** 获取版本号 */ /** 获取版本号 */
...@@ -30,106 +29,42 @@ export const getVersion = async () => await DeviceInfo.getVersion() ...@@ -30,106 +29,42 @@ export const getVersion = async () => await DeviceInfo.getVersion()
/** 获取屏幕高度 */ /** 获取屏幕高度 */
export const getHeight = () => WINDOWS.height export const getHeight = () => WINDOWS.height
/** 存储数据 */
export const setStorage = async (key, value) => {
try {
const data = {
type: typeof value,
data: value
}
if (data.type !== 'string')
switch (data.type) {
case 'number':
data.data += ''
break
case 'undefined':
data.data = ''
break
case 'boolean':
data.data = Number(data.data) + ''
break
default:
data.data = JSON.stringify(data.data)
break
}
await AsyncStorage.setItem(key, JSON.stringify(data))
} catch (error) {
return null
}
}
/** 获取数据 */
export const getStorage = async key => {
try {
const data = JSON.parse(await AsyncStorage.getItem(key))
switch (data.type) {
case 'string':
return data.data
case 'number':
return Number(data.data)
case 'undefined':
return undefined
case 'boolean':
return Boolean(Number(data.data))
default:
return JSON.parse(data.data)
}
} catch (error) {
return null
}
}
/**
* 分单位的金额转换成元单位
* @param {[type]} fen [description]
* @return {[type]} [description]
*/
export function fen2yuan(fen) {
if (typeof fen === 'string') fen = Number(fen)
let y = fen / 100
if (Number.isNaN(y))
return '金额错误'
else
return y.toFixed(2)
}
/** /**
* 校验手机号和验证码 * 校验手机号和验证码
* @param {string} phone * @param {string} phone
* @returns {Object} * @returns {Object}
*/ */
export const checkPhoneAndCode = (phone, code) => { export const checkPhoneAndCode = (phone, code) => {
if (!phone.trim().length) { if (!phone.trim().length) {
return { status: 0, msg: '手机号不能为空' } return { status: 0, msg: '手机号不能为空' }
} }
if (!CheckUtil.isMobile(phone)) { if (!CheckUtil.isMobile(phone)) {
return { status: 0, msg: '手机号格式不正确' } return { status: 0, msg: '手机号格式不正确' }
} }
if (!code.trim().length) { if (!code.trim().length) {
return { status: 0, msg: '验证码不能为空' } return { status: 0, msg: '验证码不能为空' }
} }
return { status: 1, msg: '' } return { status: 1, msg: '' }
} }
/** /**
* 校验两次输入的邮箱 * 校验两次输入的邮箱
* @param {*} email * @param {*} email
* @param {*} confirmEmail * @param {*} confirmEmail
* @returns {Object} * @returns {Object}
*/ */
export const checkEmails = (email, confirmEmail) => { export const checkEmails = (email, confirmEmail) => {
if (!email.trim().length) { if (!email.trim().length) {
return { status: 0, msg: '邮箱不能为空' } return { status: 0, msg: '邮箱不能为空' }
} }
if (!CheckUtil.isEmail(email)) { if (!CheckUtil.isEmail(email)) {
return { status: 0, msg: '邮箱格式不正确' } return { status: 0, msg: '邮箱格式不正确' }
} }
if (email !== confirmEmail) { if (email !== confirmEmail) {
return { status: 0, msg: '两次输入邮箱不一致' } return { status: 0, msg: '两次输入邮箱不一致' }
} }
return { status: 1, msg: '' } return { status: 1, msg: '' }
} }
/** /**
...@@ -137,33 +72,33 @@ export const checkEmails = (email, confirmEmail) => { ...@@ -137,33 +72,33 @@ export const checkEmails = (email, confirmEmail) => {
* @param {*} saveTime token存储时间 * @param {*} saveTime token存储时间
*/ */
export const isTokenExpired = (saveTime) => { export const isTokenExpired = (saveTime) => {
let now = new Date().getTime() let now = new Date().getTime()
return now - saveTime > APP.tokenExpires * 24 * 60 * 60 * 1000 return now - saveTime > APP.tokenExpires * 24 * 60 * 60 * 1000
} }
/** /**
* 设置网络请求头 * 设置网络请求头
* @param {*} jwt * @param {*} jwt
* @param {*} sessionId * @param {*} sessionId
*/ */
export const setHeader = (jwt, sessionId) => { export const setHeader = (jwt, sessionId) => {
FETCH.setHeader('Authorization', jwt) FETCH.setHeader('Authorization', jwt)
FETCH.setHeader('Sessionid', sessionId) FETCH.setHeader('Sessionid', sessionId)
} }
/** /**
* 重置路由栈 * 重置路由栈
* @param {*} navigation * @param {*} navigation
*/ */
export const resetRoutes = navigation => { export const resetRoutes = navigation => {
navigation.dispatch( navigation.dispatch(
CommonActions.reset({ CommonActions.reset({
index: 1, index: 1,
routes: [ routes: [
{ name: 'Index' }, { name: 'Index' },
{ name: 'Login' } { name: 'Login' }
], ],
}) })
) )
} }
...@@ -9,17 +9,17 @@ import { Icons } from '../assets/icons' ...@@ -9,17 +9,17 @@ import { Icons } from '../assets/icons'
const headerStyle = { const headerStyle = {
headerTitleAlign: 'center', // 文字居中 headerTitleAlign: 'center', // 文字居中
headerStyle: { headerStyle: {
borderBottomColor: '#eee', borderBottomColor: '#eee',
borderBottomWidth: StyleSheet.hairlineWidth, borderBottomWidth: StyleSheet.hairlineWidth,
backgroundColor: Colors.white , backgroundColor: Colors.white,
elevation: 0 elevation: 0
}, // 标题栏样式 }, // 标题栏样式
headerTintColor: '#262626', // 标题栏字体颜色 headerTintColor: '#262626', // 标题栏字体颜色
headerTitleStyle: { headerTitleStyle: {
fontSize: setUnit(38) fontSize: setUnit(38)
}, },
headerShown: false, headerShown: false,
headerBackImage: Platform.OS === 'ios' ? undefined : () => <Icons name="fanhui" size={setUnit(33)} color="#262626" />, // 标题栏返回图标 headerBackImage: Platform.OS === 'ios' ? undefined : () => <Icons name="fanhui" size={setUnit(33)} color="#262626" />, // 标题栏返回图标
headerBackTitleVisible: false, headerBackTitleVisible: false,
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, // 设置左右滑动 cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, // 设置左右滑动
gestureDirection: 'horizontal', // 初始化右滑手势配置 gestureDirection: 'horizontal', // 初始化右滑手势配置
...@@ -28,12 +28,12 @@ const headerStyle = { ...@@ -28,12 +28,12 @@ const headerStyle = {
} }
const headerRightButton = StyleSheet.create({ const headerRightButton = StyleSheet.create({
text: { text: {
fontWeight: '400', fontWeight: '400',
fontSize: setUnit(29), fontSize: setUnit(29),
color: '#6c6c6c', color: '#6c6c6c',
paddingRight: setUnit(25) paddingRight: setUnit(25)
} }
}) })
export { headerStyle, headerRightButton } export { headerStyle, headerRightButton }
\ No newline at end of file
import React from 'react'
export const navigateRef = React.createRef()
/**
* 直接导航方式,用于无法访问导航道具场景下使用
* @param {*} name
* @param {*} params
*/
export const navigate = (name, params = {}) => {
navigateRef.current?.navigate(name, params)
}
import React from "react"
import type { NavigationContainerRef } from "@react-navigation/native"
export const navigateRef: React.RefObject<NavigationContainerRef> = React.createRef()
/**
* 直接导航方式,用于无法访问导航道具场景下使用
* @param {*} name
* @param {*} params
*/
export const navigate = (name: string, params: Record<string, unknown> | undefined): void => {
if (navigateRef.current) navigateRef.current.navigate(name, params)
}
...@@ -14,15 +14,15 @@ const Stack = createStackNavigator() ...@@ -14,15 +14,15 @@ const Stack = createStackNavigator()
const Route = () => { const Route = () => {
return ( return (
<Stack.Navigator initialRouteName="Index" screenOptions={{ ...headerStyle }} mode={'card'} > <Stack.Navigator initialRouteName="Index" screenOptions={{ ...headerStyle }} mode={'card'} >
<Stack.Screen name="Index" options={{ title: '首页' }} component={ TabRouter } /> <Stack.Screen name="Index" options={{ title: '首页' }} component={TabRouter} />
{/* 关于 */} {/* 关于 */}
<Stack.Screen name='About' options={{ title: '', headerShown: true, headerStyle: {elevation: 0, backgroundColor: '#fff'} }} component={About}/> <Stack.Screen name='About' options={{ title: '', headerShown: true, headerStyle: { elevation: 0, backgroundColor: '#fff' } }} component={About} />
{/* 隐私协议与政策 */} {/* 隐私协议与政策 */}
<Stack.Screen name='Privacy' options={{title: '隐私协议', headerShown: true}} component={Privacy}/> <Stack.Screen name='Privacy' options={{ title: '隐私协议', headerShown: true }} component={Privacy} />
{/* 功能介绍 */} {/* 功能介绍 */}
<Stack.Screen name='Features' options={{ headerShown: true, title: '功能介绍'}} component={Features}/> <Stack.Screen name='Features' options={{ headerShown: true, title: '功能介绍' }} component={Features} />
{/* 功能介绍 */} {/* 功能介绍 */}
<Stack.Screen name='FeatureDetail' options={{ headerShown: true, title: '', headerStyle: {elevation: 0, backgroundColor: '#fff'}}} component={FeatureDetail}/> <Stack.Screen name='FeatureDetail' options={{ headerShown: true, title: '', headerStyle: { elevation: 0, backgroundColor: '#fff' } }} component={FeatureDetail} />
</Stack.Navigator> </Stack.Navigator>
) )
} }
......
...@@ -8,22 +8,22 @@ const Tab = createBottomTabNavigator() // 创建tab栈堆 ...@@ -8,22 +8,22 @@ const Tab = createBottomTabNavigator() // 创建tab栈堆
/** 选项配置函数 */ /** 选项配置函数 */
const tabScreen = ({ route }) => ({ const tabScreen = ({ route }) => ({
tabBarIcon: ({ focused, size }) => { tabBarIcon: ({ focused, size }) => {
switch (route.name) { switch (route.name) {
case 'home': case 'home':
return null return null
}
} }
}
}) })
const TabRoute = () => { const TabRoute = () => {
return ( return (
<Tab.Navigator backBehavior={'none'} screenOptions={tabScreen} tabBarOptions={APP.tabConfig}> <Tab.Navigator backBehavior={'none'} screenOptions={tabScreen} tabBarOptions={APP.tabConfig}>
<Tab.Screen options={{ title: '首页' }} name="home" component={Home} /> <Tab.Screen options={{ title: '首页' }} name="home" component={Home} />
</Tab.Navigator> </Tab.Navigator>
) )
} }
export default TabRoute export default TabRoute
\ No newline at end of file
...@@ -10,4 +10,4 @@ createConetxt(store) ...@@ -10,4 +10,4 @@ createConetxt(store)
export const { dispatch, getState } = store export const { dispatch, getState } = store
export default store export default store
\ No newline at end of file
...@@ -2,15 +2,15 @@ import { StyleSheet } from 'react-native' ...@@ -2,15 +2,15 @@ import { StyleSheet } from 'react-native'
import { setUnit } from '../../../libs/utils' import { setUnit } from '../../../libs/utils'
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
padding: setUnit(32), padding: setUnit(32),
backgroundColor: '#fff' backgroundColor: '#fff'
}, },
desc: { desc: {
color: '#434343', color: '#434343',
fontSize: setUnit(24) fontSize: setUnit(24)
} }
}) })
export { styles } export { styles }
\ No newline at end of file
...@@ -9,27 +9,27 @@ import { styles } from './style' ...@@ -9,27 +9,27 @@ import { styles } from './style'
import { Icons } from '../../../assets/icons' import { Icons } from '../../../assets/icons'
import { setUnit } from '../../../libs/utils' import { setUnit } from '../../../libs/utils'
const Page = ({route, navigation }) => { const Page = ({ route, navigation }) => {
useLayoutEffect(() => { useLayoutEffect(() => {
navigation.setOptions({ navigation.setOptions({
headerLeft: () => ( headerLeft: () => (
<Icons <Icons
name='guanbi' name='guanbi'
color='#555' color='#555'
size={setUnit(32)} size={setUnit(32)}
style={{ paddingHorizontal: setUnit(24) }} style={{ paddingHorizontal: setUnit(24) }}
onPress={() => navigation.goBack()} onPress={() => navigation.goBack()}
/> />
) )
}) })
}, [navigation]) }, [navigation])
return ( return (
<View style={styles.container}> <View style={styles.container}>
<Text style={styles.desc}>{route.params?.content}</Text> <Text style={styles.desc}>{route.params?.content}</Text>
</View> </View>
) )
} }
export default Page export default Page
\ No newline at end of file
...@@ -2,36 +2,36 @@ import { StyleSheet } from 'react-native' ...@@ -2,36 +2,36 @@ import { StyleSheet } from 'react-native'
import { setUnit } from '../../../libs/utils' import { setUnit } from '../../../libs/utils'
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
backgroundColor: '#fff' backgroundColor: '#fff'
}, },
item: { item: {
paddingHorizontal: setUnit(25), paddingHorizontal: setUnit(25),
paddingVertical: setUnit(16), paddingVertical: setUnit(16),
alignItems: 'center', alignItems: 'center',
flexDirection: 'row' flexDirection: 'row'
}, },
content: { content: {
flex: 1 flex: 1
}, },
title: { title: {
fontSize: setUnit(28), fontSize: setUnit(28),
color: '#434343' color: '#434343'
}, },
subtitle: { subtitle: {
color: '#8c8c8c', color: '#8c8c8c',
fontSize: setUnit(24) fontSize: setUnit(24)
}, },
emptyText: { emptyText: {
fontSize: setUnit(33), fontSize: setUnit(33),
color: '#434343' color: '#434343'
}, },
containerStyle: { containerStyle: {
flex: 1, flex: 1,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center' alignItems: 'center'
} }
}) })
export { styles } export { styles }
\ No newline at end of file
...@@ -12,74 +12,74 @@ import { Toast, Divider, Empty } from 'react-native-mb-ui' ...@@ -12,74 +12,74 @@ import { Toast, Divider, Empty } from 'react-native-mb-ui'
import { getVersionList } from '../../../api/version' import { getVersionList } from '../../../api/version'
const Item = memo(({ navigation, item }) => { const Item = memo(({ navigation, item }) => {
const { version, create_time, remark } = item const { version, create_time, remark } = item
return ( return (
<> <>
<Pressable <Pressable
style={styles.item} style={styles.item}
android_ripple={{ color: '#eee' }} android_ripple={{ color: '#eee' }}
onPress={() => { navigation.navigate('FeatureDetail', {content: remark || ''}) }} onPress={() => { navigation.navigate('FeatureDetail', { content: remark || '' }) }}
> >
<View style={styles.content}> <View style={styles.content}>
<Text style={styles.title}>商品交易所{version}主要更新</Text> <Text style={styles.title}>商品交易所{version}主要更新</Text>
<Text style={styles.subtitle}>{dateFormat('MM/DD', new Date(create_time).getTime())}</Text> <Text style={styles.subtitle}>{dateFormat('MM/DD', new Date(create_time).getTime())}</Text>
</View> </View>
<Icons name='you' size={setUnit(32)} color='#C2C3C4' /> <Icons name='you' size={setUnit(32)} color='#C2C3C4' />
</Pressable> </Pressable>
<Divider style={{ marginLeft: setUnit(25) }} /> <Divider style={{ marginLeft: setUnit(25) }} />
</> </>
) )
}) })
let http let http
const Page = ({ navigation }) => { const Page = ({ navigation }) => {
const [records, setRecords] = useState([]) const [records, setRecords] = useState([])
useLayoutEffect(() => { useLayoutEffect(() => {
navigation.setOptions({ navigation.setOptions({
headerLeft: () => ( headerLeft: () => (
<Icons <Icons
name='guanbi' name='guanbi'
color='#555' color='#555'
size={setUnit(32)} size={setUnit(32)}
style={{ paddingHorizontal: setUnit(24) }} style={{ paddingHorizontal: setUnit(24) }}
onPress={() => navigation.goBack()} onPress={() => navigation.goBack()}
/> />
) )
}) })
}, [navigation]) }, [navigation])
useEffect(() => { useEffect(() => {
fetchData() fetchData()
return () => { return () => {
http && http.cancel() http && http.cancel()
} }
}, []) }, [])
const fetchData = useCallback(() => { const fetchData = useCallback(() => {
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {
Toast.loading() Toast.loading()
http = getVersionList(res => { http = getVersionList(res => {
setRecords(res?.reverse() || []) setRecords(res?.reverse() || [])
Toast.hideLoading() Toast.hideLoading()
}, err => { }, err => {
Toast.hideLoading() Toast.hideLoading()
alert(err) alert(err)
}) })
}) })
}, []) }, [])
return ( return (
<View style={styles.container}> <View style={styles.container}>
<FlatList <FlatList
data={records} data={records}
contentContainerStyle={!records.length ? styles.containerStyle : {}} contentContainerStyle={!records.length ? styles.containerStyle : {}}
keyExtractor={(item, index) => item.id?.toString()} keyExtractor={(item, index) => item.id?.toString()}
renderItem={({ item }) => <Item navigation={navigation} item={item} />} renderItem={({ item }) => <Item navigation={navigation} item={item} />}
ListEmptyComponent={() => <Empty style={{ paddingTop: 100 }} />} ListEmptyComponent={() => <Empty style={{ paddingTop: 100 }} />}
/> />
</View> </View>
) )
} }
export default Page export default Page
\ No newline at end of file
import { StyleSheet } from 'react-native' import { StyleSheet } from 'react-native'
const styles = StyleSheet.create({ const styles = StyleSheet.create({
wrapper: { wrapper: {
position: 'absolute', position: 'absolute',
left: 0, left: 0,
bottom: 0, bottom: 0,
right: 0, right: 0,
top: 0, top: 0,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center' alignItems: 'center'
} }
}) })
export { styles } export { styles }
\ No newline at end of file
...@@ -11,40 +11,40 @@ import { APP } from '../../../config' ...@@ -11,40 +11,40 @@ import { APP } from '../../../config'
import { styles } from './style' import { styles } from './style'
const Page = ({ navigation }) => { const Page = ({ navigation }) => {
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
const indicator = () => { const indicator = () => {
return ( return (
<View style={styles.wrapper}> <View style={styles.wrapper}>
<ActivityIndicator size={'large'} color={Colors.primary} /> <ActivityIndicator size={'large'} color={Colors.primary} />
</View> </View>
) )
} }
useEffect(()=>{ useEffect(() => {
setShow(true) setShow(true)
const remove = navigation.addListener('beforeRemove', e => { const remove = navigation.addListener('beforeRemove', e => {
e.preventDefault() e.preventDefault()
setShow(false) setShow(false)
remove() remove()
navigation.goBack() navigation.goBack()
}) })
return () => remove && remove() return () => remove && remove()
}, []) }, [])
return ( return (
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
{ show && { show &&
<WebView <WebView
style={{ flex: 1 }} style={{ flex: 1 }}
startInLoadingState={true} startInLoadingState={true}
renderLoading={indicator} renderLoading={indicator}
source={{ uri: APP.privacyLink }} source={{ uri: APP.privacyLink }}
/> />
} }
</View> </View>
) )
} }
export default Page export default Page
\ No newline at end of file
...@@ -2,45 +2,45 @@ import { StyleSheet } from 'react-native' ...@@ -2,45 +2,45 @@ import { StyleSheet } from 'react-native'
import { setUnit } from '../../libs/utils' import { setUnit } from '../../libs/utils'
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
backgroundColor: '#fff' backgroundColor: '#fff'
}, },
header: { header: {
marginTop: setUnit(112), marginTop: setUnit(112),
alignItems: 'center' alignItems: 'center'
}, },
logo: { logo: {
width: setUnit(160), width: setUnit(160),
height: setUnit(160) height: setUnit(160)
}, },
name: { name: {
marginTop: setUnit(32), marginTop: setUnit(32),
color: '#262626', color: '#262626',
fontWeight: '500', fontWeight: '500',
fontSize: setUnit(40) fontSize: setUnit(40)
}, },
version: { version: {
marginTop: setUnit(12), marginTop: setUnit(12),
color: '#262626', color: '#262626',
fontSize: setUnit(32) fontSize: setUnit(32)
}, },
center: { center: {
marginTop: setUnit(56) marginTop: setUnit(56)
}, },
footer: { footer: {
alignItems: 'center', alignItems: 'center',
paddingBottom: setUnit(48) paddingBottom: setUnit(48)
}, },
private: { private: {
fontSize: setUnit(26), fontSize: setUnit(26),
color: '#6292D0' color: '#6292D0'
}, },
copyright: { copyright: {
marginTop: setUnit(24), marginTop: setUnit(24),
textAlign: 'center', textAlign: 'center',
color: '#8c8c8c', color: '#8c8c8c',
} }
}) })
export { styles } export { styles }
\ No newline at end of file
/** /**
* @author sheng * @author sheng
* @description 关于信巴迪 * @description 关于信巴迪
* @date 2020/09/03 * @date 2020/09/03
*/ */
...@@ -14,81 +14,81 @@ import { APP } from '../../config' ...@@ -14,81 +14,81 @@ import { APP } from '../../config'
let http let http
const Page = ({ navigation }) => { const Page = ({ navigation }) => {
const [version, setVersion] = useState('') const [version, setVersion] = useState('')
const downUrl = useRef('') const downUrl = useRef('')
useEffect(() => { useEffect(() => {
getCurVersion() getCurVersion()
return () => http && http.cancel() return () => http && http.cancel()
}, []) }, [])
/** 打开下载链接 */ /** 打开下载链接 */
const openDown = () => { const openDown = () => {
Linking.openURL(downUrl.current) Linking.openURL(downUrl.current)
.then(() => { }) .then(() => { })
.catch(err => Toast.info('打开下载地址失败,请重试')) .catch(err => Toast.info('打开下载地址失败,请重试'))
} }
const getUpdate = async () => { const getUpdate = async () => {
const versionCode = await getVersionCode() const versionCode = await getVersionCode()
http = getTopVersion(res => { http = getTopVersion(res => {
if (res === null) return Toast.info('已是最新版本') if (res === null) return Toast.info('已是最新版本')
const { version_code, down, version } = res const { version_code, down, version } = res
downUrl.current = down downUrl.current = down
if (version_code > versionCode) {
ModalManager.alert({
title: '提示',
content: `发现新版本${version}需要更新,是否更新`,
button: [
{ text: '取消' },
{ text: '立即更新', onPress: openDown }
]
})
} else {
Toast.info('已是最新版本')
}
}, err => Toast.info(err))
} if (version_code > versionCode) {
ModalManager.alert({
title: '提示',
content: `发现新版本${version}需要更新,是否更新`,
button: [
{ text: '取消' },
{ text: '立即更新', onPress: openDown }
]
})
} else {
Toast.info('已是最新版本')
}
}, err => Toast.info(err))
/**获取当前版本号 */ }
const getCurVersion = useCallback(async () => {
const version = await getVersion()
setVersion(version)
}, [])
const goPage = useCallback(() => { /**获取当前版本号 */
navigation.navigate('Privacy') const getCurVersion = useCallback(async () => {
}, [navigation]) const version = await getVersion()
setVersion(version)
}, [])
return ( const goPage = useCallback(() => {
<View style={styles.container}> navigation.navigate('Privacy')
<View style={{ flex: 1 }}> }, [navigation])
<View style={styles.header}>
<Image return (
source={require('../../assets/images/ic_launcher.png')} <View style={styles.container}>
style={styles.logo} <View style={{ flex: 1 }}>
/> <View style={styles.header}>
<Text style={styles.name}>{APP.appName}</Text> <Image
<Text style={styles.version}>Version {version}</Text> source={require('../../assets/images/ic_launcher.png')}
</View> style={styles.logo}
<View style={styles.center}> />
<Divider style={{ marginHorizontal: setUnit(25) }} /> <Text style={styles.name}>{APP.appName}</Text>
<Cell label={'功能介绍'} onClick={() => navigation.navigate('Features')} /> <Text style={styles.version}>Version {version}</Text>
<Cell label={'版本更新'} onClick={getUpdate} /> </View>
<View style={styles.center}>
<Divider style={{ marginHorizontal: setUnit(25) }} />
<Cell label={'功能介绍'} onClick={() => navigation.navigate('Features')} />
<Cell label={'版本更新'} onClick={getUpdate} />
</View>
</View>
<View style={styles.footer}>
<Text style={styles.private} onPress={goPage}>《商城平台隐私权政策》</Text>
<Text style={styles.copyright}>
{`广州信巴迪信息科技有限公司 版权所有\nCopyright© 粤ICP备18005051号-1`}
</Text>
</View>
</View> </View>
</View> )
<View style={styles.footer}>
<Text style={styles.private} onPress={goPage}>《商城平台隐私权政策》</Text>
<Text style={styles.copyright}>
{`广州信巴迪信息科技有限公司 版权所有\nCopyright© 粤ICP备18005051号-1`}
</Text>
</View>
</View>
)
} }
export default Page export default Page
\ No newline at end of file
import View from './view'
export default View
import View from './view' import View from './view'
export default View export default View
\ No newline at end of file
import React from 'react' import React from 'react'
import { View, Text } from 'react-native' import { View, Text } from 'react-native'
import { styles } from './styles' import { styles } from './styles'
import {name as appName} from '../../../app.json'; import { name as appName } from '../../../app.json';
const Page = ({ navigation }) => { const Page = ({ navigation }) => {
return ( return (
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!