react展开收缩实现

在组件中通过遍历,改变数据项
或者组件中改变数据后,更新redux数据,从而更新组件


//这里customerBaseinInfo包含newDataContacts数组,可以通过redux中updateStateProps更新数据
 dispatch({
            type: 'customerDetail/updateStateProps',
            payload: {
                name: 'customerBaseinInfo',
                value: {
                    newDataContacts: change,
                },
            },
        });

如果数据为单层,可以使用

  dispatch({
            type: 'customerDetail/overrideStateProps',
            payload: {
                id: customerId,
            },
        });

更新数据

//展开收缩事件
    const handleContactsCollapse = item => {
        let change = [];
        change = customerBaseinInfo.newDataContacts.map(el => {
            let collapse = el.collapse;
            if (el.id === item.id) {
                collapse = !collapse;
            }
            return { ...el, collapse };
        });
       dispatch({
            type: 'customerDetail/updateStateProps',
            payload: {
                name: 'customerBaseinInfo',
                value: {
                    newDataContacts: change,
                },
            },
        });
    };

redux

import customerProfileListApi from '../services/customerProfileList';
import Taro from '@tarojs/taro';

const namespace = 'customerDetail';

const selectState = state => state[namespace];

export default {
    namespace,
    state: {
        id: '',
        customerData: {},
        machine: null,
        clientMainInfo: {},
        customerBaseinInfo: {},
        reviewsInfo: {},
    },
    reducers: {
        overrideStateProps(state, { payload }) {
            return {
                ...state,
                ...payload,
            };
        },

        updateStateProps(state, { payload }) {
            const { name, value } = payload;
            return {
                ...state,
                ...{ [name]: { ...state[name], ...value } },
            };
        },
    },
    effects: {
        // 获取客户信息
        *getCustomerBaseinIoDetail(_, { call, put, select }) {
            const { id } = yield select(selectState);
            const response = yield call(customerProfileListApi.getCustomerBaseinInfoDetail, id);
            const result = response.XCmdrResult;
            const clientBaseInfo = result.clientBaseInfo;
            const clientMainInfo = result.clientMainInfo;
            const reviewsInfo = result.reviewsInfo;
            const data = {
                ...clientBaseInfo,
                selfArea: '',
                selFallArea: '',
                selfClient_source: '', // 客户来源
                selfIntroduction: '',
                newDataContacts: [],
            };
            if (clientBaseInfo.area) {
                data.selfArea = `${clientBaseInfo.area.province_name}/${clientBaseInfo.area.city_name}/${clientBaseInfo.area.county_name}`;
                data.selfArea = clientBaseInfo.area.full_name;
            }
            if (clientBaseInfo.contacts) {
                let newData = [];
                newData = clientBaseInfo.contacts.map(item => {
                    return { ...item, collapse: false };
                });
                clientBaseInfo.contacts = newData;
                data.newDataContacts = newData;
            }
            switch (response.XCmdrCode) {
                case 0:
                    yield put({
                        type: 'overrideStateProps',
                        payload: {
                            customerBaseinInfo: data,
                            clientMainInfo,
                            reviewsInfo,
                        },
                    });
                    break;
                case 210:
                    Taro.navigateTo({ url: '../login/index' });
                    break;
                default:
                    break;
            }
        },

        // 删除客户
        *deleteClient(_, { call, select }) {
            const { id } = yield select(selectState);
            const response = yield call(customerProfileListApi.getCustomerBaseinInfoDetail, id);
            switch (response.XCmdrCode) {
                case 0:
                    Taro.showToast({
                        title: '删除成功',
                        icon: 'none',
                        mask: true,
                    });
                    setTimeout(() => {
                        Taro.navigateBack();
                    }, 1500);
                    break;
                case 721:
                    Taro.showToast({
                        title: '当前客户下已存在关联的终端 or 传感器 or 合同,不允许删除!',
                        icon: 'none',
                    });
                    setTimeout(() => {
                        Taro.navigateBack();
                    }, 1500);
                    break;
                case 722:
                    Taro.showToast({
                        title: '当前客户下已存在跟进记录,不允许删除!',
                        icon: 'none',
                    });
                    setTimeout(() => {
                        Taro.navigateBack();
                    }, 1500);
                    break;
                default:
                    Taro.showToast({
                        title: '删除失败!',
                        icon: 'none',
                    });
                    break;
            }
        },
    },
};

组件

import React, { useState, useEffect } from 'react';
import { View, Text, Image } from '@tarojs/components';
import Taro, { useDidShow, useRouter } from '@tarojs/taro';
import './index.scss';
import downImg from '../../assets/down.png';
import { useDispatch, useSelector } from 'react-redux';

