Commit f1f30bd8 by wong.peiyi

select组件及各未完成初始化的业务页面

parent d459e3e0
...@@ -11,6 +11,7 @@ import Resolution from './components/common/Resolution' ...@@ -11,6 +11,7 @@ import Resolution from './components/common/Resolution'
import Home from './pages/index/index' import Home from './pages/index/index'
import Mine from './pages/mine/mine' import Mine from './pages/mine/mine'
import Signin from './pages/signin/signin' import Signin from './pages/signin/signin'
import Consume from './pages/consume/consume'
function createNavigator() { function createNavigator() {
const options = { const options = {
...@@ -82,6 +83,7 @@ function createNavigator() { ...@@ -82,6 +83,7 @@ function createNavigator() {
const stackNavigator = createStackNavigator( const stackNavigator = createStackNavigator(
{ {
Main: { screen: SwitchNavigator }, Main: { screen: SwitchNavigator },
Consume: { screen: Consume },
}, },
{ initialRouteName: 'Main', ...options }, { initialRouteName: 'Main', ...options },
) )
......
...@@ -19,3 +19,20 @@ ...@@ -19,3 +19,20 @@
hToR($color, opacity = 1) hToR($color, opacity = 1)
return rgba(red($color), green($color), blue($color), opacity) return rgba(red($color), green($color), blue($color), opacity)
.bg-gray
background-color home_background_color
.animated
animation-duration 1s
animation-fill-mode both
@keyframes slide-up
from
-webkit-transform translate3d(0, 100%, 0)
transform translate3d(0, 100%, 0)
visibility visible
to
-webkit-transform translate3d(0, 0, 0)
transform translate3d(0, 0, 0)
/*
* @FilePath: /BoneHouse_Business_APP/src/assets/styles/base.ts
* @Author: peii
* @Date: 2021-04-24 22:45:15
* @Vision: 1.0
* @Description:
*
* @Revision:
*
*/
import { import {
Dimensions Dimensions
} from 'react-native' } from 'react-native'
......
...@@ -8,7 +8,7 @@ let props = {} ...@@ -8,7 +8,7 @@ let props = {}
*/ */
export default class Resolution { export default class Resolution {
static get(useFixWidth = true) { static get(useFixWidth = true) {
return usefixWidth ? { ...props.fw } : { ...props.fh } return useFixWidth ? { ...props.fw } : { ...props.fh }
} }
static setDesignSize(dWidth = 414, dHeight = 896, dim = 'window'): void { static setDesignSize(dWidth = 414, dHeight = 896, dim = 'window'): void {
......
@import '../../assets/styles/base.styl'
@import '../../assets/styles/variable.styl'
.text
font-size second_text_size
font-family font_family_regular
.form
padding 18px
&-item
width 378px
height 58px
background-color #fff
padding 18px
flex-direction row
justify-content space-between
align-items center
margin-bottom 18px
&-label
@extend .text
color primary_text_color
&-input
flex-direction row
align-items center
&__placeholder
@extend .text
color placehold_text_color
&__text
@extend .text
color second_text_color
&__arrow
width 8px
height 14px
margin-left 9px
.red
color #f00
/*
* @FilePath: /BoneHouse_Business_APP/src/components/form/index.tsx
* @Author: peii
* @Date: 2021-04-25 22:40:31
* @Vision: 1.0
* @Description: 基础表单组件
*
* @Revision:
*
*/
import React, { Component } from 'react'
import { View, Text } from 'react-native'
import { IFormField } from 'bonehouse'
import { FieldType } from '../../enums'
import Select from './select'
import { g } from '../../utils/utils'
import styles from './index.styl'
type IProps = {
fields: IFromField[]
data: { [key: string]: any }
}
const formComponents = {
[FieldType.SELECT]: Select,
}
export default class Form extends Component<IProps> {
state = {
value: '',
}
onChange() {}
render() {
const { fields, data } = this.props
return (
<View style={g(styles, 'form')}>
{fields.map(item => {
const FormComponent = formComponents[item.type] || Select
return <FormComponent key={item.field} item={item} value={data[item.field]} />
})}
</View>
)
}
}
@import '../../assets/styles/base.styl'
@import '../../assets/styles/variable.styl'
.modal
position absolute
left 0
top 0
&-mask
@extend .modal
width 100%
height 100%
background-color rgba(0, 0, 0, 0.5)
@extend .animated
animation-name slide-up
&-content
position absolute
width 100%
height 400px
background-color foundation_color
bottom 0
/*
* @FilePath: /BoneHouse_Business_APP/src/components/form/select-modal.tsx
* @Author: peii
* @Date: 2021-04-27 21:53:02
* @Vision: 1.0
* @Description: 选择组件的弹出框
*
* @Revision:
*
*/
import React from 'react'
import { View, Text, TouchableOpacity, ScrollView } from 'react-native'
import { IOption } from 'bonehouse'
import * as R from 'ramda'
import { isBlank } from '../../utils/utils'
import Resolution from '../../components/common/Resolution'
import { FieldType } from '../../enums'
import { g } from '../../utils/utils'
import styles from './select-modal.styl'
import container from '../../inversify'
import { TYPES } from '../../inversify/types'
const store = container.get(TYPES.SysStore)
type IModalProps = {
data: IOption[]
value: string | number
mask?: boolean
title?: string
visible: boolean
onChange?: Function
onClose: Function
}
export function SelectModal(props: IModalProps) {
const { data = [], value, mask, onChange, visible, title, onClose } = props
if (!visible) return <></>
const { width, height } = Resolution.get()
return (
<View style={[g(styles, 'modal'), { width, height: height - store.headerHeight }]}>
{!!mask && (
<TouchableOpacity
style={g(styles, 'modal-mask')}
activeOpacity={1}
onPress={() => {
onClose()
}}
></TouchableOpacity>
)}
<View style={g(styles, 'modal-content')}>
{!!title && (
<View style={g(styles, 'modal-hd')}>
<Text style={g(styles, 'modal-header__text')}>{title}</Text>
</View>
)}
<ScrollView style={g(styles, 'modal-bd')}>
<View style={g(styles, 'select')}>
{data.map(option => {
return (
<TouchableOpacity
key={option.value}
style={g(styles, 'select-option')}
onPress={() => {
if (R.propEq('value', value, option)) return
onChange && onChange(option)
}}
>
<Text>{option.label}</Text>
</TouchableOpacity>
)
})}
</View>
</ScrollView>
</View>
</View>
)
}
/*
* @FilePath: /BoneHouse_Business_APP/src/components/form/select.tsx
* @Author: peii
* @Date: 2021-04-25 23:36:10
* @Vision: 1.0
* @Description: 选择器组件
*
* @Revision:
*
*/
import React, { Component } from 'react'
import { View, Text, Image, TouchableOpacity } from 'react-native'
import { IFormField } from 'bonehouse'
import * as R from 'ramda'
import { isBlank } from '../../utils/utils'
import { FieldType } from '../../enums'
import { g } from '../../utils/utils'
import { SelectModal } from './select-modal'
import styles from './index.styl'
type IProps = {
item: IFormField
}
/**
* @description: 是否必需
* @param {Object}
* @return {Boolean}
*/
const isRequired = R.compose(R.find(R.propEq('required', true)), R.propOr([], 'rules'))
const getText = (item, val) => {
if (!val) return null
return R.compose(R.find(R.propEq('value', val)), R.propOr([], 'options'))(item)
}
export default class Select extends Component<IProps> {
state = {
visible: false,
}
constructor(props) {
super(props)
this.onPressHandler = this.onPressHandler.bind(this)
}
shouldComponentUpdate(nextProps) {
return true
}
onPressHandler() {
const { item } = this.props
if (item.disabled) return
this.setState({ visible: true })
}
render() {
const { visible } = this.state
const { item, value } = this.props
const required = isRequired(item)
const val = getText(item, value)
return (
<>
<TouchableOpacity
style={g(styles, 'form-item')}
activeOpacity={item.disabled ? 1 : 0.8}
onPress={this.onPressHandler}
>
<Text style={g(styles, 'form-label')}>
{!!required && <Text style={g(styles, 'red', 'pr5')}>*</Text>}
<Text>{item.label}</Text>
</Text>
<View style={g(styles, 'form-input')}>
{isBlank(value) ? (
<Text style={g(styles, 'form-input__placeholder')}>
{item.placeholder || '请选择'}
</Text>
) : (
<Text style={g(styles, 'form-input__text')}>{val && val.label}</Text>
)}
{item.arrow !== false && (
<Image
source={require('../../assets/images/arr_rig.png')}
style={g(styles, 'form-input__arrow')}
/>
)}
</View>
</TouchableOpacity>
<SelectModal
data={item.options}
value={value}
visible={visible}
mask={true}
onClose={() => {
this.setState({ visible: false })
}}
/>
</>
)
}
}
...@@ -3,6 +3,10 @@ import { View, StatusBar, Platform, Text, Image, TouchableOpacity } from 'react- ...@@ -3,6 +3,10 @@ import { View, StatusBar, Platform, Text, Image, TouchableOpacity } from 'react-
import { g, isIphoneX } from '../../utils/utils' import { g, isIphoneX } from '../../utils/utils'
import { primary_color } from '../../assets/styles/base' import { primary_color } from '../../assets/styles/base'
import styles from './header.styl' import styles from './header.styl'
import container from '../../inversify'
import { TYPES } from '../../inversify/types'
const store = container.get(TYPES.SysStore)
function header({ title, backgroundColor = primary_color, back = true, backCallback = () => {} }) { function header({ title, backgroundColor = primary_color, back = true, backCallback = () => {} }) {
const [statusHeight, setStatusHeight] = useState(20) const [statusHeight, setStatusHeight] = useState(20)
...@@ -10,6 +14,7 @@ function header({ title, backgroundColor = primary_color, back = true, backCallb ...@@ -10,6 +14,7 @@ function header({ title, backgroundColor = primary_color, back = true, backCallb
useEffect(() => { useEffect(() => {
const height = Platform.OS === 'android' ? StatusBar.currentHeight : isIphoneX() ? 44 : 20 const height = Platform.OS === 'android' ? StatusBar.currentHeight : isIphoneX() ? 44 : 20
setStatusHeight(height) setStatusHeight(height)
store.setHeaderHeight(height + 58)
}, []) }, [])
return ( return (
...@@ -23,7 +28,13 @@ function header({ title, backgroundColor = primary_color, back = true, backCallb ...@@ -23,7 +28,13 @@ function header({ title, backgroundColor = primary_color, back = true, backCallb
<View style={g(styles, 'header-bar')}> <View style={g(styles, 'header-bar')}>
{/* 返回按钮 */} {/* 返回按钮 */}
{!!back && ( {!!back && (
<TouchableOpacity style={g(styles, 'header-back')} activeOpacity={0.6}> <TouchableOpacity
style={g(styles, 'header-back')}
activeOpacity={0.6}
onPress={() => {
backCallback()
}}
>
<Image <Image
style={g(styles, 'header-back__img')} style={g(styles, 'header-back__img')}
source={require('../../assets/images/back.png')} source={require('../../assets/images/back.png')}
......
/*
* @FilePath: /BoneHouse_Business_APP/src/enums/index.ts
* @Author: peii
* @Date: 2021-04-24 22:45:15
* @Vision: 1.0
* @Description:
*
* @Revision:
*
*/
export enum MsgType { export enum MsgType {
INFO, INFO,
WARN, WARN,
ERROR, ERROR,
SUCCESS, SUCCESS,
} }
export enum FieldType {
TEXT,
SELECT,
TEXTAREA,
DATE,
CHECKBOX,
RADIO,
}
@import '../../assets/styles/base.styl'
@import '../../assets/styles/variable.styl'
.container
flex 1
/*
* @FilePath: /BoneHouse_Business_APP/src/pages/consume/consume.tsx
* @Author: peii
* @Date: 2021-04-25 18:24:09
* @Vision: 1.0
* @Description: 消耗确认页面
*
* @Revision:
*
*/
import React, { Component } from 'react'
import { View, Text, ScrollView } from 'react-native'
import { inject, observer } from 'mobx-react'
import Form from '../../components/form'
import { FieldType } from '../../enums'
import Header from '../../components/header/header'
import { g } from '../../utils/utils'
import styles from './consume.styl'
type IProps = {
store: {}
userStore: {
userName: string
personName: string
}
sysStore: {}
}
class Consume extends Component<IProps> {
constructor(props) {
super(props)
}
state = {
data: {
sellerCode: this.props.userStore.userName,
},
formItems: [
{
field: 'sellerCode',
label: '销售员',
type: FieldType.SELECT,
options: [
{
label: this.props.userStore.personName,
value: this.props.userStore.userName,
},
],
placeholder: '请选择',
rules: [{ required: true, message: '请选择组织' }],
disabled: true,
},
{
field: 'orgId',
label: '组织',
type: FieldType.SELECT,
options: [],
placeholder: '请选择',
rules: [{ required: true, message: '请选择组织' }],
},
],
}
componentDidMount() {
this.setSeller()
}
setSeller() {}
render() {
const { formItems, data } = this.state
const { navigation } = this.props
const title = navigation.getParam('title', '骨科智慧仓')
return (
<View style={g(styles, 'container', 'bg-gray')}>
<Header
title={title}
backCallback={() => {
navigation.goBack()
}}
/>
<ScrollView style={g(styles, 'container')}>
<Form fields={formItems} data={data} />
</ScrollView>
</View>
)
}
}
export default inject('sysStore', 'userStore')(observer(Consume))
...@@ -39,6 +39,7 @@ class Index extends Component<IProps> { ...@@ -39,6 +39,7 @@ class Index extends Component<IProps> {
constructor(props) { constructor(props) {
super(props) super(props)
this.onRefresh = this.onRefresh.bind(this) this.onRefresh = this.onRefresh.bind(this)
this.navigateToBizPage = this.navigateToBizPage.bind(this)
} }
componentDidMount() { componentDidMount() {
...@@ -68,6 +69,18 @@ class Index extends Component<IProps> { ...@@ -68,6 +69,18 @@ class Index extends Component<IProps> {
this.props.sysStore.getSysProfile() this.props.sysStore.getSysProfile()
} }
navigateToBizPage(fun: IFunction) {
const pages = {
MOBILE_BORROW_ORDER: '',
MOBILE_SELF_HELP_ORDER: '',
MOBILE_CONSUMP_CONFIRMA: 'Consume',
MOBILE_DEVICE_INFORMATION: '',
MOBILE_TRANSFER_APPLICATION: '',
}
console.log(fun)
this.props.navigation.navigate(pages[fun.functionCode], { title: fun.functionName })
}
render() { render() {
const { navigation, store } = this.props const { navigation, store } = this.props
const { refreshing } = this.state const { refreshing } = this.state
...@@ -88,6 +101,7 @@ class Index extends Component<IProps> { ...@@ -88,6 +101,7 @@ class Index extends Component<IProps> {
key={fun.functionCode} key={fun.functionCode}
style={g(styles, 'biz-box')} style={g(styles, 'biz-box')}
activeOpacity={0.6} activeOpacity={0.6}
onPress={() => this.navigateToBizPage(fun)}
> >
<Image <Image
style={g(styles, 'biz-icon')} style={g(styles, 'biz-icon')}
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* @Revision: * @Revision:
* *
*/ */
import { observable, flow, runInAction } from 'mobx' import { observable, flow, runInAction, action } from 'mobx'
import { persist } from 'mobx-persist' import { persist } from 'mobx-persist'
import { injectable, inject } from 'inversify' import { injectable, inject } from 'inversify'
import * as R from 'ramda' import * as R from 'ramda'
...@@ -18,6 +18,10 @@ import { toBinaryNumber } from '../utils/utils' ...@@ -18,6 +18,10 @@ import { toBinaryNumber } from '../utils/utils'
@injectable() @injectable()
export default class System { export default class System {
@observable
headerHeight = 78
@inject(TYPES.Service) @inject(TYPES.Service)
private service!: Service private service!: Service
...@@ -42,6 +46,11 @@ export default class System { ...@@ -42,6 +46,11 @@ export default class System {
OBS_MOBILE_EQU_CON_DISPLAY_PRICE: 'N', OBS_MOBILE_EQU_CON_DISPLAY_PRICE: 'N',
} }
@action
setHeaderHeight(height: number) {
this.headerHeight = height
}
/** /**
* @description: 获取系统配置 * @description: 获取系统配置
* @param {*} function * @param {*} function
......
/*
* @FilePath: /BoneHouse_Business_APP/types/global.ts
* @Author: peii
* @Date: 2021-04-24 22:45:15
* @Vision: 1.0
* @Description:
*
* @Revision:
*
*/
/// <reference types="react" />
/// <reference types="react-native" />
declare module 'bonehouse' {
export type EnumType = { [s: string]: any }
export type IDepartment = {
departmentCode: string
departmentName: string
}
export type IFunction = {
child_list: IFunction[]
functionCode: string
functionName: string
functionOrder: number
}
export type IInventory = {
invCode: string
invName: string
}
export type IOption = {
label: string
value: string
}
export type IRule = {
required?: boolean
message?: string
pattern?: RegExp
func?: Function
}
export type IFormField = {
field: string
name: string
type: EnumType
options?: IOption[]
arrow?: boolean
placeholder?: string
rules?: IRule[]
disabled?: boolean
}
}
/// <reference types="react" />
declare module 'bonehouse' {
export type IDepartment = {
departmentCode: string
departmentName: string
}
export type IFunction = {
child_list: IFunction[]
function_code: string
function_name: string
function_order: number
}
export type IInventory = {
invCode: string
invName: string
}
}
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