Commit 6ae2b521 authored by 张子雨's avatar 张子雨

Merge branch 'feature/distributionArea' into 'master'

Feature/distribution area

See merge request !28
parents 216c4a93 255e09eb
......@@ -156,6 +156,12 @@ export default {
icon: 'smile',
component: './GoodsManage',
},
{
path: '/distributionArea',
name: 'distributionArea',
icon: 'smile',
component: './distributionArea',
},
// {
// path: '/GoodsManage-new',
// name: 'GoodsManageNew',
......
......@@ -6,7 +6,7 @@ const envAPi = {
kdspOpApi: 'https://kdsp-operation-test2.liangkebang.net',
kdspApi: 'https://sc-op-api-test2.liangkebang.net',
goodsApi: 'https://sc-op-api-test2.liangkebang.net',
// goodsApi: '//192.168.28.107:7000',
// goodsApi: '//192.168.188.111:7000',
prologueDomain: 'https://mall-test2.liangkebang.net',
qiniuHost: 'https://appsync.lkbang.net',
opapiHost: 'https://opapi-test2.liangkebang.net',
......
{
"compilerOptions": {
"jsx": "react",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"baseUrl": ".",
......
This diff is collapsed.
......@@ -3,7 +3,6 @@ import React, { Component } from 'react';
import { connect } from 'dva';
import styles from '../style.less';
import { stateList } from '../staticdata';
// import { uploadFile } from '../service';
const FormItem = Form.Item;
const { Option } = Select;
......@@ -34,6 +33,10 @@ class goodsManage extends Component {
this.props.addSpu();
};
setArea = isAll => {
this.props.setArea(isAll);
};
render() {
const {
form: { getFieldDecorator, getFieldValue },
......@@ -141,6 +144,12 @@ class goodsManage extends Component {
</Button>
</FormItem>
<FormItem style={{ float: 'right' }}>
<Button type="primary" className={styles.button} onClick={() => this.setArea(1)}>
全部配送不支持配置区域
</Button>
<Button type="primary" className={styles.button} onClick={() => this.setArea(0)}>
批量设置不支持配送区域
</Button>
<Button type="primary" className={styles.button} onClick={this.addSpu}>
新增商品
</Button>
......
import { Form, Modal, Input, Select, Cascader, Tag, notification } from 'antd';
import { da } from 'date-fns/locale';
import React, { useState, useEffect } from 'react';
import { getTemplate } from '../service';
const { Option } = Select;
const TempleatModal = props => {
const {
visible,
form: { getFieldDecorator, validateFields, resetFields },
selectedRowKeys,
templateList,
isALL,
} = props;
const formItemLayout = {
labelCol: {
span: 5,
},
wrapperCol: {
span: 16,
},
};
const handleOk = async () => {
console.log(props);
validateFields(async (error, fieldsValue) => {
if (!error) {
const data = await getTemplate({
isAll: isALL,
skuIdList: selectedRowKeys,
templateId: fieldsValue.templateId.key,
});
if (data.businessCode === '0000') {
notification.success({ message: '配置成功!' });
resetFields();
props.onCancel();
}
}
});
};
useEffect(() => {}, []);
return (
<Modal
title={isALL ? '全部设置不支持配送区域' : '批量设置不支持配送区域'}
visible={visible}
width="500px"
onCancel={props.onCancel}
onOk={() => handleOk()}
>
{!isALL && <p>已选择{selectedRowKeys.length}个商品</p>}
<Form {...formItemLayout}>
<Form.Item label="选择模板">
{getFieldDecorator('templateId', {
rules: [{ required: true, message: '请选择模板!' }],
})(
<Select placeholder="请选择模板" labelInValue allowClear>
{templateList.map(item => (
<Option label={item.templateName} value={item.id} key={item.id}>
{item.templateName}
</Option>
))}
</Select>,
)}
</Form.Item>
</Form>
</Modal>
);
};
export default Form.create()(TempleatModal);
......@@ -601,7 +601,7 @@ class goodsManage extends Component {
})(
<Input
style={{ width: 690 }}
maxLength="100"
maxLength={100}
placeholder="请输入商品名称"
allowClear
/>,
......
......@@ -7,12 +7,12 @@ import styles from './style.less';
import LocalStroage from '@/utils/localStorage';
import configApi from '../../../config/env.config';
import UpdateStock from './UpdateStock';
import { spuDetail, categoryList, getVirtualCategory } from './service';
import { spuDetail, categoryList, getVirtualCategory, getTemplateList } from './service';
import LogModal from './LogModal';
import CreateModal from './createModal';
import { column, JDSHOPID } from './staticdata';
import SearchForm from './SearchForm';
import TempleatModal from './TempleatModal';
@connect(({ goodsManage }) => ({
goodsManage,
......@@ -28,10 +28,13 @@ class goodsManage extends Component {
logVisible: false,
previewVisible: false,
createVisible: false, // 新增or编辑普通商品modal
selectedRowKeys: [],
updateStockVisible: false,
initData: {},
createloading: false,
templeatModalVisible: false,
selectedRowKeys: [],
isAll: 0,
templateList: [],
};
currentLog = null;
......@@ -85,10 +88,6 @@ class goodsManage extends Component {
);
};
onSelectChange = selectedRowKeys => {
this.setState({ selectedRowKeys });
};
onReset = () => {
this.setState({
pageNo: 1,
......@@ -173,6 +172,23 @@ class goodsManage extends Component {
});
};
setArea = async isAll => {
if (!this.state.selectedRowKeys.length && !isAll) {
notification.error({ message: '请选择商品' });
return;
}
const data = await getTemplateList();
if (data.code === '0000' && data.data.length) {
this.setState({
templeatModalVisible: true,
isAll,
templateList: data.data,
});
} else {
notification.error({ message: '暂无模板数据,请先添加模板' });
}
};
filterShopList = (list = [], isEdit) =>
list.filter(item => isEdit || !JDSHOPID.includes(item.id));
......@@ -235,10 +251,21 @@ class goodsManage extends Component {
}
};
onSelectChange = selectedRowKeys => {
this.setState({
selectedRowKeys,
});
};
render() {
const {
goodsManage: { tableData = {} },
} = this.props;
const rowSelection = {
selectedRowKeys: this.state.selectedRowKeys,
onChange: this.onSelectChange,
};
const { pageNo, pageSize, selectedRowKeys } = this.state;
return (
<PageHeaderWrapper>
......@@ -248,13 +275,13 @@ class goodsManage extends Component {
handleSearch={this.handleSearch}
onReset={this.onReset}
onLoad={this.onLoad}
// selectedRowKeys={this.state.selectedRowKeys}
onRef={ref => {
this.searchForm = ref;
}}
treeData={this.state.treeData}
shopList={this.shopList}
addSpu={() => this.setState({ createVisible: true, initData: {} })}
setArea={isALL => this.setArea(isALL)}
/>
</Card>
<Spin spinning={this.state.loading}>
......@@ -266,6 +293,7 @@ class goodsManage extends Component {
pagination={false}
className={styles.tabletop}
scroll={{ x: '100%', y: 500 }}
rowSelection={rowSelection}
/>
</Spin>
<br />
......@@ -325,6 +353,16 @@ class goodsManage extends Component {
info={this.state.priceInfo}
onCancel={this.cancel}
/>
<TempleatModal
visible={this.state.templeatModalVisible}
selectedRowKeys={this.state.selectedRowKeys}
onCancel={() => {
this.setState({ templeatModalVisible: false, selectedRowKeys: [] });
this.handleSearch();
}}
isALL={this.state.isAll}
templateList={this.state.templateList}
/>
</Spin>
</PageHeaderWrapper>
);
......
......@@ -148,3 +148,21 @@ export async function getVirtualCategory() {
});
return data;
}
// sku绑定模板
export async function getTemplate(params) {
const data = await request.post('/api/kdsp/sku/template', {
data: params,
prefix: goodsApi,
});
return data;
}
// 不配送区域模板列表
export async function getTemplateList(params) {
const data = await request.post('/api/kdsp/template/list', {
data: stringify(params),
prefix: goodsApi,
headers,
});
return data;
}
......@@ -86,6 +86,7 @@ export function column() {
align: 'center',
dataIndex: 'skuName',
},
{
title: '供应商价格',
dataIndex: 'marketPrice',
......@@ -124,6 +125,13 @@ export function column() {
);
},
},
{
title: '不支持配送区域',
dataIndex: 'areaTemplateName',
key: 'areaTemplateName',
width: 200,
align: 'center',
},
{
title: '审核状态',
dataIndex: 'stateDesc',
......
import { Form, Modal, Input, Select, Cascader, Tag, notification } from 'antd';
import React, { useState, useEffect } from 'react';
import RcTreeSelect from 'rc-tree-select';
import { el } from 'date-fns/locale';
import { areaList, getAddTemplate, forbiddenAddress } from '../services';
const { Option } = Select;
const AddAreaModal = props => {
const {
visible,
form: { getFieldDecorator, validateFields, resetFields },
templateData,
} = props;
const [addList, setAddList] = useState([]);
const [selectedList, setSelectedList] = useState([]);
const [selected, setSelect] = useState([]);
const a = [];
const formItemLayout = {
labelCol: {
span: 6,
},
wrapperCol: {
span: 16,
},
};
const getAreaList = async () => {
if (!addList.length) {
const data = await areaList();
const newData = [];
data.map(item =>
newData.push({
label: item.addrName,
value: item.addrId,
addressId: item.addrId,
addressLevel: item.addrLevel,
isLeaf: item.addrLevel === 4,
}),
);
setAddList(newData);
}
};
const onChange = (value, selectedOptions) => {
setSelect([...selectedOptions]);
};
// 加载
const loadData = async selectedOptions => {
const targetOption = selectedOptions.slice(-1)[0];
targetOption.loading = true;
const data = await areaList({ parentId: targetOption.addressId });
if (!data.length) {
targetOption.loading = false;
} else {
const newData = [];
data.map(itemData =>
newData.push({
label: itemData.addrName,
value: itemData.addrId,
addressId: itemData.addrId,
addressLevel: itemData.addrLevel,
// isLeaf: itemData.addrLevel === 4,
isLeaf: false,
}),
);
targetOption.children = newData;
}
targetOption.loading = false;
setAddList([...addList]);
};
// 限制区域删除
const preventDefault = val => {
const newArr = selectedList.filter(item => item !== val);
setSelectedList([...newArr]);
};
const onCancel = () => {
setSelectedList([]);
resetFields();
setSelect([]);
props.onSubmit();
};
const handleOk = async () => {
const { length } = selectedList;
// if (!selectedList.length) {
// notification.error({ message: '请选择限制区域!' });
// return;
// }
validateFields(async (error, fieldsValue) => {
const newData = [];
selectedList.map(itemData =>
newData.push({
addressId: itemData.addressId,
addressLevel: itemData.addressLevel,
addressName: itemData.addressName,
}),
);
if (!error) {
if (props.templateData.status) {
const data = await forbiddenAddress({
templateId: props.templateData.id,
templateName: fieldsValue.templateName,
areaList: newData,
});
if (data.businessCode === '0000') {
notification.success({ message: '编辑成功!' });
onCancel();
}
} else {
const data = await getAddTemplate({
templateName: fieldsValue.templateName,
areaList: newData,
});
if (data.businessCode === '0000') {
notification.success({ message: '添加成功!' });
onCancel();
}
}
}
});
};
// 判断是否重复
const getChilds = (data, { addressId }) => {
let flag = true;
const arr = [];
function judgeChildren(dat) {
// eslint-disable-next-line no-plusplus
for (let i = 0; i < dat.length; i++) {
const item = dat[i];
if (!flag) {
return;
}
if (+item.addressId === +addressId) {
flag = false;
}
// if (item.children && item.children.length) {
// judgeChildren(item.children);
// }
}
}
judgeChildren(data);
return flag;
};
const onPopupVisibleChange = labels => {
if (!labels && selected?.length) {
const select = selected.slice(-1)[0];
const arr = selected.map(x => x.label);
select.addressName = arr.join('/');
const staust = getChilds(selectedList, select);
if (staust) {
selectedList.push(select);
// 用中文字符排序
const resultArray = selectedList.sort((param1, param2) =>
param1.addressName.localeCompare(param2.addressName, 'zh'),
);
setSelectedList([...resultArray]);
setSelect([]);
}
}
};
useEffect(() => {
getAreaList();
if (props.templateData) {
setSelectedList(props.templateData.list);
}
}, [props.templateData]);
useEffect(() => {
// console.log(selectedList)
}, [selectedList]);
return (
<Modal
title={props.templateData.status ? '编辑限制区域配送模板' : '添加限制区域配送模板'}
visible={visible}
width="500px"
onCancel={() => onCancel()}
onOk={() => handleOk()}
>
<Form {...formItemLayout}>
<Form.Item label="模板名称">
{getFieldDecorator('templateName', {
rules: [{ required: true, message: '请输入模板名称!' }],
initialValue: templateData.templateName,
})(<Input placeholder="请填写模板名称" maxLength={20} />)}
</Form.Item>
<Form.Item label="限制配送区域">
{getFieldDecorator('name')(
<Cascader
options={addList}
loadData={loadData}
onChange={(val, label) => onChange(val, label)}
allowClear={false}
// expandTrigger="hover"
changeOnSelect
onPopupVisibleChange={onPopupVisibleChange}
/>,
)}
{selectedList?.map((selItem, selIndex) => (
<Tag closable key={selItem.addressId} onClose={() => preventDefault(selItem)}>
{selItem.addressName}
</Tag>
))}
</Form.Item>
</Form>
</Modal>
);
};
export default Form.create()(AddAreaModal);
import { Button, Tag, Popover } from 'antd';
import React from 'react';
import styles from './index.less';
export function columns(res) {
return [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 80,
align: 'center',
},
{
title: '名称',
dataIndex: 'templateName',
width: 200,
key: 'templateName',
align: 'center',
},
{
title: '地址',
dataIndex: 'areaNameList',
key: 'areaNameList',
align: 'center',
width: 500,
render: (_, row) => {
const data = row.areaNameList?.join(',');
const content = <p className={styles.content}>{data}</p>;
return (
<Popover content={content} title="不支持配送区域" trigger="hover">
<p className={styles.p}>{data}</p>
</Popover>
);
},
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
key: 'option',
align: 'center',
width: 100,
render: (_, row) => (
<div className={styles.option}>
<Button type="primary" onClick={() => res.edit(0, row)}>
复制
</Button>
<Button type="primary" onClick={() => res.edit(1, row)}>
编辑
</Button>
</div>
),
},
];
}
import { Button, Popconfirm, notification } from 'antd';
import React, { useRef, useEffect, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import { columns } from './data';
import AddArea from './addArea';
import { searchList, addressTree } from './services';
const TableList = () => {
const [visible, setVisible] = useState(false);
const [templateData, settemplateData] = useState('');
const actionRef = useRef();
const reload = () => {
setVisible(false);
if (actionRef.current) {
actionRef.current.reload();
}
};
const setaArea = () => {
setVisible(true);
settemplateData({ status: 0, list: [] });
};
const edit = async (status, { id, templateName }) => {
const data = await addressTree({ templateId: id });
if (data.businessCode === '0000') {
settemplateData({ status, list: data.data, id, templateName });
setVisible(true);
}
};
const res = {
edit,
};
useEffect(() => {}, []);
return (
<PageHeaderWrapper>
<ProTable
actionRef={actionRef}
columns={columns(res)}
request={searchList}
rowKey="id"
bordered
search={false}
options={false}
toolBarRender={() => [
<Button key="3" type="primary" onClick={setaArea}>
添加
</Button>,
]}
/>
<AddArea visible={visible} onSubmit={reload} templateData={templateData} />
</PageHeaderWrapper>
);
};
export default TableList;
.option {
display: flex;
align-items: center;
justify-content: space-evenly;
}
.p {
width: 450px;
margin: 0 auto;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.content {
width: 500px;
}
.option {
display: flex;
align-items: center;
justify-content: space-evenly;
}
.p {
width: 450px;
margin: 0 auto;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.content {
width: 500px;
}
import { stringify } from 'querystring';
import request from '@/utils/request';
import _ from 'lodash';
import config from '../../../config/env.config';
const { goodsApi } = config;
// 分页查询所有数据
export async function searchList(params) {
const param = {
pageNo: params.current || 1,
pageSize: params.pageSize || 20,
};
const data = await request.post('/api/kdsp/template/page', {
prefix: goodsApi,
data: stringify(_.omitBy(param, v => !v)),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
if (data.data) {
return {
total: data.data.total,
data: data.data.forbiddenAreaTemplateList,
};
}
return {
total: 0,
data: [],
};
}
// 添加区域受限模板
export async function getAddTemplate(param) {
const data = await request.post('/api/kdsp/add/template', {
prefix: goodsApi,
data: param,
});
return data;
}
// 获取区域地址
export async function areaList(params) {
const { data } = await request.get('/api/kdsp/area/addr/query', {
prefix: goodsApi,
params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
return data;
}
// 根据模板id查询受限区域
export async function forbiddenAddress(params) {
const data = await request.post('/api/kdsp/edit/template', {
prefix: goodsApi,
data: params,
});
return data;
}
// 根据模板id查询受限区域
export async function addressTree(params) {
const data = await request.post('/api/kdsp/forbidden/address', {
prefix: goodsApi,
params,
});
return data;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment