在组件中通过遍历,改变数据项
或者组件中改变数据后,更新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>
);
}