Commit 072092dd by peii

结算确认

parent 36025b34
/*
* @FilePath: /BoneHouse_Business_APP/app/action/SettlementAction.js
* @Author: peii
* @Date: 2021-12-21 16:30:41
* @LastEditTime: 2021-12-21 16:58:42
* @LastEditors: peii
* @Vision: 1.0
* @Description: 结算模块 action
*/
import { SET_SETTLEMENT_STATUS } from '../base/ActionTypes'
import * as R from 'ramda'
import { GetRequest } from '../network/RequestUtils'
import { getUrlParams } from '../utils/Utils'
const settlementStatus = [
{ value_code: 'APPROVED', value_name: '已审批' },
{ value_code: 'CANCELED', value_name: '已取消' },
{ value_code: 'ENTERED', value_name: '已创建' },
{ value_code: 'INVOICED', value_name: '已开票' },
{ value_code: 'RECEIVED', value_name: '已收款' },
{ value_code: 'REJECTED', value_name: '已拒绝' },
{ value_code: 'SETTLED', value_name: '已结算' },
{ value_code: 'SUBMITTED', value_name: '已提交' },
]
export const getSettlementStatus = () => {
return (dispatch, getState) => {
let { global_domain_config, token } = getState().login
const params = {
access_token: token,
value_set_code: 'SAL_SETTLEMENT_HEADER_STATUS',
}
GetRequest(global_domain_config, getUrlParams('/system/value_set/search', params)).then(res => {
const values = R.pathOr(settlementStatus, ['data', 'sys_values'])(res)
return dispatch(setSettlementStatus(values))
})
}
}
export function setSettlementStatus(valueSets) {
return {
type: SET_SETTLEMENT_STATUS,
values: valueSets,
}
}
......@@ -67,3 +67,6 @@ export const DEVICE_INFORMATION_UPDATE_NO = "DEVICE_INFORMATION_UPDATE_NO"
export const DEVICE_INFORMATION_UPDATE_DOING = "DEVICE_INFORMATION_UPDATE_DOING"
export const DEVICE_INFORMATION_UPDATE_SUCCESS = "DEVICE_INFORMATION_UPDATE_SUCCESS"
export const DEVICE_INFORMATION_UPDATE_FAILURE = "DEVICE_INFORMATION_UPDATE_FAILURE"
//-----------settlement information---------------------
export const SET_SETTLEMENT_STATUS = 'SET_SETTLEMENT_STATUS'
\ No newline at end of file
......@@ -14,6 +14,7 @@ import {
font_family_regular,
} from '../../base/BaseStyle'
import { exitLoginStatus, requestSysProfile, setNavigation } from '../../action/LoginAction'
import { getSettlementStatus } from '../../action/SettlementAction'
import HeadBackItem from '../common/HeadBackItem'
import StatusBarView from '../common/StatusBarView'
import TabBottomItem from './module/TabBottomItem'
......@@ -26,7 +27,6 @@ class HomePage extends Component {
constructor(props) {
super(props)
this.state = {
showList: [],
menus: {
// 业务模块
MOBILE_BUSINESS_MODULE: {
......@@ -59,7 +59,7 @@ class HomePage extends Component {
// 结算模块
MOBILE_SETTLEMENT_MODULE: {
MOBILE_DISTRIBUTION_CONFIRM: {
icon: require('../../images/quick_order.png'),
icon: require('../../images/settle_confirm.png'),
title: '分销-结算确认',
page: 'Settlement',
},
......@@ -69,7 +69,7 @@ class HomePage extends Component {
page: 'QuickOrderPage',
},
MOBILE_DISTRIBUTION_SETTLEMENT_GATHER: {
icon: require('../../images/quick_order.png'),
icon: require('../../images/settle_gather.png'),
title: '分销-结算汇总',
page: 'SettlementCollection',
},
......@@ -98,8 +98,8 @@ class HomePage extends Component {
selIcon: require('../../images/tab_mod_sel.png'),
},
MOBILE_SETTLEMENT_MODULE: {
defIcon: require('../../images/tab_mod_def.png'),
selIcon: require('../../images/tab_mod_sel.png'),
defIcon: require('../../images/tab_sett_def.png'),
selIcon: require('../../images/tab_sett_sel.png'),
},
MOBILE_HISTORICAL_ORDER: {
defIcon: require('../../images/tab_his_def.png'),
......@@ -114,6 +114,7 @@ class HomePage extends Component {
this.getMenuRuleInfo()
this.getSysConfigValue()
this.props.setNavigation(this.props.navigation)
this.getSettlementStatus()
}
componentWillReceiveProps(nextProps) {
......@@ -159,6 +160,12 @@ class HomePage extends Component {
tabs.push(tab)
}),
R.sort(R.ascend(R.prop('function_order'))),
R.filter(
R.propSatisfies(
R.includes(R.__, ['MOBILE_BUSINESS_MODULE', 'MOBILE_SETTLEMENT_MODULE', 'MOBILE_HISTORICAL_ORDER']),
'function_code',
),
),
)(functions)
this.setState({ tabs })
......@@ -184,6 +191,14 @@ class HomePage extends Component {
}
}
getSettlementStatus() {
const { tabs } = this.state
const settlementModule = R.find(R.propEq('code', 'MOBILE_SETTLEMENT_MODULE'))(tabs)
if (isBlank(settlementModule)) return
this.props.getSettlementStatus()
}
// 跳转页面
jumpToSubpage(menu) {
const page = menu.page
......@@ -226,7 +241,7 @@ class HomePage extends Component {
tabLabel={tab.name}
key={tab.code}
>
{R.includes(tab.code, ['MOBILE_BUSINESS_MODULE', 'MOBILE_SETTLEMENT_MODULE']) &&
{!R.includes(tab.code, ['MOBILE_HISTORICAL_ORDER']) &&
tab.children &&
tab.children.map((menu, index) => {
return (
......@@ -293,6 +308,7 @@ const styles = StyleSheet.create({
list_img: {
resizeMode: 'contain',
width: '100%',
height: pxSize(60),
},
list_tit: {
fontSize: second_text_size,
......@@ -317,9 +333,12 @@ const mapDispatchToProps = dispatch => ({
exitLoginStatus: () => {
dispatch(exitLoginStatus())
},
setNavigation: (navigation) => {
setNavigation: navigation => {
dispatch(setNavigation(navigation))
}
},
getSettlementStatus: () => {
dispatch(getSettlementStatus())
},
})
export default connect(mapStateToProps, mapDispatchToProps)(HomePage)
/*
* @FilePath: /BoneHouse_Business_APP/app/reducers/index.js
* @Author: peii
* @Date: 2021-02-03 20:59:10
* @LastEditTime: 2021-12-21 16:57:13
* @LastEditors: peii
* @Vision: 1.0
* @Description:
*/
import storage from 'redux-persist/es/storage';
import {persistReducer} from 'redux-persist';
import login from './module/login';
......@@ -7,6 +16,7 @@ import equip from './module/equip';
import histor from './module/histor';
import trans from './module/trans';
import deviceInfo from './module/deviceInfo';
import settlement from './module/settlement';
const loginConfig = {
key: 'login',
......@@ -57,6 +67,13 @@ const deviceConfig = {
blackList: []
}
const settlementConfig = {
key: 'settlement',
storage,
debug: false,
blackList: []
}
const rootReducer = {
login: persistReducer(loginConfig,login),
selfOrder: persistReducer(selfConfig,selfOrder),
......@@ -65,6 +82,7 @@ const rootReducer = {
histor: persistReducer(historConfig, histor),
trans: persistReducer(transConfig, trans),
deviceInfo: persistReducer(deviceConfig, deviceInfo),
settlement: persistReducer(settlementConfig, settlement),
}
export default rootReducer;
\ No newline at end of file
/*
* @FilePath: /BoneHouse_Business_APP/app/reducers/module/settlement.js
* @Author: peii
* @Date: 2021-12-21 16:52:11
* @LastEditTime: 2021-12-21 16:57:52
* @LastEditors: peii
* @Vision: 1.0
* @Description: 结算
*/
import { SET_SETTLEMENT_STATUS } from '../../base/ActionTypes'
const defaultState = {
headerStatus: [],
}
export default (state = defaultState, action) => {
switch (action.type) {
case SET_SETTLEMENT_STATUS:
return Object.assign({}, state, {
headerStatus: action.values,
})
default:
return state
}
}

1.05 KB | W: | H:

1.39 KB | W: | H:

src/assets/images/empty.png
src/assets/images/empty.png
src/assets/images/empty.png
src/assets/images/empty.png
  • 2-up
  • Swipe
  • Onion skin
// 背景色
primary_color = #007EFF// 主色
foundation_color = #ffffff // 底色
danger_color = rgb(211, 58, 58)
promary_shadow_color = #007EFF// 按钮阴影色
home_background_color = #F7F7F7 // 背景色
btn_sub_color = #007EFF // 按钮色
......
......@@ -11,6 +11,10 @@ size = 18px
width size
height size
&__indeter
width: size + 5
height @width
&-box
border-width 1px
border-color #ccc
......
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/components/checkbox/checkbox.tsx
* @Author: peii
* @Date: 2021-12-20 17:29:00
* @LastEditTime: 2021-12-20 18:35:15
* @LastEditTime: 2021-12-21 14:39:21
* @LastEditors: peii
* @Vision: 1.0
* @Description: 多选框
......@@ -39,7 +39,7 @@ export const Checkbox = ({ checked, indeterminate, onChange, activeOpacity = 0.5
{check ? (
<Image source={require('../../assets/images/cor_blue.png')} style={g(styles, 'checkbox-img')} />
) : indeter ? (
<Image source={require('../../assets/images/indeterminate.png')} style={g(styles, 'checkbox-img')} />
<Image source={require('../../assets/images/indeterminate.png')} style={g(styles, 'checkbox-img', 'checkbox-img__indeter')} />
) : (
<View style={g(styles, 'checkbox-box')}></View>
)}
......
......@@ -5,14 +5,14 @@
flex 1
@extend .middle
@extend .center
padding-top 30px
padding-top 80px
&-icon
width 80px
height 75px
width 98px
height 64px
&-text
font-size 20px
color second_text_color
font-size 18px
color third_text_color
margin-top 20px
font-family font_family_regular
/*
* @FilePath: /BoneHouse_Hospital_APP/src/components/empty/index.tsx
* @FilePath: /BoneHouse_Business_APP/src/components/empty/index.tsx
* @Author: peii
* @Date: 2021-05-30 17:04:50
* @Vision: 1.0
......@@ -16,7 +16,7 @@ import styles from './index.styl'
export default ({ text = '暂无数据', style }) => {
return (
<View style={[g(styles, 'empty'), style]}>
<Image style={[g(styles, 'empty-icon')]} source={require('../../assets/images/mail_empty.png')} />
<Image style={[g(styles, 'empty-icon')]} source={require('../../assets/images/empty.png')} />
<Text style={[g(styles, 'empty-text')]}>{text}</Text>
</View>
)
......
/*
* @FilePath: /BoneHouse_Hospital_APP/src/enums/index.ts
* @FilePath: /BoneHouse_Business_APP/src/enums/index.ts
* @Author: peii
* @Date: 2021-04-24 22:45:15
* @Vision: 1.0
......@@ -31,3 +31,9 @@ export enum SelectMode {
PAGE = 'PAGE',
MODAL = 'MODAL',
}
export enum SettlementProcessCode {
USER_CONFIRM = 'USER_CONFIRM',
USER_REJECT = 'USER_REJECT',
REQUIRE_RECONFIRM = 'REQUIRE_RECONFIRM',
}
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/pages/settlement/collection.tsx
* @Author: peii
* @Date: 2021-12-18 16:33:37
* @LastEditTime: 2021-12-20 17:09:34
* @LastEditTime: 2021-12-21 15:55:57
* @LastEditors: peii
* @Vision: 1.0
* @Description: 结算汇总
......@@ -105,7 +105,7 @@ class SettlementCollection extends React.Component<IProps, IState> {
otherFilterItems={otherFilterItems}
/>
{loading ? <Loading show={loading} /> : <SettlementList data={data} {...this.props} />}
{loading ? <Loading show={loading} /> : <SettlementList data={data} {...this.props} isCollection={true} />}
</View>
</Resolution.FixWidthView>
</View>
......
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/pages/settlement/components/filter.tsx
* @Author: peii
* @Date: 2021-12-19 10:49:42
* @LastEditTime: 2021-12-20 14:59:22
* @LastEditTime: 2021-12-21 17:35:08
* @LastEditors: peii
* @Vision: 1.0
* @Description: 过滤弹窗
......@@ -15,7 +15,7 @@ import { connect } from 'react-redux'
import * as R from 'ramda'
import { IFormField } from 'bonehouse'
import api from '../../../services/api'
import { isBlank, g, getFormItem } from '../../../utils/utils'
import { isNotBlank, g, getFormItem } from '../../../utils/utils'
import { FieldType } from '../../../enums'
import Filter from '../../../components/modals/filter/filter'
import styles from './filter.styl'
......@@ -45,6 +45,7 @@ class FilterModal extends React.Component<IProps, IState> {
}
state = {
isAutoOpen: true,
data: {
seller_code: this.props.userInfo.user_name,
},
......@@ -88,9 +89,19 @@ class FilterModal extends React.Component<IProps, IState> {
* @return {*}
*/
setData(key: string, value: any) {
const { data } = this.state
const { data, isAutoOpen } = this.state
data[key] = value
this.setState({ data })
this.setState({ data }, () => {
if (!isAutoOpen) return
const isAllParamSet = R.compose(
R.all(isNotBlank),
R.map(k => data[k]),
)(['org_code', 'seller_code', 'customer_code'])
if (!isAllParamSet) return
this.setState({ isAutoOpen: false })
this.filterHandler()
})
}
/**
......@@ -134,8 +145,8 @@ class FilterModal extends React.Component<IProps, IState> {
item.options = R.compose(
R.map(
R.applySpec({
value: R.prop('org_code'),
label: R.compose(R.take(3), R.prop('org_name')),
value: R.compose(R.take(3), R.prop('org_code')),
label: R.prop('org_name'),
}),
),
R.pathOr([], ['data', 'organizations']),
......@@ -182,7 +193,7 @@ class FilterModal extends React.Component<IProps, IState> {
{
data: {
seller_code: userInfo.user_name,
org_code: userInfo.department_code,
org_code: R.take(3, userInfo.department_code),
},
},
() => {},
......
......@@ -21,5 +21,23 @@
line-height 22px
margin-bottom 6px
&__status
font-size 16px
font-weight bold
color #000
&-left
width 70%
.text
&-red
color #f00
&-black
color #000
&-blue
color primary_color
&-gray
color #999
\ No newline at end of file
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/pages/settlement/components/list.tsx
* @Author: peii
* @Date: 2021-12-19 10:44:15
* @LastEditTime: 2021-12-20 15:35:10
* @LastEditTime: 2021-12-21 17:21:48
* @LastEditors: peii
* @Vision: 1.0
* @Description: 汇总列表
......@@ -11,8 +11,10 @@
import React, { Component } from 'react'
import { View, Text, TouchableOpacity, FlatList, Image } from 'react-native'
import { INavigation } from 'navigation'
import * as R from 'ramda'
import { connect } from 'react-redux'
import { INavigation } from 'navigation'
import Empty from '../../../components/empty'
import dayjs from 'dayjs'
import { isBlank, g } from '../../../utils/utils'
import styles from './list.styl'
......@@ -35,11 +37,32 @@ class SettlementList extends Component<IProps> {
* @return {*}
*/
itemPressHandler(item) {
console.log(item)
this.props.navigation.navigate('SettlementDetail', { order: item })
this.props.navigation.navigate('SettlementDetail', { order: item, ...this.props })
}
/**
* @description: 映射状态
* @param {*} statusCode
* @return {*}
*/
mapStatus(statusCode) {
const { status = [] } = this.props
return R.compose(R.propOr('未知状态', 'value_name'), R.find(R.propEq('value_code', statusCode)))(status)
}
/**
* @description: 状态显示类
* @param {*}
* @return {*}
*/
mapStatusClass = R.cond([
[R.includes(R.__, ['ENTERED']), R.always('text-black')],
[R.includes(R.__, ['USER_REJECTED']), R.always('text-red')],
[R.includes(R.__, ['USER_CONFIRMED']), R.always('text-blue')],
[R.T, R.always('text-gray')],
])
/**
* @description: 结算单单项
* @param {*} param1
* @return {*}
......@@ -58,7 +81,9 @@ class SettlementList extends Component<IProps> {
<Text style={g(styles, 'item-text', 'item-left-text')}>结算总数量: {item.sum_quantity}</Text>
<Text style={g(styles, 'item-text', 'item-left-text')}>结算总金额: {item.sum_settlement_amount}</Text>
</View>
<Text style={g(styles, 'item-text__rigth')}>{item.header_status}</Text>
<Text style={g(styles, ['item-text__rigth', 'item-text__status', this.mapStatusClass(item.header_status)])}>
{this.mapStatus(item.header_status)}
</Text>
</View>
<View style={g(styles, 'item-line')}>
......@@ -78,6 +103,7 @@ class SettlementList extends Component<IProps> {
<FlatList
data={data}
renderItem={this.renderItem}
ListEmptyComponent={Empty}
style={g(styles, 'list')}
keyExtractor={it => it.settlement_number}
></FlatList>
......@@ -85,4 +111,8 @@ class SettlementList extends Component<IProps> {
}
}
export default SettlementList
const mapStateToProps = state => ({
status: state.settlement.headerStatus,
})
export default connect(mapStateToProps)(SettlementList)
......@@ -21,8 +21,23 @@
flex 1
padding 15px
&-ft
@extend .row
padding-top 10px
padding-left 20px
padding-right 20px
justify-content space-around
height 70px
.list
&-header
@extend .row
margin-bottom 10px
justify-content space-between
.card
@extend .row
align-items center
background-color #fff
padding 15px
......@@ -33,7 +48,8 @@
@extend .row
&-text
font-size 16px
color second_text_color
font-size 15px
margin-bottom 5px
&-key
......@@ -43,8 +59,51 @@
@extend .middle
align-items flex-end
width 60px
height 60px
&__checkbox
width 100%
height 100%
justify-content flex-end
.btn
width 150px
height 40px
background-color danger_color
border-radius 4px
@extend .center
@extend .middle
&-primary
background-color primary_color
&-disable
background-color dis_sub_color
&-text
color #fff
font-weight bold
font-size 18px
&__disabled
color rgba(255, 255, 255, 0.5)
&-inner
@extend .row
.ml10
margin-left 10px
.download
@extend .row
@extend .center
&-text
color title_text_color
font-size 18px
font-family font_family_regular
margin-right 5px
&-img
width 18px
height @width
\ No newline at end of file
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/pages/settlement/detail.tsx
* @Author: peii
* @Date: 2021-12-20 15:27:45
* @LastEditTime: 2021-12-20 18:31:55
* @LastEditTime: 2021-12-23 12:15:45
* @LastEditors: peii
* @Vision: 1.0
* @Description: 结算详情
......@@ -11,15 +11,16 @@
// @ts-nocheck
import React from 'react'
import { View, Text, FlatList, TouchableOpacity, Image } from 'react-native'
import { View, Text, FlatList, TouchableOpacity, ActivityIndicator, Image } from 'react-native'
import { connect } from 'react-redux'
import * as R from 'ramda'
import { INavigation } from 'navigation'
import debounce from 'debounce'
import Loading from '../../../app/containers/common/LodingModel'
import { Checkbox } from '../../components/checkbox/checkbox'
import Header from '../../components/header/header'
import Resolution from '../../components/common/Resolution'
import { isBlank, g } from '../../utils/utils'
import { isBlank, g, show } from '../../utils/utils'
import { SettlementProcessCode } from '../../enums'
import api from '../../services/api'
import styles from './detail.styl'
......@@ -34,12 +35,19 @@ class Detail extends React.Component<IProps, IState> {
super(props)
this.renderHeader = this.renderHeader.bind(this)
this.renderItem = this.renderItem.bind(this)
this.itemPressHandler = this.itemPressHandler.bind(this)
this.rejectHandler = this.rejectHandler.bind(this)
this.confirmHandler = debounce(this.confirmHandler.bind(this), 200)
this.downloadHandler = debounce(this.downloadHandler.bind(this), 200)
}
state = {
refresh: false,
data: [],
items: [],
loading: false,
submitting: false,
downloading: false,
}
componentDidMount() {
......@@ -78,12 +86,100 @@ class Detail extends React.Component<IProps, IState> {
this.setState({ data })
}
renderHeader() {}
/**
* @description: 点击销售单项
* @param {*} item
* @return {*}
*/
itemPressHandler(item) {
this.props.navigation.navigate('SettlementSaleDetail', {
order: item,
refreshHandler: this.refreshHandler.bind(this),
})
}
/**
* @description: 驳回处理
* @param {*}
* @return {*}
*/
rejectHandler() {
const order = this.props.navigation.getParam('order', {})
this.props.navigation.navigate('SettlementReject', { order, title: '结算驳回' })
}
/**
* @description: 确认
* @param {*}
* @return {*}
*/
async confirmHandler() {
const order = this.props.navigation.getParam('order', {})
const data = {
process_code: SettlementProcessCode.USER_CONFIRM,
sale_settlement_number: order.settlement_number,
}
this.setState({ submitting: true })
const res = await api.postSettlementProcess(data)
this.setState({ submitting: false })
if (res.error_code !== 0) return
this.props.navigation.pop(2)
}
refreshHandler() {
this.forceUpdate()
}
async downloadHandler() {
const { downloading } = this.state
if (downloading) {
return show('下载中,无需连续点击下载')
}
const order = this.props.navigation.getParam('order', {})
if (isBlank(order)) return show('没有可下载的结算单')
const { host, token } = this.props
const params = {
access_token: token,
settlement_number: order.settlement_number,
}
this.setState({ downloading: true })
await api.downloadSettlementLine(host, params)
this.setState({ downloading: false })
}
renderHeader() {
const { items, data } = this.state
// TODO:
// const len = R.compose(
// R.length,
// R.filter(R.identity),
// R.unnest,
// R.pluck('_checked'),
// R.unnest,
// R.pluck('sal_order_list'),
// )(data)
return (
<View style={g(styles, 'list-header')}>
<Text style={g(styles, 'list-header__text')}>耗材({R.length(items || [])})</Text>
{/* <Text style={g(styles, 'list-header__text')}>已选择耗材({len})</Text> */}
</View>
)
}
renderItem({ item }) {
return (
<View style={g(styles, 'card')}>
<View style={g(styles, 'card-info')}>
<TouchableOpacity
style={g(styles, 'card-info')}
activeOpacity={0.8}
onPress={() => this.itemPressHandler(item)}
>
<View style={g(styles, 'card-line')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>销售单: </Text>
<Text style={g(styles, 'card-text')}>{item.order_number}</Text>
......@@ -100,25 +196,26 @@ class Detail extends React.Component<IProps, IState> {
<Text style={g(styles, 'card-text', 'card-text-key')}>金额: </Text>
<Text style={g(styles, 'card-text')}>{item.sum_settlement_amount}</Text>
</View>
</View>
</TouchableOpacity>
<View style={g(styles, 'card-select')}>
{/* <View style={g(styles, 'card-select')}>
<Checkbox
checked={item._checked}
indeterminate={item._indeterminate}
style={g(styles, 'card-select__checkbox')}
onChange={checked => this.selectHandler(checked, item)}
/>
</View>
</View> */}
</View>
)
}
render() {
const order = this.props.navigation.getParam('order', {})
const isCollection = this.props.navigation.getParam('isCollection', false)
const title = '结算确认详情'
const { data } = this.state
const { data, loading, submitting } = this.state
return (
<View style={g(styles, 'container')}>
......@@ -128,19 +225,53 @@ class Detail extends React.Component<IProps, IState> {
backCallback={() => {
this.props.navigation.goBack()
}}
/>
>
<TouchableOpacity style={g(styles, 'download')} activeOpacity={0.8} onPress={this.downloadHandler}>
<Text style={g(styles, 'download-text')}>下载</Text>
<Image style={g(styles, 'download-img')} source={require('../../assets/images/download.png')} />
</TouchableOpacity>
</Header>
<View style={g(styles, 'body')}>
<View style={g(styles, 'body-hd')}>
<Text style={g(styles, 'body-hd__text')}>结算单号: {order.settlement_number}</Text>
</View>
<FlatList
style={g(styles, 'body-bd')}
data={data}
keyExtractor={it => it.order_number}
renderItem={this.renderItem}
renderHeader={this.renderHeader}
></FlatList>
{loading ? (
<Loading show={loading} />
) : (
<>
<FlatList
style={g(styles, 'body-bd')}
data={data}
keyExtractor={it => it.order_number}
renderItem={this.renderItem}
ListHeaderComponent={this.renderHeader}
></FlatList>
{!isCollection && (
<View style={g(styles, 'body-ft')}>
<TouchableOpacity style={g(styles, 'btn')} activeOpacity={0.8} onPress={this.rejectHandler}>
<Text style={g(styles, 'btn-text')}>驳回</Text>
</TouchableOpacity>
<TouchableOpacity
style={g(styles, { btn: true, 'btn-primary': true, 'btn-disable': submitting })}
disabled={submitting}
activeOpacity={0.8}
onPress={this.confirmHandler}
>
{submitting ? (
<View style={g(styles, 'btn-inner')}>
<ActivityIndicator style={g(styles, 'btn__loading')} color="rgba(255,255,255,0.5)" />
<Text style={g(styles, 'btn-text', 'btn-text__disabled', 'ml10')}>提交中</Text>
</View>
) : (
<Text style={g(styles, 'btn-text')}>确认</Text>
)}
</TouchableOpacity>
</View>
)}
</>
)}
</View>
</Resolution.FixWidthView>
</View>
......@@ -148,7 +279,10 @@ class Detail extends React.Component<IProps, IState> {
}
}
const mapStateToProps = state => ({})
const mapStateToProps = state => ({
token: state.login.token,
host: state.login.global_domain_config,
})
const mapDispatchToProps = dispatch => ({})
......
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/pages/settlement/index.tsx
* @Author: peii
* @Date: 2021-12-18 16:33:37
* @LastEditTime: 2021-12-20 15:32:04
* @LastEditTime: 2021-12-23 10:58:21
* @LastEditors: peii
* @Vision: 1.0
* @Description: 结算确认首页
......@@ -60,6 +60,10 @@ class Settlement extends React.Component<IProps, IState> {
*/
async getData(args): void {
this.setState({ loading: true })
// 确认页面只过滤出已输入的那些
// TODO:
// args.header_status = 'ENTERED'
const res = await api.getSettlements(args)
this.setState({ loading: false })
if (res.error_code !== 0) return
......
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/pages/settlement/reject.tsx
* @Author: peii
* @Date: 2021-12-18 17:12:57
* @LastEditTime: 2021-12-18 17:53:46
* @LastEditTime: 2021-12-21 16:07:52
* @LastEditors: peii
* @Vision: 1.0
* @Description: 结算驳回
......@@ -18,7 +18,9 @@ import { FieldType } from '../../enums'
import Header from '../../components/header/header'
import Form from '../../components/form/index'
import Resolution from '../../components/common/Resolution'
import { isBlank, g, getFormItem } from '../../utils/utils'
import { g, getFormItem } from '../../utils/utils'
import { SettlementProcessCode } from '../../enums'
import api from '../../services/api'
import styles from './reject.styl'
type IProps = {
......@@ -71,15 +73,20 @@ class Reject extends React.Component<IProps, IState> {
* @param {*}
* @return {*}
*/
// TODO:
submitHandler() {
async submitHandler() {
const { data } = this.state
console.log(data)
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, 2000)
})
const order = this.props.navigation.getParam('order', {})
const params = {
process_code: SettlementProcessCode.USER_CONFIRM,
sale_settlement_number: order.settlement_number,
reject_reason: data.reject_reason
}
const res = await api.postSettlementProcess(params)
if (res.error_code !== 0) return
this.props.navigation.pop(3)
}
render() {
......
@import '../../assets/styles/base.styl'
@import '../../assets/styles/variable.styl'
.container
background-color home_background_color
.body
flex 1
&-hd
@extend .middle
padding-left 20px
padding-right 20px
height 40px
background-color #fff
&__text
font-size 16px
&-bd
flex 1
padding 15px
.list
&-header
@extend .row
margin-bottom 10px
justify-content space-between
.card
background-color #fff
padding 15px
margin-bottom 15px
&-info
flex 1
&-line
@extend .row
&-half
@extend .row
width 50%
&-text
font-size 15px
color second_text_color
margin-bottom 5px
&-key
padding-right 3px
&-select
@extend .middle
width 60px
height 100px
&__checkbox
width 100%
height 100%
justify-content flex-end
.ml20
margin-left 20px
\ No newline at end of file
......@@ -2,7 +2,7 @@
* @FilePath: /BoneHouse_Business_APP/src/pages/settlement/saleDetail.tsx
* @Author: peii
* @Date: 2021-12-20 15:27:45
* @LastEditTime: 2021-12-20 16:14:47
* @LastEditTime: 2021-12-21 15:03:54
* @LastEditors: peii
* @Vision: 1.0
* @Description: 结算销售物料详情
......@@ -16,10 +16,12 @@ import { connect } from 'react-redux'
import * as R from 'ramda'
import { INavigation } from 'navigation'
import Header from '../../components/header/header'
import { Checkbox } from '../../components/checkbox/checkbox'
import Resolution from '../../components/common/Resolution'
import dayjs from 'dayjs'
import { isBlank, g } from '../../utils/utils'
import api from '../../services/api'
import styles from './detail.styl'
import styles from './saleDetail.styl'
type IProps = {
navigation: INavigation
......@@ -28,15 +30,141 @@ type IProps = {
type IState = {}
class SaleDetail extends React.Component<IProps, IState> {
constructor(props) {
super(props)
this.renderHeader = this.renderHeader.bind(this)
this.renderItem = this.renderItem.bind(this)
this.checkedHandler = this.checkedHandler.bind(this)
}
state = {
data: [],
order: {},
}
componentDidMount() {
const order = this.props.navigation.getParam('order', {})
this.setState({ order })
}
/**
* @description: 选择操作
* @param {*} checked
* @param {*} item
* @return {*}
*/
checkedHandler(checked, item) {
const { order } = this.state
item._checked = checked
const items = R.propOr([], 'sal_order_list')(order)
const checkLen = R.compose(R.length, R.filter(R.identity), R.pluck('_checked'))(items)
if (items.length === 0 || checkLen === 0) {
order._checked = false
} else if (items.length > checkLen) {
order._checked = false
order._indeterminate = true
} else {
order._checked = true
order._indeterminate = false
}
this.setState({ order })
}
componentDidMount() {}
renderHeader() {
const { order } = this.state
const len = R.compose(R.length, R.propOr([], 'sal_order_list'))(order)
return (
<View style={g(styles, 'list-header')}>
<Text style={g(styles, 'list-header__text')}>耗材({len})</Text>
</View>
)
}
renderItem({ item, index }) {
return (
<View style={g(styles, 'card')}>
<View style={g(styles, 'card-line')}>
<View style={g(styles, 'card-info')}>
<View style={g(styles, 'card-line')}>
<Text style={g(styles, 'card-text')}>
{index + 1}. {item.item_name}
</Text>
</View>
<View style={g(styles, 'card-line')}>
<Text style={g(styles, 'card-text')}>{item.general_name}</Text>
</View>
<View style={g(styles, 'card-line')}>
<Text style={g(styles, 'card-text')}>{item.specification}</Text>
</View>
<View style={g(styles, 'card-line')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>序列号: </Text>
<Text style={g(styles, 'card-text')}>{item.serial_number}</Text>
</View>
<View style={g(styles, 'card-line')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>注册证号: </Text>
<Text style={g(styles, 'card-text')}>{item.reg_number}</Text>
</View>
</View>
{/* <View style={g(styles, 'card-select')}>
<Checkbox
style={g(styles, 'card-select__checkbox')}
checked={item._checked}
onChange={checked => this.checkedHandler(checked, item)}
></Checkbox>
</View> */}
</View>
<View style={g(styles, 'card-line')}>
<View style={g(styles, 'card-line-half')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>批号: </Text>
<Text style={g(styles, 'card-text')}>{item.production_batch_number}</Text>
</View>
<View style={g(styles, 'card-line-half', 'ml20')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>存储条件: </Text>
<Text style={g(styles, 'card-text')}>{item.storage_condition_name}</Text>
</View>
</View>
<View style={g(styles, 'card-line')}>
<View style={g(styles, 'card-line-half')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>生产日期: </Text>
<Text style={g(styles, 'card-text')}>
{item.production_date && dayjs(item.production_date).format('YYYY-MM-DD')}
</Text>
</View>
<View style={g(styles, 'card-line-half', 'ml20')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>过期日期: </Text>
<Text style={g(styles, 'card-text')}>
{item.expiration_date && dayjs(item.expiration_date).format('YYYY-MM-DD')}
</Text>
</View>
</View>
<View style={g(styles, 'card-line')}>
<View style={g(styles, 'card-line-half')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>数量: </Text>
<Text style={g(styles, 'card-text')}>{item.quantity}</Text>
</View>
<View style={g(styles, 'card-line-half', 'ml20')}>
<Text style={g(styles, 'card-text', 'card-text-key')}>金额: </Text>
<Text style={g(styles, 'card-text')}>{item.sale_amount}</Text>
</View>
</View>
</View>
)
}
render() {
const order = this.props.navigation.getParam('order', {})
const title = '结算确认详情'
const { order } = this.state
const data = R.propOr([], 'sal_order_list')(order)
const { refreshHandler } = this.props.navigation.state.params
return (
<View style={g(styles, 'container')}>
......@@ -44,13 +172,21 @@ class SaleDetail extends React.Component<IProps, IState> {
<Header
title={title}
backCallback={() => {
refreshHandler && refreshHandler()
this.props.navigation.goBack()
}}
/>
<View style={g(styles, 'body')}>
<View style={g(styles, 'body-hd')}>
<Text>结算单号: {order.settlement_number}</Text>
<Text style={g(styles, 'body-hd__text')}>销售单号: {order.order_number}</Text>
</View>
<FlatList
style={g(styles, 'body-bd')}
data={data}
keyExtractor={it => it.item_code}
renderItem={this.renderItem}
ListHeaderComponent={this.renderHeader}
></FlatList>
</View>
</Resolution.FixWidthView>
</View>
......
......@@ -2,13 +2,15 @@
* @FilePath: /BoneHouse_Business_APP/src/services/api.ts
* @Author: peii
* @Date: 2021-12-19 16:06:26
* @LastEditTime: 2021-12-20 12:01:25
* @LastEditTime: 2021-12-23 12:18:34
* @LastEditors: peii
* @Vision: 1.0
* @Description: 未重构完全暂用的所有请求
*/
import { request } from './baseApi'
import { download } from '../utils/download'
import { stringify } from 'querystring'
const v = '/api/latest'
......@@ -52,4 +54,32 @@ export default {
getSettlementLines(data: { settlement_number: string; line_status: string }) {
return request({ url: `${v}/sale/settlement_line/search`, data })
},
/**
* @description: 结算确认
* @param {*} data
* @return {*}
*/
postSettlementProcess(data: { process_code: string; sale_settlement_number: string; reject_reason: string }) {
return request({ url: `${v}/sale/settlement/process`, data: { data }, method: 'POST' })
},
/**
* @description: 下载结算单行
* @param {string} host
* @param {object} data
* @return {*}
*/
downloadSettlementLine(host: string, data: { settlement_number: string; access_token: string }) {
const url = `${host}${v}/excel/download/settlement_line?${stringify(data)}`
const config = {
useDownloadManager: true,
title: '结算单行下载',
mime: 'application/vnd.ms-excel',
path: `销售结算单_${data.settlement_number}.xls`,
mediaScannable: true,
notification: true,
}
return download(url, config)
},
}
......@@ -108,13 +108,22 @@ export const request = (args: Partial<RequestConfig>) => {
p.cancel()
}, requestQueue)
requestQueue = []
navigation.navigate('LoginPage')
show('登录过期,请重新登录')
R.tryCatch(
() => {
navigation.navigate('LoginPage')
},
() => {
reject(e)
},
)
return
}
if (requestTimes < options.reTries) {
if (requestTimes < options.reTries && !e.error_code) {
return doRequest()
}
failHandler(e, pid)
reject(e)
})
}
......
/*
* @FilePath: /BoneHouse_Business_APP/src/utils/download.ts
* @Author: peii
* @Date: 2021-12-23 11:19:21
* @LastEditTime: 2021-12-23 12:16:09
* @LastEditors: peii
* @Vision: 1.0
* @Description: 下载工具
*/
import RNFetchBlob from 'rn-fetch-blob'
import { Platform, PermissionsAndroid, Linking } from 'react-native'
import { show } from './utils'
/**
* @description: 文件下载
* @param {string} url 下载url
* @param {any} config android下载配置
* @return {*}
*/
export const download = async (url: string, config?: any) => {
try {
if (Platform.OS === 'ios') {
await Linking.openURL(url)
return true
} else {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE)
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
return show('请给APP读写权限授权')
}
config.path && (config.path = RNFetchBlob.fs.dirs.DownloadDir + '/' + config.path)
show('下载中')
return await RNFetchBlob.config({
addAndroidDownloads: config,
})
.fetch('get', url)
.then(res => {
return show('下载成功')
})
.catch(e => {
console.log(e)
return
})
}
} catch (error: any) {
show(error.message || '下载出错,请重试')
}
}
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