import { connect, Dispatch } from 'dva';
import styles from './index.less';
import { useEffect, useState } from 'react';
import { Space, Checkbox, Popover, Button, Modal } from 'antd';
import { UNVIcon, UNVMessageBox } from 'UNV-DESIGN';
import AddOne from './AddOne';
import { set } from 'lodash';
interface Props {
dispatch: Dispatch;
regions: any[];
}
const RegionSetting = (props: Props) => {
const { dispatch, regions } = props;
// 是否显示添加区域
const [showAdd, setShowAdd] = useState<boolean>(false);
// 当前选择的一级区域
const [currentFirst, setCurrentFirst] = useState<any>('');
// 当前选择的二级区域
const [currentSecond, setCurrentSecond] = useState<any>('');
// 当前选择的三级区域
const [currentThird, setCurrentThird] = useState<any>('');
// 二级列表
const [seconds, setSeconds] = useState<any[]>([]);
// 三级列表
const [thirds, setThirds] = useState<any[]>([]);
// 当前勾选的一级区域
const [selectOne, setSelectOne] = useState<any[]>([]);
// 当前勾选的二级区域
const [selectTwo, setSelectTwo] = useState<any[]>([]);
// 当前勾选的三级区域
const [selectThree, setSelectThree] = useState<any[]>([]);
// 当前编辑的区域
const [currentEdit, setCurrentEdit] = useState<any>({});
// 当前要添加的目录等级
const [addLevel, setAddLevel] = useState<number>(1);
useEffect(() => {
_getRegion();
}, []);
useEffect(() => {
// 一级缪璐
setCurrentFirst(currentFirst ? currentFirst : regions[0]?.id);
let newSecondList: Array<any> = [];
// 二级目录相关
if (currentFirst) {
const tempObj = regions.find((item: any) => item.id === currentFirst);
if (tempObj.children && tempObj.children.length > 0) {
setSeconds(tempObj.children);
setCurrentSecond(tempObj.children[0]?.id);
} else {
setSeconds([]);
}
newSecondList = tempObj.children || [];
} else {
setSeconds(regions[0]?.children || []);
setCurrentSecond(regions[0]?.children[0]?.id);
newSecondList = regions[0]?.children || [];
}
// 三级目录相关
if (currentSecond) {
const tempObj =
(newSecondList.length > 0 &&
newSecondList.find((item: any) => item.id === currentSecond)) ||
{};
setThirds(tempObj.children || []);
} else {
const tempObj = newSecondList[0] || {};
setThirds(tempObj.children || []);
}
}, [regions]);
/**
* 勾选区域
* @param e 组件属性
* @param item 当前勾选项
* @param type 类型
*/
const _checkRegion = (e: any, item: any, type: number) => {
e.stopPropagation();
switch (type) {
case 1:
if (e.target.checked) {
setSelectOne([...selectOne, item.id]);
} else {
setSelectOne(selectOne.filter((id: any) => id !== item.id));
}
break;
case 2:
if (e.target.checked) {
setSelectTwo([...selectTwo, item.id]);
} else {
setSelectTwo(selectTwo.filter((id: any) => id !== item.id));
}
break;
case 3:
if (e.target.checked) {
setSelectThree([...selectThree, item.id]);
} else {
setSelectThree(selectThree.filter((id: any) => id !== item.id));
}
break;
default:
break;
}
};
/**
* 删除区域
* @param type 类型
*/
const _delRegion = (type: number) => {
Modal.confirm({
title: intl.formatMessage({
id: 'Are you sure you want to delete it?'
}),
cancelText: intl.formatMessage({ id: 'Cancel' }),
okText: intl.formatMessage({ id: 'OK' }),
onOk: () => {
switch (type) {
case 1:
_delAction(selectOne);
break;
case 2:
_delAction(selectTwo);
break;
case 3:
_delAction(selectThree);
break;
default:
break;
}
}
});
};
/**
* 获取区域
*/
const _getRegion = () => {
dispatch({
type: 'newRegion/getRegion'
});
};
/**
* 删除区域
* @param ids 区域id
*/
const _delAction = (ids: any[]) => {
dispatch({
type: 'newRegion/delRegion',
payload: [...ids],
callback: () => {
_getRegion();
}
});
};
/**
* 提交区域信息
* @param data
*/
const onSubmit = (res: any) => {
let method = 'newRegion/addRegion';
if (currentEdit.id) {
method = 'newRegion/editRegion';
}
let newRes = { ...res, level: addLevel };
switch (addLevel) {
case 1:
newRes.parentId = undefined;
break;
case 2:
newRes.parentId = currentFirst;
break;
case 3:
newRes.parentId = currentSecond;
break;
default:
break;
}
dispatch({
type: method,
payload: {
...newRes
},
callback: () => {
_getRegion();
setShowAdd(false);
}
});
};
/**
* 选择一级目录
* @param item
*/
const _selectOneLevel = (item: any) => {
setCurrentFirst(item.id);
const newSecond = item.children || [];
setCurrentSecond(newSecond[0]?.id || {});
setSeconds(newSecond);
const newThird = newSecond[0]?.children || [];
setThirds(newThird);
setSelectTwo([]);
setSelectThree([]);
};
/**
* 选择二级目录
* @param item
*/
const _selectTwoLevel = (item: any) => {
setCurrentSecond(item.id);
setThirds(item.children || []);
setSelectThree([]);
};
/**
* 编辑区域
* @param item 当前编辑的区域
*/
const _editRegion = (item: any, type: number) => {
switch (type) {
case 1:
setCurrentFirst(item.id);
break;
case 2:
setCurrentSecond(item.id);
break;
case 3:
setCurrentThird(item.id);
break;
default:
break;
}
setCurrentEdit(item);
setShowAdd(true);
};
/**
* 移动区域
* @param item 当前移动的区域
* @param type 移动方向
* @param level 移动级别
*/
const _moveRegion = (item: any, type: string, level: number) => {
let index = 0;
let target: any = {};
switch (level) {
case 1:
index = regions.findIndex((item: any) => item.id === item.id);
if (type === 'up') {
target = regions[index - 1];
} else {
target = regions[index + 1];
}
_moveAction(item.id, target.id, type);
break;
case 2:
index = regions.findIndex((item: any) => item.id === item.id);
if (type === 'up') {
target = seconds[index - 1];
} else {
target = seconds[index + 1];
}
_moveAction(item.id, target.id, type);
break;
case 3:
index = regions.findIndex((item: any) => item.id === item.id);
if (type === 'up') {
target = thirds[index - 1];
} else {
target = thirds[index + 1];
}
_moveAction(item.id, target.id, type);
break;
default:
break;
}
};
/**
* 移动区域
* @param id 当前移动的区域id
* @param target 目标区域id
* @param type 移动方向
*/
const _moveAction = (id: number, target: number, type: string) => {
dispatch({
type: 'newRegion/moveRegion',
payload: {
id,
target,
type
},
callback: () => {
_getRegion();
}
});
};
return (
<div className={styles.regionSetting}>
<div className={styles.regionSetting_title}>
{intl.formatMessage({ id: 'National and regional allocation' })}
</div>
<div className={styles.regionSetting_content}>
<div className={styles.regionSetting_first}>
<div className={styles.regionSetting_first_header}>
<div className={styles.regionSetting_header_font}>
{intl.formatMessage({ id: 'District' })}
</div>
<Space>
<UNVIcon
icon="addIcon"
onClick={() => {
setCurrentEdit({});
setAddLevel(1);
setShowAdd(true);
}}
/>
<UNVIcon
icon="deleteIcon"
onClick={() => _delRegion(1)}
style={{ marginTop: '3px' }}
disabled={selectOne.length < 1}
/>
</Space>
</div>
<div className={styles.regionSetting_first_list}>
{Array.isArray(regions) &&
regions.length > 0 &&
regions.map((item: any, index: number) => {
return (
<div
key={item.id}
className={styles.regionSetting_first_listOne}
onClick={() => _selectOneLevel(item)}
data-index={currentFirst === item.id}
>
<Space>
<Checkbox
onChange={(e) => _checkRegion(e, item, 1)}
checked={selectOne.includes(item.id)}
/>
<div className={styles.regionSetting_first_listOneFont}>
{item.fullName}
</div>
</Space>
<Popover
placement="bottom"
overlayClassName={styles.popovers}
content={
<>
<div
onClick={() => _editRegion(item, 1)}
className={styles.popovers_item}
>
{intl.formatMessage({ id: 'Edit' })}
</div>
{/* <div
onClick={() => _delRegion(item)}
className={styles.popovers_item}
>
{intl.formatMessage({ id: 'Delete' })}
</div> */}
<div
onClick={() => _moveRegion(item, 'up', 1)}
data-index={index === 0}
className={styles.popovers_itemMove}
>
{intl.formatMessage({ id: 'Up' })}
</div>
<div
onClick={() => _moveRegion(item, 'down', 1)}
className={styles.popovers_itemMove}
data-index={index === regions.length - 1}
data-index1={'down'}
>
{intl.formatMessage({ id: 'Down' })}
</div>
</>
}
>
<UNVIcon
icon="moreAIcon"
className={styles.regionSetting_first_listOneIcon}
/>
</Popover>
</div>
);
})}
</div>
</div>
<div className={styles.regionSetting_first}>
<div className={styles.regionSetting_first_header}>
<div className={styles.regionSetting_header_font}>
{intl.formatMessage({ id: 'Country' })}
</div>
<Space>
<UNVIcon
icon="addIcon"
onClick={() => {
setCurrentEdit({});
setAddLevel(2);
if (currentFirst) {
setShowAdd(true);
} else {
UNVMessageBox.info(
intl.formatMessage({
id: 'Please select first level category'
})
);
}
}}
/>
<UNVIcon
icon="deleteIcon"
onClick={() => _delRegion(1)}
style={{ marginTop: '3px' }}
disabled={selectTwo.length < 1}
/>
</Space>
</div>
<div className={styles.regionSetting_first_list}>
{Array.isArray(seconds) &&
seconds.length > 0 &&
seconds.map((item: any, index: number) => {
return (
<div
key={item.id}
className={styles.regionSetting_first_listOne}
onClick={() => _selectTwoLevel(item)}
data-index={currentSecond === item.id}
>
<Space>
<Checkbox
onChange={(e) => _checkRegion(e, item, 2)}
checked={selectTwo.includes(item.id)}
/>
<div className={styles.regionSetting_first_listOneFont}>
{item.fullName}
</div>
</Space>
<Popover
placement="bottom"
overlayClassName={styles.popovers}
content={
<>
<div
onClick={() => _editRegion(item, 2)}
className={styles.popovers_item}
>
{intl.formatMessage({ id: 'Edit' })}
</div>
{/* <div
onClick={() => _delRegion(item)}
className={styles.popovers_item}
>
{intl.formatMessage({ id: 'Delete' })}
</div> */}
<div
onClick={() => _moveRegion(item, 'up', 2)}
data-index={index === 0}
className={styles.popovers_itemMove}
>
{intl.formatMessage({ id: 'Up' })}
</div>
<div
onClick={() => _moveRegion(item, 'down', 2)}
className={styles.popovers_itemMove}
data-index={index === seconds.length - 1}
data-index1={'down'}
>
{intl.formatMessage({ id: 'Down' })}
</div>
</>
}
>
<UNVIcon
icon="moreAIcon"
className={styles.regionSetting_first_listOneIcon}
/>
</Popover>
</div>
);
})}
</div>
</div>
<div className={styles.regionSetting_first}>
<div className={styles.regionSetting_first_header}>
<div className={styles.regionSetting_header_font}>
{intl.formatMessage({ id: 'Region' })}
</div>
<Space>
<UNVIcon
icon="addIcon"
onClick={() => {
setCurrentEdit({});
setAddLevel(3);
if (currentSecond) {
setShowAdd(true);
} else {
UNVMessageBox.info(
intl.formatMessage({
id: 'Please select the secondary category first'
})
);
}
}}
/>
<UNVIcon
icon="deleteIcon"
onClick={() => _delRegion(1)}
style={{ marginTop: '3px' }}
disabled={selectThree.length < 1}
/>
</Space>
</div>
<div className={styles.regionSetting_first_list}>
{Array.isArray(thirds) &&
thirds.length > 0 &&
thirds.map((item: any, index: number) => {
return (
<div
key={item.id}
className={styles.regionSetting_first_listOne}
onClick={() => {
setCurrentThird(item.id);
}}
data-index={currentThird === item.id}
>
<Space>
<Checkbox
onChange={(e) => _checkRegion(e, item, 3)}
checked={selectThree.includes(item.id)}
/>
<div className={styles.regionSetting_first_listOneFont}>
{item.fullName}
</div>
</Space>
<Popover
placement="bottom"
overlayClassName={styles.popovers}
content={
<>
<div
onClick={() => _editRegion(item, 3)}
className={styles.popovers_item}
>
{intl.formatMessage({ id: 'Edit' })}
</div>
{/* <div
onClick={() => _delRegion(item)}
className={styles.popovers_item}
>
{intl.formatMessage({ id: 'Delete' })}
</div> */}
<div
onClick={() => _moveRegion(item, 'up', 2)}
data-index={index === 0}
className={styles.popovers_itemMove}
>
{intl.formatMessage({ id: 'Up' })}
</div>
<div
onClick={() => _moveRegion(item, 'down', 3)}
className={styles.popovers_itemMove}
data-index={index === thirds.length - 1}
data-index1={'down'}
>
{intl.formatMessage({ id: 'Down' })}
</div>
</>
}
>
<UNVIcon
icon="moreAIcon"
className={styles.regionSetting_first_listOneIcon}
/>
</Popover>
</div>
);
})}
</div>
</div>
</div>
{showAdd && (
<AddOne
onSubmit={onSubmit}
onCancel={() => setShowAdd(false)}
currentEdit={currentEdit}
/>
)}
</div>
);
};
export default connect(({ newRegion, loading }: any) => {
const { regions } = newRegion;
return {
regions,
loading: loading.effects['regions/getRegion']
};
})(RegionSetting);
css样式
.regionSetting {
padding: 10px;
border-radius: 8px;
background-color: white;
height: 100%;
width: 100%;
.regionSetting_title {
height: 30px;
line-height: 22px;
padding-left: 10px;
border-bottom: 1px solid rgb(234, 234, 234);
font-size: 14px;
color: rgba(0, 0, 0, 0.5);
}
.regionSetting_content {
display: flex;
height: calc(100% - 30px);
.regionSetting_first {
width: 260px;
padding: 0 10px 0 10px;
border-right: 2px solid rgb(234, 234, 234);
.regionSetting_first_header {
display: flex;
justify-content: space-between;
height: 40px;
border-bottom: 1px solid rgb(234, 234, 234);
font-weight: 700;
font-style: normal;
font-size: 16px;
color: rgba(0, 0, 0, 0.5);
.regionSetting_header_font {
padding: 10px 0 0 10px;
}
}
.regionSetting_first_list {
height: calc(100% - 42px);
overflow-y: auto;
.regionSetting_first_listOne {
display: flex;
justify-content: space-between;
height: 40px;
padding-left: 10px;
cursor: pointer;
&[data-index=true] {
background-color: rgb(237, 248, 255);
color: #0183CC;
}
.regionSetting_first_listOneFont {
width: 164px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.regionSetting_first_listOneIcon {
margin-top: 6px;
visibility: hidden;
}
&:hover {
.regionSetting_first_listOneIcon {
visibility: visible;
}
}
}
}
}
}
}
.popovers {
.popovers_item {
border-bottom: 1px solid rgb(226, 226, 226);
cursor: pointer;
margin-bottom: 4px
}
.popovers_itemMove {
border-bottom: 1px solid rgb(226, 226, 226);
cursor: pointer;
&[data-index=true] {
pointer-events: none;
color: rgba(0, 0, 0, 0.25);
cursor: not-allowed;
}
&[data-index1='down'] {
border-bottom: none;
}
}
}