Commit bff71fd8 by 杨周龙

更改为tsx

1 parent f91781a1
Showing with 89 additions and 383 deletions
......@@ -6,42 +6,45 @@
* @flow strict-local
*/
import React, { useLayoutEffect } from 'react'
import React, { useLayoutEffect, useEffect } from 'react'
import { StatusBar, Platform, Text, TextInput } from 'react-native'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { RouterView } from './src/router'
import { Provider } from 'react-redux'
import { ThemeProvider } from 'rn-ui'
import { defaultTheme } from './src/commo/theme'
import { PrivacyAlert, Update } from './src/components'
import store from './src/store'
import { PrivacyAlert } from './src/components'
import { PortalHot, Update } from 'react-native-mb-ui'
import { getVersionCode } from './src/libs/utils'
import { APP } from './src/config'
import SplashScreen from 'react-native-splash-screen'
import store from './src/store'
//阻止系统缩放
TextInput.defaultProps = Object.assign({}, TextInput.defaultProps, { allowFontScaling: false })
Text.defaultProps = Object.assign({}, Text.defaultProps, { allowFontScaling: false })
const App = () => {
const Page = () => {
useLayoutEffect(() => {
store.dispatch.site.init()
SplashScreen.hide()
}, [])
useEffect(() => {
(async () => Update(`${APP.appAdminUrl}/api/app/version/${APP.APP_CODE}`, await getVersionCode()))()
}, [])
return (
<>
<PrivacyAlert />
{Platform.OS === 'android' && <Update />}
{Platform.OS === 'ios' && <StatusBar translucent={true} backgroundColor="rgba(255,255,255,0)" barStyle="dark-content" />}
<Provider store={store}>
{Platform.OS === 'ios' && <StatusBar translucent={true} backgroundColor="rgba(255,255,255,0)" barStyle="dark-content" />}
<PortalHot>
<SafeAreaProvider>
<ThemeProvider theme={defaultTheme}>
<RouterView />
</ThemeProvider>
<PrivacyAlert />
</SafeAreaProvider>
</PortalHot>
</Provider>
</>
)
}
export default App
export default Page
This diff could not be displayed because it is too large.
......@@ -23,18 +23,19 @@
"react-native": "0.62.2",
"react-native-device-info": "^5.5.8",
"react-native-gesture-handler": "^1.6.1",
"react-native-mb-ui": "^1.6.16",
"react-native-reanimated": "^1.8.0",
"react-native-safe-area-context": "^1.0.0",
"react-native-screens": "^2.7.0",
"react-native-splash-screen": "^3.2.0",
"react-native-vector-icons": "^6.6.0",
"react-redux": "^7.2.0",
"rn-ui": "^0.3.17"
"react-redux": "^7.2.0"
},
"devDependencies": {
"@babel/core": "^7.6.2",
"@babel/runtime": "^7.6.2",
"@react-native-community/eslint-config": "^0.0.5",
"@types/node": "^14.14.10",
"babel-jest": "^24.9.0",
"eslint": "^6.5.1",
"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'
export { PrivacyAlert }
\ No newline at end of file
export default PrivacyAlert
......@@ -5,12 +5,12 @@
*/
import React, { useCallback, useEffect, useState } from 'react'
import { Text, Linking } from 'react-native'
import { XbdAlertDialog } from 'rn-ui'
import { Modal, Storage } from 'react-native-mb-ui'
import { APP } from '../../config'
import { getStorage, setStorage, setUnit } from '../../libs/utils'
import { setUnit } from '../../libs/utils'
import { styles } from './style'
const Component = () => {
const PrivacyAlert = () => {
const [visible, setVisible] = useState(false)
useEffect(() => {
......@@ -20,7 +20,7 @@ const Component = () => {
const goPrivacy = useCallback(() => Linking.openURL(APP.privacyLink), [])
const showPrivacy = async () => {
const notFirst = await getStorage(APP.notFirstInstall)
const notFirst = await Storage.getItem(APP.notFirstInstall)
if (notFirst === null)
setVisible(true)
......@@ -28,21 +28,18 @@ const Component = () => {
const onOk = useCallback(() => {
setVisible(false)
setStorage(APP.notFirstInstall, true)
Storage.setItem(APP.notFirstInstall, true)
})
return (
<XbdAlertDialog
<Modal
visible={visible}
title='温馨提示'
closable={false}
okText={'我知道了'}
maskClosable={false}
onOk={onOk}
onClose={onOk}
button={[{ text: '我知道了' }]}
style={{ width: setUnit(560) }}
onVisibleChange={visible => setVisible(visible)}
center={
<Text style={styles.content}>{`欢迎来到欢迎来到信巴迪商品交易所, 感谢您对信巴迪的信任和支持!\n`}
content={
<Text style={styles.content}>{`欢迎来到信巴迪商品交易所, 感谢您对信巴迪的信任和支持!\n`}
为了提供给您更加优质和个性化的服务, 我们会收集或使用您的搜索、浏览与购买等信息。具体内容请您详阅
<Text style={styles.privacy} onPress={goPrivacy}>《商城平台隐私权政策》</Text>
全文, 我们已采用业内先进的信息保护措施, 并会持续优化信息保护技术和安全管理流程, 来保护您的个人信息安全。
......@@ -52,4 +49,4 @@ const Component = () => {
)
}
export default Component
\ No newline at end of file
export default PrivacyAlert
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
......@@ -34,10 +34,10 @@ export function formatEmail(str) {
export function thousandBitSeparator(num) {
return num && (num.toString().indexOf('.') != -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) {
return $1 + ",";
}));
return $1 + ","
}))
}
/**
......@@ -78,7 +78,7 @@ export function dateFormat(fmt, time) {
"h+": newDate.getHours().toString(), // 时
"m+": newDate.getMinutes().toString(), // 分
"s+": newDate.getSeconds().toString() // 秒
};
}
for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt)
if (ret) {
......@@ -90,14 +90,6 @@ export function dateFormat(fmt, time) {
}
/**
* 分钱转换为元
* @param {*} num
*/
export function fenToYuan(num) {
return (Number(num) / 100).toFixed(2)
}
/**
* 请求参数格式化为字符串
* @param {Object} query
* @author sheng
......
import axios, { CancelToken } from 'axios'
import axios from 'axios'
import { APP } from '../config'
import { getStore } from '../store/context'
import { navigate } from '../router/ref'
import { ModalManager } from 'react-native-mb-ui'
class HttpRequest {
constructor (baseUrl, loginUrl = APP.loginPath) {
this.baseUrl = baseUrl
this.loginUrl = loginUrl
public instance = null
public header = null
constructor(private baseUrl) {
this.header = { ...APP.header }
this.instance = null
this.init()
}
/**初始化 */
......@@ -17,11 +19,12 @@ class HttpRequest {
}
/**绑定请求拦截器 */
interceptors (instance) {
interceptors(instance) {
// 请求
instance.interceptors.request.use(config => {
return config
}, error => {
// if (process.env.NODE_ENV === 'development') console.warn(error)
return Promise.reject(error)
})
......@@ -38,7 +41,7 @@ class HttpRequest {
}
/**请求 */
async request (options) {
async request(options) {
return this.instance(options)
}
......@@ -49,7 +52,7 @@ class HttpRequest {
* @param {function} errorCallback
*/
sourceRequest(options, successCallback, errorCallback) {
const source = CancelToken.source()
const source = axios.CancelToken.source()
options = Object.assign(options, { cancelToken: source.token })
this.instance(options)
.then(successCallback)
......@@ -81,18 +84,26 @@ class HttpRequest {
*/
handleRespone(res) {
const { code, message, data } = res.data
switch(code) {
case 200:
switch (code) {
case 200: 1590
return data
case 401:
return Promise.reject(`错误: ${code};详情:未登录或登录状态已过期`)
ModalManager.alert({ title: '提示', content: '登陆状态失效,请重新登陆' })
this.resetState()
return Promise.reject(`未登录或登录状态已过期 错误代码: ${code}`)
case 403:
return Promise.reject(`错误: ${code};详情:无权限使用此功能`)
return Promise.reject(`无权限使用此功能 错误代码: ${code};`)
default:
if (process.env.NODE_ENV === 'development') console.warn(JSON.stringify(res.config))
return Promise.reject(`错误: ${code};详情:${message || '未知原因'}`)
return Promise.reject(`${message || '未知原因'} 错误代码: ${code}`)
}
}
resetState() {
getStore().dispatch.user.reset()
getStore().dispatch.me.reset()
navigate('Login')
}
}
export default HttpRequest
......@@ -2,7 +2,6 @@ import { Dimensions } from 'react-native'
import { UI_WIDTH } from '../config'
import DeviceInfo from 'react-native-device-info'
import { CommonActions } from '@react-navigation/native'
import AsyncStorage from '@react-native-community/async-storage'
import CheckUtil from './check'
import { APP } from '../config'
import { FETCH } from './fetch'
......@@ -30,70 +29,6 @@ export const getVersion = async () => await DeviceInfo.getVersion()
/** 获取屏幕高度 */
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)
}
/**
* 校验手机号和验证码
......
......@@ -11,7 +11,7 @@ const headerStyle = {
headerStyle: {
borderBottomColor: '#eee',
borderBottomWidth: StyleSheet.hairlineWidth,
backgroundColor: Colors.white ,
backgroundColor: Colors.white,
elevation: 0
}, // 标题栏样式
headerTintColor: '#262626', // 标题栏字体颜色
......
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()
const Route = () => {
return (
<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>
)
}
......
......@@ -9,7 +9,7 @@ import { styles } from './style'
import { Icons } from '../../../assets/icons'
import { setUnit } from '../../../libs/utils'
const Page = ({route, navigation }) => {
const Page = ({ route, navigation }) => {
useLayoutEffect(() => {
navigation.setOptions({
......
......@@ -18,7 +18,7 @@ const Item = memo(({ navigation, item }) => {
<Pressable
style={styles.item}
android_ripple={{ color: '#eee' }}
onPress={() => { navigation.navigate('FeatureDetail', {content: remark || ''}) }}
onPress={() => { navigation.navigate('FeatureDetail', { content: remark || '' }) }}
>
<View style={styles.content}>
<Text style={styles.title}>商品交易所{version}主要更新</Text>
......
......@@ -20,7 +20,7 @@ const Page = ({ navigation }) => {
)
}
useEffect(()=>{
useEffect(() => {
setShow(true)
const remove = navigation.addListener('beforeRemove', e => {
e.preventDefault()
......
import View from './view'
export default View
import React from 'react'
import { View, Text } from 'react-native'
import { styles } from './styles'
import {name as appName} from '../../../app.json';
import { name as appName } from '../../../app.json';
const Page = ({ navigation }) => {
return (
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!