import { connect, Dispatch } from 'dva';
import {
Switch,
Button,
Pagination,
Space,
Table,
Popconfirm,
Input,
Select,
Modal,
Form,
Input,
Loading
} from 'antd';
import React, { useEffect, useState } from 'react';
import empty from '@/Images/others/empty.png';
import AddTemp from './compoments/AddTemp';
import { getGuid } from '@/utils';
import GoPreview from './compoments/GoPreview';
import SelectProduct from '@/components/SelectProduct';
import styles from './index.less';
interface Props {
dispatch: Dispatch;
searchParams: { [key: string]: any };
initialValues: { [key: string]: any };
pageNum: number;
pageSize: number;
total: number;
tempList: Array<any>;
searchLoading: boolean;
currentRow: any;
getDetailLoading: boolean;
}
const ProductParamTemp = (props: Props) => {
const {
dispatch,
searchParams,
initialValues,
pageNum,
pageSize,
total,
tempList,
searchLoading,
getDetailLoading
} = props;
// 添加模板参数弹框显隐
const [showAdd, setShowAdd] = useState<boolean>(false);
// 当前编辑的模板信息
const [currentEdit, setCurrentEdit] = useState<any>({});
// 勾选的列表
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
// 更多搜索条件显隐
const [showMore, setShowMore] = useState<boolean>(false);
// 产品目录分类(只有一级、二级)
const [catalogs, setCatalogs] = useState<Array<any>>([]);
// 产品目录分类,平铺数组
const [catalogList, setCatalogList] = useState<Array<any>>([]);
// 预览数据
const [previewData, setPreviewData] = useState<any>([]);
// 是否展示预览弹框
const [showLook, setShowLook] = useState<boolean>(false);
// 产品弹框显隐
const [showProduct, setShowProduct] = useState<boolean>(false);
// 当前产品数据(已绑定的)
const [currentProducts, setCurrentProducts] = useState<Array<any>>([]);
// 表单实例
const [forms] = Form.useForm();
// 表头
const columns: any = [
{
title: intl.formatMessage({ id: 'Template Name' }),
dataIndex: 'templateName',
align: 'center',
ellipsis: true
},
{
title: intl.formatMessage({ id: 'Category1' }),
dataIndex: 'catalogName',
align: 'center',
ellipsis: true
},
{
title: intl.formatMessage({ id: 'Remark' }),
dataIndex: 'remark',
align: 'center',
ellipsis: true
},
{
title: intl.formatMessage({ id: 'Enable Status' }),
dataIndex: 'enableStatus',
align: 'center',
ellipsis: true,
render: (_: any, record: any) => {
return (
<Switch
onChange={(e: any) => _changeAble(record, e)}
checked={record.enableStatus}
/>
);
}
},
{
title: intl.formatMessage({ id: 'Operation' }),
dataIndex: 'operation',
align: 'center',
className: styles.drag_hidden,
render: (_: any, record: any) => {
return (
<Space size={32}>
<Icon
title={intl.formatMessage({ id: 'Bulk binding products' })}
icon="bindIcon"
onClick={() => {
setCurrentEdit(record);
setTimeout(() => {
setShowProduct(true);
}, 300);
}}
/>
<Icon
title={intl.formatMessage({ id: 'Preview' })}
icon="previewIcon"
onClick={() => _goLook(record)}
/>
<Icon icon="modifyIcon" onClick={() => _getDetail(record)} />
<Popconfirm
title={intl.formatMessage({
id: 'Are you sure you want to delete it?'
})}
onConfirm={() => _delTemp(record.id)}
>
<Icon
title={intl.formatMessage({ id: 'Delete' })}
icon="deleteIcon"
/>
</Popconfirm>
</Space>
);
}
}
];
/**
* 预览
* @param record 模板数据
*/
const _goLook = (record: any) => {
setShowLook(true);
const { id } = record;
dispatch({
type: 'paramTemp/getDetail',
payload: {
id
},
callback: (data: any) => {
const { items } = data;
const newList: Array<any> =
(Array.isArray(items) &&
items.length > 0 &&
items.map((item: any) => {
return {
...item,
identifyId: getGuid()
};
})) ||
[];
setPreviewData(newList);
}
});
};
/**
* 获取详情
* @param record 模板部分信息
*/
const _getDetail = (record: any) => {
setCurrentEdit({});
dispatch({
type: 'paramTemp/getDetail',
payload: {
id: record.id
},
callback: (data: any) => {
setCurrentEdit(data);
}
});
setShowAdd(true);
};
useEffect(() => {
dispatch({
type: 'paramTemp/getCatalog',
callback: (data: Array<any>) => {
setCatalogs(_treeToTree(data));
setCatalogList(_treeToArray(data));
}
});
}, []);
useEffect(() => {
const { productIdList } = currentEdit;
if (Array.isArray(productIdList) && productIdList.length > 0) {
dispatch({
type: 'paramTemp/queryProductList',
payload: {
idList: [...productIdList],
pageNum: 1,
pageSize: 400,
isAggBomCode: false
},
callback: (res: any) => {
setCurrentProducts(res);
}
});
} else {
setCurrentProducts([]);
}
}, [currentEdit]);
/**
* 获取一二级产品目录列表
* @param data 待改造数据
* @returns 返回新的树
*/
const _treeToTree = (data: Array<any>) => {
const newTree: Array<any> =
data.map((item: any) => {
return {
...item,
title: item.productCatalogName,
key: item.id,
value: item.id,
disabled: [1].includes(item.catalogLevel) ? true : false,
children:
Array.isArray(item.childList) && item.childList.length > 0 ?
_treeToTree(item.childList) :
null
};
}) || [];
return newTree;
};
/**
*
* @param tree
* @returns
*/
const _treeToArray = (tree: Array<any>) => {
const newList: Array<any> = [];
const _getChild = (tree: Array<any>) => {
tree.forEach((item: any) => {
const { childList } = item;
newList.push(item);
if (Array.isArray(childList) && childList.length > 0) {
_getChild(childList);
}
});
};
_getChild(tree);
return newList;
};
useEffect(() => {
_getTemps();
}, [searchParams]);
/**
* 获取模板
*/
const _getTemps = () => {
dispatch({
type: 'paramTemp/getTemp',
payload: {
...searchParams
}
});
setSelectedRowKeys([]);
};
/**
* 删除模板
* @param id 模板id
*/
const _delTemp = (id: any) => {
dispatch({
type: 'paramTemp/delTemp',
payload: [id],
callback: () => {
_getTemps();
}
});
};
/**
* 切换启用状态
* @param record 当前模板信息
* @param e 组件自带属性
*/
const _changeAble = (record: any, e: any) => {
dispatch({
type: 'paramTemp/editTemp',
payload: {
id: record.id,
enableStatus: e ? 0 : 1
},
callback: () => {
_getTemps();
}
});
};
/**
* 关键字查询
* @param key 搜索关键字
*/
const _onSearch = (key: string) => {
dispatch({
type: 'paramTemp/updateState',
payload: {
searchParams: {
...searchParams,
searchKey: key
}
}
});
};
/**
* 切换分页
* @param page 页码
* @param pageSize 条数
*/
const _changePage = (page: number, size: number) => {
dispatch({
type: 'paramTemp/updateState',
payload: {
searchParams: {
...searchParams,
pageNum: page,
pageSize: size
}
}
});
};
/**
* 多条件查询
*/
const _moreSearch = () => {
const tempObj = forms.getFieldsValue();
const { enableStatus, ...left } = tempObj;
dispatch({
type: 'paramTemp/updateState',
payload: {
searchParams: {
pageNum: 1,
pageSize: searchParams.pageSize,
...left,
enableStatus: enableStatus === 'all' ? undefined : enableStatus
}
}
});
};
/**
* 重置方法
*/
const _onReset = () => {
forms.setFieldsValue({
...initialValues
});
dispatch({
type: 'paramTemp/updateState',
payload: {
searchParams: {
pageNum: 1,
pageSize: 10
}
}
});
};
/**
* 提交模板数据
*/
const submitTemp = (data: any) => {
dispatch({
type: 'paramTemp/addTemp',
payload: {
...data
},
callback: () => {
_getTemps();
setShowAdd(false);
// 重新给当前模板下的产品再换绑一次
const { id, templateId, productIdList } = currentEdit;
if (Array.isArray(productIdList) && productIdList.length > 0) {
dispatch({
type: 'paramTemp/bindTemp',
payload: {
productIdList: productIdList,
templateId,
baseId: id
},
callback: () => {
_getTemps();
}
});
}
}
});
};
/**
* 批量删除模板
*/
const _delTempMore = () => {
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: () => {
dispatch({
type: 'paramTemp/delTemp',
payload: [...selectedRowKeys],
callback: () => {
_getTemps();
}
});
}
});
};
/**
* 批量绑定
* @param data 产品列表
*/
const addProducts = (data: any) => {
console.log('data6969', data);
const { id, templateId } = currentEdit;
const ids = data.map((item: any) => item.id);
dispatch({
type: 'paramTemp/bindTemp',
payload: {
productIdList: [...ids],
templateId,
baseId: id,
clearTemplateAllBindRelation: true
},
callback: () => {
setShowProduct(false);
_getTemps();
}
});
};
return (
<div className={styles.pParamTemp}>
<div className={styles.pParamTemp_header}>
{intl.formatMessage({ id: 'Product Parameter Template' })}
</div>
<div className={styles.pParamTemp_content}>
<div className={styles.pParamTemp_btns}>
<Space size={4} className={styles.pParamTemp_btns_left}>
<Button
type="primary"
onClick={() => {
setCurrentEdit({});
setShowAdd(true);
}}
>
{intl.formatMessage({ id: 'Add2' })}
</Button>
<Button
onClick={() => _delTempMore()}
disabled={selectedRowKeys.length < 1}
>
{intl.formatMessage({ id: 'Delete' })}
</Button>
<Button onClick={_getTemps}>
{intl.formatMessage({ id: 'Refresh1' })}
</Button>
</Space>
<Space>
<Input
onSearch={_onSearch}
onEnterPress={_onSearch}
placeholder={intl.formatMessage({
id: 'Please enter search criteria'
})}
/>
<Icon
icon="selectionIcon"
onClick={() => setShowMore(!showMore)}
/>
</Space>
</div>
{showMore && (
<Form
form={forms}
layout="inline"
className={styles.pParamTemp_forms}
labelAlign="left"
>
<Form.Item
label={intl.formatMessage({ id: 'Template Name' })}
name="templateName"
>
<Input />
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'Category1' })}
name="catalogName"
>
<Input />
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'Remark' })}
name="remark"
>
<Input />
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'Enable Status' })}
name="enableStatus"
initialValue={'all'}
>
<Select>
<Select.Option key="all" value="all">
{intl.formatMessage({ id: 'All' })}
</Select.Option>
<Select.Option key={1} value={1}>
{intl.formatMessage({ id: 'Enable' })}
</Select.Option>
<Select.Option key={0} value={0}>
{intl.formatMessage({ id: 'Disable' })}
</Select.Option>
</Select>
</Form.Item>
<div className={styles.pParamTemp_forms_emptyOne} />
<Space className={styles.pParamTemp_forms_btns}>
<Button type="primary" onClick={_moreSearch}>
{intl.formatMessage({ id: 'Search1' })}
</Button>
<Button onClick={_onReset}>
{intl.formatMessage({ id: 'Reset' })}
</Button>
</Space>
</Form>
)}
<div className={styles.pParamTemp_tables}>
<Loading loading={searchLoading}>
<Table
className={styles.pParamTemp_table}
dataSource={tempList}
columns={columns}
size="small"
bordered
rowKey="id"
scroll={{ y: 'calc(100% - 40px)' }}
rowSelection={{
selectedRowKeys,
onChange: (selectedRowKeys: React.Key[]) => {
setSelectedRowKeys(selectedRowKeys);
}
}}
onRow={(record: any) => {
return {
onDoubleClick: () => {
_getDetail(record);
}
};
}}
pagination={false}
locale={{
emptyText: (
<div
className="empty"
style={{
height: '100%',
paddingTop: '10%'
}}
>
<img src={empty} />
<div>{intl.formatMessage({ id: 'No data' })}</div>
</div>
)
}}
/>
<Pagination
className={styles.pParamTemp_page}
showTotal={(total: number) =>
intl.formatMessage({ id: 'Total xx items' }, { total: total })
}
current={pageNum}
pageSize={pageSize}
total={total}
showSizeChanger
showQuickJumper
onChange={_changePage}
/>
</Loading>
</div>
</div>
{showAdd && (
<AddTemp
// <ForProduct
currentEdit={currentEdit}
// setCurrentEdit={setCurrentEdit}
onCancel={() => setShowAdd(false)}
submitTemp={submitTemp}
catalogs={catalogs}
catalogList={catalogList}
setPreviewData={setPreviewData}
previewData={previewData}
setShowLook={setShowLook}
showLook={showLook}
getDetailLoading={getDetailLoading}
/>
)}
{showLook && (
<GoPreview
onCancel={() => setShowLook(false)}
data={previewData}
getDetailLoading={getDetailLoading}
/>
)}
{showProduct && (
<SelectProduct
onCancel={() => setShowProduct(false)}
onConfirm={addProducts}
selectType="multi"
initList={currentProducts || undefined}
bottomText="binded"
isAggBomCode={false}
/>
)}
</div>
);
};
export default connect(({ paramTemp, loading }: any) => {
const { searchParams, tempList, pageNum, pageSize, total, initialValues } =
paramTemp;
return {
searchParams,
initialValues,
tempList,
pageNum,
pageSize,
total,
searchLoading: loading.effects['paramTemp/getTemp'] || false,
getDetailLoading: loading.effects['paramTemp/getDetail'] || false
};
})(ProductParamTemp);
.pParamTemp {
height: 100%;
width: 100%;
padding: 10px;
border-radius: 8px;
background-color: white;
:global {
.ant4-form-item-label {
width: 108px !important;
}
.ant-select {
width: 180px;
}
.ant4-form-item {
margin-bottom: 12px !important;
}
.ant-switch-checked {
background: #70b603;
}
}
.pParamTemp_header {
height: 30px;
width: 100%;
border-bottom: 1px solid rgb(234, 234, 234);
font-size: 14px;
color: rgba(0, 0, 0, 0.5);
padding-left: 10px;
}
.pParamTemp_content {
width: 100%;
height: calc(100% - 40px);
flex-direction: column;
display: flex;
.pParamTemp_btns {
display: flex;
justify-content: space-between;
margin-top: 10px;
padding-right: 10px;
.pParamTemp_btns_left {
button {
width: 80px;
height: 30px;
padding: 0;
}
}
}
.pParamTemp_forms {
margin-top: 10px;
position: relative;
padding: 20px 20px 8px;
background-color: #f7f8fa;
.pParamTemp_forms_emptyOne {
width: 190px;
height: 32px;
visibility: hidden;
margin-bottom: 12px;
}
.pParamTemp_forms_btns {
position: absolute;
right: 10px;
bottom: 20px;
height: 32px;
button {
width: 80px;
height: 30px;
}
}
}
.pParamTemp_tables {
flex: 1 1 auto;
overflow-y: hidden;
margin-top: 10px;
:global {
.ant-table-thead {
.ant-table-cell {
text-align: center !important;
}
}
.ant-spin-nested-loading,
.ant-spin-container,
.ant-table,
.ant-table-container,
.ant-table-content {
width: 100%;
height: 100%;
}
.ant-table-container {
background-color: #f7f8fa;
}
.ant-table-row {
background-color: #fff;
}
}
.pParamTemp_table {
height: calc(100% - 42px);
}
.pParamTemp_page {
margin-top: 10px;
text-align: center;
}
}
}
}
Tabs组件样式
:global {
.ant-tabs-tab {
width: 170px;
text-align: center;
height: 40px;
margin-left: 0;
}
.ant-tabs-tab-btn {
margin: auto;
&:hover {
color: #0183cc;
}
}
.ant-tabs-tab-active .ant-tabs-tab-btn {
margin: auto;
color: #0183cc;
}
.ant-tabs-nav {
margin: 0;
}
.ant-tabs-ink-bar {
background: #0183cc;
}
.ant-tabs>.ant-tabs-nav {
position: relative;
display: flex;
flex: none;
align-items: center;
margin: 0;
}
}