wushaodong il y a 4 ans
Parent
commit
82776107b6

+ 52 - 1
jscore/models/customer.js

@@ -4,7 +4,7 @@ import ResponseError from '../components/ResponseError';
 import TurnPage from '../components/TurnPage';
 import {REFRESH_STATE} from 'react-native-refresh-flatlist';
 
-let reportCustomerData = [], reviewTodayData = [], reviewRecordData = [], checkCustomerData = [];
+let reportCustomerData = [], reviewTodayData = [], reviewRecordData = [], processRecordData = [], orderListData = [], checkCustomerData = [];
 export default {
     namespace: 'customer',
     state: {
@@ -16,9 +16,14 @@ export default {
         reviewRecordRState: REFRESH_STATE.Ready,
         checkCustomerData: [],
         checkCustomerRState: REFRESH_STATE.Ready,
+        orderListData: [],
+        orderListRState: REFRESH_STATE.Ready,
         reviewRecordData: [],
+        processRecordRState: REFRESH_STATE.Ready,
+        processRecordData: [],
         projectDict: [],
         customerDetail: {},
+        processDetail: {},
         customerReviewDetail: {},
     },
     reducers: {
@@ -245,6 +250,52 @@ export default {
                 ResponseError(response);
             }
         },
+        * fetchOrderList({payload}, {call, put}) {
+            if (payload.page > 1) {
+                yield put(createAction('queryList')({orderListRState: REFRESH_STATE.FooterRefreshing}));
+            } else {
+                yield put(createAction('queryList')({orderListRState: REFRESH_STATE.HeaderRefreshing}));
+            }
+            const response = yield call(customer.queryOrderList, payload);
+            if (!response.code) {
+                const result = TurnPage(response, payload, orderListData);
+                orderListData = result.data;
+                yield put(createAction('queryList')({
+                    orderListData: orderListData, orderListRState: result.state,
+                    total: response.totalResult, page: payload.page,
+                }));
+            } else {
+                ResponseError(response);
+                yield put(createAction('queryList')({orderListRState: REFRESH_STATE.Ready}));
+            }
+        },
+        * fetchProcessDetail({payload, callback}, {call, put}) {
+            const response = yield call(customer.queryProcessDetail, payload);
+            if (response.id) {
+                yield put(createAction('queryList')({processDetail: response}));
+            } else {
+                ResponseError(response);
+            }
+        },
+        * fetchProcessRecord({payload}, {call, put}) {
+            if (payload.page > 1) {
+                yield put(createAction('queryList')({ProcessRecordRState: REFRESH_STATE.FooterRefreshing}));
+            } else {
+                yield put(createAction('queryList')({ProcessRecordRState: REFRESH_STATE.HeaderRefreshing}));
+            }
+            const response = yield call(customer.queryProcessRecord, payload);
+            if (!response.code) {
+                const result = TurnPage(response, payload, processRecordData);
+                processRecordData = result.data;
+                yield put(createAction('queryList')({
+                    processRecordData: processRecordData, processRecordRState: result.state,
+                    totalRecord: response.totalResult, page: payload.page,
+                }));
+            } else {
+                ResponseError(response);
+                yield put(createAction('queryList')({processRecordRState: REFRESH_STATE.Ready}));
+            }
+        },
     },
     subscriptions: {
         setup({dispatch}) {

+ 4 - 4
jscore/pages/Sales/Home.js

@@ -56,15 +56,15 @@ const qkgl = [
     {
         name: '进度跟踪',
         img: require('../../../assets/images/jdgl2.png'),
-        navetion: '',
-        param: {track_status: 'today', title: '今日需跟', status: ''},
+        navetion: 'ProcessList',
+        param: {source:1},
         premission: 'order.view_order',
     },
     {
         name: '进度审核',
         img: require('../../../assets/images/jcgl2.png'),
-        navetion: '',
-        param: {track_status: 'today_ok', title: '今日已跟', status: ''},
+        navetion: 'ProcessList',
+        param: {status: 3, source:2},
         badge: 'order_count',
         premission: 'order.order_process_dispatch',
     },

+ 14 - 0
jscore/pages/Sales/Index.js

@@ -16,6 +16,8 @@ import CheckCustomerList from './CheckCustomerList';
 import checkCustomerDetail from './checkCustomerDetail';
 import CheckCustomer from './CheckCustomer';
 import UpdateProcess from './UpdateProcess';
+import ProcessList from './ProcessList';
+import ProcessDetail from './ProcessDetail';
 
 const HomeStack = createStackNavigator({
         SalesHome: {
@@ -102,6 +104,18 @@ const HomeStack = createStackNavigator({
                 title: '更新进度',
             },
         },
+        ProcessList: {
+            screen: ProcessList,
+            navigationOptions: {
+                title: '进度跟踪',
+            },
+        },
+        ProcessDetail: {
+            screen: ProcessDetail,
+            navigationOptions: {
+                title: '进度详情',
+            },
+        },
     },
     {
         initialRouteName: 'SalesHome',

+ 304 - 0
jscore/pages/Sales/ProcessDetail.js

@@ -0,0 +1,304 @@
+import React, {Component} from 'react';
+import {
+    View,
+    Text,
+    StyleSheet,
+    ScrollView,
+    Dimensions, DeviceEventEmitter,
+} from 'react-native';
+import {Tabs, Provider, Button, List,} from '@ant-design/react-native';
+import {createAction} from '../../utils';
+import {connect} from 'react-redux';
+import CallPhone from '../../components/CallPhone';
+import ComponentsStyles from '../../components/ComponentsStyles';
+import RefreshFlatList from 'react-native-refresh-flatlist';
+const tabs = [
+    {title: '基本信息', id: 1},
+    {title: '进度明细', id: 2},
+];
+const {width} = Dimensions.get('window');
+
+@connect(customer => ({...customer}))
+class ProcessDetail extends Component {
+    //  潜客跟踪
+    constructor(props) {
+        super(props);
+        this.state = {
+            page: 1,
+            rows: 10,
+            order_id: this.props.navigation.state.params.order_id,
+            source: this.props.navigation.state.params.source,
+        };
+    };
+
+    componentDidMount() {
+        this._fetchProcessReoprt();
+        this._fetchData();
+        this.refeshReport = DeviceEventEmitter.addListener('refeshReport', (param) => {
+            this._fetchProcessReoprt(1);
+        });
+        this.refeshProcessDetail = DeviceEventEmitter.addListener('refeshProcessDetail', (param) => {
+            this._fetchData();
+        });
+    }
+
+    componentWillUnmount() {
+        this.refeshReport.remove();
+        this.refeshProcessDetail.remove();
+    }
+
+    _fetchData = () => {
+        this.props.dispatch({
+            type: 'customer/fetchProcessDetail',
+            payload: {id: this.state.order_id},
+        });
+    };
+    _fetchMore = () => {
+        const {page, totalRecord} = this.props.customer;
+        if (page * this.state.rows >= totalRecord) {
+            return;
+        }
+        const currentPage = page + 1;
+        this._fetchProcessReoprt(currentPage);
+    };
+
+    _keyExtractor = (item, index) => {
+        return index.toString();
+    };
+
+    _fetchProcessReoprt = (page) => {
+        if (page) {
+            this.state.page = page;
+        }
+        this.props.dispatch(createAction('customer/fetchProcessRecord')(this.state));
+    };
+
+    baseInfo = (ProcessDetailData) => {
+        return <View style={{marginTop: 5}}>
+            <List>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{ProcessDetailData.name}</Text>} arrow="empty">
+                    <Text style={ComponentsStyles.font15}>单号</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{ProcessDetailData.no}</Text>} arrow="empty">
+                    <Text style={ComponentsStyles.font15}>姓名</Text>
+                </List.Item>
+                <View style={styles.telItemView}>
+                    <Text style={ComponentsStyles.font15}>电话</Text>
+                    <View style={styles.telView}>
+                        <Text style={ComponentsStyles.icon}>{'\ue61a'}</Text>
+                        <Text
+                            style={styles.telText}
+                            onPress={() => CallPhone(ProcessDetailData.tel, 1)}>
+                            {ProcessDetailData.tel}
+                        </Text>
+                    </View>
+                </View>
+
+                <List.Item extra={<Text style={ComponentsStyles.IDText}>{ProcessDetailData.address}</Text>}
+                           wrap
+                           multipleLine arrow="empty">
+                    <Text style={ComponentsStyles.font15}>地址</Text>
+                </List.Item>
+
+                <List.Item extra={<Text style={ComponentsStyles.IDText}>{ProcessDetailData.village}</Text>}
+                           wrap
+                           multipleLine arrow="empty">
+                    <Text style={ComponentsStyles.font15}>小区</Text>
+                </List.Item>
+
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{ProcessDetailData.project_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>项目</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{ProcessDetailData.status_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>订单状态</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{ProcessDetailData.stage_progress_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>阶段进度</Text>
+                </List.Item>
+
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{ProcessDetailData.service_user_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>当前服务人员</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{ProcessDetailData.create_time_f}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>下单时间</Text>
+                </List.Item>
+            </List>
+        </View>;
+    };
+
+    renderItem = (data) => {
+        const item = data.item;
+        return <View style={styles.reportMain}>
+            <View style={styles.row5}>
+                <View style={ComponentsStyles.itemView}>
+                    <Text style={ComponentsStyles.icon}>{'\ue619'} <Text
+                        style={ComponentsStyles.font15}>{item.user_text}</Text>
+                    </Text>
+                </View>
+                <View style={ComponentsStyles.itemViewEnd}>
+                    <Text style={ComponentsStyles.icon}>{'\ue6cc'}</Text>
+                    <Text style={ComponentsStyles.font15}>{item.operation_time_f}</Text>
+                </View>
+            </View>
+            <View style={styles.row5}>
+                <Text style={ComponentsStyles.icon}>{'\ue6ed'} </Text>
+                <Text style={ComponentsStyles.font15}>{item.operation}</Text>
+            </View>
+            <View style={styles.row5}>
+                <Text style={ComponentsStyles.font15}>备注:</Text>
+                <Text style={ComponentsStyles.font15}>{item.notes}</Text>
+            </View>
+        </View>;
+    };
+
+    render() {
+        const {processRecordData, processRecordRState, processDetail} = this.props.customer;
+
+        return (
+            <Provider>
+                <Tabs
+                    tabs={tabs}
+                    initialPage={1}
+                    tabBarPosition="top"
+                    styles={{
+                        topTabBarSplitLine: {
+                            borderBottomWidth: 0,
+                        },
+                    }}
+                    tabBarUnderlineStyle={{
+                        backgroundColor: '#03C762',
+                        width: 40,
+                        marginLeft: (width / 2 - 38) / 2,
+                        height: 3,
+                        borderRadius: 2,
+                    }}
+                    tabBarActiveTextColor="#000"
+                >
+                    {/*基本信息*/}
+                    <ScrollView>
+                        {this.baseInfo(processDetail)}
+                    </ScrollView>
+                    {/*    跟踪记录*/}
+                    <View>
+                        <RefreshFlatList
+                            data={processRecordData}
+                            renderItem={(item) => this.renderItem(item)}
+                            keyExtractor={this._keyExtractor}
+                            themeColor="#5eafe4"
+                            refreshState={processRecordRState}
+                            footerRefreshingText="正在加载"
+                            footerFailureText="加载失败"
+                            onHeaderRefresh={() => this._fetchProcessReoprt(1)}
+                            onFooterRefresh={() => this._fetchMore()}
+                            ListHeaderComponent={() => <View style={{height: 0}}/>}
+                            ItemSeparatorComponent={() => <View style={{height: 0}}/>}
+                        />
+                    </View>
+                </Tabs>
+                {this.state.source === 1 ?
+                    <Button
+                        type="primary"
+                        onPress={() => this.props.navigation.navigate('UpdateProcess',
+                            {
+                                customer: processDetail.customer,
+                            })}
+                        style={ComponentsStyles.button}
+                    >
+                        <Text
+                            style={{color: '#fff'}}>更新进度</Text>
+                    </Button>
+                    :
+                    <Button
+                        type="primary"
+                        onPress={() => this.props.navigation.navigate('WriteTrackReport',
+                            {
+                                item: 1,
+                            })}
+                        style={ComponentsStyles.button}
+                    >
+                        <Text
+                            style={{color: '#fff'}}>分配</Text>
+                    </Button>
+                }
+            </Provider>
+        );
+    }
+}
+
+const styles = StyleSheet.create({
+    modalText: {
+        color: '#333',
+        fontSize: 16,
+        textAlign: 'center',
+        textAlignVertical: 'center',
+    },
+    textInput: {
+        width: '80%',
+        textAlign: 'left',
+        paddingHorizontal: 10,
+    },
+    modalContainer: {
+        flexDirection: 'row',
+        paddingHorizontal: 10,
+        paddingLeft: 13,
+        borderBottomWidth: 1,
+        borderBottomColor: '#eee',
+    },
+    textStyle: {
+        fontSize: 16,
+        paddingVertical: 10,
+    },
+    telItemView: {
+        flex: 1,
+        flexDirection: 'row',
+        marginLeft: 15,
+        paddingRight: 18,
+        paddingVertical: 8,
+        borderBottomWidth: 0.5,
+        borderBottomColor: '#eaeaea',
+    },
+    telName: {
+        color: '#333',
+        fontSize: 18,
+    },
+    telView: {
+        flex: 1,
+        flexDirection: 'row',
+        justifyContent: 'flex-end',
+        alignItems: 'center',
+    },
+    telText: {
+        color: '#2b90ea',
+        fontSize: 15,
+    },
+    listStyle: {
+        // borderBottomWidth: 10,
+        borderBottomColor: '#f6f7f8',
+    },
+    reportMain: {
+        marginTop: 5,
+        backgroundColor: '#fff',
+        paddingHorizontal: 10,
+        // borderWidth:1,
+    },
+    customerText: {
+        color: '#333',
+        fontSize: 16,
+    },
+    row5: {
+        flexDirection: 'row',
+        paddingVertical: 5,
+    },
+    red5: {
+        fontSize: 15,
+        color: 'red',
+        padding: 2,
+    },
+});
+
+export default ProcessDetail;

+ 158 - 0
jscore/pages/Sales/ProcessList.js

@@ -0,0 +1,158 @@
+import React, {Component} from 'react';
+import {
+    View,
+    TouchableOpacity, Text, StatusBar, DeviceEventEmitter,
+} from 'react-native';
+
+import {createAction} from '../../utils';
+import {connect} from 'react-redux';
+import {Button, Provider} from '@ant-design/react-native';
+import RefreshFlatList from 'react-native-refresh-flatlist';
+import CallPhone from '../../components/CallPhone';
+import CheckPrem from '../../components/CheckPrem';
+import ComponentsStyles from '../../components/ComponentsStyles';
+
+@connect(customer => ({...customer}))
+@connect(auth => ({...auth}))
+class ProcessList extends Component {
+    // 进度跟踪
+    constructor(props) {
+        super(props);
+        this.state = {
+            rows: 10,
+            page: 1,
+            status: this.props.navigation.state.params.status,
+            source: this.props.navigation.state.params.source,
+        };
+    }
+
+    componentDidMount() {
+        this._fetchData();
+        this.refesh = DeviceEventEmitter.addListener('backRefesh', (param) => {
+            this.props.dispatch(createAction('auth/fetchTipsCount')());
+            this._fetchData();
+        });
+    }
+
+    componentWillUnmount() {
+        this.refesh.remove();
+    }
+
+    _fetchData = (page) => {
+        if (page) {
+            this.state.page = page;
+        }
+        this.props.dispatch(createAction('customer/fetchOrderList')(this.state));
+    };
+    _fetchMore = () => {
+        const {page, total} = this.props.customer;
+        if (page * this.state.rows >= total) {
+            return;
+        }
+        const currentPage = page + 1;
+        this._fetchData(currentPage);
+    };
+    _keyExtractor = (item, index) => {
+        return index.toString();
+    };
+
+    _renderItem = (data) => {
+        const item = data.item;
+        return (
+            <TouchableOpacity style={ComponentsStyles.mainTouch}
+                              onPress={() => this.props.navigation.navigate('ProcessDetail',
+                                  {
+                                      order_id: item.id,
+                                      source: this.state.source,
+                                  },
+                              )}>
+
+                <View style={{flexDirection: 'row'}}>
+                    {/*姓名 电话*/}
+                    <View style={{flex: 1, justifyContent: 'flex-start', flexDirection: 'row'}}>
+                        <Text style={ComponentsStyles.icon}>{'\ue660'} <Text style={ComponentsStyles.fontBold}>
+                            {item.name}
+                        </Text>
+                        </Text>
+                    </View>
+                    <View style={{justifyContent: 'flex-end', flexDirection: 'row'}}>
+                        <Text style={ComponentsStyles.icon}>{'\ue61a'}</Text>
+                        <Text
+                            onPress={() => CallPhone(item.tel, 1)}
+                            style={{
+                                fontSize: 15,
+                                color: '#2b90ea',
+                            }}>
+                            {item.tel}
+                        </Text>
+                    </View>
+                </View>
+                <View style={{flexDirection: 'row', paddingTop: 5}}>
+                    <View style={ComponentsStyles.itemView}>
+                        <Text style={ComponentsStyles.icon}>{'\ue6ed'} <Text
+                            style={ComponentsStyles.font15}>{item.no}</Text>
+                        </Text>
+                    </View>
+                    <Text
+                        style={[ComponentsStyles.font15, item.status === 1 ? {color: 'green'} : {color: 'red'}]}>
+                        {item.status_text}</Text>
+                </View>
+                <View style={{flexDirection: 'row', paddingTop: 5}}>
+                    <View style={ComponentsStyles.itemView}>
+                        <Text style={ComponentsStyles.icon}>{'\ue6ed'} <Text
+                            style={ComponentsStyles.font15}>{item.project_text}</Text>
+                        </Text>
+                    </View>
+                    <View style={{justifyContent: 'flex-end', flexDirection: 'row'}}>
+                        <Text style={ComponentsStyles.icon}>{'\ue605'}</Text>
+                        <Text
+                            style={ComponentsStyles.font15}>
+                            {item.stage_progress_text}</Text>
+                    </View>
+                </View>
+
+                <View style={{flexDirection: 'row', flex: 1, paddingTop: 5}}>
+                    <View style={ComponentsStyles.itemView}>
+                        <Text style={ComponentsStyles.icon}>{'\ue6cc'}</Text>
+                        <Text style={ComponentsStyles.font15}>{item.create_time_f}</Text>
+                    </View>
+
+                    <View style={{justifyContent: 'flex-end', flexDirection: 'row'}}>
+                        <Text style={ComponentsStyles.icon}>{'\ue619'}</Text>
+                        <Text style={ComponentsStyles.font15}>
+                            {item.service_user_text}
+                        </Text>
+                    </View>
+                </View>
+            </TouchableOpacity>
+        );
+    };
+
+    render() {
+        const {orderListData, orderListRState, total} = this.props.customer;
+        return (
+            <View style={{flex: 1}}>
+                <Provider>
+                    <StatusBar backgroundColor={'#fff'} barStyle='dark-content'/>
+                    <RefreshFlatList
+                        data={orderListData}
+                        renderItem={(item) => this._renderItem(item)}
+                        keyExtractor={this._keyExtractor}
+                        themeColor="#5eafe4"
+                        refreshState={orderListRState}
+                        footerRefreshingText="正在加载"
+                        footerFailureText="加载失败"
+                        onHeaderRefresh={() => this._fetchData(1)}
+                        onFooterRefresh={() => this._fetchMore()}
+                    />
+                    <View style={ComponentsStyles.bottomTotal}>
+                        <Text style={ComponentsStyles.totalText}>合计数量:<Text
+                            style={{color: '#333333'}}>{total}</Text></Text>
+                    </View>
+                </Provider>
+            </View>
+        );
+    }
+}
+
+export default ProcessList;

+ 13 - 1
jscore/services/customer.js

@@ -37,6 +37,18 @@ export async function getProcess(params) {
     return request(`/order/get_process/?customer_id=` + params.customer);
 }
 
+export async function queryOrderList(params) {
+    return request(`/order/?${stringify(params)}`);
+}
+
+export async function queryProcessDetail(params) {
+    return request(`/order/` + params.id + `/`);
+}
+
+export async function queryProcessRecord(params) {
+    return request(`/order/get_details/?${stringify(params)}`);
+}
+
 export async function dispatchUser(params) {
     let formdata = new FormData();
     formdata.append('user', params.user[0]);
@@ -50,7 +62,7 @@ export async function addOrder(params) {
     let formdata = new FormData();
     formdata.append('notes', params.notes);
     formdata.append('stage_progress', params.next_process_id);
-    formdata.append('source', 'app');
+
     params.file.map((item, index) => {
         formdata.append('file' + index.toString(), {
             uri: item.uri,