Commit 90658caf authored by luoxiaodong's avatar luoxiaodong

合并分支

parents 5dd50b67 6ae2b521
......@@ -158,6 +158,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": ".",
......
......@@ -15757,25 +15757,6 @@
"node": ">=0.10.0"
}
},
"node_modules/fork-ts-checker-webpack-plugin/node_modules/fsevents": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"dependencies": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
},
"engines": {
"node": ">= 4.0"
}
},
"node_modules/fork-ts-checker-webpack-plugin/node_modules/glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
......@@ -15930,19 +15911,6 @@
"resolved": "http://npmprivate.quantgroups.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "http://npmprivate.quantgroups.com/function-bind/-/function-bind-1.1.1.tgz",
......@@ -19403,25 +19371,6 @@
"node": ">=6"
}
},
"node_modules/jest-environment-jsdom-fourteen/node_modules/fsevents": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"dependencies": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
},
"engines": {
"node": ">= 4.0"
}
},
"node_modules/jest-environment-jsdom-fourteen/node_modules/html-encoding-sniffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
......@@ -44553,8 +44502,7 @@
"dev": true
},
"bindings": {
"version": "1.5.0",
"resolved": "http://npmprivate.quantgroups.com/bindings/-/bindings-1.5.0.tgz",
"version": "http://npmprivate.quantgroups.com/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"optional": true,
......@@ -48659,17 +48607,6 @@
"to-regex-range": "^2.1.0"
}
},
"fsevents": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
......@@ -48792,12 +48729,6 @@
"resolved": "http://npmprivate.quantgroups.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "http://npmprivate.quantgroups.com/function-bind/-/function-bind-1.1.1.tgz",
......@@ -51570,17 +51501,6 @@
"locate-path": "^3.0.0"
}
},
"fsevents": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"html-encoding-sniffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
......@@ -55632,8 +55552,7 @@
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
},
"nan": {
"version": "2.14.2",
"resolved": "http://npmprivate.quantgroups.com/nan/-/nan-2.14.2.tgz",
"version": "http://npmprivate.quantgroups.com/nan/-/nan-2.14.2.tgz",
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
"dev": true,
"optional": true
......@@ -6,7 +6,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;
......@@ -44,6 +43,10 @@ class goodsManage extends Component {
this.props.addSpu();
};
setArea = isAll => {
this.props.setArea(isAll);
};
render() {
const { treeData } = this.props;
const selectW = { width: 250 };
......@@ -134,6 +137,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);
......@@ -603,7 +603,7 @@ class goodsManage extends Component {
})(
<Input
style={{ width: 690 }}
maxLength="100"
maxLength={100}
placeholder="请输入商品名称"
allowClear
/>,
......
......@@ -9,12 +9,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,
......@@ -30,10 +30,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;
......@@ -87,10 +90,6 @@ class goodsManage extends Component {
);
};
onSelectChange = selectedRowKeys => {
this.setState({ selectedRowKeys });
};
onReset = () => {
this.setState({
pageNo: 1,
......@@ -175,6 +174,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));
......@@ -237,10 +253,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>
......@@ -250,13 +277,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}>
......@@ -268,6 +295,7 @@ class goodsManage extends Component {
pagination={false}
className={styles.tabletop}
scroll={{ x: '100%', y: 500 }}
rowSelection={rowSelection}
/>
</Spin>
<br />
......@@ -327,6 +355,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