export default function Index() {
    const dispatch = useDispatch();
    const {
        params: { id: customerId },
    } = useRouter();
    const { clientMainInfo, customerBaseinInfo, reviewsInfo } = useSelector(
        store => store.customerDetail,
    );
    // 获取客户信息;
    useDidShow(() => {
        dispatch({
            type: 'customerDetail/overrideStateProps',
            payload: {
                id: customerId,
            },
        });
        dispatch({
            type: 'customerDetail/getCustomerBaseinIoDetail',
        });
    });

    const defaultBaseInfo = {
        baseInfoCollapse: false,
        Contact1: false,
        Contact2: false,
        CustomerInsight: false,
        currentProgress: false,
    };
    const [expandCollapse, setExpandCollapse] = useState(defaultBaseInfo);

    useEffect(() => {
        console.log('customerBaseinInfo.contacts');
        console.log(customerBaseinInfo.newDataContacts);
    });
    //
    const handleExpandCollapse = type => {
        switch (type) {
            case 'baseInfo':
                setExpandCollapse({
                    baseInfoCollapse: !expandCollapse.baseInfoCollapse,
                });
                break;
            case 'Contact1':
                setExpandCollapse({
                    Contact1: !expandCollapse.Contact1,
                });
                break;
            case 'Contact2':
                setExpandCollapse({
                    Contact2: !expandCollapse.Contact2,
                });
                break;
            case 'CustomerInsight':
                setExpandCollapse({
                    CustomerInsight: !expandCollapse.CustomerInsight,
                });
                break;
            case 'currentProgress':
                setExpandCollapse({
                    currentProgress: !expandCollapse.currentProgress,
                });
                break;
            default:
                break;
        }
    };
    const handleContactsCollapse = item => {
        let change = [];
        change = customerBaseinInfo.newDataContacts.map(el => {
            let collapse = el.collapse;
            if (el.id === item.id) {
                collapse = !collapse;
            }
            return { ...el, collapse };
        });
        const aa = dispatch({
            type: 'customerDetail/updateStateProps',
            payload: {
                name: 'customerBaseinInfo',
                value: {
                    newDataContacts: change,
                },
            },
        });
        console.log(aa);
        console.log(customerBaseinInfo.newDataContacts);
    };
    const clientSource = record => {
        const text = record?.reduce((total, current, index, self) => {
            let sTmp = current.name;
            if (index !== self.length - 1 && sTmp) {
                sTmp += '/';
            }
            return total + sTmp;
        }, '');
        return text || '';
    };

    const ApproveStatus = status => {
        switch (status) {
            case 'agree':
                return <Text>同意</Text>;
            case 'disagree':
                return <Text>拒绝</Text>;
            default:
                break;
        }
    };
    const customerFollow = e => {
        e.stopPropagation();
        Taro.navigateTo({
            url: `../customerFollow/index?id=${customerId}`,
        });
    };
    const customerProgress = e => {
        e.stopPropagation();
        Taro.navigateTo({
            url: `../customerProgress/index?id=${customerId}`,
        });
    };

    const goToDelete = () => {
        Taro.showModal({
            title: '提示',
            content: '确认要删除该客户信息吗?',
            confirmColor: '#FF7A45',
            success: res => {
                if (res.confirm) {
                    dispatch({
                        type: 'customerDetail/deleteClient',
                    });
                }
            },
        });
    };
    return (
        <View className="container">
            {/* 第一部分 */}
            <View className="firstBox">
                <View className="firstLeft">{clientMainInfo.name || '-'}</View>
                <View className="firstRigt" onClick={customerFollow}>
                    {/*   ④ 跟进记录:点击进入《跟进记录》页面,显示客户的跟进记录。 */}
                    <View className="firstRigtBtn">跟进记录</View>
                </View>
            </View>
            {/* 时间 */}
            <View className="itemtTime DividingLine">
                <View className="itemKey">{clientMainInfo.create_log?.admin || '-'}</View>
                <View className="itemName">{clientMainInfo.create_log?.created_at || '-'}</View>
            </View>
            {/* 第二部分 */}
            <View className="secondBox">
                <View className="seconUp">
                    <View className="seconUpLeft">
                        <View className="itemcontainer">
                            <View className="itemKey">客户分类:</View>
                            <View className="itemName">
                                {clientSource(clientMainInfo.client_classify)}
                            </View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">用户来源:</View>
                            {/* <View className="itemName"> {clientSource(item.source)}</View> */}
                        </View>
                    </View>
                    <View className="seconUpRight"></View>
                </View>
                {/*   ⑥ 业务阶段:点击进入《阶段进展》页面,显示客户业务阶段变更记录。 */}
                <View className="itemcontainer selected" onClick={customerProgress}>
                    <View className="itemKey">业务阶段:</View>
                    <View className="itemName rengColor">
                        {clientMainInfo.phase_of_operations?.name || '-'}
                    </View>
                </View>
                <View className="itemcontainer">
                    <View className="itemKey">经营组:</View>
                    <View className="itemName">
                        {clientMainInfo.operations_group_id?.length > 0
                            ? clientMainInfo.operations_group_id[
                                  clientMainInfo.operations_group_id.length - 1
                              ].name
                            : '-'}
                    </View>
                </View>
                <View className="itemcontainer">
                    <View className="itemKey">营销经理:</View>
                    <View className="itemName">{clientMainInfo.marketing_admin?.name || '-'}</View>
                </View>
                <View className="itemcontainer">
                    <View className="itemKey">实施经理:</View>
                    <View className="itemName">{clientMainInfo.practice_admin?.name || '-'}</View>
                </View>
                <View className="itemcontainer">
                    <View className="itemKey">营销助理:</View>
                    <View className="itemName">
                        {clientMainInfo.marketing_assistant_admin?.name || '-'}
                    </View>
                </View>
            </View>
            {/* 基本信息 */}
            <View className="threeBox">
                <View className="groupTitle">基本信息</View>
                <View className="itemcontainer">
                    <View className="itemKey">客户简称:</View>
                    <View className="itemName">{customerBaseinInfo.short_name || '-'}</View>
                </View>
                <View className="itemcontainer">
                    <View className="itemKey">客户权重:</View>
                    <View className="itemName">{customerBaseinInfo.client_weight || '-'}</View>
                </View>
                {/* 展开选项 */}
                {expandCollapse.baseInfoCollapse ? (
                    <>
                        <View
                            className={`${'itemcontainer'} ${
                                customerBaseinInfo.selfArea ? 'selected' : ''
                            }`}
                        >
                            {/*   ⑦ 上级单位:点击进入《关联客户》页面,显示 客户关联记录。 */}
                            <View className="itemKey">上级单位:</View>
                            <View className="itemName">{customerBaseinInfo.selfArea || '-'}</View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">地区:</View>
                            <View className="itemName">{customerBaseinInfo.selfArea || '-'}</View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">详细地址:</View>
                            <View className="itemName">{customerBaseinInfo.address || '-'}</View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">客户简介:</View>
                            <View className="itemName">
                                {customerBaseinInfo.introduction || '-'}
                            </View>
                        </View>
                    </>
                ) : null}

                <View className="ExpandCollapse" onClick={() => handleExpandCollapse('baseInfo')}>
                    {!expandCollapse.baseInfoCollapse ? <Text>展开</Text> : <Text>收起</Text>}
                </View>
            </View>
            {/* 联系人1 */}
            <View className="threeBox">
                {customerBaseinInfo.newDataContacts?.length > 0
                    ? customerBaseinInfo.newDataContacts.map((item, index) => {
                          return (
                              <>
                                  <View className="groupTitle">联系人{index + 1}</View>
                                  <View className="itemcontainer">
                                      <View className="itemKey">联系人:</View>
                                      <View className="itemName">{item.name}</View>
                                  </View>
                                  <View className="itemcontainer">
                                      <View className="itemKey">联系电话:</View>
                                      <View className="itemName">
                                          {[item.phone1, item.phone2, item.phone3]
                                              .filter(e => !!e)
                                              .join(',') || '-'}
                                      </View>
                                  </View>
                                  {/* 展开选项 */}
                                  <View>展开选项{String(item.collapse)}</View>
                                  {item.collapse ? (
                                      <>
                                          <View className="itemcontainer">
                                              <View className="itemKey">来源:</View>
                                              <View className="itemName">
                                                  {clientSource(item.source)}
                                              </View>
                                          </View>
                                          <View className="itemcontainer">
                                              <View className="itemKey">角色:</View>
                                              <View className="itemName">{item.role || '-'}</View>
                                          </View>
                                          <View className="itemcontainer">
                                              <View className="itemKey">微信:</View>
                                              <View className="itemName">
                                                  {item.we_chat || '-'}
                                              </View>
                                          </View>
                                          <View className="itemcontainer">
                                              <View className="itemKey">部门:</View>
                                              <View className="itemName">
                                                  {item.department || '-'}
                                              </View>
                                          </View>
                                          <View className="itemcontainer">
                                              <View className="itemKey">客户分析:</View>
                                              <View className="itemName">
                                                  {item.client_analysis || '-'}
                                              </View>
                                          </View>
                                      </>
                                  ) : null}

                                  <View
                                      className="ExpandCollapse"
                                      onClick={() => handleContactsCollapse(item)}
                                  >
                                      {!item.collapse ? <Text>展开</Text> : <Text>收起</Text>}
                                  </View>
                              </>
                          );
                      })
                    : null}
            </View>
            {/* 客户洞察 */}
            <View className="threeBox">
                <View className="groupTitle">客户洞察</View>
                <View className="itemcontainer">
                    <View className="itemKey">预计客户体量:</View>
                    <View className="itemName">{customerBaseinInfo.expected_volume || '-'}</View>
                </View>
                <View className="itemcontainer">
                    <View className="itemKey">年产值:</View>
                    <View className="itemName">
                        {customerBaseinInfo.yearly_output_value || '-'}
                    </View>
                </View>
                {/* 展开选项 */}
                {expandCollapse.CustomerInsight ? (
                    <>
                        <View className="itemcontainer">
                            <View className="itemKey">自有设备:</View>
                            <View className="itemName">
                                {customerBaseinInfo.private_equipment || '-'}
                            </View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">租赁设备:</View>
                            <View className="itemName">
                                {customerBaseinInfo.rent_equipment || '-'}
                            </View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">施工类型:</View>
                            <View className="itemName">
                                {customerBaseinInfo.construction_type || '-'}
                            </View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">客户痛点:</View>
                            <View className="itemName"> {customerBaseinInfo.pain_spot || '-'}</View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">竞品分析:</View>
                            <View className="itemName">
                                {customerBaseinInfo.competitor_situation || '-'}
                            </View>
                        </View>
                        <View className="itemcontainer">
                            <View className="itemKey">其他分析:</View>
                            <View className="itemName">
                                {customerBaseinInfo.other_analysis || '-'}
                            </View>
                        </View>
                    </>
                ) : null}

                <View
                    className="ExpandCollapse"
                    onClick={() => handleExpandCollapse('CustomerInsight')}
                >
                    {!expandCollapse.CustomerInsight ? <Text>展开</Text> : <Text>收起</Text>}
                </View>
            </View>
            {/* 目前进展 */}
            <View className="threeBox">
                <View className="groupTitle">目前进展</View>
                <View className="itemcontainer">
                    <View className="itemKey">跟进情况:</View>
                    <View className="itemName">
                        {customerBaseinInfo.current_progress?.follow_up_situation || '-'}
                    </View>
                </View>
                <View className="itemcontainer">
                    <View className="itemKey">待解决问题:</View>
                    <View className="itemName">
                        {customerBaseinInfo.current_progress?.problems_to_be_solved || '-'}
                    </View>
                </View>
                {/* 展开选项 */}
                {expandCollapse.currentProgress ? (
                    <>
                        <View className="itemcontainer">
                            <View className="itemKey">预解决方案</View>
                            <View className="itemName">
                                {customerBaseinInfo.current_progress?.pre_solution || '-'}
                            </View>
                        </View>
                    </>
                ) : null}

                <View
                    className="ExpandCollapse"
                    onClick={() => handleExpandCollapse('currentProgress')}
                >
                    {!expandCollapse.currentProgress ? <Text>展开</Text> : <Text>收起</Text>}
                </View>
            </View>
            {/* 组织结构图 */}
            <View className="threeBox">
                <View className="groupTitle">组织结构图</View>
                <View className="organizationChart">
                    <View className="organizationChartLeft">
                        <View className="itemKey">附件</View>
                    </View>
                    {customerBaseinInfo.organization_chart_url ? (
                        <View className="organizationChartRight">
                            <View className="organizationChartRightBox">
                                <View className="itemKey">
                                    {customerBaseinInfo.organization_chart_url || '-'}
                                </View>
                                <Image className="downImg" src={downImg} alt="" />
                            </View>
                        </View>
                    ) : (
                        // <Empty description="暂无附件" />
                        <View className="fileEmpty">暂无附件</View>
                    )}
                </View>
            </View>
            {/* 审批 */}
            <View className="threeBox">
                <View className="groupTitle">审批</View>

                {reviewsInfo?.length > 0
                    ? reviewsInfo.map(item => {
                          return (
                              <>
                                  <View className="ApproveGroup">
                                      <View className="ApproveUp">
                                          <View className="itemKey">{item.operator}</View>
                                          <View className="itemName">{item.approve_time}</View>
                                      </View>
                                      <View className="ApproveStatus">
                                          {ApproveStatus(item.final_state)}
                                      </View>
                                  </View>
                              </>
                          );
                      })
                    : null}
            </View>
            <View className="downBtn">
                <View className="downBtnDelete" onClick={goToDelete}>
                    <Text>删除</Text>
                </View>
                <View className="downBtnEdit">
                    <Text cl>编辑</Text>
                </View>
            </View>
        </View>
    );
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值