columns.js 文件是表格的标题
import moment from ‘moment’;
const columns = [
{
title: ‘Category’,
dataIndex: ‘onlineTaxonomyName’,
key: ‘Category’,
sorter: true
},
{
title: ‘Offline Category’,
dataIndex: ‘offlineTaxonomyName’,
key: ‘Offline Category’
},
{
title: ‘Hierarchy’,
dataIndex: ‘hierarchy’,
key: ‘Hierarchy’
},
{
title: ‘Date Added’,
dataIndex: ‘createdTime’,
key: ‘Date Added’,
sorter: true,
render: createdTime => {
return createdTime
? moment(parseInt(createdTime)).format(‘MMM D,YYYY HH:mm:ss’)
: ‘-’;
}
},
{
title: ‘Added By’,
dataIndex: ‘email’,
key: ‘Added By’
},
{
title: ‘’,
key: ‘action’,
width: ‘1px’
}
];
export default columns;
dropList.js 文件select的option的内容
const dropList = [
{
// label: 'Hierarchy',
name: 'Hierarchy',
placeholder: 'Hierarchy',
options: [
{
option: 'Division',
value: 'Division'
},
{
option: 'Group',
value: 'Group'
},
{
option: 'Dept',
value: 'Dept'
},
{
option: 'Class',
value: 'Class'
},
{
option: 'Subclass',
value: 'Subclass'
}
]
}
];
export default dropList;
表格的数据
import React, { useState, useEffect, useRef } from 'react';
import { Modal, message } from 'antd';
import axios from '@/api';
import SearchInput from '@/components/SearchInput/SearchInput';
import TableFilterBar from '@/components/BasicTable/TableFilterBar/TableFilterBar';
import BasicTable from '@/components/BasicTable/BasicTable';
import BasePagination from '../../../mpe/components/BasePagination/BasePagination';
import {
Section,
Header,
TableStyle,
ButtonAdd,
DivFlex,
DeleteImg
} from './MerchandiseAndHierarchy.style.js';
import columns from './columns.js';
import dropList from './dropList.js';
import AddModals from './AddModal.jsx';
import IconTrash from './assets/trash.svg';
function MerchandiseAndHierarchy() {
const [pagination, setPagination] = useState({
pageNum: 1,
pageSize: 10,
total: 0,
sort: '',
field: ''
});
const [totalItem, setTotalItem] = useState('');
const [tableList, setTableList] = useState([]);
const [loading, setLoading] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
const [deleteModal, setDeleteModal] = useState(false);
const [inputValue, setInputValue] = useState('');
const [hierarchy, setHierarchy] = useState('');
const [currentModalRecordId, setCurrentModalRecordId] = useState(0);
const addModalsRef = useRef(null);
const [deleteRecord, setDeleteRecord] = useState('');
const [distance, setDistance] = useState(0);
const [movingDistance, setmovingDistance] = useState(-72);
// 添加数据成功的弹框
function success() {
message.success({
content: `Successfully added, You can view the relevant list.`,
className: 'custom-class',
style: {
marginTop: '20vh'
}
});
}
function handleFormSubmit(value) {
const hierarchyValue = value?.Hierarchy ?? '';
setHierarchy(hierarchyValue);
}
useEffect(() => {
const { pageSize } = pagination;
getList(1, pageSize);
}, [hierarchy]);
const SearchInputEvent = e => {
setInputValue(e);
};
const onPressEnter = e => {
setInputValue(inputValue);
const { pageNum, pageSize } = pagination;
getList(pageNum, pageSize);
};
// 表格的排序
function getList(pageNum, pageSize, sort, field) {
setLoading(true);
axios
.get(
`${
window.ENV.IFR_API
}/online-offline-mapping/list/page?pageNum=${pageNum}&pageSize=${pageSize}&category=${inputValue}&hierarchy=${hierarchy}&orderBy=${
sort ? sort : ''
}&field
=${field ? field : ''}`
)
.then(res => {
setTableList(res.data.list);
setTotalItem(res.data.totalItem);
setPagination({
...pagination,
pageNum: pageNum,
pageSize: pageSize,
total: res.data.totalItem
});
setLoading(false);
});
}
// 删除当前行的数据
async function deleteData() {
const res = await axios.delete(
`${window.ENV.IFR_API}/online-offline-mapping/${currentModalRecordId}`
);
if (Number(res?.data?.code) === 200) {
const { pageNum, pageSize } = pagination;
if (pageNum > 1) {
getList(pageNum, pageSize);
} else {
getList(1, pageSize);
}
setLoading(false);
setDeleteModal(false);
message.success('Delete current data successfully');
} else {
message.error('Failed to delete current data');
}
}
async function postData() {
const postDataTree = addModalsRef?.current?.beatFlatTreeData;
const res = await axios.post(
`${window.ENV.IFR_API}/online-offline-mapping/add`,
postDataTree
);
const postDat = res || [];
if (postDat?.data.code == 200) {
setModalVisible(false);
const { pageSize } = pagination;
getList(1, pageSize);
setLoading(false);
success();
} else {
message.error('Failed add, Please try again.');
}
}
useEffect(() => {
const { pageNum, pageSize } = pagination;
getList(pageNum, pageSize);
}, []);
function changePageNum(pageNum) {
const { pageSize } = pagination;
getList(pageNum, pageSize);
}
function changePageSize(pageSize) {
getList(1, pageSize);
}
const onclickDelete = deleteRecord => {
setLoading(false);
setDeleteModal(true);
setCurrentModalRecordId(deleteRecord);
};
const onOkPost = () => {
postData();
};
const onChangeTableSort = (pagination, filters, sorter) => {
const { pageNum, pageSize } = pagination;
if (sorter.field) {
pagination.field = sorter.field;
pagination.sort = sorter.order === 'ascend' ? 'asc' : 'desc';
setPagination({
sort: pagination.sort,
field: pagination.field
});
} else {
pagination.field = sorter.field;
pagination.sort = 'asc';
setPagination({
sort: pagination.sort,
field: pagination.field
});
}
if (pageNum > 1) {
getList(pageNum, pageSize, pagination.sort, pagination.field);
} else {
getList(1, pageSize, pagination.sort, pagination.field);
}
};
const onClickRow = record => {
return {
onMouseEnter: () => {
let currentClassName = 'uuid-' + record.id;
let slider = document.getElementsByClassName(currentClassName)[0];
let perIndexChild = slider.offsetTop;
setDistance(perIndexChild);
setmovingDistance(0);
setDeleteRecord(record.id);
},
onMouseLeave: () => {
setmovingDistance(-75);
}
};
};
return (
Merchandise and Hierarchy
<>
setModalVisible(true)}>Add Mapping
setModalVisible(false)}
>
>
handleFormSubmit(value)}
style={{
marginTop: '20px'
}}
/>
{
let className = 'light-row' + ' uuid-' + record.id;
if (index % 2 === 1) className = 'dark-row' + ' uuid-' + record.id;
return className;
}}
>
{
setmovingDistance(0);
}}
onMouseLeave={() => {
setmovingDistance(-75);
}}
>
onclickDelete(deleteRecord)}
className="deleteImg"
/>
changePageSize(value)}
changePageNum={value => changePageNum(value)}
showSizeChange={true}
>
setDeleteModal(false)}
style={{ borderTop: 'unset' }}
className={'ModalDelete'}
>
Please confirm to delete the mapping?
);
}
export default MerchandiseAndHierarchy;
styled component写样式
import styled from '@emotion/styled/macro';
export const Section = styled.div`
font-family: Nunito Sans;
font-style: normal;
padding: 33px 40px 151px 40px;
background-color: white;
position: relative;
min-height: 100%;
.ant-modal-title {
color: 1b1b1b;
}
.ModalDelete {
.ant-modal-content {
.ant-modal-footer {
border-top: unset !important;
}
}
}
.ant-modal-content {
width: 672px;
height: 612px;
}
.ant-spin-nested-loading > div > .ant-spin {
top: 230px;
}
`;
export const Header = styled.div`
font-family: ibm-plex-serif;
font-size: 32px;
color: #000000;
letter-spacing: 0;
font-weight: 900;
line-height: 40px;
margin-bottom: 30px;
`;
export const ButtonAdd = styled.div`
width: 136px;
height: 48px;
background: #e9425b;
color: #ffffff;
text-align: center;
line-height: 48px;
border-radius: 28px;
font-size: 14px;
cursor: pointer;
`;
export const DivFlex = styled.div`
display: flex;
just-content: space-between;
.ant-modal-header {
background: #f2f2f2;
}
.ant-modal-title {
color: #1b1b1b;
font-weight: Bold;
}
`;
export const TableStyle = styled.div`
position: relative;
.ant-table-tbody {
> tr.ant-table-row:hover {
background: #eff7fb;
width: 100%;
}
}
.ant-table-tbody {
> tr.ant-table-row:hover {
> td {
background: #eff7fb;
}
}
}
tbody > tr > td:first-of-type:hover {
text-decoration: underline;
}
.css-begbtt-Section .dark-row {
background-color: unset;
}
`;
export const DeleteImg = styled.div`
width: 72px;
height: 48px;
background: #eff7fb;
position: absolute;
right: -72px;
.deleteImg {
width: 72px;
height: 24px;
cursor: pointer;
margin-top: 12px;
}
`;
AddModal.jsx 弹框添加数据
import React, {
useState,
useEffect,
Fragment,
useImperativeHandle,
forwardRef
} from 'react';
import axios from '@/api';
import { AddBox, BoxLeft, BoxRight, LoadingBox } from './AddModal.style.js';
import { Tree, Spin } from 'antd';
export default forwardRef((props, ref) => {
const [onlineTaxonomyId, setOnlineTaxonomyId] = useState('');
const [onlineTaxonomyName, setOnlineTaxonomyName] = useState('');
const [data, setResData] = useState([]);
const [treeDataCheckout, setTreeDataCheckout] = useState([]);
const [selectedKeys, setSelectedKeys] = useState([]);
const [checkedKeys, setCheckedKeys] = useState();
const [beatFlatTreeData, setBeatFlatTreeData] = useState();
useImperativeHandle(ref, () => ({
beatFlatTreeData
}));
const loopTree = data =>
data.map(item => {
if (item.children) {
return {
title: item.taxonomyName,
key: item.taxonomyId + ' ' + item.taxonomyName + ' ' + item.createdTime,
hierarchy: item.hierarchy,
// path: item.path,
children: loopTree(item.children)
// children: []
};
}
return {
title: item.taxonomyName,
key: item.taxonomyId + ' ' + item.taxonomyName + ' ' + item.createdTime,
hierarchy: item.hierarchy
// path: item.path,
};
});
async function getTreeData() {
const res = await axios.get(
`${window.ENV.IFR_API}/listing/category/tree?taxonomyId=45&depth=3&platform=Web`
);
const list = [res?.data?.data] ?? [];
setResData(loopTree(list));
}
async function getTreeDataCheckout() {
const res = await axios.get(
`${window.ENV.IFR_API}/offline-taxonomy/full-tree?taxonomyId=0&depth=3&hierarchy=Root`
);
const resData = [res?.data.data] ?? [];
setTreeDataCheckout(loopTree(resData));
}
useEffect(() => {
getTreeData();
getTreeDataCheckout();
}, []);
const onCheck = (checkedKeysValue, title) => {
let beatFlatTreeData = [];
const BeatFlat = (treeData, id) => {
treeData &&
treeData.forEach(val => {
if (treeData.children && treeData.children.length) {
BeatFlat(val.children, id);
}
beatFlatTreeData.push({
onlineTaxonomyId: onlineTaxonomyId,
onlineTaxonomyName: onlineTaxonomyName,
offlineTaxonomyName: val?.title,
offlineTaxonomyId: val?.key?.split(' ')[0],
hierarchy: val.hierarchy
});
});
};
BeatFlat(title?.checkedNodes);
setBeatFlatTreeData(beatFlatTreeData);
setCheckedKeys(checkedKeysValue);
};
const onSelect = (selectedKeysValue, info) => {
const onlineTaxonomyName = info?.node?.title;
const onlineTaxonomyId = info?.node?.key && info?.node?.key.split(' ')[0];
setOnlineTaxonomyId(onlineTaxonomyId);
setOnlineTaxonomyName(onlineTaxonomyName);
setSelectedKeys(selectedKeysValue);
};
return (
<>
{data.length > 0 ? (
) : (
)}
{/*
function(checkedKeys, e:{checked: bool, checkedNodes, node, event, halfCheckedKeys})
*/}
{treeDataCheckout.length > 0 ? (
) : (
)}
>
);
});
AddModal.style.js 弹框的样式
import styled from '@emotion/styled/macro';
export const AddBox = styled.div`
width: 624px;
height: 422px;
display: flex;
> div {
width: 300px;
height: 422px;
border: 1px solid #f2f2f2;
border-radius: 8px;
overflow-y: auto;
overflow-x: hidden;
}
`;
export const BoxLeft = styled.div`
margin-right: 24px;
`;
export const BoxRight = styled.div``;
export const LoadingBox = styled.div`
margin: 164px 0;
margin-bottom: 20px;
padding: 30px 50px;
text-align: center;
border-radius: 4px;
`;
是把数据牌平,
const loopTree = data =>
data.map(item => {
if (item.children) {
return {
title: item.taxonomyName,
key: item.taxonomyId + ' ' + item.taxonomyName + ' ' + item.createdTime,
hierarchy: item.hierarchy,
// path: item.path,
children: loopTree(item.children)
// children: []
};
}
return {
title: item.taxonomyName,
key: item.taxonomyId + ' ' + item.taxonomyName + ' ' + item.createdTime,
hierarchy: item.hierarchy
// path: item.path,
};
});
后端的数据格式
[
{
"taxonomyId": "4724531",
"code": "20000055",
"taxonomyName": "New Arrivals",
"parentTaxonomyId": "45",
"parentTaxonomyCode": "Categories",
"icon": "",
"image": "https://imgproxy.dev.platform.michaels.com/XXTpt9MjeIKtJwhEo-W6WCFk1c9-K_Ll4qb5g7o5vco/aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Ntcy1mZ20tZGV2MDAvNTYzMzYxNDM4Nzc2NDY0MTc5Mg.jpg",
"channel": 1,
"isActive": true,
"isLeaf": true,
"isTranslateComplete": true,
"isChain": true,
"isLanding": true,
"type": 3,
"onlineBegin": null,
"onlineEnd": null,
"keywords": "",
"metaDescription": "Browse all of our new arrivals across all categories, including new craft supplies, frames, kids’ activities, and party supplies. Shop online for same-day delivery, curbside pickup, or at a Michaels near you.",
"seoHeadline": "New Arrivals | Michaels",
"seoUrl": "",
"path": "root//Shop Categories//New Arrivals",
"parentTaxonomyPath": "root//Shop Categories",
"urlPath": "root//shop-categories//new-arrivals",
"urlCode": "new-arrivals",
"sort": 0,
"filters": "",
"description": "",
"siteMerchantDescription": "New Arrivals",
"siteMerchantOnline": true,
"isShowWeb": true,
"isShowMobile": false,
"siteMerchantShowSubCategoriesInMenu": true,
"mkrPlanCommissionRate": null,
"mkrPlusPlanCommissionRate": null,
"createdBy": "0",
"createdTime": "1619392287000",
"updatedBy": "5185569240601894912",
"updatedTime": "1630401236199",
"version": null,
"platform": "Web",
"isDeleted": false,
"isBottom": false,
"sortBy": 4,
"children": []
},
{
"taxonomyId": "5145631",
"code": "20000591",
"taxonomyName": "Cricut",
"parentTaxonomyId": "45",
"parentTaxonomyCode": "Categories",
"icon": "",
"image": "https://imgproxy.dev.platform.michaels.com/XXTpt9MjeIKtJwhEo-W6WCFk1c9-K_Ll4qb5g7o5vco/aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Ntcy1mZ20tZGV2MDAvNTM2Mjg3NTc5ODUwMjY0NTc2MA.jpg",
"channel": 1,
"isActive": true,
"isLeaf": false,
"isTranslateComplete": false,
"isChain": false,
"isLanding": true,
"type": 1,
"onlineBegin": null,
"onlineEnd": null,
"keywords": "wre",
"metaDescription": "Create personalized crafts with Cricut die-cutting machines, tools, and accessories. Shop online for same-day delivery, curbside pickup, or at a Michaels near you for the biggest Cricut destination in the world.",
"seoHeadline": "Cricut Machine, Tools & Accessories | Michaels",
"seoUrl": "",
"path": "root//Shop Categories//Cricut",
"parentTaxonomyPath": "root//Shop Categories",
"urlPath": "root//shop-categories//cricut",
"urlCode": "cricut",
"sort": 1,
"filters": "",
"description": "rewre",
"siteMerchantDescription": "Cricut",
"siteMerchantOnline": true,
"isShowWeb": true,
"isShowMobile": true,
"siteMerchantShowSubCategoriesInMenu": true,
"mkrPlanCommissionRate": null,
"mkrPlusPlanCommissionRate": null,
"createdBy": "0",
"createdTime": "1619312900000",
"updatedBy": "5185569240601894912",
"updatedTime": "1630311120302",
"version": null,
"platform": "All",
"isDeleted": false,
"isBottom": true,
"sortBy": 6,
"children": [
{
"taxonomyId": "5183518",
"code": "20000660",
"taxonomyName": "Cricut Joy",
"parentTaxonomyId": "5145631",
"parentTaxonomyCode": "20000591",
"icon": "",
"image": "",
"channel": 1,
"isActive": false,
"isLeaf": false,
"isTranslateComplete": false,
"isChain": false,
"isLanding": false,
"type": 2,
"onlineBegin": null,
"onlineEnd": null,
"keywords": "",
"metaDescription": "",
"seoHeadline": "",
"seoUrl": "",
"path": "root//Shop Categories//Cricut//Cricut Joy",
"parentTaxonomyPath": "root//Shop Categories//Cricut",
"urlPath": "root//shop-categories//cricut//cricut-joy",
"urlCode": "cricut-joy",
"sort": 0,
"filters": "",
"description": "",
"siteMerchantDescription": "Cricut",
"siteMerchantOnline": true,
"isShowWeb": true,
"isShowMobile": true,
"siteMerchantShowSubCategoriesInMenu": true,
"mkrPlanCommissionRate": null,
"mkrPlusPlanCommissionRate": null,
"createdBy": "0",
"createdTime": "1619312900000",
"updatedBy": "0",
"updatedTime": "1628837533619",
"version": null,
"platform": "All",
"isDeleted": false,
"isBottom": false,
"sortBy": null,
"children": [
{
"taxonomyId": "5183527",
"code": "20000667",
"taxonomyName": "Cricut Joy Insert Cards",
"parentTaxonomyId": "5183518",
"parentTaxonomyCode": "20000660",
"icon": "",
"image": "",
"channel": 1,
"isActive": false,
"isLeaf": true,
"isTranslateComplete": false,
"isChain": false,
"isLanding": false,
"type": 2,
"onlineBegin": null,
"onlineEnd": null,
"keywords": "",
"metaDescription": "",
"seoHeadline": "",
"seoUrl": "",
"path": "root//Shop Categories//Cricut//Cricut Joy//Cricut Joy Insert Cards",
"parentTaxonomyPath": "root//Shop Categories//Cricut//Cricut Joy",
"urlPath": "root//shop-categories//cricut//cricut-joy//cricut-joy-insert-cards",
"urlCode": "cricut-joy-insert-cards",
"sort": 0,
"filters": "",
"description": "",
"siteMerchantDescription": "Cricut",
"siteMerchantOnline": true,
"isShowWeb": true,
"isShowMobile": true,
"siteMerchantShowSubCategoriesInMenu": true,
"mkrPlanCommissionRate": null,
"mkrPlusPlanCommissionRate": null,
"createdBy": "0",
"createdTime": "1619392287000",
"updatedBy": "0",
"updatedTime": "1628837534967",
"version": null,
"platform": "All",
"isDeleted": false,
"isBottom": false,
"sortBy": null,
"children": []
},
{
"taxonomyId": "5183525",
"code": "20000665",
"taxonomyName": "Cricut Joy Cutting Machine",
"parentTaxonomyId": "5183518",
"parentTaxonomyCode": "20000660",
"icon": "",
"image": "",
"channel": 1,
"isActive": false,
"isLeaf": true,
"isTranslateComplete": false,
"isChain": false,
"isLanding": false,
"type": 2,
"onlineBegin": null,
"onlineEnd": null,
"keywords": "",
"metaDescription": "",
"seoHeadline": "",
"seoUrl": "",
"path": "root//Shop Categories//Cricut//Cricut Joy//Cricut Joy Cutting Machine",
"parentTaxonomyPath": "root//Shop Categories//Cricut//Cricut Joy",
"urlPath": "root//shop-categories//cricut//cricut-joy//cricut-joy-cutting-machine",
"urlCode": "cricut-joy-cutting-machine",
"sort": 1,
"filters": "",
"description": "",
"siteMerchantDescription": "Cricut",
"siteMerchantOnline": true,
"isShowWeb": true,
"isShowMobile": true,
"siteMerchantShowSubCategoriesInMenu": true,
"mkrPlanCommissionRate": null,
"mkrPlusPlanCommissionRate": null,
"createdBy": "0",
"createdTime": "1619392287000",
"updatedBy": "0",
"updatedTime": "1623998092000",
"version": null,
"platform": "All",
"isDeleted": false,
"isBottom": false,
"sortBy": null,
"children": []
},
{
"taxonomyId": "5183526",
"code": "20000666",
"taxonomyName": "Cricut Joy Materials, Mats & Tools",
"parentTaxonomyId": "5183518",
"parentTaxonomyCode": "20000660",
"icon": "",
"image": "",
"channel": 1,
"isActive": false,
"isLeaf": false,
"isTranslateComplete": false,
"isChain": false,
"isLanding": false,
"type": 2,
"onlineBegin": null,
"onlineEnd": null,
"keywords": "",
"metaDescription": "",
"seoHeadline": "",
"seoUrl": "",
"path": "root//Shop Categories//Cricut//Cricut Joy//Cricut Joy Materials, Mats & Tools",
"parentTaxonomyPath": "root//Shop Categories//Cricut//Cricut Joy",
"urlPath": "root//shop-categories//cricut//cricut-joy//cricut-joy-materials-mats-tools",
"urlCode": "cricut-joy-materials-mats-tools",
"sort": 2,
"filters": "",
"description": "",
"siteMerchantDescription": "Cricut",
"siteMerchantOnline": true,
"isShowWeb": true,
"isShowMobile": true,
"siteMerchantShowSubCategoriesInMenu": true,
"mkrPlanCommissionRate": null,
"mkrPlusPlanCommissionRate": null,
"createdBy": "0",
"createdTime": "1619312900000",
"updatedBy": "0",
"updatedTime": "1628837537430",
"version": null,
"platform": "All",
"isDeleted": false,
"isBottom": false,
"sortBy": null,
"children": []
},
]