Kaynağa Gözat

客户跟踪详情

wushaodong 4 yıl önce
ebeveyn
işleme
9f5597fbc3

+ 43 - 1
jscore/models/customer.js

@@ -4,13 +4,17 @@ import ResponseError from '../components/ResponseError';
 import TurnPage from '../components/TurnPage';
 import {REFRESH_STATE} from 'react-native-refresh-flatlist';
 
-let reportCustomerData = [];
+let reportCustomerData = [], reviewTodayData = [], reviewRecordData = [];
 export default {
     namespace: 'customer',
     state: {
         loading: false,
         reportCustomerDataRState: REFRESH_STATE.Ready,
         reportCustomerData: [],
+        reviewTodayRState: REFRESH_STATE.Ready,
+        reviewTodayData: [],
+        reviewRecordRState: REFRESH_STATE.Ready,
+        reviewRecordData: [],
         projectDict: [],
     },
     reducers: {
@@ -92,6 +96,44 @@ export default {
                 ResponseError(response);
             }
         },
+        * fetchReviewToday({payload}, {call, put}) {
+            if (payload.page > 1) {
+                yield put(createAction('queryList')({reviewTodayRState: REFRESH_STATE.FooterRefreshing}));
+            } else {
+                yield put(createAction('queryList')({reviewTodayRState: REFRESH_STATE.HeaderRefreshing}));
+            }
+            const response = yield call(customer.queryReviewToday, payload);
+            if (!response.code) {
+                const result = TurnPage(response, payload, reviewTodayData);
+                reviewTodayData = result.data;
+                yield put(createAction('queryList')({
+                    reviewTodayData: reviewTodayData, reviewTodayRState: result.state,
+                    total: response.totalResult, page: payload.page,
+                }));
+            } else {
+                ResponseError(response);
+                yield put(createAction('queryList')({reviewTodayRState: REFRESH_STATE.Ready}));
+            }
+        },
+        * fetchReviewRecord({payload}, {call, put}) {
+            if (payload.page > 1) {
+                yield put(createAction('queryList')({reviewRecordRState: REFRESH_STATE.FooterRefreshing}));
+            } else {
+                yield put(createAction('queryList')({reviewRecordRState: REFRESH_STATE.HeaderRefreshing}));
+            }
+            const response = yield call(customer.queryReviewRecord, payload);
+            if (!response.code) {
+                const result = TurnPage(response, payload, reviewRecordData);
+                reviewRecordData = result.data;
+                yield put(createAction('queryList')({
+                    reviewRecordData: reviewRecordData, reviewRecordRState: result.state,
+                    total: response.totalResult, page: payload.page,
+                }));
+            } else {
+                ResponseError(response);
+                yield put(createAction('queryList')({reviewRecordRState: REFRESH_STATE.Ready}));
+            }
+        },
     },
     subscriptions: {
         setup({dispatch}) {

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

@@ -41,14 +41,14 @@ const qkgl = [
     {
         name: '客户跟踪',
         img: require('../../../assets/images/jrxg2.png'),
-        navetion: 'CallList',
-        param: {},
+        navetion: 'ReviewTodayList',
+        param: {status: 1},
         premission: 'customer.view_new_customer',
     },
     {
         name: '跟踪审核',
         img: require('../../../assets/images/jryg2.png'),
-        navetion: 'NetworkList',
+        navetion: '',
         param: {},
         premission: 'customer.check_review',
         badge: 'review_count',
@@ -56,14 +56,14 @@ const qkgl = [
     {
         name: '进度跟踪',
         img: require('../../../assets/images/jdgl2.png'),
-        navetion: 'ReviewTodayList',
+        navetion: '',
         param: {track_status: 'today', title: '今日需跟', status: ''},
         premission: 'order.view_order',
     },
     {
         name: '进度审核',
         img: require('../../../assets/images/jcgl2.png'),
-        navetion: 'ReviewTodayList',
+        navetion: '',
         param: {track_status: 'today_ok', title: '今日已跟', status: ''},
         badge: 'order_count',
         premission: 'order.order_process_dispatch',

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

@@ -7,6 +7,8 @@ import ReportCustomerList from './ReportCustomerList';
 import ReportCustomerDetail from './ReportCustomerDetail';
 import ReportCustomerAdd from './ReportCustomerAdd';
 import SearchProject from './SearchProject';
+import ReviewTodayList from './ReviewTodayList';
+import ReviewDetail from './ReviewDetail';
 
 const HomeStack = createStackNavigator({
         SalesHome: {
@@ -39,6 +41,18 @@ const HomeStack = createStackNavigator({
                 title: '选择项目',
             },
         },
+        ReviewTodayList: {
+            screen: ReviewTodayList,
+            navigationOptions: {
+                title: '客户跟踪',
+            },
+        },
+        ReviewDetail: {
+            screen: ReviewDetail,
+            navigationOptions: {
+                title: '客户详情',
+            },
+        },
     },
     {
         initialRouteName: 'SalesHome',

+ 326 - 0
jscore/pages/Sales/ReviewDetail.js

@@ -0,0 +1,326 @@
+import React, {Component} from 'react';
+import {
+    View,
+    Text,
+    StyleSheet,
+    ScrollView,
+    TextInput,
+    Dimensions,
+} from 'react-native';
+import {Tabs, Modal, Provider, Toast, Button, Picker, 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 CheckValid from '../../components/CheckValid';
+import RefreshFlatList from 'react-native-refresh-flatlist';
+
+const tabs = [
+    {title: '基本信息', id: 1},
+    {title: '跟踪记录', id: 2},
+];
+const {width} = Dimensions.get('window');
+
+@connect(customer => ({...customer}))
+class ReviewDetail extends Component {
+    //  潜客跟踪
+    constructor(props) {
+        super(props);
+        this.state = {
+            getParm: {
+                page: 1,
+                rows: 10,
+                customer: this.props.navigation.state.params.item.id,
+            },
+            item: this.props.navigation.state.params.item,
+            moreModelVisible: false,
+        };
+
+    };
+
+    componentDidMount() {
+        this._fetchReviewReoprt();
+    }
+
+    _fetchMore = () => {
+        const {page, total} = this.props.customer;
+        if (page * this.state.getParm.rows >= total) {
+            return;
+        }
+        const currentPage = page + 1;
+        this._fetchReviewReoprt(currentPage);
+    };
+
+    _keyExtractor = (item, index) => {
+        return index.toString();
+    };
+
+    _fetchReviewReoprt = (page) => {
+        if (page) {
+            this.state.getParm.page = page;
+        }
+        this.props.dispatch(createAction('customer/fetchReviewRecord')(this.state.getParm));
+    };
+
+    baseInfo = () => {
+        const reviewDetailData = this.state.item;
+        return <View style={{marginTop: 5}}>
+            <List style={styles.listStyle}>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.name}</Text>} arrow="empty">
+                    <Text style={ComponentsStyles.font15}>姓名</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.gender_text}</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(reviewDetailData.tel, 1)}>
+                            {reviewDetailData.tel}
+                        </Text>
+                    </View>
+                </View>
+
+                <List.Item extra={<Text style={ComponentsStyles.IDText}>{reviewDetailData.address}</Text>}
+                           wrap
+                           multipleLine arrow="empty">
+                    <Text style={ComponentsStyles.font15}>地址</Text>
+                </List.Item>
+
+                <List.Item extra={<Text style={ComponentsStyles.IDText}>{reviewDetailData.village}</Text>}
+                           wrap
+                           multipleLine arrow="empty">
+                    <Text style={ComponentsStyles.font15}>小区</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.source_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>来源</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.project_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>项目</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.stage_progress_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>阶段进度</Text>
+                </List.Item>
+
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.status_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>状态</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.track_user_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>跟踪人员</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.store_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>门店</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.next_time_f}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>下次跟踪</Text>
+                </List.Item>
+
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.enter_count}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>进店次数</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.last_enter_time}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>最后进店时间</Text>
+                </List.Item>
+
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.create_time_f}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>建档时间</Text>
+                </List.Item>
+
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.create_user_text}</Text>}
+                           arrow="empty">
+                    <Text style={ComponentsStyles.font15}>建档人</Text>
+                </List.Item>
+                <List.Item extra={<Text style={ComponentsStyles.font15}>{reviewDetailData.notes}</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>
+                    <Text style={ComponentsStyles.font15}>{item.create_user_text}</Text>
+                </View>
+            </View>
+            <View style={styles.row5}>
+                <Text style={ComponentsStyles.icon}>{'\ue6ed'} </Text>
+                <Text style={ComponentsStyles.font15}>{item.description}</Text>
+            </View>
+            <View style={styles.row5}>
+                <Text style={ComponentsStyles.icon}>{'\ue6cc'} </Text>
+                <Text style={{fontSize: 15}}>{item.create_time_f}</Text>
+            </View>
+
+            <View style={styles.row5}>
+                <Text style={styles.red5}>支援或放弃:</Text>
+                <Text style={ComponentsStyles.font15}>{item.instruction}</Text>
+            </View>
+
+            <View style={styles.row5}>
+                <Text style={styles.red5}>审核:</Text>
+                <Text style={ComponentsStyles.font15}>{item.check_status_text}--{item.check_comment}</Text>
+            </View>
+        </View>;
+    };
+
+    render() {
+        const {reviewRecordData, reviewRecordRState} = this.props.customer;
+
+        return (
+            <Provider>
+                <Tabs
+                    tabs={tabs}
+                    initialPage={0}
+                    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()}
+                    </ScrollView>
+                    {/*    跟踪记录*/}
+                    <View>
+                        <RefreshFlatList
+                            data={reviewRecordData}
+                            renderItem={(item) => this.renderItem(item)}
+                            keyExtractor={this._keyExtractor}
+                            themeColor="#5eafe4"
+                            refreshState={reviewRecordRState}
+                            footerRefreshingText="正在加载"
+                            footerFailureText="加载失败"
+                            onHeaderRefresh={() => this._fetchReviewReoprt(1)}
+                            onFooterRefresh={() => this._fetchMore()}
+                            ListHeaderComponent={() => <View style={{height: 0}}/>}
+                            ItemSeparatorComponent={() => <View style={{height: 0}}/>}
+                        />
+                    </View>
+                </Tabs>
+                <View style={{flexDirection: 'row', justifyContent: 'center', backgroundColor: '#fff'}}>
+                    <Button
+                        type="primary"
+                        onPress={() => this.props.navigation.navigate('WriteTrackReport',
+                            {
+                                customer_id: this.state.getParm.touch_id,
+                                backKey: this.props.navigation.state.key,
+                            })}
+                        style={{width: 200, margin: 5}}
+                    >
+                        <Text
+                            style={{color: '#fff'}}>填写跟踪报告</Text></Button>
+                    <Button
+                        type="warning"
+                        onPress={() => this.setState({moreModelVisible: true})}
+                        style={{width: 100, margin: 5}}
+                    >
+                        <Text
+                            style={{color: '#fff'}}>更多</Text></Button>
+                </View>
+            </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,
+        // marginBottom: 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 ReviewDetail;

+ 149 - 0
jscore/pages/Sales/ReviewTodayList.js

@@ -0,0 +1,149 @@
+import React, {Component} from 'react';
+import {
+    View,
+    TouchableOpacity, Text, StyleSheet,
+} from 'react-native';
+
+import {createAction} from '../../utils';
+import {connect} from 'react-redux';
+import RefreshFlatList from 'react-native-refresh-flatlist';
+import CallPhone from '../../components/CallPhone';
+import ComponentsStyles from '../../components/ComponentsStyles';
+
+@connect(customer => ({...customer}))
+class ReviewTodayList extends Component {
+    // 今日待跟踪、逾期未跟踪、潜客管理
+    constructor(props) {
+        super(props);
+        this.state = {
+            rows: 10,
+            page: 1,
+            status: this.props.navigation.state.params.status, //默认查询正常客户
+        };
+    }
+
+    componentDidMount() {
+        this._fetchData();
+    }
+
+    _fetchData = (page) => {
+        if (page) {
+            this.state.page = page;
+        }
+        this.props.dispatch(createAction('customer/fetchReviewToday')(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('ReviewDetail', {
+                                  item: item,
+                              })}>
+                <View style={{flexDirection: 'row'}}>
+                    <View style={ComponentsStyles.itemView}>
+                        <Text style={ComponentsStyles.icon}>{'\ue660'} </Text>
+                        <Text style={ComponentsStyles.fontBold}>{item.name}</Text>
+                    </View>
+                    <View style={ComponentsStyles.itemViewEnd}>
+                        <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.project_text}</Text>
+                        </Text>
+                    </View>
+                    <View style={ComponentsStyles.itemViewEnd}>
+                        <Text style={ComponentsStyles.icon}>{'\ue65c'}</Text>
+                        <Text style={ComponentsStyles.font15}>{item.village}</Text>
+                    </View>
+                </View>
+                <View style={{
+                    flex: 1,
+                    flexDirection: 'row',
+                    marginTop: 5,
+                }}>
+                    <View style={ComponentsStyles.itemView}>
+                        <Text style={ComponentsStyles.icon}>{'\ue619'}</Text>
+                        <Text style={ComponentsStyles.font15}>{item.track_user_text}</Text>
+                    </View>
+                    <View style={ComponentsStyles.itemViewEnd}>
+                        <Text style={ComponentsStyles.icon}>{'\ue6cc'}</Text>
+                        <Text style={ComponentsStyles.font15}>{item.end_time_f}</Text>
+                    </View>
+                </View>
+            </TouchableOpacity>
+        );
+    };
+
+    render() {
+        const {reviewTodayData, reviewTodayRState, total} = this.props.customer;
+
+        return (
+            <View style={{marginBottom: 10, flex: 1}}>
+                <RefreshFlatList
+                    data={reviewTodayData}
+                    renderItem={(item) => this._renderItem(item)}
+                    keyExtractor={this._keyExtractor}
+                    themeColor="#5eafe4"
+                    refreshState={reviewTodayRState}
+                    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>
+            </View>
+        );
+    }
+}
+
+const styles = StyleSheet.create({
+    selectedMenus: {
+        padding: 5,
+        backgroundColor: '#ffffff',
+        flexDirection: 'row',
+    },
+    menuItem: {
+        textAlign: 'center',
+        marginHorizontal: 5,
+        borderRadius: 20,
+        paddingVertical: 5,
+        paddingHorizontal: 8,
+        backgroundColor: '#f5f5f9',
+    },
+    selectedMenuItem: {
+        backgroundColor: '#2b90ea',
+        color: '#ffffff',
+        marginHorizontal: 5,
+        borderRadius: 20,
+        paddingVertical: 5,
+        paddingHorizontal: 8,
+    },
+});
+export default ReviewTodayList;

+ 9 - 3
jscore/services/customer.js

@@ -2,9 +2,7 @@ import {stringify} from 'qs';
 import request from './../utils/request';
 
 export async function queryReportCustomerData(params) {
-    return request(
-        `/customer/report_customer/?${stringify(params)}`,
-    );
+    return request(`/customer/report_customer/?${stringify(params)}`);
 }
 
 export async function queryReportDict() {
@@ -15,6 +13,14 @@ export async function getUser() {
     return request(`/customer/get_user/`);
 }
 
+export async function queryReviewToday(params) {
+    return request(`/customer/new_customer/?${stringify(params)}`);
+}
+
+export async function queryReviewRecord(params) {
+    return request(`/customer/get_review/?${stringify(params)}`);
+}
+
 export async function dispatchUser(params) {
     let formdata = new FormData();
     formdata.append('user', params.user[0]);

+ 5 - 5
jscore/utils/request.js

@@ -106,7 +106,7 @@ export default function request(url, option,) {
                             ],);
                     }
                 });
-                return {success: false};
+                return {code: 1};
             }
             else if (response.status == 460) {
                 SyncStorage.remove('credential');
@@ -117,7 +117,7 @@ export default function request(url, option,) {
                         {text: '我知道了', style: 'cancel'},
                     ],
                 );
-                return {success: false};
+                return {code: 1};
             }
             else if (response.status == 404) {
                 // Alert.alert(
@@ -127,7 +127,7 @@ export default function request(url, option,) {
                 //         {text: '我知道了', style: 'cancel'},
                 //     ],
                 // );
-                return {success: false};
+                return {code: 1};
             }
             else if (response.status == 500) {
                 Alert.alert(
@@ -137,7 +137,7 @@ export default function request(url, option,) {
                         {text: '我知道了', style: 'cancel'},
                     ],
                 );
-                return {success: false};
+                return {code: 1};
             }
 
             // DELETE and 204 do not return data by default
@@ -192,6 +192,6 @@ export default function request(url, option,) {
                     ],
                 );
             }
-            return {success: false};
+            return {code: 1};
         });
 }